diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/dummy.c linux-2.6.24.3-20100304/arch/mips/boot/compressed/dummy.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/dummy.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/compressed/dummy.c 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/head.S linux-2.6.24.3-20100304/arch/mips/boot/compressed/head.S --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/head.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/compressed/head.S 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,85 @@ +/* + * linux/arch/mips/boot/compressed/head.S + * + * Copyright (C) 2005-2008 Ingenic Semiconductor Inc. + */ + +#include +#include +#include +#include + +#define IndexInvalidate_I 0x00 +#define IndexWriteBack_D 0x01 + + .set noreorder + LEAF(startup) +startup: + move s0, a0 /* Save the boot loader transfered args */ + move s1, a1 + move s2, a2 + move s3, a3 + + la a0, _edata + la a1, _end +1: sw zero, 0(a0) /* Clear BSS section */ + bne a1, a0, 1b + addu a0, 4 + + la sp, (.stack + 8192) + + la a0, __image_begin + la a1, IMAGESIZE + la a2, LOADADDR + la ra, 1f + la k0, decompress_kernel + jr k0 + nop +1: + + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + li k0, KERNEL_ENTRY + jr k0 + nop +2: + b 32 + END(startup) + + + LEAF(flushcaches) + la t0, 1f + la t1, 0xa0000000 + or t0, t0, t1 + jr t0 + nop +1: + li k0, 0x80000000 # start address + li k1, 0x80004000 # end address (16KB I-Cache) + subu k1, 128 + +2: + .set mips3 + cache IndexWriteBack_D, 0(k0) + cache IndexWriteBack_D, 32(k0) + cache IndexWriteBack_D, 64(k0) + cache IndexWriteBack_D, 96(k0) + cache IndexInvalidate_I, 0(k0) + cache IndexInvalidate_I, 32(k0) + cache IndexInvalidate_I, 64(k0) + cache IndexInvalidate_I, 96(k0) + .set mips0 + + bne k0, k1, 2b + addu k0, k0, 128 + la t0, 3f + jr t0 + nop +3: + jr ra + nop + END(flushcaches) + + .comm .stack,4096*2,4 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/ld.script linux-2.6.24.3-20100304/arch/mips/boot/compressed/ld.script --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/ld.script 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/compressed/ld.script 2010-03-03 19:05:06.000000000 -0800 @@ -0,0 +1,151 @@ +OUTPUT_ARCH(mips) +ENTRY(startup) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __ramdisk_begin = .; + *(.initrd) + __ramdisk_end = .; + . = ALIGN(4096); + + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/Makefile linux-2.6.24.3-20100304/arch/mips/boot/compressed/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/compressed/Makefile 2010-03-03 19:05:06.000000000 -0800 @@ -0,0 +1,42 @@ +# +# linux/arch/mips/boot/compressed/Makefile +# +# create a compressed zImage from the original vmlinux +# + +targets := zImage vmlinuz vmlinux.bin.gz head.o misc.o piggy.o dummy.o + +OBJS := $(obj)/head.o $(obj)/misc.o + +LD_ARGS := -T $(obj)/ld.script -Ttext 0x80600000 -Bstatic +OBJCOPY_ARGS := -O elf32-tradlittlemips + +ENTRY := $(obj)/../tools/entry +FILESIZE := $(obj)/../tools/filesize + +drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + + +$(obj)/vmlinux.bin.gz: vmlinux + rm -f $(obj)/vmlinux.bin.gz + $(OBJCOPY) -O binary $(strip-flags) vmlinux $(obj)/vmlinux.bin + gzip -v9f $(obj)/vmlinux.bin + +$(obj)/head.o: $(obj)/head.S $(obj)/vmlinux.bin.gz vmlinux + $(CC) $(KBUILD_AFLAGS) -Iinclude \ + -DIMAGESIZE=$(shell sh $(FILESIZE) $(obj)/vmlinux.bin.gz) \ + -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) vmlinux ) \ + -DLOADADDR=$(loadaddr) \ + -c -o $(obj)/head.o $< + +$(obj)/vmlinuz: $(OBJS) $(obj)/ld.script $(obj)/vmlinux.bin.gz $(obj)/dummy.o + $(OBJCOPY) \ + --add-section=.image=$(obj)/vmlinux.bin.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/dummy.o $(obj)/piggy.o + $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/piggy.o + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap + +zImage: $(obj)/vmlinuz + $(OBJCOPY) -O binary $(obj)/vmlinuz $(obj)/zImage diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/misc.c linux-2.6.24.3-20100304/arch/mips/boot/compressed/misc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/compressed/misc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/compressed/misc.c 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,242 @@ +/* + * linux/arch/mips/boot/compressed/misc.c + * + * This is a collection of several routines from gzip-1.0.3 + * adapted for Linux. + * + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + * + * Adapted for JZSOC by Peter Wei, 2008 + * + */ + +#define size_t int +#define NULL 0 + +/* + * gzip declarations + */ + +#define OF(args) args +#define STATIC static + +#undef memset +#undef memcpy +#define memzero(s, n) memset ((s), 0, (n)) + +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 = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* 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);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +void* memset(void* s, int c, size_t n); +void* memcpy(void* __dest, __const void* __src, size_t __n); + +extern void flushcaches(void); /* defined in head.S */ + +char *input_data; +int input_len; + +static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; + + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +static void puts(const char *str) +{ +} + +extern unsigned char _end[]; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#define HEAP_SIZE 0x10000 + +#include "../../../../lib/inflate.c" + +static void *malloc(int size) +{ + void *p; + + if (size <0) error("Malloc error\n"); + if (free_mem_ptr == 0) error("Memory error\n"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *)free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_end_ptr) + error("\nOut of memory\n"); + + return p; +} + +static void free(void *where) +{ /* Don't care */ +} + +static void gzip_mark(void **ptr) +{ + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + free_mem_ptr = (long) *ptr; +} + +void* memset(void* s, int c, size_t n) +{ + int i; + char *ss = (char*)s; + + for (i=0;i> 3; i > 0; i--) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1 << 2) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1 << 1) { + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1) + *d++ = *s++; + + return __dest; +} + +/* =========================================================================== + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf(void) +{ + if (insize != 0) { + error("ran out of input data\n"); + } + + inbuf = input_data; + insize = input_len; + inptr = 1; + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window(void) +{ + ulg c = crc; /* temporary variable */ + 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; +} + +static void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +void decompress_kernel(unsigned int imageaddr, unsigned int imagesize, unsigned int loadaddr) +{ + input_data = (char *)imageaddr; + input_len = imagesize; + output_ptr = 0; + output_data = (uch *)loadaddr; + free_mem_ptr = (unsigned long)_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + + makecrc(); + puts("Uncompressing Linux..."); + gunzip(); + flushcaches(); + puts("Ok, booting the kernel."); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/Makefile linux-2.6.24.3-20100304/arch/mips/boot/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/Makefile 2010-03-03 19:05:05.000000000 -0800 @@ -7,6 +7,9 @@ # Copyright (C) 2004 Maciej W. Rozycki # +# This one must match the LOADADDR in arch/mips/Makefile! +LOADADDR=0x80010000 + # # Some DECstations need all possible sections of an ECOFF executable # @@ -25,7 +28,7 @@ VMLINUX = vmlinux -all: vmlinux.ecoff vmlinux.srec addinitrd +all: vmlinux.ecoff vmlinux.srec addinitrd uImage zImage vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS) @@ -42,8 +45,24 @@ $(obj)/addinitrd: $(obj)/addinitrd.c $(HOSTCC) -o $@ $^ +uImage: $(VMLINUX) vmlinux.bin + rm -f $(obj)/vmlinux.bin.gz + gzip -9 $(obj)/vmlinux.bin + mkimage -A mips -O linux -T kernel -C gzip \ + -a $(LOADADDR) -e $(shell sh ./$(obj)/tools/entry $(NM) $(VMLINUX) ) \ + -n 'Linux-$(KERNELRELEASE)' \ + -d $(obj)/vmlinux.bin.gz $(obj)/uImage + @echo ' Kernel: arch/mips/boot/$@ is ready' + +zImage: + $(Q)$(MAKE) $(build)=$(obj)/compressed loadaddr=$(LOADADDR) $@ + @echo ' Kernel: arch/mips/boot/compressed/$@ is ready' + clean-files += addinitrd \ elf2ecoff \ vmlinux.bin \ vmlinux.ecoff \ - vmlinux.srec + vmlinux.srec \ + vmlinux.bin.gz \ + uImage \ + zImage diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/tools/entry linux-2.6.24.3-20100304/arch/mips/boot/tools/entry --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/tools/entry 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/tools/entry 2010-03-03 19:05:06.000000000 -0800 @@ -0,0 +1,12 @@ +#!/bin/sh + +# grab the kernel_entry address from the vmlinux elf image +entry=`$1 $2 | grep kernel_entry` + +fs=`echo $entry | grep ffffffff` # check toolchain output + +if [ -n "$fs" ]; then + echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` +else + echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` +fi diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/tools/filesize linux-2.6.24.3-20100304/arch/mips/boot/tools/filesize --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/boot/tools/filesize 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/boot/tools/filesize 2010-03-03 19:05:06.000000000 -0800 @@ -0,0 +1,7 @@ +#!/bin/sh +HOSTNAME=`uname` +if [ "$HOSTNAME" = "Linux" ]; then +echo `ls -l $1 | awk '{print $5}'` +else +echo `ls -l $1 | awk '{print $6}'` +fi diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/apus_defconfig linux-2.6.24.3-20100304/arch/mips/configs/apus_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/apus_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/apus_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1249 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Fri Feb 26 12:21:57 2010 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +CONFIG_JZ4750_APUS=y +# CONFIG_JZ4750D_CETUS is not set +# CONFIG_JZ4750L_F4750L is not set +# CONFIG_JZ4750L_VOLANS is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# 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=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4750=y +CONFIG_MTD_NAND_CS2=y +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +CONFIG_MTD_NAND_MULTI_PLANE=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +# CONFIG_MTD_HW_BCH_4BIT is not set +CONFIG_MTD_HW_BCH_8BIT=y +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_DMABUF is not set +# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZCS8900=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_JZ is not set +# CONFIG_5x5_KEYBOARD_JZ is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_JZ=y +# CONFIG_JZ_ADKEY is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_INGENIC is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +# CONFIG_JZ_UDC_HOTPLUG is not set +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +CONFIG_JZ_TCSM=y +# CONFIG_JZ_TSSI is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +CONFIG_FB_JZ4750_LCD=y +# CONFIG_FB_JZ4750_LCD_USE_2LAYER_FRAMEBUFFER is not set +CONFIG_FB_JZ4750_TVE=y +# CONFIG_IPU_JZ4750 is not set +# CONFIG_FB_JZ4750_SLCD is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF01 is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF02 is not set +CONFIG_JZ4750_LCD_AUO_A043FL01V2=y +# CONFIG_JZ4750_LCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZ4750_LCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD025THEA7_RGB_DELTA is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD043MGEB1 is not set +# CONFIG_JZ4750_LCD_TRULY_TFTG320240DTSW_18BIT is not set +# CONFIG_JZ4750_LCD_TRULY_TFT_GG1P0319LTSW_W is not set +# CONFIG_JZ4750_SLCD_KGM701A3_TFT_SPFD5420A is not set +# CONFIG_JZ4750D_VGA_DISPLAY is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_SOUND_JZ_PCM is not set +# CONFIG_I2S_AK4642EN is not set +# CONFIG_I2S_ICODEC is not set +CONFIG_I2S_DLV=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_JZ4740 is not set +CONFIG_USB_GADGET_JZ4750=y +CONFIG_USB_JZ4750=m +# CONFIG_USB_GADGET_JZ4750D is not set +# CONFIG_USB_GADGET_JZ4750L is not set +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_UDC_USE_LB_CACHE=y +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MSC0_JZ4750=y +# CONFIG_JZ4750_MSC0_BUS_1 is not set +CONFIG_JZ4750_MSC0_BUS_4=y +# CONFIG_JZ4750_MSC0_BUS_8 is not set +# CONFIG_MSC1_JZ4750 is not set +# CONFIG_JZ4750_BOOT_FROM_MSC0 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/cetus_defconfig linux-2.6.24.3-20100304/arch/mips/configs/cetus_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/cetus_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/cetus_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1062 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Fri Feb 26 12:22:38 2010 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +# CONFIG_JZ4750_APUS is not set +CONFIG_JZ4750D_CETUS=y +# CONFIG_JZ4750L_F4750L is not set +# CONFIG_JZ4750L_VOLANS is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750D=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4750=y +# CONFIG_MTD_NAND_CS2 is not set +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +CONFIG_MTD_NAND_MULTI_PLANE=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +# CONFIG_MTD_HW_BCH_4BIT is not set +CONFIG_MTD_HW_BCH_8BIT=y +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_DMABUF is not set +CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY=y +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_JZ=y +# CONFIG_JZ_ADKEY is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_INGENIC is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +# CONFIG_JZ_UDC_HOTPLUG is not set +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +CONFIG_JZ_TCSM=y +# CONFIG_JZ_TSSI is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +CONFIG_FB_JZ4750_LCD=y +# CONFIG_FB_JZ4750_LCD_USE_2LAYER_FRAMEBUFFER is not set +CONFIG_FB_JZ4750_TVE=y +# CONFIG_IPU_JZ4750 is not set +# CONFIG_FB_JZ4750_SLCD is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF01 is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF02 is not set +CONFIG_JZ4750_LCD_AUO_A043FL01V2=y +# CONFIG_JZ4750_LCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZ4750_LCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD025THEA7_RGB_DELTA is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD043MGEB1 is not set +# CONFIG_JZ4750_LCD_TRULY_TFTG320240DTSW_18BIT is not set +# CONFIG_JZ4750_LCD_TRULY_TFT_GG1P0319LTSW_W is not set +# CONFIG_JZ4750_SLCD_KGM701A3_TFT_SPFD5420A is not set +# CONFIG_JZ4750D_VGA_DISPLAY is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_I2S_AK4642EN is not set +# CONFIG_I2S_ICODEC is not set +CONFIG_I2S_DLV=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_JZ4740 is not set +# CONFIG_USB_GADGET_JZ4750 is not set +CONFIG_USB_GADGET_JZ4750D=y +CONFIG_USB_JZ4750D=m +# CONFIG_USB_GADGET_JZ4750L is not set +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_UDC_USE_LB_CACHE=y +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MSC0_JZ4750 is not set +CONFIG_MSC1_JZ4750=y +# CONFIG_JZ4750_MSC1_BUS_1 is not set +CONFIG_JZ4750_MSC1_BUS_4=y +# CONFIG_JZ4750_BOOT_FROM_MSC0 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/dipper_defconfig linux-2.6.24.3-20100304/arch/mips/configs/dipper_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/dipper_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/dipper_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1281 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Jun 12 13:55:45 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +CONFIG_JZ4725_DIPPER=y +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4740=y +CONFIG_SOC_JZ4725=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4740=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +CONFIG_MTD_HW_RS_ECC=y +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=0 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=256 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_BLKDEVS=m +CONFIG_MTD_UBI_BLOCK=m +# CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_PNPACPI is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZCS8900=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +CONFIG_JZ_TPANEL=y +CONFIG_JZ_SADC=y +# CONFIG_JZ_TPANEL_AK4182 is not set +# CONFIG_JZ_TPANEL_UCB1400 is not set +# CONFIG_JZ_TPANEL_WM9712 is not set +CONFIG_JZ_UDC_HOTPLUG=y +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_VIDEO_JZ_CIM=y +CONFIG_VIDEO_JZ_SENSOR=y +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +# CONFIG_FB_JZ4740_SLCD is not set +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set +CONFIG_JZLCD_SAMSUNG_LTP400WQF02=y +# CONFIG_JZLCD_AUO_A030FL01_V1 is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_SOUND_JZ_PCM is not set +# CONFIG_I2S_AK4642EN is not set +CONFIG_I2S_ICODEC=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_JZ4740=y +CONFIG_USB_JZ4740=m +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_JZ=y +# CONFIG_JZ_MMC_BUS_4 is not set +CONFIG_JZ_MMC_BUS_1=y +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/f4750l_defconfig linux-2.6.24.3-20100304/arch/mips/configs/f4750l_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/f4750l_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/f4750l_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,981 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Tue May 26 18:04:53 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +# CONFIG_JZ4750_APUS is not set +# CONFIG_JZ4750D_CETUS is not set +CONFIG_JZ4750L_F4750L=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750L=y +CONFIG_JZ_FPGA=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZ_ETH=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ 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 + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +CONFIG_FB_JZ4750_LCD=y +# CONFIG_FB_JZ4750_LCD_USE_2LAYER_FRAMEBUFFER is not set +# CONFIG_FB_JZ4750_TVE is not set +# CONFIG_IPU_JZ4750 is not set +# CONFIG_FB_JZ4750_SLCD is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF01 is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF02 is not set +CONFIG_JZ4750_LCD_AUO_A043FL01V2=y +# CONFIG_JZ4750_LCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZ4750_LCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD025THEA7_RGB_DELTA is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD043MGEB1 is not set +# CONFIG_JZ4750_LCD_TRULY_TFTG320240DTSW_18BIT is not set +# CONFIG_JZ4750_LCD_TRULY_TFT_GG1P0319LTSW_W is not set +# CONFIG_JZ4750_SLCD_KGM701A3_TFT_SPFD5420A is not set +# CONFIG_JZ4750D_VGA_DISPLAY is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_I2S_AK4642EN is not set +# CONFIG_I2S_ICODEC is not set +# CONFIG_I2S_DLV is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_JZ4740 is not set +# CONFIG_USB_GADGET_JZ4750 is not set +# CONFIG_USB_GADGET_JZ4750D is not set +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_M66592=y +CONFIG_USB_M66592=m +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/fuwa1_defconfig linux-2.6.24.3-20100304/arch/mips/configs/fuwa1_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/fuwa1_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/fuwa1_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1029 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Wed Apr 1 14:00:33 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +CONFIG_JZ4750D_FUWA1=y +# CONFIG_JZ4750_APUS is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750D=y +CONFIG_JZ_FPGA=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_SYS_HAS_EARLY_PRINTK is not set +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4750=y +# CONFIG_MTD_NAND_CS2 is not set +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +# CONFIG_MTD_NAND_MULTI_PLANE is not set +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +CONFIG_MTD_HW_BCH_4BIT=y +# CONFIG_MTD_HW_BCH_8BIT is not set +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_DMABUF is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +# CONFIG_JZ_TPANEL is not set +# CONFIG_JZ_UDC_HOTPLUG is not set +# CONFIG_JZ_POWEROFF is not set +# CONFIG_JZ_OW is not set +CONFIG_JZ_TCSM=y +# CONFIG_JZ_TSSI is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +CONFIG_FB_JZ4750_TVE=y +# CONFIG_IPU_JZ4750 is not set +CONFIG_FB_JZ4750_LCD=y +# CONFIG_FB_JZ4750_LCD_USE_2LAYER_FRAMEBUFFER is not set +# CONFIG_FB_JZ4750_SLCD is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF01 is not set +# CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF02 is not set +CONFIG_JZ4750_LCD_AUO_A043FL01V2=y +# CONFIG_JZ4750_LCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZ4750_LCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD025THEA7_RGB_DELTA is not set +# CONFIG_JZ4750_LCD_TOPPOLY_TD043MGEB1 is not set +# CONFIG_JZ4750_LCD_TRULY_TFTG320240DTSW_18BIT is not set +# CONFIG_JZ4750_LCD_TRULY_TFT_GG1P0319LTSW_W is not set +# CONFIG_JZ4750_SLCD_KGM701A3_TFT_SPFD5420A is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_I2S_AK4642EN is not set +# CONFIG_I2S_ICODEC is not set +CONFIG_I2S_DLV=y +# CONFIG_I2S_NULL is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_JZ4740 is not set +CONFIG_USB_GADGET_JZ4750=y +CONFIG_USB_JZ4750=m +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_UDC_USE_LB_CACHE=y +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MSC0_JZ4750 is not set +CONFIG_MSC1_JZ4750=y +# CONFIG_JZ4750_MSC1_BUS_1 is not set +CONFIG_JZ4750_MSC1_BUS_4=y +# CONFIG_JZ4750_BOOT_FROM_MSC0 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/fuwa_defconfig linux-2.6.24.3-20100304/arch/mips/configs/fuwa_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/fuwa_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/fuwa_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,928 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Fri Jul 4 19:20:22 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +CONFIG_JZ4750_FUWA=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750=y +CONFIG_JZ_FPGA=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4750=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_NO_DMA is not set +CONFIG_MTD_HW_BCH_4BIT=y +# CONFIG_MTD_HW_BCH_8BIT is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=0 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZ_ETH=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +# CONFIG_JZCHAR is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/leo_defconfig linux-2.6.24.3-20100304/arch/mips/configs/leo_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/leo_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/leo_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1256 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Jun 12 13:59:18 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +CONFIG_JZ4740_LEO=y +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4740=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=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_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLOCK2MTD=y + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4740=y +# CONFIG_MTD_HW_HM_ECC is not set +CONFIG_MTD_SW_HM_ECC=y +# CONFIG_MTD_HW_RS_ECC is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=0 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_BLKDEVS=m +CONFIG_MTD_UBI_BLOCK=m +# CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_PNPACPI is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# 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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +CONFIG_JZ_TPANEL=y +CONFIG_JZ_SADC=y +# CONFIG_JZ_TPANEL_AK4182 is not set +# CONFIG_JZ_TPANEL_UCB1400 is not set +# CONFIG_JZ_TPANEL_WM9712 is not set +CONFIG_JZ_UDC_HOTPLUG=y +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_VIDEO_JZ_CIM=y +CONFIG_VIDEO_JZ_SENSOR=y +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +# CONFIG_FB_JZ4740_SLCD is not set +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set +CONFIG_JZLCD_SAMSUNG_LTP400WQF02=y +# CONFIG_JZLCD_AUO_A030FL01_V1 is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA MIPS devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +CONFIG_SND_SOC=y + +# +# SoC Audio support for SuperH +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_JZ4740=y +CONFIG_USB_JZ4740=m +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_FILE_STORAGE_TEST=y +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_JZ=y +CONFIG_JZ_MMC_BUS_4=y +# CONFIG_JZ_MMC_BUS_1 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_DEBUG=y +CONFIG_UBIFS_FS_DEBUG_MSG_LVL=0 +# CONFIG_UBIFS_FS_DEBUG_CHKS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/lyra_defconfig linux-2.6.24.3-20100304/arch/mips/configs/lyra_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/lyra_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/lyra_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,981 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Jun 12 13:53:57 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +CONFIG_JZ4740_LYRA=y +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4740=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=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_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y + +# +# Networking +# +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLOCK2MTD=y + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4740=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +CONFIG_MTD_HW_RS_ECC=y +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_SCSI_DEBUG 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 + +# +# 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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +CONFIG_JZ_TPANEL_ATA2508=y +# CONFIG_JZ_TPANEL is not set +CONFIG_JZ_UDC_HOTPLUG=y +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +# CONFIG_FB_JZ4740_SLCD is not set +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF02 is not set +CONFIG_JZLCD_AUO_A030FL01_V1=y +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_SOUND_JZ_PCM is not set +# CONFIG_I2S_AK4642EN is not set +CONFIG_I2S_ICODEC=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +CONFIG_USB_GADGET_DEBUG_FILES=y +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_JZ4740=y +CONFIG_USB_JZ4740=m +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MMC_JZ is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_DEBUG=y +CONFIG_UBIFS_FS_DEBUG_MSG_LVL=0 +# CONFIG_UBIFS_FS_DEBUG_CHKS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/pavo_defconfig linux-2.6.24.3-20100304/arch/mips/configs/pavo_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/pavo_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/pavo_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1311 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Fri Feb 26 12:21:15 2010 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +CONFIG_JZ4740_PAVO=y +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +# CONFIG_JZ4750_APUS is not set +# CONFIG_JZ4750D_CETUS is not set +# CONFIG_JZ4750L_F4750L is not set +# CONFIG_JZ4750L_VOLANS is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4740=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=12 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4740=y +# CONFIG_MTD_NAND_CS2 is not set +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +CONFIG_MTD_NAND_MULTI_PLANE=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +CONFIG_MTD_HW_RS_ECC=y +# CONFIG_MTD_HW_BCH_ECC is not set +# CONFIG_MTD_NAND_DMA is not set +# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=256 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_BLKDEVS=m +CONFIG_MTD_UBI_BLOCK=m +# CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_PNPACPI is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZCS8900=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_JZ=y +# CONFIG_JZ_ADKEY is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_INGENIC is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +CONFIG_JZ_UDC_HOTPLUG=y +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_JZ_TCSM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_JZ4740_CIM is not set +CONFIG_VIDEO_JZ_SENSOR=y +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +# CONFIG_FB_JZ4740_SLCD is not set +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set +CONFIG_JZLCD_SAMSUNG_LTP400WQF02=y +# CONFIG_JZLCD_AUO_A030FL01_V1 is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_I2S_AK4642EN is not set +CONFIG_I2S_ICODEC=y +# CONFIG_I2S_DLV is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_JZ4740=y +CONFIG_USB_JZ4740=m +# CONFIG_USB_GADGET_JZ4750 is not set +# CONFIG_USB_GADGET_JZ4750D is not set +# CONFIG_USB_GADGET_JZ4750L is not set +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_UDC_USE_LB_CACHE=y +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_JZ=y +# CONFIG_JZ_MMC_BUS_1 is not set +CONFIG_JZ_MMC_BUS_4=y +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_ECC_RS=y +# CONFIG_YAFFS_ECC_HAMMING is not set +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/pmp_defconfig linux-2.6.24.3-20100304/arch/mips/configs/pmp_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/pmp_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/pmp_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1212 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Jun 12 13:37:10 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +CONFIG_JZ4730_PMP=y +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4730=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4730=y +CONFIG_MTD_HW_HM_ECC=y +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=0 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZ_ETH=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +CONFIG_RTC_PCF8563=y +# CONFIG_RTC_JZ is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +CONFIG_JZ_TPANEL=y +# CONFIG_JZ_SADC is not set +CONFIG_JZ_TPANEL_AK4182=y +# CONFIG_JZ_TPANEL_UCB1400 is not set +# CONFIG_JZ_TPANEL_WM9712 is not set +# CONFIG_JZ_UDC_HOTPLUG is not set +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +# CONFIG_VIDEO_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_JZ_CIM=m +CONFIG_VIDEO_JZ_SENSOR=m +# CONFIG_V4L_USB_DRIVERS is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +CONFIG_JZLCD_SAMSUNG_LTP400WQF01=y +# CONFIG_JZLCD_SAMSUNG_LTP400WQF02 is not set +# CONFIG_JZLCD_AUO_A030FL01_V1 is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_JZ4740 is not set +CONFIG_USB_GADGET_JZ4730=y +CONFIG_USB_JZ4730=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_JZ=y +CONFIG_JZ_MMC_BUS_4=y +# CONFIG_JZ_MMC_BUS_1 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_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 is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/slt50_defconfig linux-2.6.24.3-20100304/arch/mips/configs/slt50_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/slt50_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/slt50_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1036 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Tue Nov 25 09:38:56 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750_APUS is not set +CONFIG_JZ4750_SLT50=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4750=y +# CONFIG_MTD_NAND_CS2 is not set +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +# CONFIG_MTD_NAND_MULTI_PLANE is not set +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +CONFIG_MTD_HW_BCH_4BIT=y +# CONFIG_MTD_HW_BCH_8BIT is not set +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_DMABUF is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# 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 is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_JZ is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +# CONFIG_JZ_TPANEL is not set +CONFIG_JZ_UDC_HOTPLUG=y +# CONFIG_JZ_POWEROFF is not set +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +# CONFIG_YAFFS_ECC_BCH is not set +CONFIG_YAFFS_ECC_RS=y +# CONFIG_YAFFS_ECC_HAMMING is not set +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/virgo_defconfig linux-2.6.24.3-20100304/arch/mips/configs/virgo_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/virgo_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/virgo_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,1281 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Jun 12 13:52:15 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +CONFIG_JZ4720_VIRGO=y +# CONFIG_JZ4750_FUWA is not set +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4740=y +CONFIG_SOC_JZ4720=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ_JZ=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_JZ4740=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +CONFIG_MTD_HW_RS_ECC=y +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=256 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_BLKDEVS=m +CONFIG_MTD_UBI_BLOCK=m +# CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +# CONFIG_PNPACPI is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_JZCS8900=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=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 is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +CONFIG_RTC_JZ=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set + +# +# JZSOC char device support +# +CONFIG_JZCHAR=y +# CONFIG_JZ_CIM is not set +# CONFIG_JZ_TPANEL_ATA2508 is not set +CONFIG_JZ_TPANEL=y +CONFIG_JZ_SADC=y +# CONFIG_JZ_TPANEL_AK4182 is not set +# CONFIG_JZ_TPANEL_UCB1400 is not set +# CONFIG_JZ_TPANEL_WM9712 is not set +CONFIG_JZ_UDC_HOTPLUG=y +CONFIG_JZ_POWEROFF=y +# CONFIG_JZ_OW is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_JZ_WDT=y +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_VIDEO_JZ_CIM=y +CONFIG_VIDEO_JZ_SENSOR=y +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_JZSOC=y +# CONFIG_FB_JZ4740_SLCD is not set +CONFIG_FB_JZLCD_4730_4740=y +CONFIG_JZLCD_FRAMEBUFFER_MAX=1 +# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set +# CONFIG_JZLCD_SHARP_LQ035Q7 is not set +# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set +# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set +# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set +CONFIG_JZLCD_SAMSUNG_LTP400WQF02=y +# CONFIG_JZLCD_AUO_A030FL01_V1 is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set +# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set +# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set +# CONFIG_JZLCD_FOXCONN_PT035TN01 is not set +# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set +# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set +# CONFIG_JZLCD_HYNIX_HT10X21 is not set +# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set +# CONFIG_JZLCD_CSTN_800x600 is not set +# CONFIG_JZLCD_CSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_480x320 is not set +# CONFIG_JZLCD_MSTN_320x240 is not set +# CONFIG_JZLCD_MSTN_240x128 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +CONFIG_OSS_OBSOLETE=y +# CONFIG_SOUND_JZ_AC97 is not set +CONFIG_SOUND_JZ_I2S=y +# CONFIG_SOUND_JZ_PCM is not set +# CONFIG_I2S_AK4642EN is not set +CONFIG_I2S_ICODEC=y +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_JZ4740=y +CONFIG_USB_JZ4740=m +# CONFIG_USB_GADGET_JZ4730 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_JZ=y +CONFIG_JZ_MMC_BUS_4=y +# CONFIG_JZ_MMC_BUS_1 is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/volans_512nand_defconfig linux-2.6.24.3-20100304/arch/mips/configs/volans_512nand_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/volans_512nand_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/volans_512nand_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,910 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Thu Dec 24 16:24:05 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +# CONFIG_JZ4750_APUS is not set +# CONFIG_JZ4750D_CETUS is not set +# CONFIG_JZ4750L_F4750L is not set +CONFIG_JZ4750L_VOLANS=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750L=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4750=y +# CONFIG_MTD_NAND_CS2 is not set +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +# CONFIG_MTD_NAND_MULTI_PLANE is not set +# CONFIG_MTD_HW_HM_ECC is not set +CONFIG_MTD_SW_HM_ECC=y +# CONFIG_MTD_HW_RS_ECC is not set +# CONFIG_MTD_HW_BCH_ECC is not set +# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=0 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_JZ=y +CONFIG_JZ_ADKEY=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_INGENIC is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ 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 + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +CONFIG_YAFFS_DOES_ECC=y +# CONFIG_YAFFS_ECC_WRONG_ORDER is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/volans_defconfig linux-2.6.24.3-20100304/arch/mips/configs/volans_defconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/configs/volans_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/configs/volans_defconfig 2010-03-03 19:05:05.000000000 -0800 @@ -0,0 +1,912 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.3 +# Tue Dec 22 12:08:28 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_JZ4730_PMP is not set +# CONFIG_JZ4740_PAVO is not set +# CONFIG_JZ4740_LEO is not set +# CONFIG_JZ4740_LYRA is not set +# CONFIG_JZ4725_DIPPER is not set +# CONFIG_JZ4720_VIRGO is not set +# CONFIG_JZ4750_FUWA is not set +# CONFIG_JZ4750D_FUWA1 is not set +# CONFIG_JZ4750_APUS is not set +# CONFIG_JZ4750D_CETUS is not set +# CONFIG_JZ4750L_F4750L is not set +CONFIG_JZ4750L_VOLANS=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_SOC_JZ4750L=y +CONFIG_JZSOC=y +CONFIG_JZRISC=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ_JZ is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_JZ4750=y +CONFIG_MTD_NAND_CS2=y +# CONFIG_MTD_NAND_CS3 is not set +# CONFIG_MTD_NAND_CS4 is not set +CONFIG_MTD_NAND_MULTI_PLANE=y +# CONFIG_MTD_HW_HM_ECC is not set +# CONFIG_MTD_SW_HM_ECC is not set +# CONFIG_MTD_HW_RS_ECC is not set +CONFIG_MTD_HW_BCH_ECC=y +CONFIG_MTD_HW_BCH_4BIT=y +# CONFIG_MTD_HW_BCH_8BIT is not set +CONFIG_MTD_NAND_DMA=y +# CONFIG_MTD_NAND_DMABUF is not set +# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set +# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set +CONFIG_MTD_OOB_COPIES=3 +CONFIG_MTD_BADBLOCK_FLAG_PAGE=127 +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_MTD_UBI_BLKDEVS is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN 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_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN 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 + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_JZ=y +CONFIG_JZ_ADKEY=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=2 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_PCF8563 is not set +# CONFIG_RTC_JZ 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 + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +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_OCFS2_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +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=y +# 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 +# CONFIG_DLM is not set + +# +# Yaffs2 Filesystems +# +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/board-pmp.c linux-2.6.24.3-20100304/arch/mips/jz4730/board-pmp.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/board-pmp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/board-pmp.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,109 @@ +/* + * linux/arch/mips/jz4730/board-pmp.c + * + * JZ4730 PMP board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned int count = 0; + + count ++; + count &= 1; + if (count) + __gpio_set_pin(GPIO_LED_EN); + else + __gpio_clear_pin(GPIO_LED_EN); +} + +static void pmp_timer_ack(void) +{ + static unsigned int count = 0; + count ++; + if (count % 100 == 0) { + count = 0; + dancing(); + } +} + +static void __init board_cpm_setup(void) +{ + __cpm_start_all(); +} + +static void __init board_gpio_setup(void) +{ + /* + * Most of the gpios have been setup in the bootloader. + */ + + __harb_usb0_uhc(); + __gpio_as_dma(); + __gpio_as_eth(); + __gpio_as_usb(); + __gpio_as_lcd_master(); +#if defined(CONFIG_I2S_AK4642EN) + __gpio_as_scc1(); +#endif +#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23) + __gpio_as_ssi(); +#endif + //__gpio_as_ac97(); +#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23) || defined(CONFIG_I2S_CS42L51) + __gpio_as_i2s_slave(); +#endif + __gpio_as_cim(); + __gpio_as_msc(); + + __gpio_as_output(GPIO_LED_EN); + __gpio_set_pin(GPIO_LED_EN); + + __gpio_as_output(GPIO_DISP_OFF_N); + __gpio_set_pin(GPIO_DISP_OFF_N); + __gpio_as_output(GPIO_PWM0); + __gpio_set_pin(GPIO_PWM0); + + __gpio_as_input(GPIO_RTC_IRQ); + __gpio_as_output(GPIO_USB_CLK_EN); + __gpio_set_pin(GPIO_USB_CLK_EN); + + __gpio_as_input(GPIO_CHARG_STAT); + __gpio_disable_pull(GPIO_CHARG_STAT); + + __gpio_as_input(GPIO_UDC_HOTPLUG); + __gpio_disable_pull(GPIO_UDC_HOTPLUG); + __gpio_disable_pull(54); /* fixed ic bug, the pull of gpio pin 86 is as pin 54 */ +} + +void __init jz_board_setup(void) +{ + printk("JZ4730 PMP board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = pmp_timer_ack; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/cpufreq.c linux-2.6.24.3-20100304/arch/mips/jz4730/cpufreq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/cpufreq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/cpufreq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,596 @@ + +/* + * linux/arch/mips/jz4730/cpufreq.c + * + * cpufreq driver for JZ4730 + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ + "cpufreq-jz4730", msg) + +#undef CHANGE_PLL + +#define PLL_UNCHANGED 0 +#define PLL_GOES_UP 1 +#define PLL_GOES_DOWN 2 + +#define PLL_WAIT_500NS (500*(__cpm_get_iclk()/1000000000)) + +/* Saved the boot-time parameters */ +static struct { + /* SDRAM parameters */ + unsigned int mclk; /* memory clock, KHz */ + unsigned int tras; /* RAS pulse width, cycles of mclk */ + unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ + unsigned int tpc; /* RAS Precharge time, cycles of mclk */ + unsigned int trwl; /* Write Precharge Time, cycles of mclk */ + unsigned int trc; /* RAS Cycle Time, cycles of mclk */ + unsigned int rtcor; /* Refresh Time Constant */ + unsigned int sdram_initialized; + + /* LCD parameters */ + unsigned int lcd_clk; /* LCD clock, Hz */ + unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ + unsigned int lcd_clks_initialized; +} boot_config; + +struct jz4730_freq_percpu_info { + struct cpufreq_frequency_table table[7]; +}; + +static struct jz4730_freq_percpu_info jz4730_freq_table; + +/* + * This contains the registers value for an operating point. + * If only part of a register needs to change then there is + * a mask value for that register. + * When going to a new operating point the current register + * value is ANDed with the ~mask and ORed with the new value. + */ +struct dpm_regs { + u32 cfcr; /* Clock Freq Control Register */ + u32 cfcr_mask; /* Clock Freq Control Register mask */ + u32 cfcr2; /* Clock Freq Control Register 2 */ + u32 cfcr2_mask; /* Clock Freq Control Register 2 mask */ + u32 plcr1; /* PLL1 Control Register */ + u32 plcr1_mask; /* PLL1 Control Register mask */ + u32 pll_up_flag; /* New PLL freq is higher than current or not */ +}; + +extern jz_clocks_t jz_clocks; + +static void jz_update_clocks(void) +{ + /* Next clocks must be updated if we have changed + * the PLL or divisors. + */ + jz_clocks.iclk = __cpm_get_iclk(); + jz_clocks.sclk = __cpm_get_sclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); +} + +static void +jz_init_boot_config(void) +{ + if (!boot_config.lcd_clks_initialized) { + /* the first time to scale pll */ + boot_config.lcd_clk = __cpm_get_lcdclk(); + boot_config.lcdpix_clk = __cpm_get_pixclk(); + boot_config.lcd_clks_initialized = 1; + } + + if (!boot_config.sdram_initialized) { + /* the first time to scale frequencies */ + unsigned int dmcr, rtcor; + unsigned int tras, rcd, tpc, trwl, trc; + + dmcr = REG_EMC_DMCR; + rtcor = REG_EMC_RTCOR; + + tras = (dmcr >> 13) & 0x7; + rcd = (dmcr >> 11) & 0x3; + tpc = (dmcr >> 8) & 0x7; + trwl = (dmcr >> 5) & 0x3; + trc = (dmcr >> 2) & 0x7; + + boot_config.mclk = __cpm_get_mclk() / 1000; + boot_config.tras = tras + 4; + boot_config.rcd = rcd + 1; + boot_config.tpc = tpc + 1; + boot_config.trwl = trwl + 1; + boot_config.trc = trc * 2 + 1; + boot_config.rtcor = rtcor; + + boot_config.sdram_initialized = 1; + } +} + +static void jz_update_dram_rtcor(unsigned int new_mclk) +{ + unsigned int rtcor; + + new_mclk /= 1000; + rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; + rtcor--; + + if (rtcor < 1) rtcor = 1; + if (rtcor > 255) rtcor = 255; + + REG_EMC_RTCOR = rtcor; + REG_EMC_RTCNT = rtcor; +} + +static void jz_update_dram_dmcr(unsigned int new_mclk) +{ + unsigned int dmcr; + unsigned int tras, rcd, tpc, trwl, trc; + unsigned int valid_time, new_time; /* ns */ + + new_mclk /= 1000; + tras = boot_config.tras * new_mclk / boot_config.mclk; + rcd = boot_config.rcd * new_mclk / boot_config.mclk; + tpc = boot_config.tpc * new_mclk / boot_config.mclk; + trwl = boot_config.trwl * new_mclk / boot_config.mclk; + trc = boot_config.trc * new_mclk / boot_config.mclk; + + /* Validation checking */ + valid_time = (boot_config.tras * 1000000) / boot_config.mclk; + new_time = (tras * 1000000) / new_mclk; + if (new_time < valid_time) tras += 1; + + valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; + new_time = (rcd * 1000000) / new_mclk; + if (new_time < valid_time) rcd += 1; + + valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; + new_time = (tpc * 1000000) / new_mclk; + if (new_time < valid_time) tpc += 1; + + valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; + new_time = (trwl * 1000000) / new_mclk; + if (new_time < valid_time) trwl += 1; + + valid_time = (boot_config.trc * 1000000) / boot_config.mclk; + new_time = (trc * 1000000) / new_mclk; + if (new_time < valid_time) trc += 2; + + tras = (tras < 4) ? 4: tras; + tras = (tras > 11) ? 11: tras; + tras -= 4; + + rcd = (rcd < 1) ? 1: rcd; + rcd = (rcd > 4) ? 4: rcd; + rcd -= 1; + + tpc = (tpc < 1) ? 1: tpc; + tpc = (tpc > 8) ? 8: tpc; + tpc -= 1; + + trwl = (trwl < 1) ? 1: trwl; + trwl = (trwl > 4) ? 4: trwl; + trwl -= 1; + + trc = (trc < 1) ? 1: trc; + trc = (trc > 15) ? 15: trc; + trc /= 2; + + dmcr = REG_EMC_DMCR; + + dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); + dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); + + REG_EMC_DMCR = dmcr; +} + +static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL + * and TRC of DMCR before changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } else { + /* We're going SLOWER: first update RTCOR value + * before changing the frequency. + */ + jz_update_dram_rtcor(new_mclk); + } +} + +static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so update RTCOR + * after changing the frequency + */ + jz_update_dram_rtcor(new_mclk); + } else { + /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL + * and TRC of DMCR after changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } +} + +static void jz_scale_divisors(struct dpm_regs *regs) +{ + unsigned int cfcr; + unsigned int cur_mclk, new_mclk; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + cfcr = REG_CPM_CFCR; + cfcr &= ~((unsigned long)regs->cfcr_mask); + cfcr |= regs->cfcr; + cfcr |= CPM_CFCR_UPE; /* update immediately */ + + cur_mclk = __cpm_get_mclk(); + new_mclk = __cpm_get_pllout() / div[(cfcr & CPM_CFCR_MFR_MASK) >> CPM_CFCR_MFR_BIT]; + + /* Update some DRAM parameters before changing frequency */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CFCR), "r" (cfcr), "r" (wait), "r" (tmp)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} + +#ifdef CHANGE_PLL +/* Maintain the LCD clock and pixel clock */ +static void jz_scale_lcd_divisors(struct dpm_regs *regs) +{ + unsigned int new_pll, new_lcd_div, new_lcdpix_div; + unsigned int cfcr; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + if (!boot_config.lcd_clks_initialized) return; + + new_pll = __cpm_get_pllout(); + new_lcd_div = new_pll / boot_config.lcd_clk; + new_lcdpix_div = new_pll / boot_config.lcdpix_clk; + + if (new_lcd_div < 1) + new_lcd_div = 1; + if (new_lcd_div > 16) + new_lcd_div = 16; + + if (new_lcdpix_div < 1) + new_lcdpix_div = 1; + if (new_lcdpix_div > 512) + new_lcdpix_div = 512; + + REG_CPM_CFCR2 = new_lcdpix_div - 1; + + cfcr = REG_CPM_CFCR; + cfcr &= ~CPM_CFCR_LFR_MASK; + cfcr |= ((new_lcd_div - 1) << CPM_CFCR_LFR_BIT); + cfcr |= CPM_CFCR_UPE; /* update immediately */ + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CFCR), "r" (cfcr), "r" (wait), "r" (tmp)); +} + +static void jz_scale_pll(struct dpm_regs *regs) +{ + unsigned int plcr1; + unsigned int cur_mclk, new_mclk, new_pll; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + int od[] = {1, 2, 2, 4}; + + plcr1 = REG_CPM_PLCR1; + plcr1 &= ~(regs->plcr1_mask | CPM_PLCR1_PLL1S | CPM_PLCR1_PLL1EN | CPM_PLCR1_PLL1ST_MASK); + regs->plcr1 &= ~CPM_PLCR1_PLL1EN; + plcr1 |= (regs->plcr1 | 0xff); + + /* Update some DRAM parameters before changing frequency */ + new_pll = JZ_EXTAL * ((plcr1>>23)+2) / ((((plcr1>>18)&0x1f)+2) * od[(plcr1>>16)&0x03]); + cur_mclk = __cpm_get_mclk(); + new_mclk = new_pll / div[(REG_CPM_CFCR>>16) & 0xf]; + + /* + * Update some SDRAM parameters + */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* + * Update PLL, align code to cache line. + */ + plcr1 |= CPM_PLCR1_PLL1EN; + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_PLCR1), "r" (plcr1)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} +#endif + +static void jz4730_transition(struct dpm_regs *regs) +{ + /* + * Get and save some boot-time conditions. + */ + jz_init_boot_config(); + +#ifdef CHANGE_PLL + /* + * Disable LCD before scaling pll. + * LCD and LCD pixel clocks should not be changed even if the PLL + * output frequency has been changed. + */ + REG_LCD_CTRL &= ~LCD_CTRL_ENA; +#endif + /* + * Stop module clocks before scaling PLL + */ + __cpm_stop_eth(); + __cpm_stop_aic_pclk(); + __cpm_stop_aic_bitclk(); + + /* ... add more as necessary */ + + if (regs->pll_up_flag == PLL_GOES_UP) { + /* the pll frequency is going up, so change dividors first */ + jz_scale_divisors(regs); +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + } + else if (regs->pll_up_flag == PLL_GOES_DOWN) { + /* the pll frequency is going down, so change pll first */ +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + jz_scale_divisors(regs); + } + else { + /* the pll frequency is unchanged, so change divisors only */ + jz_scale_divisors(regs); + } + + /* + * Restart module clocks before scaling PLL + */ + __cpm_start_eth(); + __cpm_start_aic_pclk(); + __cpm_start_aic_bitclk(); + + /* ... add more as necessary */ + +#ifdef CHANGE_PLL + /* Scale the LCD divisors after scaling pll */ + if (regs->pll_up_flag != PLL_UNCHANGED) { + jz_scale_lcd_divisors(regs); + } + + /* Enable LCD controller */ + REG_LCD_CTRL &= ~LCD_CTRL_DIS; + REG_LCD_CTRL |= LCD_CTRL_ENA; +#endif + + /* Update system clocks */ + jz_update_clocks(); +} + +extern unsigned int idle_times; +static unsigned int jz4730_freq_get(unsigned int cpu) +{ + return (__cpm_get_iclk() / 1000); +} + +static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) +{ + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; + int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ + unsigned int div_of_cclk, new_freq, i; + + regs->pll_up_flag = PLL_UNCHANGED; + regs->cfcr_mask = CPM_CFCR_IFR_MASK | CPM_CFCR_SFR_MASK | CPM_CFCR_PFR_MASK | CPM_CFCR_MFR_MASK; + + new_freq = jz4730_freq_table.table[index].frequency; + + do { + div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); + } while (div_of_cclk==0); + + if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { + for(i = 1; i<4; i++) { + div[i] = 3; + } + } else { + for(i = 1; i<4; i++) { + div[i] = 2; + } + } + + for(i = 0; i<4; i++) { + div[i] *= div_of_cclk; + } + + dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); + + regs->cfcr = (n2FR[div[0]] << CPM_CFCR_IFR_BIT) | + (n2FR[div[1]] << CPM_CFCR_SFR_BIT) | + (n2FR[div[2]] << CPM_CFCR_PFR_BIT) | + (n2FR[div[3]] << CPM_CFCR_MFR_BIT); + + return div_of_cclk; +} + +static void jz4730_set_cpu_divider_index(unsigned int cpu, unsigned int index) +{ + unsigned long divisor, old_divisor; + struct cpufreq_freqs freqs; + struct dpm_regs regs; + + old_divisor = __cpm_get_pllout() / __cpm_get_iclk(); + divisor = index_to_divisor(index, ®s); + + freqs.old = __cpm_get_iclk() / 1000; + freqs.new = __cpm_get_pllout() / (1000 * divisor); + freqs.cpu = cpu; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (old_divisor != divisor) + jz4730_transition(®s); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + +static int jz4730_freq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int new_index = 0; + + if (cpufreq_frequency_table_target(policy, + &jz4730_freq_table.table[0], + target_freq, relation, &new_index)) + return -EINVAL; + + jz4730_set_cpu_divider_index(policy->cpu, new_index); + + dprintk("new frequency is %d KHz (REG_CPM_CFCR:0x%x)\n", __cpm_get_iclk() / 1000, REG_CPM_CFCR); + + return 0; +} + +static int jz4730_freq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &jz4730_freq_table.table[0]); +} + +static int __init jz4730_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + + struct cpufreq_frequency_table *table = &jz4730_freq_table.table[0]; + unsigned int MAX_FREQ; + + dprintk(KERN_INFO "Jz4730 cpufreq driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = MAX_FREQ = __cpm_get_iclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.min_freq = MAX_FREQ/8; + policy->cpuinfo.max_freq = MAX_FREQ; + policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ + + table[0].index = 0; + table[0].frequency = MAX_FREQ/8; + table[1].index = 1; + table[1].frequency = MAX_FREQ/6; + table[2].index = 2; + table[2].frequency = MAX_FREQ/4; + table[3].index = 3; + table[3].frequency = MAX_FREQ/3; + table[4].index = 4; + table[4].frequency = MAX_FREQ/2; + table[5].index = 5; + table[5].frequency = MAX_FREQ; + table[6].index = 6; + table[6].frequency = CPUFREQ_TABLE_END; + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static struct cpufreq_driver cpufreq_jz4730_driver = { +// .flags = CPUFREQ_STICKY, + .init = jz4730_cpufreq_driver_init, + .verify = jz4730_freq_verify, + .target = jz4730_freq_target, + .get = jz4730_freq_get, + .name = "jz4730", +}; + +static int __init jz4730_cpufreq_init(void) +{ + return cpufreq_register_driver(&cpufreq_jz4730_driver); +} + +static void __exit jz4730_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cpufreq_jz4730_driver); +} + +module_init(jz4730_cpufreq_init); +module_exit(jz4730_cpufreq_exit); + +MODULE_AUTHOR("Regen "); +MODULE_DESCRIPTION("cpufreq driver for Jz4730"); +MODULE_LICENSE("GPL"); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/dma.c linux-2.6.24.3-20100304/arch/mips/jz4730/dma.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/dma.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,509 @@ +/* + * linux/arch/mips/jz4730/dma.c + * + * JZ4730 DMA PC-like APIs. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `jz_request_dma()' and `jz_free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from jz_request_dma(). + */ + +struct jz_dma_chan jz_dma_table[NUM_DMA] = { + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, +}; + + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; + unsigned int dma_source; +} dma_dev_table[NUM_DMA_DEV] = { + {CPHYSADDR(UART0_BASE), DMA_8bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, + {CPHYSADDR(UART0_BASE), DMA_8bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, + {CPHYSADDR(UART1_BASE), DMA_8bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT}, + {CPHYSADDR(UART1_BASE), DMA_8bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_UART1IN}, + {CPHYSADDR(UART2_BASE), DMA_8bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT}, + {CPHYSADDR(UART2_BASE), DMA_8bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_UART2IN}, + {CPHYSADDR(UART3_BASE), DMA_8bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT}, + {CPHYSADDR(UART3_BASE), DMA_8bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_UART3IN}, + {CPHYSADDR(SSI_DR), DMA_32bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_SSIOUT}, + {CPHYSADDR(SSI_DR), DMA_32bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_SSIIN}, + {CPHYSADDR(MSC_TXFIFO), DMA_32bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_MSCOUT}, + {CPHYSADDR(MSC_RXFIFO), DMA_32bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_MSCIN}, + {CPHYSADDR(AIC_DR), DMA_32bit_TX_CONF|DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, + {CPHYSADDR(AIC_DR), DMA_32bit_RX_CONF|DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, + {0, DMA_AUTOINIT, 0}, +}; + + +int jz_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct jz_dma_chan *chan; + + for (i = 0; i < NUM_DMA; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_jz_dma_channel(unsigned int dmanr) +{ + struct jz_dma_chan *chan; + + if (dmanr > NUM_DMA) + return; + chan = &jz_dma_table[dmanr]; + + printk(KERN_INFO "DMA%d Register Dump:\n", dmanr); + printk(KERN_INFO " DMACR= 0x%08x\n", REG_DMAC_DMACR); + printk(KERN_INFO " DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); + printk(KERN_INFO " DDAR = 0x%08x\n", REG_DMAC_DDAR(dmanr)); + printk(KERN_INFO " DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); + printk(KERN_INFO " DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); + printk(KERN_INFO " DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); +} + + +/** + * jz_request_dma - dynamically allcate an idle DMA channel to return + * @dev_id: the specified dma device id or DMA_ID_RAW_REQ + * @dev_str: the specified dma device string name + * @irqhandler: the irq handler, or NULL + * @irqflags: the irq handler flags + * @irq_dev_id: the irq handler device id for shared irq + * + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + * +*/ +int jz_request_dma(int dev_id, const char *dev_str, + irqreturn_t (*irqhandler)(int, void *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct jz_dma_chan *chan; + int i, ret; + + if (dev_id < 0 || dev_id >= NUM_DMA_DEV) + return -EINVAL; + + for (i = 0; i < NUM_DMA; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == NUM_DMA) + return -ENODEV; + + chan = &jz_dma_table[i]; + + if (irqhandler) { + chan->irq = IRQ_DMA_0 + i; // see intc.h + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = 0; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = 0; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = i; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + chan->source = dma_dev_table[dev_id].dma_source; + + return i; +} + +void jz_free_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = 0; + chan->irq_dev = NULL; + chan->dev_id = -1; +} + +void jz_set_dma_dest_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + chan->mode &= ~DMAC_DCCSR_DWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCCSR_DWDH_8; + break; + case 16: + chan->mode |= DMAC_DCCSR_DWDH_16; + break; + case 32: + chan->mode |= DMAC_DCCSR_DWDH_32; + break; + } +} + +void jz_set_dma_src_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + chan->mode &= ~DMAC_DCCSR_SWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCCSR_SWDH_8; + break; + case 16: + chan->mode |= DMAC_DCCSR_SWDH_16; + break; + case 32: + chan->mode |= DMAC_DCCSR_SWDH_32; + break; + } +} + +void jz_set_dma_block_size(int dmanr, int nbyte) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + chan->mode &= ~DMAC_DCCSR_DS_MASK; + switch (nbyte) { + case 1: + chan->mode |= DMAC_DCCSR_DS_8b; + break; + case 2: + chan->mode |= DMAC_DCCSR_DS_16b; + break; + case 4: + chan->mode |= DMAC_DCCSR_DS_32b; + break; + case 16: + chan->mode |= DMAC_DCCSR_DS_16B; + break; + case 32: + chan->mode |= DMAC_DCCSR_DS_32B; + break; + } +} + +/** + * jz_set_dma_mode - do the raw settings for the specified DMA channel + * @dmanr: the specified DMA channel + * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE + * @dma_mode: dma raw mode + * @dma_source: dma raw request source + * @fifo_addr: dma raw device fifo address + * + * Ensure call jz_request_dma(DMA_ID_RAW_REQ, ...) first, then call + * jz_set_dma_mode() rather than set_dma_mode() if you work with + * and external request dma device. + * + * NOTE: Don not dynamically allocate dma channel if one external request + * dma device will occupy this channel. +*/ +int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, + unsigned int dma_mode, unsigned int dma_source, + unsigned int fifo_addr) +{ + int dev_id, i; + struct jz_dma_chan *chan; + + if (dmanr > NUM_DMA) + return -ENODEV; + for (i = 0; i < NUM_DMA; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == NUM_DMA) + return -ENODEV; + + chan = &jz_dma_table[dmanr]; + dev_id = chan->dev_id; + if (dev_id > 0) { + printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", + __FUNCTION__, dmanr); + return -ENODEV; + } + + /* clone it from the dynamically allocated. */ + if (i != dmanr) { + chan->irq = jz_dma_table[i].irq; + chan->irq_dev = jz_dma_table[i].irq_dev; + chan->dev_str = jz_dma_table[i].dev_str; + jz_dma_table[i].irq = 0; + jz_dma_table[i].irq_dev = NULL; + jz_dma_table[i].dev_id = -1; + } + chan->dev_id = DMA_ID_RAW_SET; + chan->io = dmanr; + chan->fifo_addr = fifo_addr; + chan->mode = dma_mode; + chan->source = dma_source; + + set_dma_mode(dmanr, dma_mode); + + return dmanr; +} + +void enable_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + + REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TC | DMAC_DCCSR_AR); + __dmac_enable_channel(dmanr); + if (chan->irq) + __dmac_channel_enable_irq(dmanr); +} + +#define DMA_DISABLE_POLL 0x5000 + +void disable_dma(unsigned int dmanr) +{ + int i; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + if (!__dmac_channel_enabled(dmanr)) + return; + + for (i = 0; i < DMA_DISABLE_POLL; i++) + if (__dmac_channel_transmit_end_detected(dmanr)) + break; +#if 0 + if (i == DMA_DISABLE_POLL) + printk(KERN_INFO "disable_dma: poll expired!\n"); +#endif + + __dmac_disable_channel(dmanr); + if (chan->irq) + __dmac_channel_disable_irq(dmanr); +} + +/* note: DMA_MODE_MASK is simulated by sw, DCCSR_MODE_MASK mask hw bits */ +void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + mode &= ~(DMAC_DCCSR_TC | DMAC_DCCSR_AR); + chan->mode |= mode & ~(DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM | DMAC_DCCSR_DAM); + mode &= DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + chan->mode |= DMAC_DCCSR_DAM; + chan->mode &= ~DMAC_DCCSR_SAM; + } else if (mode == DMA_MODE_WRITE) { + chan->mode |= DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM; + chan->mode &= ~DMAC_DCCSR_DAM; + } else { + printk(KERN_DEBUG "set_dma_mode() support DMA_MODE_READ or DMA_MODE_WRITE!\n"); + } + REG_DMAC_DCCSR(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; +} + +void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case AFMT_U8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case AFMT_S16_LE: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + mode &= ~(DMAC_DCCSR_TC | DMAC_DCCSR_AR); + chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM | DMAC_DCCSR_DAM); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCCSR_DAM; + chan->mode &= ~DMAC_DCCSR_SAM; + } else if (mode == DMA_MODE_WRITE) { + mode &= ~(DMAC_DCCSR_TC | DMAC_DCCSR_AR); + chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM |DMAC_DCCSR_DAM); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM; + chan->mode &= ~DMAC_DCCSR_DAM; + } else + printk("jz_set_oss_dma() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCCSR(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case 8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case 16: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + mode &= ~(DMAC_DCCSR_TC | DMAC_DCCSR_AR); + chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM | DMAC_DCCSR_DAM); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCCSR_DAM; + chan->mode &= ~DMAC_DCCSR_SAM; + } else if (mode == DMA_MODE_WRITE) { + mode &= ~(DMAC_DCCSR_TC | DMAC_DCCSR_AR); + chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM | DMAC_DCCSR_DAM); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCCSR_SAM | DMAC_DCCSR_EACKM; + chan->mode &= ~DMAC_DCCSR_DAM; + } else + printk("jz_set_alsa_dma() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCCSR(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + unsigned int mode; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + mode = chan->mode & DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + REG_DMAC_DSAR(chan->io) = chan->fifo_addr; + REG_DMAC_DDAR(chan->io) = a; + } else if (mode == DMA_MODE_WRITE) { + REG_DMAC_DSAR(chan->io) = a; + REG_DMAC_DDAR(chan->io) = chan->fifo_addr; + } else + printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); +} + +void set_dma_count(unsigned int dmanr, unsigned int count) +{ + unsigned int mode; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + mode = (chan->mode & DMAC_DCCSR_DS_MASK) >> DMAC_DCCSR_DS_BIT; + count = count / dma_ds[mode]; + REG_DMAC_DTCR(chan->io) = count; +} + +int get_dma_residue(unsigned int dmanr) +{ + int count; + unsigned int mode; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + mode = (chan->mode & DMAC_DCCSR_DS_MASK) >> DMAC_DCCSR_DS_BIT; + count = REG_DMAC_DTCR(chan->io); + count = count * dma_ds[mode]; + + return count; +} + +EXPORT_SYMBOL(jz_dma_table); +EXPORT_SYMBOL(jz_request_dma); +EXPORT_SYMBOL(jz_free_dma); +EXPORT_SYMBOL(jz_set_dma_src_width); +EXPORT_SYMBOL(jz_set_dma_dest_width); +EXPORT_SYMBOL(jz_set_dma_block_size); +EXPORT_SYMBOL(jz_set_dma_mode); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(jz_set_oss_dma); +EXPORT_SYMBOL(jz_set_alsa_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(dump_jz_dma_channel); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/i2c.c linux-2.6.24.3-20100304/arch/mips/jz4730/i2c.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/i2c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/i2c.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,214 @@ +/* + * linux/arch/mips/jz4730/i2c.c + * + * JZ4730 I2C APIs. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT * 10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (!__i2c_received_ack() && timeout) + timeout--; + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else + return -ETIMEDOUT; +} + +/* + * I2C interface + */ +void i2c_open(void) +{ + __i2c_set_clk(jz_clocks.devclk, 10000); /* default 10 KHz */ + __i2c_enable(); +} + +void i2c_close(void) +{ + udelay(300); /* wait for STOP goes over. */ + __i2c_disable(); +} + +void i2c_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.devclk, i2cclk); +} + +int i2c_lseek(unsigned char device, unsigned char offset) +{ + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(offset) < 0) + goto address_err; + return 0; + device_err: + printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device); + __i2c_send_stop(); + return -ENODEV; + address_err: + printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device); + __i2c_send_stop(); + return -EREMOTEIO; +} + +int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int timeout = 5; + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; + if (i2c_put_data(address) < 0) + goto address_err; + + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_READ ) < 0) + goto device_rerr; + __i2c_send_ack(); /* Master sends ACK for continue reading */ + while (cnt) { + if (cnt == 1) { + if (i2c_get_data(buf, 0) < 0) + break; + } else { + if (i2c_get_data(buf, 1) < 0) + break; + } + cnt--; + buf++; + } + + __i2c_send_stop(); + return count - cnt; + device_rerr: + device_werr: + address_err: + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + +int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + unsigned char tmpaddr; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = count; + tmpbuf = (unsigned char *)buf; + tmpaddr = address; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + __i2c_send_stop(); + return count - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + + W_timeout: + printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +EXPORT_SYMBOL(i2c_open); +EXPORT_SYMBOL(i2c_close); +EXPORT_SYMBOL(i2c_setclk); +EXPORT_SYMBOL(i2c_read); +EXPORT_SYMBOL(i2c_write); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/irq.c linux-2.6.24.3-20100304/arch/mips/jz4730/irq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/irq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,266 @@ +/* + * linux/arch/mips/jz4730/irq.c + * + * JZ4730 interrupt routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * INTC irq type + */ + +static void enable_intc_irq(unsigned int irq) +{ + __intc_unmask_irq(irq); +} + +static void disable_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); +} + +static void mask_and_ack_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); + __intc_ack_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_intc_irq(irq); + } +} + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static struct irq_chip intc_irq_type = { + .typename = "INTC", + .startup = startup_intc_irq, + .shutdown = shutdown_intc_irq, + .enable = enable_intc_irq, + .disable = disable_intc_irq, + .ack = mask_and_ack_intc_irq, + .end = end_intc_irq, +}; + +/* + * GPIO irq type + */ + +static void enable_gpio_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if (irq < (IRQ_GPIO_0 + 32)) { + intc_irq = IRQ_GPIO0; + } + else if (irq < (IRQ_GPIO_0 + 64)) { + intc_irq = IRQ_GPIO1; + } + else if (irq < (IRQ_GPIO_0 + 96)) { + intc_irq = IRQ_GPIO2; + } + else { + intc_irq = IRQ_GPIO3; + } + + enable_intc_irq(intc_irq); + __gpio_unmask_irq(irq - IRQ_GPIO_0); +} + +static void disable_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); +} + +static void mask_and_ack_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); + __gpio_ack_irq(irq - IRQ_GPIO_0); +} + +static void end_gpio_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_gpio_irq(irq); + } +} + +static unsigned int startup_gpio_irq(unsigned int irq) +{ + enable_gpio_irq(irq); + return 0; +} + +static void shutdown_gpio_irq(unsigned int irq) +{ + disable_gpio_irq(irq); +} + +static struct irq_chip gpio_irq_type = { + .typename = "GPIO", + .startup = startup_gpio_irq, + .shutdown = shutdown_gpio_irq, + .enable = enable_gpio_irq, + .disable = disable_gpio_irq, + .ack = mask_and_ack_gpio_irq, + .end = end_gpio_irq, +}; + +/* + * DMA irq type + */ + +static void enable_dma_irq(unsigned int irq) +{ + __intc_unmask_irq(IRQ_DMAC); + __dmac_channel_enable_irq(irq - IRQ_DMA_0); +} + +static void disable_dma_irq(unsigned int irq) +{ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void mask_and_ack_dma_irq(unsigned int irq) +{ + __intc_ack_irq(IRQ_DMAC); + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void end_dma_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_dma_irq(irq); + } +} + +static unsigned int startup_dma_irq(unsigned int irq) +{ + enable_dma_irq(irq); + return 0; +} + +static void shutdown_dma_irq(unsigned int irq) +{ + disable_dma_irq(irq); +} + +static struct irq_chip dma_irq_type = { + .typename = "DMA", + .startup = startup_dma_irq, + .shutdown = shutdown_dma_irq, + .enable = enable_dma_irq, + .disable = disable_dma_irq, + .ack = mask_and_ack_dma_irq, + .end = end_dma_irq, +}; + +//---------------------------------------------------------------------- + +void __init arch_init_irq(void) +{ + int i; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + /* Set up INTC irq + */ + for (i = 0; i < 32; i++) { + disable_intc_irq(i); + irq_desc[i].chip = &intc_irq_type; + } + + /* Set up DMAC irq + */ + for (i = 0; i < NUM_DMA; i++) { + disable_dma_irq(IRQ_DMA_0 + i); + irq_desc[IRQ_DMA_0 + i].chip = &dma_irq_type; + } + + /* Set up GPIO irq + */ + for (i = 0; i < NUM_GPIO; i++) { + disable_gpio_irq(IRQ_GPIO_0 + i); + irq_desc[IRQ_GPIO_0 + i].chip = &gpio_irq_type; + } +} + +static int plat_real_irq(int irq) +{ + switch (irq) { + case IRQ_GPIO0: + irq = __gpio_group_irq(0) + IRQ_GPIO_0; + break; + case IRQ_GPIO1: + irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32; + break; + case IRQ_GPIO2: + irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64; + break; + case IRQ_GPIO3: + irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96; + break; + case IRQ_DMAC: + irq = __dmac_get_irq() + IRQ_DMA_0; + break; + } + + return irq; +} + +asmlinkage void plat_irq_dispatch(void) +{ + int irq = 0; + static unsigned long intc_ipr = 0; + + intc_ipr |= REG_INTC_IPR; + + if (!intc_ipr) return; + + irq = ffs(intc_ipr) - 1; + intc_ipr &= ~(1< + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include +#include + +#include + +/* OHCI (USB full speed host controller) */ +static struct resource jz_usb_ohci_resources[] = { + [0] = { + .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap + .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UHC, + .end = IRQ_UHC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct platform_device jz_usb_ohci_device = { + .name = "jz-ohci", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_ohci_resources), + .resource = jz_usb_ohci_resources, +}; + +/*** LCD controller ***/ +static struct resource jz_lcd_resources[] = { + [0] = { + .start = CPHYSADDR(LCD_BASE), + .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_lcd_dmamask = ~(u32)0; + +static struct platform_device jz_lcd_device = { + .name = "jz-lcd", + .id = 0, + .dev = { + .dma_mask = &jz_lcd_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_lcd_resources), + .resource = jz_lcd_resources, +}; + +/* UDC (USB gadget controller) */ +static struct resource jz_usb_gdt_resources[] = { + [0] = { + .start = CPHYSADDR(UDC_BASE), + .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UDC, + .end = IRQ_UDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device jz_usb_gdt_device = { + .name = "jz-udc", + .id = 0, + .dev = { + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_gdt_resources), + .resource = jz_usb_gdt_resources, +}; + +/** MMC/SD controller **/ +static struct resource jz_mmc_resources[] = { + [0] = { + .start = CPHYSADDR(MSC_BASE), + .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MSC, + .end = IRQ_MSC, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_mmc_dmamask = ~(u32)0; + +static struct platform_device jz_mmc_device = { + .name = "jz-mmc", + .id = 0, + .dev = { + .dma_mask = &jz_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_mmc_resources), + .resource = jz_mmc_resources, +}; + +/* All */ +static struct platform_device *jz_platform_devices[] __initdata = { + &jz_usb_ohci_device, + &jz_lcd_device, + &jz_usb_gdt_device, + &jz_mmc_device, +}; + +static int __init jz_platform_init(void) +{ + return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices)); +} + +arch_initcall(jz_platform_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/pm.c linux-2.6.24.3-20100304/arch/mips/jz4730/pm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/pm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/pm.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,1098 @@ +/* + * linux/arch/mips/jz4730/pm.c + * + * Jz4730 Power Management Routines + * + * Copyright 2005 Ingenic Semiconductor + * Wei Jianli + * Huang Lihong + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +extern void jz_cpu_suspend(void); +extern void jz_cpu_resume(void); + +static void jz_board_pm_suspend(void); + +#define SAVE(x,s) sleep_save[SLEEP_SAVE_##x] = REG##s(x) +#define RESTORE(x,s) REG##s(x) = sleep_save[SLEEP_SAVE_##x] + +/* + * List of global jz4730 peripheral registers to preserve. + * More ones like core register and general purpose register values + * are preserved with the stack pointer in sleep.S. + */ +enum { SLEEP_SAVE_START = 0, + + /* CPM */ + SLEEP_SAVE_CPM_MSCR, SLEEP_SAVE_CPM_PLCR1, + + /* WDT */ + SLEEP_SAVE_WDT_WTCNT, SLEEP_SAVE_WDT_WTCSR, + + /* OST */ + SLEEP_SAVE_OST_TER, + SLEEP_SAVE_OST_TCSR0, SLEEP_SAVE_OST_TCSR1, SLEEP_SAVE_OST_TCSR2, + SLEEP_SAVE_OST_TRDR0, SLEEP_SAVE_OST_TRDR1, SLEEP_SAVE_OST_TRDR2, + SLEEP_SAVE_OST_TCNT0, SLEEP_SAVE_OST_TCNT1, SLEEP_SAVE_OST_TCNT2, + + /* HARB */ + SLEEP_SAVE_HARB_HAPOR, SLEEP_SAVE_HARB_HMCTR, SLEEP_SAVE_HARB_HMLTR, + + /* EMC */ + SLEEP_SAVE_EMC_SMCR0, SLEEP_SAVE_EMC_SMCR1, SLEEP_SAVE_EMC_SMCR2, SLEEP_SAVE_EMC_SMCR3, + SLEEP_SAVE_EMC_SMCR4, SLEEP_SAVE_EMC_SMCR5, + + /* GPIO */ + SLEEP_SAVE_GPIO_GPDR0, SLEEP_SAVE_GPIO_GPDR1, SLEEP_SAVE_GPIO_GPDR2, SLEEP_SAVE_GPIO_GPDR3, + SLEEP_SAVE_GPIO_GPDIR0, SLEEP_SAVE_GPIO_GPDIR1, SLEEP_SAVE_GPIO_GPDIR2, SLEEP_SAVE_GPIO_GPDIR3, + SLEEP_SAVE_GPIO_GPODR0, SLEEP_SAVE_GPIO_GPODR1, SLEEP_SAVE_GPIO_GPODR2, SLEEP_SAVE_GPIO_GPODR3, + SLEEP_SAVE_GPIO_GPPUR0, SLEEP_SAVE_GPIO_GPPUR1, SLEEP_SAVE_GPIO_GPPUR2, SLEEP_SAVE_GPIO_GPPUR3, + SLEEP_SAVE_GPIO_GPALR0, SLEEP_SAVE_GPIO_GPALR1, SLEEP_SAVE_GPIO_GPALR2, SLEEP_SAVE_GPIO_GPALR3, + SLEEP_SAVE_GPIO_GPAUR0, SLEEP_SAVE_GPIO_GPAUR1, SLEEP_SAVE_GPIO_GPAUR2, SLEEP_SAVE_GPIO_GPAUR3, + SLEEP_SAVE_GPIO_GPIDLR0, SLEEP_SAVE_GPIO_GPIDLR1, SLEEP_SAVE_GPIO_GPIDLR2, SLEEP_SAVE_GPIO_GPIDLR3, + SLEEP_SAVE_GPIO_GPIDUR0, SLEEP_SAVE_GPIO_GPIDUR1, SLEEP_SAVE_GPIO_GPIDUR2, SLEEP_SAVE_GPIO_GPIDUR3, + SLEEP_SAVE_GPIO_GPIER0, SLEEP_SAVE_GPIO_GPIER1, SLEEP_SAVE_GPIO_GPIER2, SLEEP_SAVE_GPIO_GPIER3, + SLEEP_SAVE_GPIO_GPIMR0, SLEEP_SAVE_GPIO_GPIMR1, SLEEP_SAVE_GPIO_GPIMR2, SLEEP_SAVE_GPIO_GPIMR3, + SLEEP_SAVE_GPIO_GPFR0, SLEEP_SAVE_GPIO_GPFR1, SLEEP_SAVE_GPIO_GPFR2, SLEEP_SAVE_GPIO_GPFR3, + + /* UART(0-3) */ + SLEEP_SAVE_UART0_IER, SLEEP_SAVE_UART0_LCR, SLEEP_SAVE_UART0_MCR, SLEEP_SAVE_UART0_SPR, SLEEP_SAVE_UART0_DLLR, SLEEP_SAVE_UART0_DLHR, + SLEEP_SAVE_UART1_IER, SLEEP_SAVE_UART1_LCR, SLEEP_SAVE_UART1_MCR, SLEEP_SAVE_UART1_SPR, SLEEP_SAVE_UART1_DLLR, SLEEP_SAVE_UART1_DLHR, + SLEEP_SAVE_UART2_IER, SLEEP_SAVE_UART2_LCR, SLEEP_SAVE_UART2_MCR, SLEEP_SAVE_UART2_SPR, SLEEP_SAVE_UART2_DLLR, SLEEP_SAVE_UART2_DLHR, + SLEEP_SAVE_UART3_IER, SLEEP_SAVE_UART3_LCR, SLEEP_SAVE_UART3_MCR, SLEEP_SAVE_UART3_SPR, SLEEP_SAVE_UART3_DLLR, SLEEP_SAVE_UART3_DLHR, + + /* DMAC */ + SLEEP_SAVE_DMAC_DMACR, + SLEEP_SAVE_DMAC_DSAR0, SLEEP_SAVE_DMAC_DSAR1, SLEEP_SAVE_DMAC_DSAR2, SLEEP_SAVE_DMAC_DSAR3, SLEEP_SAVE_DMAC_DSAR4, SLEEP_SAVE_DMAC_DSAR5, SLEEP_SAVE_DMAC_DSAR6, SLEEP_SAVE_DMAC_DSAR7, + SLEEP_SAVE_DMAC_DDAR0, SLEEP_SAVE_DMAC_DDAR1, SLEEP_SAVE_DMAC_DDAR2, SLEEP_SAVE_DMAC_DDAR3, SLEEP_SAVE_DMAC_DDAR4, SLEEP_SAVE_DMAC_DDAR5, SLEEP_SAVE_DMAC_DDAR6, SLEEP_SAVE_DMAC_DDAR7, + SLEEP_SAVE_DMAC_DTCR0, SLEEP_SAVE_DMAC_DTCR1, SLEEP_SAVE_DMAC_DTCR2, SLEEP_SAVE_DMAC_DTCR3, SLEEP_SAVE_DMAC_DTCR4, SLEEP_SAVE_DMAC_DTCR5, SLEEP_SAVE_DMAC_DTCR6, SLEEP_SAVE_DMAC_DTCR7, + SLEEP_SAVE_DMAC_DRSR0, SLEEP_SAVE_DMAC_DRSR1, SLEEP_SAVE_DMAC_DRSR2, SLEEP_SAVE_DMAC_DRSR3, SLEEP_SAVE_DMAC_DRSR4, SLEEP_SAVE_DMAC_DRSR5, SLEEP_SAVE_DMAC_DRSR6, SLEEP_SAVE_DMAC_DRSR7, + SLEEP_SAVE_DMAC_DCCSR0, SLEEP_SAVE_DMAC_DCCSR1, SLEEP_SAVE_DMAC_DCCSR2, SLEEP_SAVE_DMAC_DCCSR3, SLEEP_SAVE_DMAC_DCCSR4, SLEEP_SAVE_DMAC_DCCSR5, SLEEP_SAVE_DMAC_DCCSR6, SLEEP_SAVE_DMAC_DCCSR7, + + /* INTC */ + SLEEP_SAVE_INTC_IPR, SLEEP_SAVE_INTC_ISR, SLEEP_SAVE_INTC_IMR, + + /* Checksum */ + SLEEP_SAVE_CKSUM, + + SLEEP_SAVE_SIZE +}; + +static unsigned long sleep_save[SLEEP_SAVE_SIZE]; + +static int jz_pm_do_suspend(void) +{ + unsigned long checksum = 0; + unsigned long imr = REG_INTC_IMR; + int i; + + printk("Put cpu into suspend mode.\n"); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* Preserve current time */ + REG_RTC_RSR = xtime.tv_sec; + + REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY0; /* suspend USB PHY 0 */ + REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY1; /* suspend USB PHY 1 */ + REG_CPM_OCR |= CPM_OCR_EXT_RTC_CLK; /* select the external RTC clock (32.768KHz) */ + + /* Disable NAND ctroller */ + REG_EMC_NFCSR &= ~(EMC_NFCSR_NFE | EMC_NFCSR_FCE); + + /* + * Temporary solution. This won't be necessary once + * we move this support into the device drivers. + * Save the on-chip modules + */ + SAVE(UART0_LCR, 8); SAVE(UART0_MCR, 8); SAVE(UART0_SPR, 8); + REG8(UART0_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + SAVE(UART0_DLLR, 8); SAVE(UART0_DLHR, 8); + REG8(UART0_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + SAVE(UART0_IER, 8); + + SAVE(UART1_LCR, 8); SAVE(UART1_MCR, 8); SAVE(UART1_SPR, 8); + REG8(UART1_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + SAVE(UART1_DLLR, 8); SAVE(UART1_DLHR, 8); + REG8(UART1_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + SAVE(UART1_IER, 8); + + SAVE(UART2_LCR, 8); SAVE(UART2_MCR, 8); SAVE(UART2_SPR, 8); + REG8(UART2_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + SAVE(UART2_DLLR, 8); SAVE(UART2_DLHR, 8); + REG8(UART2_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + SAVE(UART2_IER, 8); + + SAVE(UART3_LCR, 8); SAVE(UART3_MCR, 8); SAVE(UART3_SPR, 8); + REG8(UART3_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + SAVE(UART3_DLLR, 8); SAVE(UART3_DLHR, 8); + REG8(UART3_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + SAVE(UART3_IER, 8); + + /* Save vital registers */ + + SAVE(OST_TER, 8); + SAVE(OST_TCSR0, 16); SAVE(OST_TCSR1, 16); SAVE(OST_TCSR2, 16); + SAVE(OST_TRDR0, 32); SAVE(OST_TRDR1, 32); SAVE(OST_TRDR2, 32); + SAVE(OST_TCNT0, 32); SAVE(OST_TCNT1, 32); SAVE(OST_TCNT2, 32); + + SAVE(HARB_HAPOR, 32); SAVE(HARB_HMCTR, 32); SAVE(HARB_HMLTR, 32); + + SAVE(EMC_SMCR0, 32); SAVE(EMC_SMCR1, 32); SAVE(EMC_SMCR2, 32); SAVE(EMC_SMCR3, 32); + SAVE(EMC_SMCR4, 32); SAVE(EMC_SMCR5, 32); + + SAVE(GPIO_GPDR0, 32); SAVE(GPIO_GPDR1, 32); SAVE(GPIO_GPDR2, 32); + SAVE(GPIO_GPDR3, 32); + SAVE(GPIO_GPDIR0, 32); SAVE(GPIO_GPDIR1, 32); SAVE(GPIO_GPDIR2, 32); + SAVE(GPIO_GPDIR3, 32); + SAVE(GPIO_GPODR0, 32); SAVE(GPIO_GPODR1, 32); SAVE(GPIO_GPODR2, 32); + SAVE(GPIO_GPODR3, 32); + SAVE(GPIO_GPPUR0, 32); SAVE(GPIO_GPPUR1, 32); SAVE(GPIO_GPPUR2, 32); + SAVE(GPIO_GPPUR3, 32); + SAVE(GPIO_GPALR0, 32); SAVE(GPIO_GPALR1, 32); SAVE(GPIO_GPALR2, 32); + SAVE(GPIO_GPALR3, 32); + SAVE(GPIO_GPAUR0, 32); SAVE(GPIO_GPAUR1, 32); SAVE(GPIO_GPAUR2, 32); + SAVE(GPIO_GPAUR3, 32); + SAVE(GPIO_GPIDLR0, 32); SAVE(GPIO_GPIDLR1, 32); SAVE(GPIO_GPIDLR2, 32); + SAVE(GPIO_GPIDLR3, 32); + SAVE(GPIO_GPIDUR0, 32); SAVE(GPIO_GPIDUR1, 32); SAVE(GPIO_GPIDUR2, 32); + SAVE(GPIO_GPIDUR3, 32); + SAVE(GPIO_GPIER0, 32); SAVE(GPIO_GPIER1, 32); SAVE(GPIO_GPIER2, 32); + SAVE(GPIO_GPIER3, 32); + SAVE(GPIO_GPIMR0, 32); SAVE(GPIO_GPIMR1, 32); SAVE(GPIO_GPIMR2, 32); + SAVE(GPIO_GPIMR3, 32); + SAVE(GPIO_GPFR0, 32); SAVE(GPIO_GPFR1, 32); SAVE(GPIO_GPFR2, 32); + SAVE(GPIO_GPFR3, 32); + + SAVE(DMAC_DMACR, 32); + SAVE(DMAC_DSAR0, 32); SAVE(DMAC_DSAR1, 32); SAVE(DMAC_DSAR2, 32); SAVE(DMAC_DSAR3, 32); SAVE(DMAC_DSAR4, 32); SAVE(DMAC_DSAR5, 32); SAVE(DMAC_DSAR6, 32); SAVE(DMAC_DSAR7, 32); + SAVE(DMAC_DDAR0, 32); SAVE(DMAC_DDAR1, 32); SAVE(DMAC_DDAR2, 32); SAVE(DMAC_DDAR3, 32); SAVE(DMAC_DDAR4, 32); SAVE(DMAC_DDAR5, 32); SAVE(DMAC_DDAR6, 32); SAVE(DMAC_DDAR7, 32); + SAVE(DMAC_DTCR0, 32); SAVE(DMAC_DTCR1, 32); SAVE(DMAC_DTCR2, 32); SAVE(DMAC_DTCR3, 32); SAVE(DMAC_DTCR4, 32); SAVE(DMAC_DTCR5, 32); SAVE(DMAC_DTCR6, 32); SAVE(DMAC_DTCR7, 32); + SAVE(DMAC_DRSR0, 32); SAVE(DMAC_DRSR1, 32); SAVE(DMAC_DRSR2, 32); SAVE(DMAC_DRSR3, 32); SAVE(DMAC_DRSR4, 32); SAVE(DMAC_DRSR5, 32); SAVE(DMAC_DRSR6, 32); SAVE(DMAC_DRSR7, 32); + SAVE(DMAC_DCCSR0, 32); SAVE(DMAC_DCCSR1, 32); SAVE(DMAC_DCCSR2, 32); SAVE(DMAC_DCCSR3, 32); SAVE(DMAC_DCCSR4, 32); SAVE(DMAC_DCCSR5, 32); SAVE(DMAC_DCCSR6, 32); SAVE(DMAC_DCCSR7, 32); + + SAVE(INTC_IPR, 32);SAVE(INTC_ISR, 32);SAVE(INTC_IMR, 32); + + SAVE(WDT_WTCNT, 32);SAVE(WDT_WTCSR, 8); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* Save module clocks */ + SAVE(CPM_MSCR, 32); + + /* Save PLL */ + SAVE(CPM_PLCR1, 32); + + /* Stop module clocks */ + __cpm_stop_uart0(); + __cpm_stop_uart1(); + __cpm_stop_uart2(); + __cpm_stop_uart3(); + __cpm_stop_uhc(); + __cpm_stop_udc(); + __cpm_stop_eth(); + __cpm_stop_cim(); + __cpm_stop_kbc(); + __cpm_stop_scc(); + __cpm_stop_ssi(); + __cpm_stop_ost(); + + /* platform-specific pm routine */ + jz_board_pm_suspend(); + + /* Clear previous reset status */ + REG_CPM_RSTR &= ~(CPM_RSTR_HR | CPM_RSTR_WR | CPM_RSTR_SR); + + /* Set resume return address */ + REG_CPM_SPR = virt_to_phys(jz_cpu_resume); + + /* Before sleeping, calculate and save a checksum */ + for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) + checksum += sleep_save[i]; + sleep_save[SLEEP_SAVE_CKSUM] = checksum; + + /* *** go zzz *** */ + jz_cpu_suspend(); +#if 0 + /* after sleeping, validate the checksum */ + checksum = 0; + for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) + checksum += sleep_save[i]; + + /* if invalid, display message and wait for a hardware reset */ + if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) { + /** Add platform-specific message display codes here **/ + while (1); + } +#endif + /* Restore PLL */ + RESTORE(CPM_PLCR1, 32); + + /* Restore module clocks */ + RESTORE(CPM_MSCR, 32); + + /* Ensure not to come back here if it wasn't intended */ + REG_CPM_SPR = 0; + + /* Restore registers */ + + RESTORE(GPIO_GPDR0, 32); RESTORE(GPIO_GPDR1, 32); RESTORE(GPIO_GPDR2, 32); + RESTORE(GPIO_GPDR3, 32); + RESTORE(GPIO_GPDIR0, 32); RESTORE(GPIO_GPDIR1, 32); RESTORE(GPIO_GPDIR2, 32); + RESTORE(GPIO_GPDIR3, 32); + RESTORE(GPIO_GPODR0, 32); RESTORE(GPIO_GPODR1, 32); RESTORE(GPIO_GPODR2, 32); + RESTORE(GPIO_GPODR3, 32); + RESTORE(GPIO_GPPUR0, 32); RESTORE(GPIO_GPPUR1, 32); RESTORE(GPIO_GPPUR2, 32); + RESTORE(GPIO_GPPUR3, 32); + RESTORE(GPIO_GPALR0, 32); RESTORE(GPIO_GPALR1, 32); RESTORE(GPIO_GPALR2, 32); + RESTORE(GPIO_GPALR3, 32); + RESTORE(GPIO_GPAUR0, 32); RESTORE(GPIO_GPAUR1, 32); RESTORE(GPIO_GPAUR2, 32); + RESTORE(GPIO_GPAUR3, 32); + RESTORE(GPIO_GPIDLR0, 32);RESTORE(GPIO_GPIDLR1, 32);RESTORE(GPIO_GPIDLR2, 32); + RESTORE(GPIO_GPIDLR3, 32); + RESTORE(GPIO_GPIDUR0, 32);RESTORE(GPIO_GPIDUR1, 32);RESTORE(GPIO_GPIDUR2, 32); + RESTORE(GPIO_GPIDUR3, 32); + RESTORE(GPIO_GPIER0, 32); RESTORE(GPIO_GPIER1, 32); RESTORE(GPIO_GPIER2, 32); + RESTORE(GPIO_GPIER3, 32); + RESTORE(GPIO_GPIMR0, 32); RESTORE(GPIO_GPIMR1, 32); RESTORE(GPIO_GPIMR2, 32); + RESTORE(GPIO_GPIMR3, 32); + RESTORE(GPIO_GPFR0, 32); RESTORE(GPIO_GPFR1, 32); RESTORE(GPIO_GPFR2, 32); + RESTORE(GPIO_GPFR3, 32); + + RESTORE(EMC_SMCR0, 32); RESTORE(EMC_SMCR1, 32); RESTORE(EMC_SMCR2, 32); RESTORE(EMC_SMCR3, 32); + RESTORE(EMC_SMCR4, 32); RESTORE(EMC_SMCR5, 32); + + RESTORE(HARB_HAPOR, 32); RESTORE(HARB_HMCTR, 32); RESTORE(HARB_HMLTR, 32); + + RESTORE(OST_TCNT0, 32); RESTORE(OST_TCNT1, 32); RESTORE(OST_TCNT2, 32); + RESTORE(OST_TRDR0, 32); RESTORE(OST_TRDR1, 32); RESTORE(OST_TRDR2, 32); + RESTORE(OST_TCSR0, 16); RESTORE(OST_TCSR1, 16); RESTORE(OST_TCSR2, 16); + RESTORE(OST_TER, 8); + + RESTORE(DMAC_DMACR, 32); + RESTORE(DMAC_DSAR0, 32); RESTORE(DMAC_DSAR1, 32); RESTORE(DMAC_DSAR2, 32); RESTORE(DMAC_DSAR3, 32); RESTORE(DMAC_DSAR4, 32); RESTORE(DMAC_DSAR5, 32); RESTORE(DMAC_DSAR6, 32); RESTORE(DMAC_DSAR7, 32); + RESTORE(DMAC_DDAR0, 32); RESTORE(DMAC_DDAR1, 32); RESTORE(DMAC_DDAR2, 32); RESTORE(DMAC_DDAR3, 32); RESTORE(DMAC_DDAR4, 32); RESTORE(DMAC_DDAR5, 32); RESTORE(DMAC_DDAR6, 32); RESTORE(DMAC_DDAR7, 32); + RESTORE(DMAC_DTCR0, 32); RESTORE(DMAC_DTCR1, 32); RESTORE(DMAC_DTCR2, 32); RESTORE(DMAC_DTCR3, 32); RESTORE(DMAC_DTCR4, 32); RESTORE(DMAC_DTCR5, 32); RESTORE(DMAC_DTCR6, 32); RESTORE(DMAC_DTCR7, 32); + RESTORE(DMAC_DRSR0, 32); RESTORE(DMAC_DRSR1, 32); RESTORE(DMAC_DRSR2, 32); RESTORE(DMAC_DRSR3, 32); RESTORE(DMAC_DRSR4, 32); RESTORE(DMAC_DRSR5, 32); RESTORE(DMAC_DRSR6, 32); RESTORE(DMAC_DRSR7, 32); + RESTORE(DMAC_DCCSR0, 32); RESTORE(DMAC_DCCSR1, 32); RESTORE(DMAC_DCCSR2, 32); RESTORE(DMAC_DCCSR3, 32); RESTORE(DMAC_DCCSR4, 32); RESTORE(DMAC_DCCSR5, 32); RESTORE(DMAC_DCCSR6, 32); RESTORE(DMAC_DCCSR7, 32); + + RESTORE(INTC_IPR, 32);RESTORE(INTC_ISR, 32);RESTORE(INTC_IMR, 32); + + REG_WDT_WTCNT = 0; RESTORE(WDT_WTCSR, 8); + + /* + * Temporary solution. This won't be necessary once + * we move this support into the device drivers. + * Restore the on-chip modules. + */ + + /* FIFO control reg, write-only */ + REG8(UART0_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; + REG8(UART1_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; + REG8(UART2_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; + REG8(UART3_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; + + REG8(UART0_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + RESTORE(UART0_DLLR, 8); RESTORE(UART0_DLHR, 8); + REG8(UART0_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + RESTORE(UART0_IER, 8); + RESTORE(UART0_MCR, 8); RESTORE(UART0_SPR, 8); RESTORE(UART0_LCR, 8); + + REG8(UART1_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + RESTORE(UART1_DLLR, 8); RESTORE(UART1_DLHR, 8); + REG8(UART1_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + RESTORE(UART1_IER, 8); + RESTORE(UART1_MCR, 8); RESTORE(UART1_SPR, 8); RESTORE(UART1_LCR, 8); + + REG8(UART2_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + RESTORE(UART2_DLLR, 8); RESTORE(UART2_DLHR, 8); + REG8(UART2_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + RESTORE(UART2_IER, 8); + RESTORE(UART2_MCR, 8); RESTORE(UART2_SPR, 8); RESTORE(UART2_LCR, 8); + + REG8(UART3_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ + RESTORE(UART3_DLLR, 8); RESTORE(UART3_DLHR, 8); + REG8(UART3_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ + RESTORE(UART3_IER, 8); + RESTORE(UART3_MCR, 8); RESTORE(UART3_SPR, 8); RESTORE(UART3_LCR, 8); + + REG_CPM_OCR &= ~CPM_OCR_SUSPEND_PHY0; /* resume USB PHY 0 */ + REG_CPM_OCR &= ~CPM_OCR_SUSPEND_PHY1; /* resume USB PHY 1 */ +#if 0 + REG_CPM_OCR &= ~CPM_OCR_EXT_RTC_CLK; /* use internal RTC clock (JZ_EXTAL/128 Hz) */ +#else + REG_CPM_OCR |= CPM_OCR_EXT_RTC_CLK; /* use external RTC clock (32.768 KHz) */ +#endif + + /* Enable NAND ctroller */ + REG_EMC_NFCSR |= EMC_NFCSR_NFE; + + /* Restore current time */ + xtime.tv_sec = REG_RTC_RSR; + + /* Restore interrupts */ + REG_INTC_IMSR = imr; + REG_INTC_IMCR = ~imr; + + return 0; +} + +/* NOTES: + * 1: Pins that are floated (NC) should be set as input and pull-enable. + * 2: Pins that are pull-up or pull-down by outside should be set as input + * and pull-disable. + * 3: Pins that are connected to a chipset should be set as pull-disable. + */ +static void jz_board_pm_gpio_setup(void) +{ + /* CIM_D0(IN)/PULL-UP/GP0 */ + __gpio_as_input(0); + __gpio_enable_pull(0); + + /* CIM_D1(IN)/PULL-UP/GP1 */ + __gpio_as_input(1); + __gpio_enable_pull(1); + + /* CIM_D2(IN)/PULL-UP/GP2 */ + __gpio_as_input(2); + __gpio_enable_pull(2); + + /* CIM_D3(IN)/PULL-UP/GP3 */ + __gpio_as_input(3); + __gpio_enable_pull(3); + + /* CIM_D4(IN)/PULL-DOWN/GP4 */ + __gpio_as_input(4); + __gpio_enable_pull(4); + + /* CIM_D5(IN)/PULL-DOWN/GP5 */ + __gpio_as_input(5); + __gpio_enable_pull(5); + + /* CIM_D6(IN)/PULL-DOWN/GP6 */ + __gpio_as_input(6); + __gpio_enable_pull(6); + + /* CIM_D7(IN)/PULL-DOWN/GP7 */ + __gpio_as_input(7); + __gpio_enable_pull(7); + + /* CIM_VSYNC(IN)/PULL-DOWN/GP8 */ + __gpio_as_input(8); + __gpio_enable_pull(8); + + /* CIM_HSYNC(IN)/PULL-UP/GP9 */ + __gpio_as_input(9); + __gpio_enable_pull(9); + + /* CIM_PCLK(IN)/PULL-DOWN/GP10 */ + __gpio_as_input(10); + __gpio_enable_pull(10); + + /* CIM_MCLK(OUT)/PULL-DOWN/GP11 */ + __gpio_as_input(11); + __gpio_enable_pull(11); + + /* DMA_DREQ0(IN)/CHIP_MODE/PULL-UP/GP12 */ + __gpio_as_input(12); + __gpio_enable_pull(12); + + /* DMA_DACK0(OUT)/PULL-UP/GP13 */ /* GPIO13 */ + __gpio_as_input(13); + __gpio_disable_pull(13); + + /* GP14 */ + /* GP15 */ + + /* RXD3(IN)/PULL-UP/GP16 */ + __gpio_as_input(16); + __gpio_enable_pull(16); + + /* CTS3(IN)/PULL-UP/GP17 */ + __gpio_as_input(17); + __gpio_enable_pull(17); + + /* GP18 */ + /* GP19 */ + /* GP20 */ + + /* TXD3(OUT)/PULL-UP/GP21 */ + __gpio_as_input(21); + __gpio_enable_pull(21); + + /* GP22 */ + + /* RTS3(OUT)/PULL-UP/GP23 */ + __gpio_as_input(23); + __gpio_enable_pull(23); + + /* RXD1(IN)/PULL-UP/GP24 */ /* IR_RXD */ + __gpio_as_input(24); + __gpio_enable_pull(24); + + /* TXD1(OUT)/PULL-UP/GP25 */ /* IR_TXD */ + __gpio_disable_pull(25); + __gpio_as_output(25); + __cpm_set_pin(25); + + /* DMA_AEN(OUT)/PULL-UP/GP26 */ /* CIM_PWD_N */ + __gpio_as_input(26); + __gpio_disable_pull(26); + + /* DMA_EOP(OUT)/PULL-UP/GP27 */ /* SW4 */ + __gpio_as_input(27); + __gpio_disable_pull(27); + + /* USB_CLK(IN)/PULL-UP/GP28 */ + __gpio_as_input(28); + __gpio_disable_pull(28); + + /* USB_PPWR0(OUT)/PULL-UP/GP29 */ /* USB_CLK_EN */ + __gpio_disable_pull(29); + __gpio_as_output(29); + __cpm_clear_pin(29); /* disable USB 48MHz clock */ + + /* GP30 */ + /* GP31 */ + + /* PS2_KCLK(IO)/PULL-UP/GP32 */ + __gpio_as_input(32); + __gpio_enable_pull(32); + + /* PS2_KDATA(IO)/PULL-UP/GP33 */ /* CIM_RST */ + __gpio_as_input(33); + __gpio_enable_pull(33); + + /* MSC_D0(IO)/PULL-UP/GP34 */ + __gpio_as_input(34); + __gpio_disable_pull(34); + + /* MSC_D1(IO)/PULL-UP/GP35 */ + __gpio_as_input(35); + __gpio_disable_pull(35); + + /* MSC_D2(IO)/PULL-UP/GP36 */ + __gpio_as_input(36); + __gpio_disable_pull(36); + + /* MSC_D3(IO)/PULL-UP/GP37 */ + __gpio_as_input(37); + __gpio_disable_pull(37); + + /* MSC_CMD(IO)/PULL-UP/GP38 */ + __gpio_as_input(38); + __gpio_disable_pull(38); + + /* MSC_CLK(OUT)/PULL-UP/GP39 */ + __gpio_as_input(39); + __gpio_enable_pull(39); + + /* LCD_D0(OUT)/PULL-UP/GP40 */ + __gpio_as_input(40); + __gpio_enable_pull(40); + + /* LCD_D1(OUT)/PULL-UP/GP41 */ + __gpio_as_input(41); + __gpio_enable_pull(41); + + /* LCD_D2(OUT)/PULL-UP/GP42 */ + __gpio_as_input(42); + __gpio_enable_pull(42); + + /* LCD_D3(OUT)/PULL-UP/GP43 */ + __gpio_as_input(43); + __gpio_enable_pull(43); + + /* LCD_D4(OUT)/PULL-UP/GP44 */ + __gpio_as_input(44); + __gpio_enable_pull(44); + + /* LCD_D5(OUT)/PULL-UP/GP45 */ + __gpio_as_input(45); + __gpio_enable_pull(45); + + /* LCD_D6(OUT)/PULL-UP/GP46 */ + __gpio_as_input(46); + __gpio_enable_pull(46); + + /* LCD_D7(OUT)/PULL-UP/GP47 */ + __gpio_as_input(47); + __gpio_enable_pull(47); + + /* LCD_D8(OUT)/PULL-DOWN/GP48 */ + __gpio_as_input(48); + __gpio_enable_pull(48); + + /* LCD_D9(OUT)/PULL-DOWN/GP49 */ + __gpio_as_input(49); + __gpio_enable_pull(49); + + /* LCD_D10(OUT)/PULL-DOWN/GP50 */ + __gpio_as_input(50); + __gpio_enable_pull(50); + + /* LCD_D11(OUT)/PULL-DOWN/GP51 */ + __gpio_as_input(51); + __gpio_enable_pull(51); + + /* LCD_D12(OUT)/PULL-DOWN/GP52 */ + __gpio_as_input(52); + __gpio_enable_pull(52); + + /* LCD_D13(OUT)/PULL-DOWN/GP53 */ + __gpio_as_input(53); + __gpio_enable_pull(53); + + /* LCD_D14(OUT)/PULL-DOWN/GP54 */ + __gpio_as_input(54); + __gpio_enable_pull(54); + + /* LCD_D15(OUT)/PULL-DOWN/GP55 */ + __gpio_as_input(55); + __gpio_enable_pull(55); + + /* LCD_VSYNC(IN)/PULL-DOWN/GP56 */ + __gpio_as_input(56); + __gpio_enable_pull(56); + + /* LCD_HSYNC(IN)/PULL-UP/GP57 */ + __gpio_as_input(57); + __gpio_enable_pull(57); + + /* LCD_PCLK(IN)/PULL-DOWN/GP58 */ + __gpio_as_input(58); + __gpio_enable_pull(58); + + /* LCD_DE(OUT)/PULL-DOWN/GP59 */ + __gpio_as_input(59); + __gpio_enable_pull(59); + + /* LCD_SPL(OUT)/PULL-UP/GP60 */ + __gpio_as_input(60); + __gpio_disable_pull(60); + + /* LCD_CLS(OUT)/PULL-UP/GP61 */ + __gpio_as_input(61); + __gpio_disable_pull(61); + + /* LCD_PS(OUT)/PULL-UP/GP62 */ + __gpio_as_input(62); + __gpio_disable_pull(62); + + /* LCD_REV(OUT)/PULL-UP/GP63 */ + __gpio_as_input(63); + __gpio_enable_pull(63); + + /* SCC0_DAT(IO)/PULL-UP/GP64 */ /* Keypad */ + __gpio_as_input(64); + __gpio_enable_pull(64); + + /* SCC1_DAT(IO)/PULL-UP/GP65 */ /* SW5 */ + __gpio_as_input(65); + __gpio_disable_pull(65); + + /* SCC0_CLK(OUT)/PULL-UP/GP66 */ /* PW_O */ + __gpio_disable_pull(66); + __gpio_as_output(66); + __cpm_set_pin(66); + + /* SCC1_CLK(OUT)/PULL-UP/GP67 */ /* SW6 */ + __gpio_as_input(67); + __gpio_disable_pull(67); + + /* SYS_CLK(OUT)/PULL-UP/GP68 */ /* I2S_CLK */ + __gpio_disable_pull(68); + + /* ACRESET_N(OUT)/PULL-UP/GP69 */ /* AK4642 PDN */ + __gpio_disable_pull(69); + __gpio_as_output(69); + __cpm_clear_pin(69); + + /* SDATA_OUT(OUT)/PULL-UP/GP70 */ /* I2S_DIN */ + __gpio_disable_pull(70); + + /* SDATA_IN(IN)/PULL-UP/GP71 */ /* I2S_DOUT */ + __gpio_disable_pull(71); + + /* SSI_CLK(OUT)/PULL-UP/GP72 */ /* SSI_CLK */ + __gpio_as_input(72); + __gpio_enable_pull(72); + + /* SSI_CE1_N(OUT)/PULL-UP/GP73 */ /* SSI_CE1_N */ + __gpio_as_input(73); + __gpio_enable_pull(73); + + /* SSI_DT(OUT)/PULL-UP/GP74 */ /* SSI_DT */ + __gpio_as_input(74); + __gpio_enable_pull(74); + + /* SSI_DR(IN)/PULL-UP/GP75 */ /* SSI_DR */ + __gpio_as_input(75); + __gpio_enable_pull(75); + + /* SSI_CE2_N(OUT)/SSI_GPC/PULL-UP/GP76 */ + __gpio_as_input(76); + __gpio_enable_pull(76); + + /* BITCLK_IN(IN)/PULL-UP/GP77 */ /* I2S_BITCLK */ + __gpio_disable_pull(77); + + /* SYNC_IN(IN)/PULL-UP/GP78 */ /* I2S_LRCIN */ + __gpio_disable_pull(78); + + /* FRE_N(OUT)/PULL-UP/GP79 */ + __gpio_enable_pull(79); + __gpio_as_input(79); + + /* FWE_N(OUT)/PULL-UP/GP80 */ + __gpio_enable_pull(80); + __gpio_as_input(80); + + /* FRB_N(IN)/PULL-UP/GP81 */ + __gpio_enable_pull(81); + __gpio_as_input(81); + + /* DCS1_N(OUT)/PULL-UP/GP82 */ /* SD_WP */ + __gpio_as_input(82); + __gpio_enable_pull(82); + + /* CS1_N(OUT)/PULL-UP/GP83 */ /* JACK_PLUG */ + __gpio_as_input(83); + __gpio_disable_pull(83); + + /* CS2_N(OUT)/PULL-UP/GP84 */ /* DC_DETE */ + __gpio_as_input(84); + __gpio_disable_pull(84); + + /* CS3_N(OUT)/PULL-UP/GP85 */ /* NAND CS# */ + __gpio_enable_pull(85); + __gpio_as_input(85); + + /* CS4_N/(OUT)PULL-UP/GP86 */ /* PULL_OFF */ + __gpio_disable_pull(86); + __gpio_as_output(86); +// __cpm_set_pin(86); + __cpm_clear_pin(86); + + /* CS5_N(OUT)/PULL-UP/GP87 */ /* IR_SD */ + __gpio_as_input(87); + __gpio_disable_pull(87); + + /* INPACK_N(IN)/PULL-UP/GP88 */ /* SW7 */ + __gpio_as_input(88); + __gpio_disable_pull(88); + + /* BVD2(IN)/PULL-UP/GP89 */ /* SW8 */ + __gpio_as_input(89); + __gpio_disable_pull(89); + + /* PCE1_N(OUT)/PULL-UP/GP90 */ /* SD_CD_N */ + __gpio_as_input(90); + __gpio_enable_pull(90); + + /* PSKTSEL_N(OUT)/PULL-UP/GP91 */ /* SD_VCC_3V_EN_N */ + __gpio_disable_pull(91); + __gpio_as_output(91); + __cpm_clear_pin(91); + + /* IOIS16_N(IN)/PULL-UP/GP92 */ /* LED_EN */ + __gpio_disable_pull(92); + __gpio_as_output(92); + __cpm_clear_pin(92); + + /* PCE2_N(OUT)/PULL-UP/GP93 */ /* LCD_DISP_OFF_N */ + __gpio_disable_pull(93); + __gpio_as_input(93); + + /* PWM0(OUT)/PULL-UP/GP94 */ /* LCD backlight off */ + __gpio_disable_pull(94); + __gpio_as_output(94); + __cpm_clear_pin(94); + + /* PWM1(OUT)/PULL-UP/GP95 */ + __gpio_disable_pull(95); + __gpio_as_output(95); + __cpm_clear_pin(95); + + /* PRT(OUT)/PULL-UP/GP96 */ /* RTC_IRQ */ + __gpio_as_input(96); + __gpio_disable_pull(96); + + /* PRT(OUT)/PULL-UP/GP97 */ /* PW_I */ + __gpio_as_input(97); + __gpio_disable_pull(97); + + /* PRT(OUT)/PULL-UP/GP98 */ /* Keypad */ + __gpio_as_input(98); + __gpio_disable_pull(98); + + /* PRT(OUT)/PULL-UP/GP99 */ /* Keypad */ + __gpio_as_input(99); + __gpio_disable_pull(99); + + /* PRT(OUT)/PULL-UP/GP100 */ /* Keypad */ + __gpio_as_input(100); + __gpio_disable_pull(100); + + /* PRT(OUT)/PULL-UP/GP101 */ /* Keypad */ + __gpio_as_input(101); + __gpio_disable_pull(101); + + /* PRT(OUT)/PULL-UP/GP102 */ /* Keypad */ + __gpio_as_input(102); + __gpio_disable_pull(102); + + /* PRT(OUT)/PULL-UP/GP103 */ /* Keypad */ + __gpio_as_input(103); + __gpio_enable_pull(103); + + /* PRT(OUT)/PULL-UP/GP104 */ /* Keypad */ + __gpio_as_input(104); + __gpio_enable_pull(104); + + /* PRT(OUT)/PULL-UP/GP105 */ /* Keypad */ + __gpio_as_input(105); + __gpio_enable_pull(105); + + /* PRT(OUT)/PULL-UP/GP106 */ /* 5V_ON */ + __gpio_disable_pull(106); + __gpio_as_output(106); + __cpm_clear_pin(106); + + /* PRT(IN)/PULL-UP/GP107 */ /* GSM_BOOT */ + __gpio_as_input(107); + __gpio_enable_pull(107); + + /* PRT(IN)/PULL-UP/GP108 */ /* GSM_RESET */ + __gpio_as_input(108); + __gpio_enable_pull(108); + + /* PRT(IN)/PULL-UP/GP109 */ /* GSM_EN */ + __gpio_as_input(109); + __gpio_enable_pull(109); + + /* PRT(IN)/PULL-UP/GP110 */ /* GSM_RING */ + __gpio_as_input(110); + __gpio_enable_pull(110); + + /* PRT(IN)/UART2_RXD/PULL-UP/GP111 */ /* Keypad */ + __gpio_as_input(111); + __gpio_enable_pull(111); + + /* MII_TX_EN(OUT)/PULL-UP/GP112 */ + __gpio_as_input(112); + __gpio_enable_pull(112); + + /* MII_RX_DV(IN)/PULL-UP/GP113 */ + __gpio_as_input(113); + __gpio_enable_pull(113); + + /* MII_RX_ER(IN)/PULL-UP/GP114 */ + __gpio_as_input(114); + __gpio_enable_pull(114); + + /* MII_COL(IN)/PULL-UP/GP115 */ + __gpio_as_input(115); + __gpio_enable_pull(115); + + /* MII_CRS(IN)/PULL-UP/GP116 */ + __gpio_as_input(116); + __gpio_enable_pull(116); + + /* MII_TXD0(OUT)/PULL-UP/GP117 */ + __gpio_as_input(117); + __gpio_enable_pull(117); + + /* MII_TXD1(OUT)/PULL-UP/GP118 */ + __gpio_as_input(118); + __gpio_enable_pull(118); + + /* MII_TXD2(OUT)/PULL-UP/GP119 */ + __gpio_as_input(119); + __gpio_enable_pull(119); + + /* MII_TXD3(OUT)/PULL-UP/GP120 */ + __gpio_as_input(120); + __gpio_enable_pull(120); + + /* MII_RXD0(IN)/PULL-UP/GP121 */ + __gpio_as_input(121); + __gpio_enable_pull(121); + + /* MII_RXD1(IN)/PULL-UP/GP122 */ + __gpio_as_input(122); + __gpio_enable_pull(122); + + /* MII_RXD2(IN)/PULL-UP/GP123 */ + __gpio_as_input(123); + __gpio_enable_pull(123); + + /* MII_RXD3(IN)/PULL-UP/GP124 */ + __gpio_as_input(124); + __gpio_enable_pull(124); + + /* UART2_TXD(OUT)/PULL-UP/GP125 */ /* CHARG_STAT */ + __gpio_as_output(125); + __gpio_disable_pull(125); + __cpm_clear_pin(125); + + /* UART0_RXD(IN)/PULL-UP/GP126 */ + __gpio_as_input(126); + __gpio_enable_pull(126); + + /* UART0_TXD(OUT)/PULL-UP/GP127 */ + __gpio_as_input(127); + __gpio_enable_pull(127); +} + +/* + * In order to save power most, all gpio pins should be put to their + * proper states during low power mode. + */ +static void jz_board_pm_suspend(void) +{ + /* Setup the state of all the GPIO pins during low-power mode */ + jz_board_pm_gpio_setup(); + + /* Allow next interrupts to wakeup the system. + */ + REG_CPM_WER = 0; /* Clear all first */ + + /* RTC alarm */ + REG_CPM_WER |= 1 << 0; + REG_CPM_WRER |= 1 << 0; + REG_CPM_WFER |= 1 << 0; + __gpio_as_irq_rise_edge(96); + + /* Power_I key */ + REG_CPM_WER |= 1 << 1; + REG_CPM_WRER |= 1 << 1; + REG_CPM_WFER |= 1 << 1; + __gpio_as_irq_rise_edge(97); + + /* enable INTC irq */ + __intc_unmask_irq(IRQ_GPIO3); + +#if 0 + /* Enable RTC alarm */ + REG_CPM_WER |= CPM_WER_WERTC; + REG_RTC_RGR = 32767; + REG_RTC_RCR &= ~RTC_RCR_AE; + REG_RTC_RSR = 0; + REG_RTC_RSAR = 30; + REG_RTC_RCR = RTC_RCR_AE | RTC_RCR_AIE | RTC_RCR_START; +#endif +} + +/* + * We don't use sleep mode of jz4730 for it has bug, the suspend mode + * implemented by hibernate mode is used instead of it. + */ +static int jz_pm_do_sleep(void) +{ + printk("It was deprecated, please use /proc/sys/pm/suspend.\n"); +#if 0 + unsigned long imr = REG_INTC_IMR; + + /* Preserve current time */ + REG_RTC_RSR = xtime.tv_sec; + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* Just allow next interrupts to wakeup the system. + * Note: modify this according to your system. + */ + /* RTC alarm */ + __gpio_as_irq_fall_edge(96); /* GPIO 96 */ + + /* POWER_I key */ + __gpio_as_irq_rise_edge(97); /* GPIO 97 */ + + /* Enable INTC */ + __intc_unmask_irq(IRQ_GPIO3); + + /* Disable modules e.g. LCD backlight */ + + /* Stop module clocks */ + __cpm_stop_uhc(); + + /* Enter SLEEP mode + * Put SDRAM into self-refresh mode. + */ + REG_CPM_LPCR &= ~CPM_LPCR_LPM_MASK; + REG_CPM_LPCR |= CPM_LPCR_LPM_SLEEP; + + __asm__(".set\tmips3\n\t" + ".set noreorder\n\t" + ".align 5\n\t" + "wait\n\t" + "nop\n\t" + ".set reorder\n\t" + ".set\tmips0"); + + /* Restore to IDLE mode */ + REG_CPM_LPCR &= ~CPM_LPCR_LPM_MASK; + REG_CPM_LPCR |= CPM_LPCR_LPM_IDLE; + + /* Restore clock of usb host */ + __cpm_start_uhc(); + + /* Restore interrupts */ + REG_INTC_IMSR = imr; + REG_INTC_IMCR = ~imr; + + /* Restore current time */ + xtime.tv_sec = REG_RTC_RSR; +#endif + return 0; +} + +#define K0BASE KSEG0 +void jz_flush_cache_all(void) +{ + unsigned long addr; + + /* Clear CP0 TagLo */ + asm volatile ("mtc0 $0, $28\n\t"::); + + for (addr = K0BASE; addr < (K0BASE + 0x4000); addr += 32) { + asm volatile ( + ".set mips3\n\t" + " cache %0, 0(%1)\n\t" + ".set mips2\n\t" + : + : "I" (Index_Writeback_Inv_D), "r"(addr)); + + asm volatile ( + ".set mips3\n\t" + " cache %0, 0(%1)\n\t" + ".set mips2\n\t" + : + : "I" (Index_Store_Tag_I), "r"(addr)); + } + + asm volatile ("sync\n\t"::); + + /* invalidate BTB */ + asm volatile ( + ".set mips32\n\t" + " mfc0 %0, $16, 7\n\t" + " nop\n\t" + " ori $0, 2\n\t" + " mtc0 %0, $16, 7\n\t" + " nop\n\t" + ".set mips2\n\t" + : + : "r"(addr)); +} + +/* Put CPU to HIBERNATE mode */ +int jz_pm_suspend(void) +{ + int retval; + + pm_send_all(PM_SUSPEND, (void *)3); + + retval = jz_pm_do_suspend(); + + pm_send_all(PM_RESUME, (void *)0); + + return retval; +} + +#if 0 +/* Put CPU to SLEEP mode */ +int jz_pm_sleep(void) +{ + return jz_pm_do_sleep(); +} + +/* Put CPU to IDLE mode, used for dpm in linux 2.4 */ +void jz_pm_idle(void) +{ + local_irq_disable(); + if (!need_resched()) { + local_irq_enable(); + cpu_wait(); + } +} +#endif + +#ifdef CONFIG_SYSCTL + +/* + * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6 + * when all the PM interfaces exist nicely. + */ +#define CTL_PM_SUSPEND 1 +#define CTL_PM_HIBERNATE 2 + +/*---------------------------------------------------------------------------- + * Power Management sleep sysctl proc interface + * + * A write to /proc/sys/pm/suspend invokes this function + * which initiates a sleep. + *--------------------------------------------------------------------------*/ +static int sysctl_jz_pm_sleep(void) +{ + return jz_pm_suspend(); +} + +static struct ctl_table pm_table[] = +{ + { + .ctl_name = CTL_UNNUMBERED, + .procname = "suspend", + .data = NULL, + .maxlen = 0, + .mode = 0600, + .proc_handler = &sysctl_jz_pm_sleep, + }, + { .ctl_name = 0} +}; + +static struct ctl_table pm_dir_table[] = +{ + { + .ctl_name = CTL_UNNUMBERED, + .procname = "pm", + .mode = 0555, + .child = pm_table, + }, + { .ctl_name = 0} +}; + +#endif /* CONFIG_SYSCTL */ + +/* + * Initialize power interface + */ +static int __init jz_pm_init(void) +{ + printk("Power Management for JZ\n"); + +#ifdef CONFIG_SYSCTL + register_sysctl_table(pm_dir_table); +#endif + + return 0; +} + +module_init(jz_pm_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/proc.c linux-2.6.24.3-20100304/arch/mips/jz4730/proc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/proc.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,292 @@ +/* + * linux/arch/mips/jz4730/proc.c + * + * /proc/jz/ procfs for on-chip peripherals. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct proc_dir_entry *proc_jz_root; + +/* + * EMC Module + */ +static int emc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "BCR: 0x%08x\n", REG_EMC_BCR); + len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4, REG_EMC_SMCR5); + len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4, REG_EMC_SACR5); + len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); + len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); + len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); + len += sprintf (page+len, "DMAR(0-1): 0x%08x 0x%08x\n", REG_EMC_DMAR1, REG_EMC_DMAR2); + return len; +} + +/* + * Power Manager Module + */ +static int pmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned long lpcr = REG_CPM_LPCR; + unsigned long mscr = REG_CPM_MSCR; + + len += sprintf (page+len, "LPCR : 0x%08lx\n", lpcr); + len += sprintf (page+len, "Low Power Mode : %s\n", + ((lpcr & CPM_LPCR_LPM_MASK) == (CPM_LPCR_LPM_IDLE)) ? + "idle" : (((lpcr & CPM_LPCR_LPM_MASK) == (CPM_LPCR_LPM_SLEEP)) ? "sleep" : "hibernate")); + len += sprintf (page+len, "Doze Mode : %s\n", + (lpcr & CPM_LPCR_DOZE) ? "on" : "off"); + if (lpcr & CPM_LPCR_DOZE) + len += sprintf (page+len, " duty : %d\n", (int)((lpcr & CPM_LPCR_DUTY_MASK) >> CPM_LPCR_DUTY_BIT)); + len += sprintf (page+len, "CKO1 : %s\n", + (REG_CPM_CFCR & CPM_CFCR_CKOEN1) ? "enable" : "disable"); + len += sprintf (page+len, "UART0 : %s\n", + (mscr & CPM_MSCR_MSTP_UART0) ? "stopped" : "running"); + len += sprintf (page+len, "UART1 : %s\n", + (mscr & CPM_MSCR_MSTP_UART1) ? "stopped" : "running"); + len += sprintf (page+len, "UART2 : %s\n", + (mscr & CPM_MSCR_MSTP_UART2) ? "stopped" : "running"); + len += sprintf (page+len, "UART3 : %s\n", + (mscr & CPM_MSCR_MSTP_UART3) ? "stopped" : "running"); + len += sprintf (page+len, "OST : %s\n", + (mscr & CPM_MSCR_MSTP_OST) ? "stopped" : "running"); + len += sprintf (page+len, "DMAC : %s\n", + (mscr & CPM_MSCR_MSTP_DMAC) ? "stopped" : "running"); + len += sprintf (page+len, "ETH : %s\n", + (mscr & CPM_MSCR_MSTP_ETH) ? "stopped" : "running"); + len += sprintf (page+len, "UHC/UDC : %s\n", + (mscr & CPM_MSCR_MSTP_UHC) ? "stopped" : "running"); + len += sprintf (page+len, "PWM0 : %s\n", + (mscr & CPM_MSCR_MSTP_PWM0) ? "stopped" : "running"); + len += sprintf (page+len, "PWM1 : %s\n", + (mscr & CPM_MSCR_MSTP_PWM1) ? "stopped" : "running"); + len += sprintf (page+len, "I2C : %s\n", + (mscr & CPM_MSCR_MSTP_I2C) ? "stopped" : "running"); + len += sprintf (page+len, "SSI : %s\n", + (mscr & CPM_MSCR_MSTP_SSI) ? "stopped" : "running"); + len += sprintf (page+len, "SCC : %s\n", + (mscr & CPM_MSCR_MSTP_SCC) ? "stopped" : "running"); + return len; +} + +static int pmc_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) +{ + REG_CPM_MSCR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * Clock Generation Module + */ +static int cgm_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int cfcr = REG_CPM_CFCR; + unsigned int plcr1 = REG_CPM_PLCR1; + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + + len += sprintf (page+len, "PLCR1 : 0x%08x\n", plcr1); + len += sprintf (page+len, "CFCR : 0x%08x\n", cfcr); + len += sprintf (page+len, "PLL : %s\n", + (plcr1 & CPM_PLCR1_PLL1EN) ? "ON" : "OFF"); + len += sprintf (page+len, "NF:NR:NO : %d:%d:%d\n", + __cpm_plcr1_fd() + 2, + __cpm_plcr1_rd() + 2, + od[__cpm_plcr1_od()] + ); + len += sprintf (page+len, "I:S:M:P : %d:%d:%d:%d\n", + div[(cfcr & CPM_CFCR_IFR_MASK) >> CPM_CFCR_IFR_BIT], + div[(cfcr & CPM_CFCR_SFR_MASK) >> CPM_CFCR_SFR_BIT], + div[(cfcr & CPM_CFCR_MFR_MASK) >> CPM_CFCR_MFR_BIT], + div[(cfcr & CPM_CFCR_PFR_MASK) >> CPM_CFCR_PFR_BIT] + ); + len += sprintf (page+len, "PLL Freq : %d MHz\n", __cpm_get_pllout()/1000000); + len += sprintf (page+len, "ICLK : %d MHz\n", __cpm_get_iclk()/1000000); + len += sprintf (page+len, "SCLK : %d MHz\n", __cpm_get_sclk()/1000000); + len += sprintf (page+len, "MCLK : %d MHz\n", __cpm_get_mclk()/1000000); + len += sprintf (page+len, "PCLK : %d MHz\n", __cpm_get_pclk()/1000000); + len += sprintf (page+len, "DEVCLK : %d MHz\n", __cpm_get_devclk()/1000000); + len += sprintf (page+len, "RTCCLK : %d KHz\n", __cpm_get_rtcclk()/1000); + len += sprintf (page+len, "USBCLK : %d MHz\n", __cpm_get_usbclk()/1000000); +#if defined(CONFIG_FB_JZ) + len += sprintf (page+len, "LCDCLK : %d MHz\n", __cpm_get_lcdclk()/1000000); + len += sprintf (page+len, "PIXCLK : %d MHz\n", __cpm_get_pixclk()/1000000); +#endif + return len; +} + +static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CFCR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * WDT + */ +static int wdt_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "WDT_WTCSR : 0x%08x\n", REG_WDT_WTCSR); + len += sprintf (page+len, "WDT_WTCNT : 0x%08x\n", REG_WDT_WTCNT); + + return len; +} + +static int wdt_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned long cnt = simple_strtoul(buffer, 0, 16); + + REG_WDT_WTCNT = cnt; + REG_WDT_WTCSR = WDT_WTCSR_START; + + return count; +} + +/* + * PWM + */ + +static int proc_jz_pwm_read_byte(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return sprintf (page, "0x%02x\n", REG8(data)); +} + +static int proc_jz_pwm_read_word(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return sprintf (page, "0x%04x\n", REG16(data)); +} + +static int proc_jz_pwm_write_byte(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG8(data) = simple_strtoul(buffer, 0, 16); + return count; +} + +static int proc_jz_pwm_write_word(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG16(data) = simple_strtoul(buffer, 0, 16); + return count; +} + +#define PWM_NUM 2 + +static int jz_pwm_proc_init(void) +{ + struct proc_dir_entry *proc_jz_pwm, *res; + char name[16]; + unsigned char i; + + for (i = 0; i < PWM_NUM; i++) { + sprintf(name, "pwm%d", i); + proc_jz_pwm = proc_mkdir(name, proc_jz_root); + res = create_proc_entry("control", 0600, proc_jz_pwm); + if ( res) { + res->read_proc = proc_jz_pwm_read_byte; + res->write_proc = proc_jz_pwm_write_byte; + if (i) + res->data = (void * )PWM_CTR(1); + else + res->data = (void * )PWM_CTR(0); + } + res = create_proc_entry("period", 0600, proc_jz_pwm); + if ( res) { + res->read_proc = proc_jz_pwm_read_word; + res->write_proc = proc_jz_pwm_write_word; + if (i) + res->data = (void *)PWM_PER(1); + else + res->data = (void *)PWM_PER(0); + } + res = create_proc_entry("duty", 0600, proc_jz_pwm); + if ( res) { + res->read_proc = proc_jz_pwm_read_word; + res->write_proc = proc_jz_pwm_write_word; + if (i) + res->data = (void * )PWM_DUT(1); + else + res->data = (void * )PWM_DUT(0); + } + } + return 0; +} + +/* + * /proc/jz/xxx entry + * + */ +static int __init jz_proc_init(void) +{ + struct proc_dir_entry *entry; + + /* create /proc/jz */ + proc_jz_root = proc_mkdir("jz", 0); + + /* create /proc/jz/emc */ + entry = create_proc_entry("emc", 0644, proc_jz_root); + if (entry) { + entry->read_proc = emc_read_proc; + entry->write_proc = NULL; + entry->data = NULL; + } + + /* create /proc/jz/pmc */ + entry = create_proc_entry("pmc", 0644, proc_jz_root); + if (entry) { + entry->read_proc = pmc_read_proc; + entry->write_proc = pmc_write_proc; + entry->data = NULL; + } + + /* create /proc/jz/cgm */ + entry = create_proc_entry("cgm", 0644, proc_jz_root); + if (entry) { + entry->read_proc = cgm_read_proc; + entry->write_proc = cgm_write_proc; + entry->data = NULL; + } + + /* create /proc/jz/wdt */ + entry = create_proc_entry("wdt", 0644, proc_jz_root); + if (entry) { + entry->read_proc = wdt_read_proc; + entry->write_proc = wdt_write_proc; + entry->data = NULL; + } + + /* PWM */ + jz_pwm_proc_init(); + + return 0; +} + +__initcall(jz_proc_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/prom.c linux-2.6.24.3-20100304/arch/mips/jz4730/prom.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/prom.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,198 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, supports YAMON and U-Boot. + * + * Copyright 2000, 2001, 2006 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +int prom_argc; +char **prom_argv, **prom_envp; + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + if (prom_argc > 1) + *cp = '\0'; + +} + + +char *prom_getenv(char *envname) +{ +#if 0 + /* + * Return a pointer to the given environment variable. + * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". + */ + + char **env = prom_envp; + int i = strlen(envname); + int yamon = (*env && strchr(*env, '=') == NULL); + + while (*env) { + if (yamon) { + if (strcmp(envname, *env++) == 0) + return *env; + } else { + if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; + } + env++; + } +#endif + return NULL; +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machtype = MACH_INGENIC_JZ4730; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +/* used by early printk */ +void prom_putchar(char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART3_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART3_BASE + OFF_TDR); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +const char *get_system_type(void) +{ + return "JZ4730"; +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/reset.c linux-2.6.24.3-20100304/arch/mips/jz4730/reset.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/reset.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,40 @@ +/* + * linux/arch/mips/jz4730/reset.c + * + * JZ4730 reset routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void jz_restart(char *command) +{ + __wdt_set_count(0xffffffff-32); /* reset after 1/1024 s */ + __wdt_start(); + while (1); +} + +void jz_halt(void) +{ + __wdt_set_count(0xffffffff-32); /* reset after 1/1024 s */ + __wdt_start(); + while (1); +} + +void jz_power_off(void) +{ + jz_halt(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/setup.c linux-2.6.24.3-20100304/arch/mips/jz4730/setup.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/setup.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,182 @@ +/* + * linux/arch/mips/jz4730/setup.c + * + * JZ4730 CPU common setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PC_KEYB +#include +#endif + +jz_clocks_t jz_clocks; + +extern char * __init prom_getcmdline(void); +extern void __init jz_board_setup(void); +extern void jz_restart(char *); +extern void jz_halt(void); +extern void jz_power_off(void); +extern void jz_time_init(void); + +static void __init sysclocks_setup(void) +{ +#ifndef CONFIG_JZ4730_URANUS + jz_clocks.iclk = __cpm_get_iclk(); + jz_clocks.sclk = __cpm_get_sclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.devclk = __cpm_get_devclk(); + jz_clocks.rtcclk = __cpm_get_rtcclk(); + jz_clocks.uartclk = __cpm_get_uartclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.mscclk = __cpm_get_mscclk(); +#else /* URANUS FPGA */ + +#define FPGACLK 8000000 + + jz_clocks.iclk = FPGACLK; + jz_clocks.sclk = FPGACLK; + jz_clocks.mclk = FPGACLK; + jz_clocks.devclk = FPGACLK; + jz_clocks.rtcclk = FPGACLK; + jz_clocks.uartclk = FPGACLK; + jz_clocks.pixclk = FPGACLK; + jz_clocks.lcdclk = FPGACLK; + jz_clocks.usbclk = FPGACLK; + jz_clocks.i2sclk = FPGACLK; + jz_clocks.mscclk = FPGACLK; +#endif + + printk("CPU clock: %dMHz, System clock: %dMHz, Memory clock: %dMHz, Peripheral clock: %dMHz\n", + (jz_clocks.iclk + 500000) / 1000000, + (jz_clocks.sclk + 500000) / 1000000, + (jz_clocks.mclk + 500000) / 1000000, + (jz_clocks.pclk + 500000) / 1000000); +} + +static void __init soc_cpm_setup(void) +{ + __cpm_idle_mode(); + __cpm_enable_cko1(); + __cpm_start_all(); + + /* get system clocks */ + sysclocks_setup(); +} + +static void __init soc_harb_setup(void) +{ +// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ + __harb_set_priority(0x08); /* DMAC>LCD>CIM>ETH>USB>CIM */ +// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ +} + +static void __init soc_emc_setup(void) +{ +} + +static void __init soc_dmac_setup(void) +{ + __dmac_enable_all_channels(); +} + +static void __init jz_soc_setup(void) +{ + soc_cpm_setup(); + soc_harb_setup(); + soc_emc_setup(); + soc_dmac_setup(); +} + +static void __init jz_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + + memset(&s, 0, sizeof(s)); + + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = UPIO_MEM; + s.regshift = 2; + s.uartclk = jz_clocks.uartclk; + + s.line = 0; + s.membase = (u8 *)UART0_BASE; + s.irq = IRQ_UART0; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS0 setup failed!\n"); + } + + s.line = 1; + s.membase = (u8 *)UART1_BASE; + s.irq = IRQ_UART1; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS1 setup failed!\n"); + } + + s.line = 2; + s.membase = (u8 *)UART2_BASE; + s.irq = IRQ_UART2; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS2 setup failed!\n"); + } + + s.line = 3; + s.membase = (u8 *)UART3_BASE; + s.irq = IRQ_UART3; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS3 setup failed!\n"); + } +#endif +} + +void __init plat_mem_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + + /* IO/MEM resources. */ + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x00000000; + iomem_resource.end = 0xffffffff; + + _machine_restart = jz_restart; + _machine_halt = jz_halt; + pm_power_off = jz_power_off; + + jz_soc_setup(); /* soc specific setup */ + jz_serial_setup(); /* serial port setup */ + jz_board_setup(); /* board specific setup */ +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/sleep.S linux-2.6.24.3-20100304/arch/mips/jz4730/sleep.S --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/sleep.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/sleep.S 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,307 @@ +/* + * linux/arch/mips/jz4730/sleep.S + * + * jz4730 Assembler Sleep/WakeUp Management Routines + * + * Copyright (C) 2005 Ingenic Semiconductor + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + + .text + .set noreorder + .set noat + + .extern jz_flush_cache_all + +/* + * jz_cpu_suspend() + * + * Forces CPU into hibernate mode + */ + + .globl jz_cpu_suspend +jz_cpu_suspend: + + /* save hi, lo and general registers except k0($26) and k1($27) (total 32) */ + move k0, sp + addiu k0, k0, -(32*4) + mfhi k1 + sw $0, 0(k0) + sw $1, 4(k0) + sw k1, 120(k0) /* hi */ + mflo k1 + sw $2, 8(k0) + sw $3, 12(k0) + sw k1, 124(k0) /* lo */ + sw $4, 16(k0) + sw $5, 20(k0) + sw $6, 24(k0) + sw $7, 28(k0) + sw $8, 32(k0) + sw $9, 36(k0) + sw $10, 40(k0) + sw $11, 44(k0) + sw $12, 48(k0) + sw $13, 52(k0) + sw $14, 56(k0) + sw $15, 60(k0) + sw $16, 64(k0) + sw $17, 68(k0) + sw $18, 72(k0) + sw $19, 76(k0) + sw $20, 80(k0) + sw $21, 84(k0) + sw $22, 88(k0) + sw $23, 92(k0) + sw $24, 96(k0) + sw $25, 100(k0) + sw $28, 104(k0) + sw $29, 108(k0) /* saved sp */ + sw $30, 112(k0) + sw $31, 116(k0) /* saved ra */ + move sp, k0 + + /* save CP0 registers and sp (total 26) */ + move k0, sp + addiu k0, k0, -(26*4) + + mfc0 $1, CP0_INDEX + mfc0 $2, CP0_RANDOM + mfc0 $3, CP0_ENTRYLO0 + mfc0 $4, CP0_ENTRYLO1 + mfc0 $5, CP0_CONTEXT + mfc0 $6, CP0_PAGEMASK + mfc0 $7, CP0_WIRED + mfc0 $8, CP0_BADVADDR + mfc0 $9, CP0_ENTRYHI + mfc0 $10, CP0_STATUS +/* mfc0 $11, $12, 1*/ /* IntCtl */ + mfc0 $12, CP0_CAUSE + mfc0 $13, CP0_EPC +/* mfc0 $14, $15, 1*/ /* EBase */ + mfc0 $15, CP0_CONFIG +/* mfc0 $16, CP0_CONFIG, 7*/ /* Config 7 */ + mfc0 $17, CP0_LLADDR + mfc0 $18, CP0_WATCHLO + mfc0 $19, CP0_WATCHHI + mfc0 $20, CP0_DEBUG + mfc0 $21, CP0_DEPC + mfc0 $22, CP0_ECC + mfc0 $23, CP0_TAGLO + mfc0 $24, CP0_ERROREPC + mfc0 $25, CP0_DESAVE + + sw $1, 0(k0) + sw $2, 4(k0) + sw $3, 8(k0) + sw $4, 12(k0) + sw $5, 16(k0) + sw $6, 20(k0) + sw $7, 24(k0) + sw $8, 28(k0) + sw $9, 32(k0) + sw $10, 36(k0) + sw $11, 40(k0) + sw $12, 44(k0) + sw $13, 48(k0) + sw $14, 52(k0) + sw $15, 56(k0) + sw $16, 60(k0) + sw $17, 64(k0) + sw $18, 68(k0) + sw $19, 72(k0) + sw $20, 76(k0) + sw $21, 80(k0) + sw $22, 84(k0) + sw $23, 88(k0) + sw $24, 92(k0) + sw $25, 96(k0) + sw $29, 100(k0) /* saved sp */ + move sp, k0 + + /* preserve virtual address of stack */ + la k0, suspend_save_sp + sw sp, 0(k0) + + /* flush caches and write buffers */ + jal jz_flush_cache_all + nop + + /* set new sdram refresh constant */ + li t0, 1 + la t1, EMC_RTCOR + sh t0, 0(t1) + + /* disable PLL */ + la t0, CPM_PLCR1 + sw $0, 0(t0) + + /* put CPU to hibernate mode */ + la t0, CPM_LPCR + lw t1, 0(t0) + li t2, ~CPM_LPCR_LPM_MASK + and t1, t2 + ori t1, CPM_LPCR_LPM_HIBERNATE + + .align 5 + /* align execution to a cache line */ + j 1f + + .align 5 +1: + /* all needed values are now in registers. + * These last instructions should be in cache + */ + nop + nop + + /* set hibernate mode */ + sw t1, 0(t0) + nop + + /* enter hibernate mode */ + .set mips3 + wait + nop + .set mips2 + +2: j 2b /* loop waiting for suspended */ + nop + +/* + * jz_cpu_resume() + * + * entry point from bootloader into kernel during resume + */ + + .align 5 + .globl jz_cpu_resume +jz_cpu_resume: + /* clear SCR.HGP */ + la t0, CPM_SCR + lw t1, 0(t0) + li t2, ~CPM_SCR_HGP + and t1, t2 + sw t1, 0(t0) + + /* restore LPCR.LPM to IDLE mode */ + la t0, CPM_LPCR + lw t1, 0(t0) + li t2, ~CPM_LPCR_LPM_MASK + and t1, t2 + ori t1, CPM_LPCR_LPM_IDLE + sw t1, 0(t0) + + /* restore saved sp */ + la t0, suspend_save_sp + lw sp, 0(t0) + + /* restore CP0 registers */ + move k0, sp + lw $1, 0(k0) + lw $2, 4(k0) + lw $3, 8(k0) + lw $4, 12(k0) + lw $5, 16(k0) + lw $6, 20(k0) + lw $7, 24(k0) + lw $8, 28(k0) + lw $9, 32(k0) + lw $10, 36(k0) + lw $11, 40(k0) + lw $12, 44(k0) + lw $13, 48(k0) + lw $14, 52(k0) + lw $15, 56(k0) + lw $16, 60(k0) + lw $17, 64(k0) + lw $18, 68(k0) + lw $19, 72(k0) + lw $20, 76(k0) + lw $21, 80(k0) + lw $22, 84(k0) + lw $23, 88(k0) + lw $24, 92(k0) + lw $25, 96(k0) + lw $29, 100(k0) /* saved sp */ + + mtc0 $1, CP0_INDEX + mtc0 $2, CP0_RANDOM + mtc0 $3, CP0_ENTRYLO0 + mtc0 $4, CP0_ENTRYLO1 + mtc0 $5, CP0_CONTEXT + mtc0 $6, CP0_PAGEMASK + mtc0 $7, CP0_WIRED + mtc0 $8, CP0_BADVADDR + mtc0 $9, CP0_ENTRYHI + mtc0 $10, CP0_STATUS +/* mtc0 $11, $12, 1*/ /* IntCtl */ + mtc0 $12, CP0_CAUSE + mtc0 $13, CP0_EPC +/* mtc0 $14, $15, 1*/ /* EBase */ + mtc0 $15, CP0_CONFIG +/* mtc0 $16, CP0_CONFIG, 7*/ /* Config 7 */ + mtc0 $17, CP0_LLADDR + mtc0 $18, CP0_WATCHLO + mtc0 $19, CP0_WATCHHI + mtc0 $20, CP0_DEBUG + mtc0 $21, CP0_DEPC + mtc0 $22, CP0_ECC + mtc0 $23, CP0_TAGLO + mtc0 $24, CP0_ERROREPC + mtc0 $25, CP0_DESAVE + + /* restore general registers */ + move k0, sp + lw k1, 120(k0) /* hi */ + lw $0, 0(k0) + lw $1, 4(k0) + mthi k1 + lw k1, 124(k0) /* lo */ + lw $2, 8(k0) + lw $3, 12(k0) + mtlo k1 + lw $4, 16(k0) + lw $5, 20(k0) + lw $6, 24(k0) + lw $7, 28(k0) + lw $8, 32(k0) + lw $9, 36(k0) + lw $10, 40(k0) + lw $11, 44(k0) + lw $12, 48(k0) + lw $13, 52(k0) + lw $14, 56(k0) + lw $15, 60(k0) + lw $16, 64(k0) + lw $17, 68(k0) + lw $18, 72(k0) + lw $19, 76(k0) + lw $20, 80(k0) + lw $21, 84(k0) + lw $22, 88(k0) + lw $23, 92(k0) + lw $24, 96(k0) + lw $25, 100(k0) + lw $28, 104(k0) + lw $29, 108(k0) /* saved sp */ + lw $30, 112(k0) + lw $31, 116(k0) /* saved ra */ + + /* return to caller */ + jr ra + nop + +suspend_save_sp: + .word 0 /* preserve sp here */ + + .set reorder diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/time.c linux-2.6.24.3-20100304/arch/mips/jz4730/time.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4730/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4730/time.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,129 @@ +/* + * linux/arch/mips/jz4730/time.c + * + * Setting up the clock on the JZ4730 boards. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include +#include + +#define JZ_TIMER_CHAN 0 +#define JZ_TIMER_IRQ IRQ_OST0 +#define JZ_TIMER_CLOCK JZ_EXTAL + +static unsigned int timer_latch; + +void (*jz_timer_callback)(void); + +static void jz_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device jz_clockevent_device = { + .name = "jz-timer", + .features = CLOCK_EVT_FEAT_PERIODIC, + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + + .rating = 300, + .irq = JZ_TIMER_IRQ, + .set_mode = jz_set_mode, +}; + +static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + __ost_clear_uf(JZ_TIMER_CHAN); /* ACK timer */ + + if (jz_timer_callback) + jz_timer_callback(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction jz_irqaction = { + .handler = jz_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "jz-timer", +}; + +cycle_t jz_get_cycles(void) +{ + unsigned int jz_timer_cnt; +#if 0 /* clock source use pll, read directly */ + jz_timer_cnt = timer_latch - REG_OST_TCNT(JZ_TIMER_CHAN); +#else /* clock source use RTCClock or Extall Clock, wait read ready */ + jz_timer_cnt = REG_OST_TCNT(JZ_TIMER_CHAN); /* dummy read */ + while ( __ost_is_busy(JZ_TIMER_CHAN) ) ; /* wait read ready */ + jz_timer_cnt = timer_latch - REG_OST_TCRB(JZ_TIMER_CHAN); +#endif + + /* convert jiffes to jz timer cycles */ + return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + jz_timer_cnt); +} + +static struct clocksource clocksource_jz = { + .name = "jz_clocksource", + .rating = 300, + .read = jz_get_cycles, + .mask = 0xFFFFFFFF, + .shift = 10, /* control clocksource.mult's accuracy */ + .flags = CLOCK_SOURCE_WATCHDOG, +}; + +static int __init jz_clocksource_init(void) +{ + clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); + clocksource_register(&clocksource_jz); + return 0; +} + +static void __init jz_timer_setup(void) +{ + struct clock_event_device *cd = &jz_clockevent_device; + struct irqaction *action = &jz_irqaction; + unsigned int cpu = smp_processor_id(); + + jz_clocksource_init(); + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); + action->dev_id = cd; + setup_irq(JZ_TIMER_IRQ, &jz_irqaction); +} + +void __init plat_time_init(void) +{ + /* Init timer, timer clock soure use extal clock */ + timer_latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ; + __ost_set_mode(JZ_TIMER_CHAN, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL); + __ost_set_reload(JZ_TIMER_CHAN, timer_latch); + __ost_set_count(JZ_TIMER_CHAN, timer_latch); + __ost_enable_channel(JZ_TIMER_CHAN); + + jz_timer_setup(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-dipper.c linux-2.6.24.3-20100304/arch/mips/jz4740/board-dipper.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-dipper.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/board-dipper.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,117 @@ +/* + * linux/arch/mips/jz4740/board-dipper.c + * + * JZ4725 Dipper board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +#if 0 +static void dancing(void) +{ + static unsigned int count = 0; + + count ++; + count &= 1; + + if (count) + __gpio_set_pin(GPIO_LED_EN); + else + __gpio_clear_pin(GPIO_LED_EN); +} +#endif + +static void dipper_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { +// dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4740/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Most of the GPIO pins should have been initialized by the boot-loader + */ + + /* + * Initialize MSC pins + */ + __gpio_as_msc(); + + /* + * Initialize Smart LCD pins + */ +// __gpio_as_slcd_18bit(); + + /* + * Initialize SSI pins + */ + __gpio_as_ssi(); + + /* + * Initialize I2C pins + */ + __gpio_as_i2c(); + + /* + * Initialize Other pins + */ + __gpio_as_output(GPIO_SD_VCC_EN_N); + __gpio_clear_pin(GPIO_SD_VCC_EN_N); + + __gpio_as_input(GPIO_SD_CD_N); + __gpio_disable_pull(GPIO_SD_CD_N); + + __gpio_as_input(GPIO_SD_WP); + __gpio_disable_pull(GPIO_SD_WP); + + __gpio_as_input(GPIO_DC_DETE_N); + __gpio_as_input(GPIO_CHARG_STAT_N); + __gpio_as_input(GPIO_USB_DETE); + + __gpio_as_output(GPIO_DISP_OFF_N); + +// __gpio_as_output(GPIO_LED_EN); +} + +void __init jz_board_setup(void) +{ + printk("JZ4725 DIPPER board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = dipper_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-leo.c linux-2.6.24.3-20100304/arch/mips/jz4740/board-leo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-leo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/board-leo.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,67 @@ +/* + * linux/arch/mips/jz4740/board-leo.c + * + * JZ4740 LEO board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned char slash[] = "\\|/-"; + static volatile unsigned char *p = (unsigned char *)0xb6000016; + static unsigned int count = 0; + *p = slash[count++]; + count &= 3; +} + +static void leo_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 10 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4740/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* All GPIO pins should have been initialized by the boot-loader */ +} + +void __init jz_board_setup(void) +{ + board_cpm_setup(); + board_gpio_setup(); + printk(" BOARD SETUP"); + jz_timer_callback = leo_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-lyra.c linux-2.6.24.3-20100304/arch/mips/jz4740/board-lyra.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-lyra.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/board-lyra.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,114 @@ +/* + * linux/arch/mips/jz4740/board-lyra.c + * + * JZ4740 LYRA board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned int count = 0; + + count ++; + count &= 1; + if (count) + __gpio_set_pin(GPIO_LED_EN); + else + __gpio_clear_pin(GPIO_LED_EN); +} + +static void lyra_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4740/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Most of the GPIO pins should have been initialized by the boot-loader + */ + + /* + * Initialize MSC pins + */ + __gpio_as_msc(); + + /* + * Initialize LCD pins + */ + __gpio_as_lcd_18bit(); + + /* + * Initialize SSI pins + */ + __gpio_as_ssi(); + + /* + * Initialize I2C pins + */ + __gpio_as_i2c(); + + /* + * Initialize Other pins + */ + __gpio_as_output(GPIO_SD_VCC_EN_N); + __gpio_clear_pin(GPIO_SD_VCC_EN_N); + + __gpio_as_input(GPIO_SD_CD_N); + __gpio_disable_pull(GPIO_SD_CD_N); + + __gpio_as_input(GPIO_SD_WP); + __gpio_disable_pull(GPIO_SD_WP); + + __gpio_as_input(GPIO_DC_DETE_N); + __gpio_as_input(GPIO_CHARG_STAT_N); + __gpio_as_input(GPIO_USB_DETE); + + __gpio_as_output(GPIO_DISP_OFF_N); + + __gpio_as_output(GPIO_LED_EN); +} + +void __init jz_board_setup(void) +{ + printk("JZ4740 LYRA board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = lyra_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-pavo.c linux-2.6.24.3-20100304/arch/mips/jz4740/board-pavo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-pavo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/board-pavo.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,114 @@ +/* + * linux/arch/mips/jz4740/board-pavo.c + * + * JZ4740 PAVO board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned int count = 0; + + count ++; + count &= 1; + if (count) + __gpio_set_pin(GPIO_LED_EN); + else + __gpio_clear_pin(GPIO_LED_EN); +} + +static void pavo_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4740/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Most of the GPIO pins should have been initialized by the boot-loader + */ + + /* + * Initialize MSC pins + */ + __gpio_as_msc(); + + /* + * Initialize LCD pins + */ + __gpio_as_lcd_18bit(); + + /* + * Initialize SSI pins + */ + __gpio_as_ssi(); + + /* + * Initialize I2C pins + */ + __gpio_as_i2c(); + + /* + * Initialize Other pins + */ + __gpio_as_output(GPIO_SD_VCC_EN_N); + __gpio_clear_pin(GPIO_SD_VCC_EN_N); + + __gpio_as_input(GPIO_SD_CD_N); + __gpio_disable_pull(GPIO_SD_CD_N); + + __gpio_as_input(GPIO_SD_WP); + __gpio_disable_pull(GPIO_SD_WP); + + __gpio_as_input(GPIO_DC_DETE_N); + __gpio_as_input(GPIO_CHARG_STAT_N); + __gpio_as_input(GPIO_USB_DETE); + + __gpio_as_output(GPIO_DISP_OFF_N); + + __gpio_as_output(GPIO_LED_EN); +} + +void __init jz_board_setup(void) +{ + printk("JZ4740 PAVO board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = pavo_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-virgo.c linux-2.6.24.3-20100304/arch/mips/jz4740/board-virgo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/board-virgo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/board-virgo.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,114 @@ +/* + * linux/arch/mips/jz4740/board-virgo.c + * + * JZ4720 VIRGO board setup routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned int count = 0; + + count ++; + count &= 1; + if (count) + __gpio_set_pin(GPIO_LED_EN); + else + __gpio_clear_pin(GPIO_LED_EN); +} + +static void virgo_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4740/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Most of the GPIO pins should have been initialized by the boot-loader + */ + + /* + * Initialize MSC pins + */ + __gpio_as_msc(); + + /* + * Initialize LCD pins + */ +// __gpio_as_lcd_18bit(); + + /* + * Initialize SSI pins + */ + __gpio_as_ssi(); + + /* + * Initialize I2C pins + */ + __gpio_as_i2c(); + + /* + * Initialize Other pins + */ + __gpio_as_output(GPIO_SD_VCC_EN_N); + __gpio_clear_pin(GPIO_SD_VCC_EN_N); + + __gpio_as_input(GPIO_SD_CD_N); + __gpio_disable_pull(GPIO_SD_CD_N); + +// __gpio_as_input(GPIO_SD_WP); +// __gpio_disable_pull(GPIO_SD_WP); + + __gpio_as_input(GPIO_DC_DETE_N); +// __gpio_as_input(GPIO_CHARG_STAT_N); + __gpio_as_input(GPIO_USB_DETE); + + __gpio_as_output(GPIO_DISP_OFF_N); + +// __gpio_as_output(GPIO_LED_EN); +} + +void __init jz_board_setup(void) +{ + printk("JZ4720 VIRGO board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = virgo_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/cpufreq.c linux-2.6.24.3-20100304/arch/mips/jz4740/cpufreq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/cpufreq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/cpufreq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,602 @@ +/* + * linux/arch/mips/jz4740/cpufreq.c + * + * cpufreq driver for JZ4740 + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ + "cpufreq-jz4740", msg) + +#undef CHANGE_PLL + +#define PLL_UNCHANGED 0 +#define PLL_GOES_UP 1 +#define PLL_GOES_DOWN 2 + +#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000)) + +/* Saved the boot-time parameters */ +static struct { + /* SDRAM parameters */ + unsigned int mclk; /* memory clock, KHz */ + unsigned int tras; /* RAS pulse width, cycles of mclk */ + unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ + unsigned int tpc; /* RAS Precharge time, cycles of mclk */ + unsigned int trwl; /* Write Precharge Time, cycles of mclk */ + unsigned int trc; /* RAS Cycle Time, cycles of mclk */ + unsigned int rtcor; /* Refresh Time Constant */ + unsigned int sdram_initialized; + + /* LCD parameters */ + unsigned int lcd_clk; /* LCD clock, Hz */ + unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ + unsigned int lcd_clks_initialized; +} boot_config; + +struct jz4740_freq_percpu_info { + struct cpufreq_frequency_table table[7]; +}; + +static struct jz4740_freq_percpu_info jz4740_freq_table; + +/* + * This contains the registers value for an operating point. + * If only part of a register needs to change then there is + * a mask value for that register. + * When going to a new operating point the current register + * value is ANDed with the ~mask and ORed with the new value. + */ +struct dpm_regs { + u32 cpccr; /* Clock Freq Control Register */ + u32 cpccr_mask; /* Clock Freq Control Register mask */ + u32 cppcr; /* PLL1 Control Register */ + u32 cppcr_mask; /* PLL1 Control Register mask */ + u32 pll_up_flag; /* New PLL freq is higher than current or not */ +}; + +extern jz_clocks_t jz_clocks; + +static void jz_update_clocks(void) +{ + /* Next clocks must be updated if we have changed + * the PLL or divisors. + */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(); +} + +static void +jz_init_boot_config(void) +{ + if (!boot_config.lcd_clks_initialized) { + /* the first time to scale pll */ + boot_config.lcd_clk = __cpm_get_lcdclk(); + boot_config.lcdpix_clk = __cpm_get_pixclk(); + boot_config.lcd_clks_initialized = 1; + } + + if (!boot_config.sdram_initialized) { + /* the first time to scale frequencies */ + unsigned int dmcr, rtcor; + unsigned int tras, rcd, tpc, trwl, trc; + + dmcr = REG_EMC_DMCR; + rtcor = REG_EMC_RTCOR; + + tras = (dmcr >> 13) & 0x7; + rcd = (dmcr >> 11) & 0x3; + tpc = (dmcr >> 8) & 0x7; + trwl = (dmcr >> 5) & 0x3; + trc = (dmcr >> 2) & 0x7; + + boot_config.mclk = __cpm_get_mclk() / 1000; + boot_config.tras = tras + 4; + boot_config.rcd = rcd + 1; + boot_config.tpc = tpc + 1; + boot_config.trwl = trwl + 1; + boot_config.trc = trc * 2 + 1; + boot_config.rtcor = rtcor; + + boot_config.sdram_initialized = 1; + } +} + +static void jz_update_dram_rtcor(unsigned int new_mclk) +{ + unsigned int rtcor; + + new_mclk /= 1000; + rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; + rtcor--; + + if (rtcor < 1) rtcor = 1; + if (rtcor > 255) rtcor = 255; + + REG_EMC_RTCOR = rtcor; + REG_EMC_RTCNT = rtcor; +} + +static void jz_update_dram_dmcr(unsigned int new_mclk) +{ + unsigned int dmcr; + unsigned int tras, rcd, tpc, trwl, trc; + unsigned int valid_time, new_time; /* ns */ + + new_mclk /= 1000; + tras = boot_config.tras * new_mclk / boot_config.mclk; + rcd = boot_config.rcd * new_mclk / boot_config.mclk; + tpc = boot_config.tpc * new_mclk / boot_config.mclk; + trwl = boot_config.trwl * new_mclk / boot_config.mclk; + trc = boot_config.trc * new_mclk / boot_config.mclk; + + /* Validation checking */ + valid_time = (boot_config.tras * 1000000) / boot_config.mclk; + new_time = (tras * 1000000) / new_mclk; + if (new_time < valid_time) tras += 1; + + valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; + new_time = (rcd * 1000000) / new_mclk; + if (new_time < valid_time) rcd += 1; + + valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; + new_time = (tpc * 1000000) / new_mclk; + if (new_time < valid_time) tpc += 1; + + valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; + new_time = (trwl * 1000000) / new_mclk; + if (new_time < valid_time) trwl += 1; + + valid_time = (boot_config.trc * 1000000) / boot_config.mclk; + new_time = (trc * 1000000) / new_mclk; + if (new_time < valid_time) trc += 2; + + tras = (tras < 4) ? 4: tras; + tras = (tras > 11) ? 11: tras; + tras -= 4; + + rcd = (rcd < 1) ? 1: rcd; + rcd = (rcd > 4) ? 4: rcd; + rcd -= 1; + + tpc = (tpc < 1) ? 1: tpc; + tpc = (tpc > 8) ? 8: tpc; + tpc -= 1; + + trwl = (trwl < 1) ? 1: trwl; + trwl = (trwl > 4) ? 4: trwl; + trwl -= 1; + + trc = (trc < 1) ? 1: trc; + trc = (trc > 15) ? 15: trc; + trc /= 2; + + dmcr = REG_EMC_DMCR; + + dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); + dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); + + REG_EMC_DMCR = dmcr; +} + +static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL + * and TRC of DMCR before changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } else { + /* We're going SLOWER: first update RTCOR value + * before changing the frequency. + */ + jz_update_dram_rtcor(new_mclk); + } +} + +static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so update RTCOR + * after changing the frequency + */ + jz_update_dram_rtcor(new_mclk); + } else { + /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL + * and TRC of DMCR after changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } +} + +static void jz_scale_divisors(struct dpm_regs *regs) +{ + unsigned int cpccr; + unsigned int cur_mclk, new_mclk; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~((unsigned long)regs->cpccr_mask); + cpccr |= regs->cpccr; + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + cur_mclk = __cpm_get_mclk(); + new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; + + /* Update some DRAM parameters before changing frequency */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} + +#ifdef CHANGE_PLL +/* Maintain the LCD clock and pixel clock */ +static void jz_scale_lcd_divisors(struct dpm_regs *regs) +{ + unsigned int new_pll, new_lcd_div, new_lcdpix_div; + unsigned int cpccr; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + if (!boot_config.lcd_clks_initialized) return; + + new_pll = __cpm_get_pllout(); + new_lcd_div = new_pll / boot_config.lcd_clk; + new_lcdpix_div = new_pll / boot_config.lcdpix_clk; + + if (new_lcd_div < 1) + new_lcd_div = 1; + if (new_lcd_div > 16) + new_lcd_div = 16; + + if (new_lcdpix_div < 1) + new_lcdpix_div = 1; + if (new_lcdpix_div > 512) + new_lcdpix_div = 512; + +// REG_CPM_CPCCR2 = new_lcdpix_div - 1; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~CPM_CPCCR_LDIV_MASK; + cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT); + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); +} + +static void jz_scale_pll(struct dpm_regs *regs) +{ + unsigned int cppcr; + unsigned int cur_mclk, new_mclk, new_pll; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + int od[] = {1, 2, 2, 4}; + + cppcr = REG_CPM_CPPCR; + cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK); + regs->cppcr &= ~CPM_CPPCR_PLLEN; + cppcr |= (regs->cppcr | 0xff); + + /* Update some DRAM parameters before changing frequency */ + new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]); + cur_mclk = __cpm_get_mclk(); + new_mclk = new_pll / div[(REG_CPM_CPCCR>>CPM_CPCCR_MDIV_BIT) & 0xf]; + + /* + * Update some SDRAM parameters + */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* + * Update PLL, align code to cache line. + */ + cppcr |= CPM_CPPCR_PLLEN; + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPPCR), "r" (cppcr)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} +#endif + +static void jz4740_transition(struct dpm_regs *regs) +{ + /* + * Get and save some boot-time conditions. + */ + jz_init_boot_config(); + +#ifdef CHANGE_PLL + /* + * Disable LCD before scaling pll. + * LCD and LCD pixel clocks should not be changed even if the PLL + * output frequency has been changed. + */ + REG_LCD_CTRL &= ~LCD_CTRL_ENA; + + /* + * Stop module clocks before scaling PLL + */ + __cpm_stop_eth(); + __cpm_stop_aic(1); + __cpm_stop_aic(2); +#endif + + /* ... add more as necessary */ + + if (regs->pll_up_flag == PLL_GOES_UP) { + /* the pll frequency is going up, so change dividors first */ + jz_scale_divisors(regs); +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + } + else if (regs->pll_up_flag == PLL_GOES_DOWN) { + /* the pll frequency is going down, so change pll first */ +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + jz_scale_divisors(regs); + } + else { + /* the pll frequency is unchanged, so change divisors only */ + jz_scale_divisors(regs); + } + +#ifdef CHANGE_PLL + /* + * Restart module clocks before scaling PLL + */ + __cpm_start_eth(); + __cpm_start_aic(1); + __cpm_start_aic(2); + + /* ... add more as necessary */ + + /* Scale the LCD divisors after scaling pll */ + if (regs->pll_up_flag != PLL_UNCHANGED) { + jz_scale_lcd_divisors(regs); + } + + /* Enable LCD controller */ + REG_LCD_CTRL &= ~LCD_CTRL_DIS; + REG_LCD_CTRL |= LCD_CTRL_ENA; +#endif + + /* Update system clocks */ + jz_update_clocks(); +} + +extern unsigned int idle_times; +static unsigned int jz4740_freq_get(unsigned int cpu) +{ + return (__cpm_get_cclk() / 1000); +} + +static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) +{ + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; + int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ + unsigned int div_of_cclk, new_freq, i; + + regs->pll_up_flag = PLL_UNCHANGED; + regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK; + + new_freq = jz4740_freq_table.table[index].frequency; + + do { + div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); + } while (div_of_cclk==0); + + if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { + for(i = 1; i<4; i++) { + div[i] = 3; + } + } else { + for(i = 1; i<4; i++) { + div[i] = 2; + } + } + + for(i = 0; i<4; i++) { + div[i] *= div_of_cclk; + } + + dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); + + regs->cpccr = + (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | + (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | + (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | + (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT); + + return div_of_cclk; +} + +static void jz4740_set_cpu_divider_index(unsigned int cpu, unsigned int index) +{ + unsigned long divisor, old_divisor; + struct cpufreq_freqs freqs; + struct dpm_regs regs; + + old_divisor = __cpm_get_pllout() / __cpm_get_cclk(); + divisor = index_to_divisor(index, ®s); + + freqs.old = __cpm_get_cclk() / 1000; + freqs.new = __cpm_get_pllout() / (1000 * divisor); + freqs.cpu = cpu; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (old_divisor != divisor) + jz4740_transition(®s); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + +static int jz4740_freq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int new_index = 0; + + if (cpufreq_frequency_table_target(policy, + &jz4740_freq_table.table[0], + target_freq, relation, &new_index)) + return -EINVAL; + + jz4740_set_cpu_divider_index(policy->cpu, new_index); + + dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR); + + return 0; +} + +static int jz4740_freq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &jz4740_freq_table.table[0]); +} + +static int __init jz4740_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + + struct cpufreq_frequency_table *table = &jz4740_freq_table.table[0]; + unsigned int MAX_FREQ; + + dprintk(KERN_INFO "Jz4740 cpufreq driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.min_freq = MAX_FREQ/8; + policy->cpuinfo.max_freq = MAX_FREQ; + policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ + + table[0].index = 0; + table[0].frequency = MAX_FREQ/8; + table[1].index = 1; + table[1].frequency = MAX_FREQ/6; + table[2].index = 2; + table[2].frequency = MAX_FREQ/4; + table[3].index = 3; + table[3].frequency = MAX_FREQ/3; + table[4].index = 4; + table[4].frequency = MAX_FREQ/2; + table[5].index = 5; + table[5].frequency = MAX_FREQ; + table[6].index = 6; + table[6].frequency = CPUFREQ_TABLE_END; + +#ifdef CONFIG_CPU_FREQ_STAT_DETAILS + cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */ +#endif + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static struct cpufreq_driver cpufreq_jz4740_driver = { +// .flags = CPUFREQ_STICKY, + .init = jz4740_cpufreq_driver_init, + .verify = jz4740_freq_verify, + .target = jz4740_freq_target, + .get = jz4740_freq_get, + .name = "jz4740", +}; + +static int __init jz4740_cpufreq_init(void) +{ + return cpufreq_register_driver(&cpufreq_jz4740_driver); +} + +static void __exit jz4740_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cpufreq_jz4740_driver); +} + +module_init(jz4740_cpufreq_init); +module_exit(jz4740_cpufreq_exit); + +MODULE_AUTHOR("Regen "); +MODULE_DESCRIPTION("cpufreq driver for Jz4740"); +MODULE_LICENSE("GPL"); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/dma.c linux-2.6.24.3-20100304/arch/mips/jz4740/dma.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/dma.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,784 @@ +/* + * linux/arch/mips/jz4740/dma.c + * + * Support functions for the JZ4740 internal DMA channels. + * No-descriptor transfer only. + * Descriptor transfer should also call jz_request_dma() to get a free + * channel and call jz_free_dma() to free the channel. And driver should + * build the DMA descriptor and setup the DMA channel by itself. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `jz_request_dma()' and `jz_free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from jz_request_dma(). + */ + +struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = { + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, +}; + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; + unsigned int dma_source; +} dma_dev_table[DMA_ID_MAX] = { + {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, + {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, + {CPHYSADDR(SSI_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSIOUT}, + {CPHYSADDR(SSI_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSIIN}, + {CPHYSADDR(AIC_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, + {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, + {CPHYSADDR(MSC_TXFIFO), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSCOUT}, + {CPHYSADDR(MSC_RXFIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSCIN}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO}, + {}, +}; + + +int jz_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct jz_dma_chan *chan; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_jz_dma_channel(unsigned int dmanr) +{ + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return; + chan = &jz_dma_table[dmanr]; + + printk("DMA%d Registers:\n", dmanr); + printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR); + printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); + printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr)); + printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); + printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); + printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); + printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr)); + printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr)); + printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR); +} + + +/** + * jz_request_dma - dynamically allcate an idle DMA channel to return + * @dev_id: the specified dma device id or DMA_ID_RAW_SET + * @dev_str: the specified dma device string name + * @irqhandler: the irq handler, or NULL + * @irqflags: the irq handler flags + * @irq_dev_id: the irq handler device id for shared irq + * + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + * +*/ +/*int jz_request_dma(int dev_id, const char *dev_str, + void (*irqhandler)(int, void *, struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id) +*/ + +int jz_request_dma(int dev_id, const char *dev_str, + irqreturn_t (*irqhandler)(int, void *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct jz_dma_chan *chan; + int i, ret; + + if (dev_id < 0 || dev_id >= DMA_ID_MAX) + return -EINVAL; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) /* no free channel */ + return -ENODEV; + + /* we got a free channel */ + chan = &jz_dma_table[i]; + + if (irqhandler) { + chan->irq = IRQ_DMA_0 + i; // allocate irq number + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = -1; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = -1; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = i; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + chan->source = dma_dev_table[dev_id].dma_source; + + return i; +} + +void jz_free_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = -1; + chan->irq_dev = NULL; + chan->dev_id = -1; +} + +void jz_set_dma_dest_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_DWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_DWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_DWDH_32; + break; + } +} + +void jz_set_dma_src_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_SWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_SWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_SWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_SWDH_32; + break; + } +} + +void jz_set_dma_block_size(int dmanr, int nbyte) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DS_MASK; + switch (nbyte) { + case 1: + chan->mode |= DMAC_DCMD_DS_8BIT; + break; + case 2: + chan->mode |= DMAC_DCMD_DS_16BIT; + break; + case 4: + chan->mode |= DMAC_DCMD_DS_32BIT; + break; + case 16: + chan->mode |= DMAC_DCMD_DS_16BYTE; + break; + case 32: + chan->mode |= DMAC_DCMD_DS_32BYTE; + break; + } +} + +unsigned int jz_get_dma_command(int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + return chan->mode; +} + +/** + * jz_set_dma_mode - do the raw settings for the specified DMA channel + * @dmanr: the specified DMA channel + * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE + * @dma_mode: dma raw mode + * @dma_source: dma raw request source + * @fifo_addr: dma raw device fifo address + * + * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call + * jz_set_dma_mode() rather than set_dma_mode() if you work with + * and external request dma device. + * + * NOTE: Don not dynamically allocate dma channel if one external request + * dma device will occupy this channel. +*/ +int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, + unsigned int dma_mode, unsigned int dma_source, + unsigned int fifo_addr) +{ + int dev_id, i; + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return -ENODEV; + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) + return -ENODEV; + + chan = &jz_dma_table[dmanr]; + dev_id = chan->dev_id; + if (dev_id > 0) { + printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", + __FUNCTION__, dmanr); + return -ENODEV; + } + + /* clone it from the dynamically allocated. */ + if (i != dmanr) { + chan->irq = jz_dma_table[i].irq; + chan->irq_dev = jz_dma_table[i].irq_dev; + chan->dev_str = jz_dma_table[i].dev_str; + jz_dma_table[i].irq = 0; + jz_dma_table[i].irq_dev = NULL; + jz_dma_table[i].dev_id = -1; + } + chan->dev_id = DMA_ID_RAW_SET; + chan->io = dmanr; + chan->fifo_addr = fifo_addr; + chan->mode = dma_mode; + chan->source = dma_source; + + set_dma_mode(dmanr, dma_mode); + + return dmanr; +} + +void enable_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); + REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */ + __dmac_enable_channel(dmanr); + if (chan->irq) + __dmac_channel_enable_irq(dmanr); +} + +#define DMA_DISABLE_POLL 0x10000 + +void disable_dma(unsigned int dmanr) +{ + int i; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + if (!__dmac_channel_enabled(dmanr)) + return; + + for (i = 0; i < DMA_DISABLE_POLL; i++) + if (__dmac_channel_transmit_end_detected(dmanr)) + break; +#if 0 + if (i == DMA_DISABLE_POLL) + printk(KERN_INFO "disable_dma: poll expired!\n"); +#endif + + __dmac_disable_channel(dmanr); + if (chan->irq) + __dmac_channel_disable_irq(dmanr); +} + +/* Note: DMA_MODE_MASK is simulated by sw */ +void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else { + printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + } + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; +} + +void set_dma_addr(unsigned int dmanr, unsigned int phyaddr) +{ + unsigned int mode; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + mode = chan->mode & DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + REG_DMAC_DSAR(chan->io) = chan->fifo_addr; + REG_DMAC_DTAR(chan->io) = phyaddr; + } else if (mode == DMA_MODE_WRITE) { + REG_DMAC_DSAR(chan->io) = phyaddr; + REG_DMAC_DTAR(chan->io) = chan->fifo_addr; + } else + printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); +} + +void set_dma_count(unsigned int dmanr, unsigned int bytecnt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + int dma_ds[] = {4, 1, 2, 16, 32}; + unsigned int ds; + + if (!chan) + return; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count +} + +unsigned int get_dma_residue(unsigned int dmanr) +{ + unsigned int count, ds; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + count = REG_DMAC_DTCR(chan->io); + count = count * dma_ds[ds]; + + return count; +} + +void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case AFMT_U8: + if (mode == DMA_MODE_READ) { + chan->mode = DMA_32BIT_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_32BIT_TX_CMD| DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + case AFMT_S16_LE: + /* burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case 8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case 16: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +#undef JZ4740_DMAC_TEST_ENABLE + +#ifdef JZ4740_DMAC_TEST_ENABLE + +/* + * DMA test: external address <--> external address + */ +#define TEST_DMA_SIZE 16*1024 + +static jz_dma_desc *dma_desc; + +static int dma_chan; +static dma_addr_t dma_desc_phys_addr; +static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr; + +static int dma_check_result(void *src, void *dst, int size) +{ + unsigned int addr1, addr2, i, err = 0; + + addr1 = (unsigned int)src; + addr2 = (unsigned int)dst; + + for (i = 0; i < size; i += 4) { + if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) { + err++; + printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2); + } + addr1 += 4; + addr2 += 4; + } + printk("check DMA result err=%d\n", err); + return err; +} + +static void jz4740_dma_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + printk("jz4740_dma_irq %d\n", irq); + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + + if (__dmac_channel_transmit_halt_detected(dma_chan)) { + printk("DMA HALT\n"); + __dmac_channel_clear_transmit_halt(dma_chan); + } + + if (__dmac_channel_address_error_detected(dma_chan)) { + printk("DMA ADDR ERROR\n"); + __dmac_channel_clear_address_error(dma_chan); + } + + if (__dmac_channel_descriptor_invalid_detected(dma_chan)) { + printk("DMA DESC INVALID\n"); + __dmac_channel_clear_descriptor_invalid(dma_chan); + } + + if (__dmac_channel_count_terminated_detected(dma_chan)) { + printk("DMA CT\n"); + __dmac_channel_clear_count_terminated(dma_chan); + } + + if (__dmac_channel_transmit_end_detected(dma_chan)) { + printk("DMA TT\n"); + __dmac_channel_clear_transmit_end(dma_chan); + dump_jz_dma_channel(dma_chan); + dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE); + } + + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +void dma_nodesc_test(void) +{ + unsigned int addr, i; + + printk("dma_nodesc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4740_dma_irq, + SA_INTERRUPT, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Init DMA module */ + printk("Starting DMA\n"); + REG_DMAC_DMACR = 0; + REG_DMAC_DCCSR(dma_chan) = 0; + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; + REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; + REG_DMAC_DTCR(dma_chan) = 512; + REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */ + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); +} + +void dma_desc_test(void) +{ + unsigned int next, addr, i; + static jz_dma_desc *desc; + + printk("dma_desc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4740_dma_irq, + SA_INTERRUPT, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Allocate DMA descriptors */ + dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0); + dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc); + + printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr); + + /* Setup DMA descriptors */ + desc = dma_desc; + next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TM | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr; /* DMA target address */ + desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE; + desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */ + desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */ + + dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc))); + + /* Setup DMA descriptor address */ + REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr; + + /* Setup request source */ + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + + /* Setup DMA channel control/status register */ + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */ + + /* Enable DMA */ + REG_DMAC_DMACR = DMAC_DMACR_DMAE; + + /* DMA doorbell set -- start DMA now ... */ + REG_DMAC_DMADBSR = 1 << dma_chan; + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); +} + +#endif + +//EXPORT_SYMBOL_NOVERS(jz_dma_table); +EXPORT_SYMBOL(jz_dma_table); +EXPORT_SYMBOL(jz_request_dma); +EXPORT_SYMBOL(jz_free_dma); +EXPORT_SYMBOL(jz_set_dma_src_width); +EXPORT_SYMBOL(jz_set_dma_dest_width); +EXPORT_SYMBOL(jz_set_dma_block_size); +EXPORT_SYMBOL(jz_set_dma_mode); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(jz_set_oss_dma); +EXPORT_SYMBOL(jz_set_alsa_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(dump_jz_dma_channel); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/i2c.c linux-2.6.24.3-20100304/arch/mips/jz4740/i2c.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/i2c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/i2c.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,273 @@ +/* + * linux/arch/mips/jz4740/i2c.c + * + * Jz4740 I2C routines. + * + * Copyright (C) 2005,2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include + +#include + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (!__i2c_received_ack() && timeout) + timeout--; + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +#ifdef CONFIG_JZ_TPANEL_ATA2508 +static int i2c_put_data_nack(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (timeout--); + return 0; +} +#endif + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else + return -ETIMEDOUT; +} + +/* + * I2C interface + */ +void i2c_open(void) +{ + __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */ + __i2c_enable(); +} + +void i2c_close(void) +{ + udelay(300); /* wait for STOP goes over. */ + __i2c_disable(); +} + +void i2c_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.extalclk, i2cclk); +} + +int i2c_lseek(unsigned char device, unsigned char offset) +{ + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(offset) < 0) + goto address_err; + return 0; + device_err: + printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device); + __i2c_send_stop(); + return -ENODEV; + address_err: + printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device); + __i2c_send_stop(); + return -EREMOTEIO; +} + +int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int timeout = 5; + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; + if (i2c_put_data(address) < 0) + goto address_err; + + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_READ ) < 0) + goto device_rerr; + __i2c_send_ack(); /* Master sends ACK for continue reading */ + while (cnt) { + if (cnt == 1) { + if (i2c_get_data(buf, 0) < 0) + break; + } else { + if (i2c_get_data(buf, 1) < 0) + break; + } + cnt--; + buf++; + } + + __i2c_send_stop(); + return count - cnt; + device_rerr: + device_werr: + address_err: + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + +int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + unsigned char tmpaddr; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = count; + tmpbuf = (unsigned char *)buf; + tmpaddr = address; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; +#ifdef CONFIG_JZ_TPANEL_ATA2508 + if (address == 0xff) { + if (i2c_put_data_nack(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data_nack(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } + else { + + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } +#else + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } +#endif + __i2c_send_stop(); + return count - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + + W_timeout: + printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +EXPORT_SYMBOL(i2c_open); +EXPORT_SYMBOL(i2c_close); +EXPORT_SYMBOL(i2c_setclk); +EXPORT_SYMBOL(i2c_read); +EXPORT_SYMBOL(i2c_write); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/irq.c linux-2.6.24.3-20100304/arch/mips/jz4740/irq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/irq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,265 @@ +/* + * linux/arch/mips/jz4740/irq.c + * + * JZ4740 interrupt routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * INTC irq type + */ + +static void enable_intc_irq(unsigned int irq) +{ + __intc_unmask_irq(irq); +} + +static void disable_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); +} + +static void mask_and_ack_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); + __intc_ack_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_intc_irq(irq); + } +} + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static struct irq_chip intc_irq_type = { + .typename = "INTC", + .startup = startup_intc_irq, + .shutdown = shutdown_intc_irq, + .enable = enable_intc_irq, + .disable = disable_intc_irq, + .ack = mask_and_ack_intc_irq, + .end = end_intc_irq, +}; + +/* + * GPIO irq type + */ + +static void enable_gpio_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if (irq < (IRQ_GPIO_0 + 32)) { + intc_irq = IRQ_GPIO0; + } + else if (irq < (IRQ_GPIO_0 + 64)) { + intc_irq = IRQ_GPIO1; + } + else if (irq < (IRQ_GPIO_0 + 96)) { + intc_irq = IRQ_GPIO2; + } + else { + intc_irq = IRQ_GPIO3; + } + + enable_intc_irq(intc_irq); + __gpio_unmask_irq(irq - IRQ_GPIO_0); +} + +static void disable_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); +} + +static void mask_and_ack_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); + __gpio_ack_irq(irq - IRQ_GPIO_0); +} + +static void end_gpio_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_gpio_irq(irq); + } +} + +static unsigned int startup_gpio_irq(unsigned int irq) +{ + enable_gpio_irq(irq); + return 0; +} + +static void shutdown_gpio_irq(unsigned int irq) +{ + disable_gpio_irq(irq); +} + +static struct irq_chip gpio_irq_type = { + .typename = "GPIO", + .startup = startup_gpio_irq, + .shutdown = shutdown_gpio_irq, + .enable = enable_gpio_irq, + .disable = disable_gpio_irq, + .ack = mask_and_ack_gpio_irq, + .end = end_gpio_irq, +}; + +/* + * DMA irq type + */ + +static void enable_dma_irq(unsigned int irq) +{ + __intc_unmask_irq(IRQ_DMAC); + __dmac_channel_enable_irq(irq - IRQ_DMA_0); +} + +static void disable_dma_irq(unsigned int irq) +{ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void mask_and_ack_dma_irq(unsigned int irq) +{ + __intc_ack_irq(IRQ_DMAC); + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void end_dma_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_dma_irq(irq); + } +} + +static unsigned int startup_dma_irq(unsigned int irq) +{ + enable_dma_irq(irq); + return 0; +} + +static void shutdown_dma_irq(unsigned int irq) +{ + disable_dma_irq(irq); +} + +static struct irq_chip dma_irq_type = { + .typename = "DMA", + .startup = startup_dma_irq, + .shutdown = shutdown_dma_irq, + .enable = enable_dma_irq, + .disable = disable_dma_irq, + .ack = mask_and_ack_dma_irq, + .end = end_dma_irq, +}; + +//---------------------------------------------------------------------- + +void __init arch_init_irq(void) +{ + int i; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + /* Set up INTC irq + */ + for (i = 0; i < 32; i++) { + disable_intc_irq(i); + irq_desc[i].chip = &intc_irq_type; + } + + /* Set up DMAC irq + */ + for (i = 0; i < NUM_DMA; i++) { + disable_dma_irq(IRQ_DMA_0 + i); + irq_desc[IRQ_DMA_0 + i].chip = &dma_irq_type; + } + + /* Set up GPIO irq + */ + for (i = 0; i < NUM_GPIO; i++) { + disable_gpio_irq(IRQ_GPIO_0 + i); + irq_desc[IRQ_GPIO_0 + i].chip = &gpio_irq_type; + } +} + +static int plat_real_irq(int irq) +{ + switch (irq) { + case IRQ_GPIO0: + irq = __gpio_group_irq(0) + IRQ_GPIO_0; + break; + case IRQ_GPIO1: + irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32; + break; + case IRQ_GPIO2: + irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64; + break; + case IRQ_GPIO3: + irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96; + break; + case IRQ_DMAC: + irq = __dmac_get_irq() + IRQ_DMA_0; + break; + } + + return irq; +} + +asmlinkage void plat_irq_dispatch(void) +{ + int irq = 0; + static unsigned long intc_ipr = 0; + + intc_ipr |= REG_INTC_IPR; + + if (!intc_ipr) return; + + irq = ffs(intc_ipr) - 1; + intc_ipr &= ~(1< + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include + +/* OHCI (USB full speed host controller) */ +static struct resource jz_usb_ohci_resources[] = { + [0] = { + .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap + .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UHC, + .end = IRQ_UHC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct platform_device jz_usb_ohci_device = { + .name = "jz-ohci", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_ohci_resources), + .resource = jz_usb_ohci_resources, +}; + +/*** LCD controller ***/ +static struct resource jz_lcd_resources[] = { + [0] = { + .start = CPHYSADDR(LCD_BASE), + .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_lcd_dmamask = ~(u32)0; + +static struct platform_device jz_lcd_device = { + .name = "jz-lcd", + .id = 0, + .dev = { + .dma_mask = &jz_lcd_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_lcd_resources), + .resource = jz_lcd_resources, +}; + +/* UDC (USB gadget controller) */ +static struct resource jz_usb_gdt_resources[] = { + [0] = { + .start = CPHYSADDR(UDC_BASE), + .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UDC, + .end = IRQ_UDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device jz_usb_gdt_device = { + .name = "jz-udc", + .id = 0, + .dev = { + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_gdt_resources), + .resource = jz_usb_gdt_resources, +}; + +/** MMC/SD controller **/ +static struct resource jz_mmc_resources[] = { + [0] = { + .start = CPHYSADDR(MSC_BASE), + .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MSC, + .end = IRQ_MSC, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_mmc_dmamask = ~(u32)0; + +static struct platform_device jz_mmc_device = { + .name = "jz-mmc", + .id = 0, + .dev = { + .dma_mask = &jz_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_mmc_resources), + .resource = jz_mmc_resources, +}; + +/** I2C controller **/ +static struct resource jz_i2c_resources[] = { + [0] = { + .start = CPHYSADDR(I2C_BASE), + .end = CPHYSADDR(I2C_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C, + .end = IRQ_I2C, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_i2c_dmamask = ~(u32)0; + +static struct platform_device jz_i2c_device = { + .name = "jz_i2c", + .id = 0, + .dev = { + .dma_mask = &jz_i2c_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_i2c_resources), + .resource = jz_i2c_resources, +}; + +/* All */ +static struct platform_device *jz_platform_devices[] __initdata = { + &jz_usb_ohci_device, + &jz_lcd_device, + &jz_usb_gdt_device, + &jz_mmc_device, + &jz_i2c_device, +}; + +static int __init jz_platform_init(void) +{ + return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices)); +} + +arch_initcall(jz_platform_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/pm.c linux-2.6.24.3-20100304/arch/mips/jz4740/pm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/pm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/pm.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,462 @@ +/* + * linux/arch/mips/jz4740/common/pm.c + * + * JZ4740 Power Management Routines + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + +#define GPIO_WAKEUP 125 /* set SW7(GPIO 125) as WAKEUP key */ + +/* + * __gpio_as_sleep set all pins to pull-disable, and set all pins as input + * except sdram, nand flash pins and the pins which can be used as CS1_N + * to CS4_N for chip select. + */ +#define __gpio_as_sleep() \ +do { \ + REG_GPIO_PXFUNC(1) = ~0x9ff9ffff; \ + REG_GPIO_PXSELC(1) = ~0x9ff9ffff; \ + REG_GPIO_PXDIRC(1) = ~0x9ff9ffff; \ + REG_GPIO_PXPES(1) = 0xffffffff; \ + REG_GPIO_PXFUNC(2) = ~0x37000000; \ + REG_GPIO_PXSELC(2) = ~0x37000000; \ + REG_GPIO_PXDIRC(2) = ~0x37000000; \ + REG_GPIO_PXPES(2) = 0xffffffff; \ + REG_GPIO_PXFUNC(3) = 0xffffffff; \ + REG_GPIO_PXSELC(3) = 0xffffffff; \ + REG_GPIO_PXDIRC(3) = 0xffffffff; \ + REG_GPIO_PXPES(3) = 0xffffffff; \ +} while (0) + +static int jz_pm_do_hibernate(void) +{ + printk("Put CPU into hibernate mode.\n"); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* + * RTC Wakeup or 1Hz interrupt can be enabled or disabled + * through RTC driver's ioctl (linux/driver/char/rtc_jz.c). + */ + + /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT); + + /* Set reset pin low-level assertion time after wakeup: must > 60ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */ + + /* Scratch pad register to be reserved */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HSPR = 0x12345678; + + /* clear wakeup status register */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWRSR = 0x0; + + /* Put CPU to power down mode */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HCR = RTC_HCR_PD; + + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + while(1); + + /* We can't get here */ + return 0; +} + +/* NOTES: + * 1: Pins that are floated (NC) should be set as input and pull-enable. + * 2: Pins that are pull-up or pull-down by outside should be set as input + * and pull-disable. + * 3: Pins that are connected to a chip except sdram and nand flash + * should be set as input and pull-disable, too. + */ +static void jz_board_do_sleep(unsigned long *ptr) +{ + unsigned char i; + + /* Print messages of GPIO registers for debug */ + for(i=0;i<4;i++) { + dprintk("run dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \ + REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \ + REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i)); + } + + /* Save GPIO registers */ + for(i = 1; i < 4; i++) { + *ptr++ = REG_GPIO_PXFUN(i); + *ptr++ = REG_GPIO_PXSEL(i); + *ptr++ = REG_GPIO_PXDIR(i); + *ptr++ = REG_GPIO_PXPE(i); + *ptr++ = REG_GPIO_PXIM(i); + *ptr++ = REG_GPIO_PXDAT(i); + *ptr++ = REG_GPIO_PXTRG(i); + } + + /* + * Set all pins to pull-disable, and set all pins as input except + * sdram, nand flash pins and the pins which can be used as CS1_N + * to CS4_N for chip select. + */ + __gpio_as_sleep(); + + /* + * Set proper status for GPB25 to GPB28 which can be used as CS1_N to CS4_N. + * Keep the pins' function used for chip select(CS) here according to your + * system to avoid chip select crashing with sdram when resuming from sleep mode. + */ + +#if defined(CONFIG_JZ4740_PAVO) + /* GPB25/CS1_N is used as chip select for nand flash, shouldn't be change. */ + + /* GPB26/CS2_N is connected to nand flash, needn't be changed. */ + + /* GPB27/CS3_N is used as EXT_INT for CS8900 on debug board, it should be set as input.*/ + __gpio_as_input(32+27); + + /* GPB28/CS4_N is used as cs8900's chip select, shouldn't be changed. */ +#endif + + /* + * Enable pull for NC pins here according to your system + */ + +#if defined(CONFIG_JZ4740_PAVO) + /* GPB30-27 <-> J1: WE_N RD_N CS4_N EXT_INT */ + for(i=27;i<31;i++) { + __gpio_enable_pull(32+i); + } + + /* GPC27<-> WAIT_N */ + __gpio_enable_pull(32*2+27); + + /* GPD16<->SD_WP; GPD13-10<->MSC_D0-3; GPD9<->MSC_CMD; GPD8<->MSC_CLK */ + __gpio_enable_pull(32*3+16); + for(i=8;i<14;i++) { + __gpio_enable_pull(32*3+i); + } +#endif + + /* + * If you must set some GPIOs as output to high level or low level, + * you can set them here, using: + * __gpio_as_output(n); + * __gpio_set_pin(n); or __gpio_clear_pin(n); + */ + +#if defined(CONFIG_JZ4740_PAVO) + /* GPD16 which is used as AMPEN_N should be set to high to disable audio amplifier */ + __gpio_set_pin(32*3+4); +#endif + +#ifdef DEBUG + /* Keep uart0 function for printing debug message */ + __gpio_as_uart0(); + + /* Print messages of GPIO registers for debug */ + for(i=0;i<4;i++) { + dprintk("sleep dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \ + REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \ + REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i)); + } +#endif +} + +static void jz_board_do_resume(unsigned long *ptr) +{ + unsigned char i; + + /* Restore GPIO registers */ + for(i = 1; i < 4; i++) { + REG_GPIO_PXFUNS(i) = *ptr; + REG_GPIO_PXFUNC(i) = ~(*ptr++); + + REG_GPIO_PXSELS(i) = *ptr; + REG_GPIO_PXSELC(i) = ~(*ptr++); + + REG_GPIO_PXDIRS(i) = *ptr; + REG_GPIO_PXDIRC(i) = ~(*ptr++); + + REG_GPIO_PXPES(i) = *ptr; + REG_GPIO_PXPEC(i) = ~(*ptr++); + + REG_GPIO_PXIMS(i)=*ptr; + REG_GPIO_PXIMC(i)=~(*ptr++); + + REG_GPIO_PXDATS(i)=*ptr; + REG_GPIO_PXDATC(i)=~(*ptr++); + + REG_GPIO_PXTRGS(i)=*ptr; + REG_GPIO_PXTRGC(i)=~(*ptr++); + } + + /* Print messages of GPIO registers for debug */ + for(i=0;i<4;i++) { + dprintk("resume dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \ + REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \ + REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i)); + } +} + + + +static int jz_pm_do_sleep(void) +{ + unsigned long delta; + unsigned long nfcsr = REG_EMC_NFCSR; + unsigned long scr = REG_CPM_SCR; + unsigned long imr = REG_INTC_IMR; + unsigned long sadc = REG_SADC_ENA; + unsigned long sleep_gpio_save[7*3]; + + printk("Put CPU into sleep mode.\n"); + + /* Preserve current time */ + delta = xtime.tv_sec - REG_RTC_RSR; + + /* Disable nand flash */ + REG_EMC_NFCSR = ~0xff; + + /* stop sadc */ + REG_SADC_ENA &= ~0x7; + while((REG_SADC_ENA & 0x7) != 0); + udelay(100); + + /*stop udc and usb*/ + REG_CPM_SCR &= ~( 1<<6 | 1<<7); + REG_CPM_SCR |= 0<<6 | 1<<7; + + /* Sleep on-board modules */ + jz_board_do_sleep(sleep_gpio_save); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* Just allow following interrupts to wakeup the system. + * Note: modify this according to your system. + */ + + /* enable RTC alarm */ + __intc_unmask_irq(IRQ_RTC); +#if 0 + /* make system wake up after n seconds by RTC alarm */ + unsigned int v, n; + n = 10; + while (!__rtc_write_ready()); + __rtc_enable_alarm(); + while (!__rtc_write_ready()); + __rtc_enable_alarm_irq(); + while (!__rtc_write_ready()); + v = __rtc_get_second(); + while (!__rtc_write_ready()); + __rtc_set_alarm_second(v+n); +#endif + + /* WAKEUP key */ + __gpio_as_irq_rise_edge(GPIO_WAKEUP); + __gpio_unmask_irq(GPIO_WAKEUP); + __intc_unmask_irq(IRQ_GPIO3); /* IRQ_GPIOn depends on GPIO_WAKEUP */ + + /* Enter SLEEP mode */ + REG_CPM_LCR &= ~CPM_LCR_LPM_MASK; + REG_CPM_LCR |= CPM_LCR_LPM_SLEEP; + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); + + /* Restore to IDLE mode */ + REG_CPM_LCR &= ~CPM_LCR_LPM_MASK; + REG_CPM_LCR |= CPM_LCR_LPM_IDLE; + + /* Restore nand flash control register */ + REG_EMC_NFCSR = nfcsr; + + /* Restore interrupts */ + REG_INTC_IMSR = imr; + REG_INTC_IMCR = ~imr; + + /* Restore sadc */ + REG_SADC_ENA = sadc; + + /* Resume on-board modules */ + jz_board_do_resume(sleep_gpio_save); + + /* Restore sleep control register */ + REG_CPM_SCR = scr; + + /* Restore current time */ + xtime.tv_sec = REG_RTC_RSR + delta; + + return 0; +} + +/* Put CPU to HIBERNATE mode */ +int jz_pm_hibernate(void) +{ + return jz_pm_do_hibernate(); +} + +#ifndef CONFIG_JZ_POWEROFF +static irqreturn_t pm_irq_handler (int irq, void *dev_id) +{ + return IRQ_HANDLED; +} +#endif + +/* Put CPU to SLEEP mode */ +int jz_pm_sleep(void) +{ + int retval; + +#ifndef CONFIG_JZ_POWEROFF + if ((retval = request_irq (IRQ_GPIO_0 + GPIO_WAKEUP, pm_irq_handler, IRQF_DISABLED, + "PM", NULL))) { + printk ("PM could not get IRQ for GPIO_WAKEUP\n"); + return retval; + } +#endif + + pm_send_all(PM_SUSPEND, (void *)3); + retval = jz_pm_do_sleep(); + pm_send_all(PM_RESUME, (void *)0); + +#ifndef CONFIG_JZ_POWEROFF + free_irq (IRQ_GPIO_0 + GPIO_WAKEUP, NULL); +#endif + + return retval; +} + +#if 0 +/* Deprecated ,was used by dpm */ +void jz_pm_idle(void) +{ + local_irq_disable(); + if (!need_resched()) { + local_irq_enable(); + cpu_wait(); + } +} +#endif + +#ifdef CONFIG_SYSCTL + +/* + * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6 + * when all the PM interfaces exist nicely. + */ +#define CTL_PM_SUSPEND 1 +#define CTL_PM_HIBERNATE 2 + +/*---------------------------------------------------------------------------- + * Power Management sleep sysctl proc interface + * + * A write to /proc/sys/pm/suspend invokes this function + * which initiates a sleep. + *--------------------------------------------------------------------------*/ +static int sysctl_jz_pm_sleep(struct ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return jz_pm_sleep(); +} + +/*---------------------------------------------------------------------------- + * Power Management sleep sysctl proc interface + * + * A write to /proc/sys/pm/hibernate invokes this function + * which initiates a poweroff. + *--------------------------------------------------------------------------*/ +static int sysctl_jz_pm_hibernate(struct ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return jz_pm_hibernate(); +} + +static struct ctl_table pm_table[] = +{ + { + .ctl_name = CTL_UNNUMBERED, + .procname = "suspend", + .data = NULL, + .maxlen = 0, + .mode = 0600, + .proc_handler = &sysctl_jz_pm_sleep, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "hibernate", + .data = NULL, + .maxlen = 0, + .mode = 0600, + .proc_handler = &sysctl_jz_pm_hibernate, + }, + { .ctl_name = 0} +}; + +static struct ctl_table pm_dir_table[] = +{ + { + .ctl_name = CTL_UNNUMBERED, + .procname = "pm", + .mode = 0555, + .child = pm_table, + }, + { .ctl_name = 0} +}; + +#endif /* CONFIG_SYSCTL */ + +/* + * Initialize power interface + */ +static int __init jz_pm_init(void) +{ + printk("Power Management for JZ\n"); + +#ifdef CONFIG_SYSCTL + register_sysctl_table(pm_dir_table); +#endif + + return 0; +} + +module_init(jz_pm_init); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/proc.c linux-2.6.24.3-20100304/arch/mips/jz4740/proc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/proc.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,887 @@ +/* + * linux/arch/mips/jz4740/proc.c + * + * /proc/jz/ procfs for jz4740 on-chip modules. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG 1 +#undef DEBUG + +/* Define this to reserve total 4MB contineous physical memory for IPU. + * MPlayer will use IPU to optimize the decoding process. + * + * If you do not want to run the MPlayer, you can comment it. + */ +#define CONFIG_RESERVE_IPU_MEM 1 + +struct proc_dir_entry *proc_jz_root; + + +/* + * EMC Modules + */ +static int emc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4); + len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4); + len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); + len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); + len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); + return len; +} + +/* + * Power Manager Module + */ +static int pmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned long lcr = REG_CPM_LCR; + unsigned long clkgr = REG_CPM_CLKGR; + + len += sprintf (page+len, "Low Power Mode : %s\n", + ((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ? + "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ? + "SLEEP" : "HIBERNATE")); + len += sprintf (page+len, "Doze Mode : %s\n", + (lcr & CPM_LCR_DOZE_ON) ? "on" : "off"); + if (lcr & CPM_LCR_DOZE_ON) + len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); + len += sprintf (page+len, "IPU : %s\n", + (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); + len += sprintf (page+len, "DMAC : %s\n", + (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); + len += sprintf (page+len, "UHC : %s\n", + (clkgr & CPM_CLKGR_UHC) ? "stopped" : "running"); + len += sprintf (page+len, "UDC : %s\n", + (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); + len += sprintf (page+len, "LCD : %s\n", + (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); + len += sprintf (page+len, "CIM : %s\n", + (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); + len += sprintf (page+len, "SADC : %s\n", + (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); + len += sprintf (page+len, "MSC : %s\n", + (clkgr & CPM_CLKGR_MSC) ? "stopped" : "running"); + len += sprintf (page+len, "AIC1 : %s\n", + (clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running"); + len += sprintf (page+len, "AIC2 : %s\n", + (clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running"); + len += sprintf (page+len, "SSI : %s\n", + (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running"); + len += sprintf (page+len, "I2C : %s\n", + (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); + len += sprintf (page+len, "RTC : %s\n", + (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); + len += sprintf (page+len, "TCU : %s\n", + (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); + len += sprintf (page+len, "UART1 : %s\n", + (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); + len += sprintf (page+len, "UART0 : %s\n", + (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); + return len; +} + +static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * Clock Generation Module + */ +#define TO_MHZ(x) (x/1000000),(x%1000000)/10000 +#define TO_KHZ(x) (x/1000),(x%1000)/10 + +static int cgm_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ + unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr); + len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr); + len += sprintf (page+len, "PLL : %s\n", + (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); + len += sprintf (page+len, "m:n:o : %d:%d:%d\n", + __cpm_get_pllm() + 2, + __cpm_get_plln() + 2, + od[__cpm_get_pllod()] + ); + len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n", + div[__cpm_get_cdiv()], + div[__cpm_get_hdiv()], + div[__cpm_get_mdiv()], + div[__cpm_get_pdiv()] + ); + len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout())); + len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk())); + len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk())); + len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk())); + len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk())); + len += sprintf (page+len, "LCDCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_lcdclk())); + len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk())); + len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk())); + len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk())); + len += sprintf (page+len, "MSCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk())); + len += sprintf (page+len, "EXTALCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk())); + len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk())); + + return len; +} + +static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16); + return count; +} + + +/* + * UDC hotplug + */ +#ifdef CONFIG_JZ_UDC_HOTPLUG +extern int jz_udc_active; /* defined in drivers/char/jzchar/jz_udc_hotplug.c */ +#endif + +#ifndef GPIO_UDC_HOTPLUG +#define GPIO_UDC_HOTPLUG 86 +#endif + +static int udc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + if (__gpio_get_pin(GPIO_UDC_HOTPLUG)) { + +#ifdef CONFIG_JZ_UDC_HOTPLUG + + /* Cable has connected, wait for disconnection. */ + __gpio_as_irq_fall_edge(GPIO_UDC_HOTPLUG); + + if (jz_udc_active) + len += sprintf (page+len, "CONNECT_CABLE\n"); + else + len += sprintf (page+len, "CONNECT_POWER\n"); +#else + len += sprintf (page+len, "CONNECT\n"); +#endif + } + else { + +#ifdef CONFIG_JZ_UDC_HOTPLUG + /* Cable has disconnected, wait for connection. */ + __gpio_as_irq_rise_edge(GPIO_UDC_HOTPLUG); +#endif + + len += sprintf (page+len, "REMOVE\n"); + } + + return len; +} + +/* + * MMC/SD hotplug + */ + +#ifndef MSC_HOTPLUG_PIN +#define MSC_HOTPLUG_PIN 90 +#endif + +static int mmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + +#if defined(CONFIG_JZ4740_LYRA) + if (!(__gpio_get_pin(MSC_HOTPLUG_PIN))) +#else + if (__gpio_get_pin(MSC_HOTPLUG_PIN)) +#endif + len += sprintf (page+len, "REMOVE\n"); + else + len += sprintf (page+len, "INSERT\n"); + + return len; +} + +#ifdef CONFIG_RESERVE_IPU_MEM + +/* USAGE: + * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages. + * echo FF > /proc/jz/ipu // 255, free all buffer + * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx + * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l) + * echo 0 > /proc/jz/ipu // debug, print ipu_buf + * od -X /proc/jz/ipu // read mem addr + */ + +typedef struct _ipu_buf { + unsigned int addr; /* phys addr */ + unsigned int page_shift; +} ipu_buf_t; + +#define IPU_BUF_MAX 4 /* 4 buffers */ + +static struct _ipu_buf ipu_buf[IPU_BUF_MAX]; +static int ipu_buf_cnt = 0; +static unsigned char g_asid=0; + +extern void local_flush_tlb_all(void); + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") +void show_tlb(void) +{ +#define ASID_MASK 0xFF + + unsigned long flags; + unsigned int old_ctx; + unsigned int entry; + unsigned int entrylo0, entrylo1, entryhi; + unsigned int pagemask; + + local_irq_save(flags); + + /* Save old context */ + old_ctx = (read_c0_entryhi() & 0xff); + + printk("TLB content:\n"); + entry = 0; + while(entry < 32) { + write_c0_index(entry); + BARRIER; + tlb_read(); + BARRIER; + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); + pagemask = read_c0_pagemask(); + printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); + printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); + printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); + + printk("\t\tpagemask=0x%08x", pagemask); + printk("\tentryhi=0x%08x\n", entryhi); + printk("\t\tentrylo0=0x%08x", entrylo0); + printk("\tentrylo1=0x%08x\n", entrylo1); + + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + + local_irq_restore(flags); +} + +static void ipu_add_wired_entry(unsigned long pid, + unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + struct task_struct *g, *p; + + /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */ + wired = read_c0_wired(); + if (wired) return; + + do_each_thread(g, p) { + if (p->pid == pid ) + g_asid = p->mm->context[0]; + } while_each_thread(g, p); + + local_irq_save(flags); + + entrylo0 = entrylo0 >> 6; /* PFN */ + entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */ + + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + entryhi &= ~0xff; /* new add, 20070906 */ + entryhi |= g_asid; /* new add, 20070906 */ +// entryhi |= old_ctx; /* new add, 20070906 */ + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +#if defined(DEBUG) + printk("\nold_ctx=%03d\n", old_ctx); + + show_tlb(); +#endif +} + +static void ipu_del_wired_entry( void ) +{ + unsigned long flags; + unsigned long wired; + + /* Free all lock entry */ + local_irq_save(flags); + wired = read_c0_wired(); + if (wired) + write_c0_wired(0); + local_irq_restore(flags); +} + +static inline void ipu_buf_get( unsigned int page_shift ) +{ + unsigned char * virt_addr; + int i; + for ( i=0; i< IPU_BUF_MAX; ++i ) { + if ( ipu_buf[i].addr == 0 ) { + break; + } + } + + if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) { + printk("Error, no free ipu buffer.\n"); + return ; + } + + virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift); + + if ( virt_addr ) { + ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr); + ipu_buf[ipu_buf_cnt].page_shift = page_shift; + + for (i = 0; i < (1<= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */ + printk("no free buffer.\n"); + *pint = 0; + } + else + *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */ + len += sizeof(unsigned int); + +#if defined(DEBUG) + show_tlb(); +#endif + return len; + +} + +static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val ; + int cnt,i; + char buf[12]; + unsigned long pid, entrylo0, entrylo1, entryhi, pagemask; +#if defined(DEBUG) + printk("ipu write count=%u\n", count); +#endif + if (count == (8*5+1)) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*0, 8); + pid = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*1, 8); + entrylo0 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*2, 8); + entrylo1 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*3, 8); + entryhi = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*4, 8); + pagemask = simple_strtoul(buf, 0, 16); + +#if defined(DEBUG) + printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n", + pid, entrylo0, entrylo1, entryhi, pagemask); +#endif + ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask); + return 41; + } else if ( count <= 8+1 ) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer, 8); + val = simple_strtoul(buf, 0, 16); + } else if (count == 44) { + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer, 10); + pid = simple_strtoul(buf, 0, 16); + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 11, 10); + entryhi = simple_strtoul(buf, 0, 16);//vaddr + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 22, 10); + entrylo0 = simple_strtoul(buf, 0, 16);//paddr + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 33, 10); + pagemask = simple_strtoul(buf, 0, 16); + pagemask = 0x3ff << 13; /* Fixed to 4MB page size */ + ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask); + return 44; + } else { + printk("ipu write count error, count=%d\n.", (unsigned int)count); + return -1; + } + + /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */ + if ( val == 0 ) { /* debug, print ipu_buf info */ + for ( cnt=0; cnt /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages + * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx + * echo FF > /proc/jz/ipu // FF, free all buffers + * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer + */ + +//#define DEBUG_IMEM 1 + +#define IMEM_MAX_ORDER 10 /* max 2^10 * 4096 = 4MB */ + +static unsigned int jz_imem_base; /* physical base address of ipu memory */ + +static unsigned int allocated_phys_addr = 0; + +/* + * Allocated buffer list + */ +typedef struct imem_list { + unsigned int phys_start; /* physical start addr */ + unsigned int phys_end; /* physical end addr */ + struct imem_list *next; +} imem_list_t; + +static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */ + +#ifdef DEBUG_IMEM +static void dump_imem_list(void) +{ + struct imem_list *imem; + + printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head); + imem = imem_list_head; + while (imem) { + printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next); + imem = imem->next; + } +} +#endif + +/* allocate 2^order pages inside the 4MB memory */ +static int imem_alloc(unsigned int order) +{ + int alloc_ok = 0; + unsigned int start, end; + unsigned int size = (1 << order) * PAGE_SIZE; + struct imem_list *imem, *imemn, *imemp; + + allocated_phys_addr = 0; + + start = jz_imem_base; + end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + imem = imem_list_head; + while (imem) { + if ((imem->phys_start - start) >= size) { + /* we got a valid address range */ + alloc_ok = 1; + break; + } + + start = imem->phys_end + 1; + imem = imem->next; + } + + if (!alloc_ok) { + if ((end - start) >= size) + alloc_ok = 1; + } + + if (alloc_ok) { + end = start + size - 1; + allocated_phys_addr = start; + + /* add to imem_list, up sorted by phys_start */ + imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); + if (!imemn) { + return -ENOMEM; + } + imemn->phys_start = start; + imemn->phys_end = end; + imemn->next = NULL; + + if (!imem_list_head) + imem_list_head = imemn; + else { + imem = imemp = imem_list_head; + while (imem) { + if (start < imem->phys_start) { + break; + } + + imemp = imem; + imem = imem->next; + } + + if (imem == imem_list_head) { + imem_list_head = imemn; + imemn->next = imem; + } + else { + imemn->next = imemp->next; + imemp->next = imemn; + } + } + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif + return 0; +} + +static void imem_free(unsigned int phys_addr) +{ + struct imem_list *imem, *imemp; + + imem = imemp = imem_list_head; + while (imem) { + if (phys_addr == imem->phys_start) { + if (imem == imem_list_head) { + imem_list_head = imem->next; + } + else { + imemp->next = imem->next; + } + + kfree(imem); + break; + } + + imemp = imem; + imem = imem->next; + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +static void imem_free_all(void) +{ + struct imem_list *imem; + + imem = imem_list_head; + while (imem) { + kfree(imem); + imem = imem->next; + } + + imem_list_head = NULL; + + allocated_phys_addr = 0; + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +/* + * Return the allocated buffer address and the max order of free buffer + */ +static int imem_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int start_addr, end_addr, max_order, max_size; + struct imem_list *imem; + + unsigned int *tmp = (unsigned int *)(page + len); + + start_addr = jz_imem_base; + end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + if (!imem_list_head) + max_size = end_addr - start_addr; + else { + max_size = 0; + imem = imem_list_head; + while (imem) { + if (max_size < (imem->phys_start - start_addr)) + max_size = imem->phys_start - start_addr; + + start_addr = imem->phys_end + 1; + imem = imem->next; + } + + if (max_size < (end_addr - start_addr)) + max_size = end_addr - start_addr; + } + + if (max_size > 0) { + max_order = get_order(max_size); + if (((1 << max_order) * PAGE_SIZE) > max_size) + max_order--; + } + else { + max_order = 0xffffffff; /* No any free buffer */ + } + + *tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */ + *tmp = max_order; /* max order of current free buffers */ + + len += 2 * sizeof(unsigned int); + + return len; +} + +static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val; + + val = simple_strtoul(buffer, 0, 16); + + if (val == 0xff) { + /* free all memory */ + imem_free_all(); + ipu_del_wired_entry(); + } + else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) { + /* allocate 2^val pages */ + imem_alloc(val); + } + else { + /* free buffer which phys_addr is val */ + imem_free(val); + } + + return count; +} + +#endif /* CONFIG_RESERVE_IPU_MEM */ + +/* + * /proc/jz/xxx entry + * + */ +static int __init jz_proc_init(void) +{ + struct proc_dir_entry *res; +#ifdef CONFIG_RESERVE_IPU_MEM + unsigned int virt_addr, i; +#endif + + proc_jz_root = proc_mkdir("jz", 0); + + /* External Memory Controller */ + res = create_proc_entry("emc", 0644, proc_jz_root); + if (res) { + res->read_proc = emc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* Power Management Controller */ + res = create_proc_entry("pmc", 0644, proc_jz_root); + if (res) { + res->read_proc = pmc_read_proc; + res->write_proc = pmc_write_proc; + res->data = NULL; + } + + /* Clock Generation Module */ + res = create_proc_entry("cgm", 0644, proc_jz_root); + if (res) { + res->read_proc = cgm_read_proc; + res->write_proc = cgm_write_proc; + res->data = NULL; + } + + /* udc hotplug */ + res = create_proc_entry("udc", 0644, proc_jz_root); + if (res) { + res->read_proc = udc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* mmc hotplug */ + res = create_proc_entry("mmc", 0644, proc_jz_root); + if (res) { + res->read_proc = mmc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + +#ifdef CONFIG_RESERVE_IPU_MEM + /* Image process unit */ + res = create_proc_entry("ipu", 0644, proc_jz_root); + if (res) { + res->read_proc = ipu_read_proc; + res->write_proc = ipu_write_proc; + res->data = NULL; + } + + /* + * Reserve a 4MB memory for IPU on JZ4740. + */ + jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER); + if (jz_imem_base) { + /* imem (IPU memory management) */ + res = create_proc_entry("imem", 0644, proc_jz_root); + if (res) { + res->read_proc = imem_read_proc; + res->write_proc = imem_write_proc; + res->data = NULL; + } + + /* Set page reserved */ + virt_addr = jz_imem_base; + for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) { + SetPageReserved(virt_to_page((void *)virt_addr)); + virt_addr += PAGE_SIZE; + } + + /* Convert to physical address */ + jz_imem_base = virt_to_phys((void *)jz_imem_base); + + printk("Total %dMB memory at 0x%x was reserved for IPU\n", + (unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base); + } +#endif + + return 0; +} + +__initcall(jz_proc_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/prom.c linux-2.6.24.3-20100304/arch/mips/jz4740/prom.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/prom.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,198 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, supports YAMON and U-Boot. + * + * Copyright 2000, 2001, 2006 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +int prom_argc; +char **prom_argv, **prom_envp; + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + if (prom_argc > 1) + *cp = '\0'; + +} + + +char *prom_getenv(char *envname) +{ +#if 0 + /* + * Return a pointer to the given environment variable. + * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". + */ + + char **env = prom_envp; + int i = strlen(envname); + int yamon = (*env && strchr(*env, '=') == NULL); + + while (*env) { + if (yamon) { + if (strcmp(envname, *env++) == 0) + return *env; + } else { + if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; + } + env++; + } +#endif + return NULL; +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machtype = MACH_INGENIC_JZ4740; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +/* used by early printk */ +void prom_putchar(char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART0_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART0_BASE + OFF_TDR); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +const char *get_system_type(void) +{ + return "JZ4740"; +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/reset.c linux-2.6.24.3-20100304/arch/mips/jz4740/reset.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/reset.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,46 @@ +/* + * linux/arch/mips/jz4740/reset.c + * + * JZ4740 reset routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void jz_restart(char *command) +{ + printk("Restarting after 4 ms\n"); + REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN; + REG_WDT_TCNT = 0; + REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */ + REG_TCU_TSCR = TCU_TSSR_WDTSC; /* enable wdt clock */ + REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */ + while (1); +} + +void jz_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void jz_power_off(void) +{ + jz_halt(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/setup.c linux-2.6.24.3-20100304/arch/mips/jz4740/setup.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/setup.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,182 @@ +/* + * linux/arch/mips/jz4740/common/setup.c + * + * JZ4740 common setup routines. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PC_KEYB +#include +#endif + +jz_clocks_t jz_clocks; + +extern char * __init prom_getcmdline(void); +extern void __init jz_board_setup(void); +extern void jz_restart(char *); +extern void jz_halt(void); +extern void jz_power_off(void); +extern void jz_time_init(void); + +static void __init sysclocks_setup(void) +{ +#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(); + jz_clocks.extalclk = __cpm_get_extalclk(); + jz_clocks.rtcclk = __cpm_get_rtcclk(); +#else + +#define FPGACLK 8000000 + + jz_clocks.cclk = FPGACLK; + jz_clocks.hclk = FPGACLK; + jz_clocks.pclk = FPGACLK; + jz_clocks.mclk = FPGACLK; + jz_clocks.lcdclk = FPGACLK; + jz_clocks.pixclk = FPGACLK; + jz_clocks.i2sclk = FPGACLK; + jz_clocks.usbclk = FPGACLK; + jz_clocks.mscclk = FPGACLK; + jz_clocks.extalclk = FPGACLK; + jz_clocks.rtcclk = FPGACLK; +#endif + + printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n", + (jz_clocks.cclk + 500000) / 1000000, + (jz_clocks.hclk + 500000) / 1000000, + (jz_clocks.pclk + 500000) / 1000000, + (jz_clocks.mclk + 500000) / 1000000); +} + +static void __init soc_cpm_setup(void) +{ + /* Start all module clocks + */ + __cpm_start_all(); + + /* Enable CKO to external memory */ + __cpm_enable_cko(); + + /* CPU enters IDLE mode when executing 'wait' instruction */ + __cpm_idle_mode(); + + /* Setup system clocks */ + sysclocks_setup(); +} + +static void __init soc_harb_setup(void) +{ +// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ +} + +static void __init soc_emc_setup(void) +{ +} + +static void __init soc_dmac_setup(void) +{ + __dmac_enable_module(); +} + +static void __init jz_soc_setup(void) +{ + soc_cpm_setup(); + soc_harb_setup(); + soc_emc_setup(); + soc_dmac_setup(); +} + +static void __init jz_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */ + memset(&s, 0, sizeof(s)); + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = SERIAL_IO_MEM; + s.regshift = 2; + s.uartclk = jz_clocks.extalclk ; + + s.line = 0; + s.membase = (u8 *)UART0_BASE; + s.irq = IRQ_UART0; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS0 setup failed!\n"); + } + + s.line = 1; + s.membase = (u8 *)UART1_BASE; + s.irq = IRQ_UART1; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS1 setup failed!\n"); + } +#endif +} + +void __init plat_mem_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + + /* IO/MEM resources. Which will be the addtion value in `inX' and + * `outX' macros defined in asm/io.h */ + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x00000000; + iomem_resource.end = 0xffffffff; + + _machine_restart = jz_restart; + _machine_halt = jz_halt; + pm_power_off = jz_power_off; + + jz_soc_setup(); + jz_serial_setup(); + jz_board_setup(); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/time.c linux-2.6.24.3-20100304/arch/mips/jz4740/time.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4740/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4740/time.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,158 @@ +/* + * linux/arch/mips/jz4740/time.c + * + * Setting up the clock on the JZ4740 boards. + * + * Copyright (C) 2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include + +#include +#include + +/* This is for machines which generate the exact clock. */ + +#define JZ_TIMER_CHAN 0 +#define JZ_TIMER_IRQ IRQ_TCU0 + +#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */ + +static struct clocksource clocksource_jz; /* Jz clock source */ +static struct clock_event_device jz_clockevent_device; /* Jz clock event */ + +void (*jz_timer_callback)(void); + +static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + REG_TCU_TFCR = 1 << JZ_TIMER_CHAN; /* ACK timer */ + + if (jz_timer_callback) + jz_timer_callback(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction jz_irqaction = { + .handler = jz_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .name = "jz-timerirq", +}; + + +cycle_t jz_get_cycles(void) +{ + /* convert jiffes to jz timer cycles */ + return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_TCNT(JZ_TIMER_CHAN)); +} + +static struct clocksource clocksource_jz = { + .name = "jz_clocksource", + .rating = 300, + .read = jz_get_cycles, + .mask = 0xFFFF, + .shift = 10, + .flags = CLOCK_SOURCE_WATCHDOG, +}; + +static int __init jz_clocksource_init(void) +{ + clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); + clocksource_register(&clocksource_jz); + return 0; +} + +static int jz_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + return 0; +} + +static void jz_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device jz_clockevent_device = { + .name = "jz-clockenvent", + .features = CLOCK_EVT_FEAT_PERIODIC, +// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */ + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + .rating = 300, + .irq = JZ_TIMER_IRQ, + .set_mode = jz_set_mode, + .set_next_event = jz_set_next_event, +}; + +static void __init jz_clockevent_init(void) +{ + struct clock_event_device *cd = &jz_clockevent_device; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); +} + +static void __init jz_timer_setup(void) +{ + jz_clocksource_init(); /* init jz clock source */ + jz_clockevent_init(); /* init jz clock event */ + + /* + * Make irqs happen for the system timer + */ + jz_irqaction.dev_id = &jz_clockevent_device; + setup_irq(JZ_TIMER_IRQ, &jz_irqaction); +} + + +void __init plat_time_init(void) +{ + unsigned int latch; + /* Init timer */ + latch = ( JZ_TIMER_CLOCK + (HZ>>1)) / HZ; + + REG_TCU_TCSR(JZ_TIMER_CHAN) = TCU_TCSR_PRESCALE16 | TCU_TCSR_EXT_EN; + REG_TCU_TCNT(JZ_TIMER_CHAN) = 0; + REG_TCU_TDHR(JZ_TIMER_CHAN) = 0; + REG_TCU_TDFR(JZ_TIMER_CHAN) = latch; + + REG_TCU_TMSR = (1 << (JZ_TIMER_CHAN + 16)); /* mask half irq */ + REG_TCU_TMCR = (1 << JZ_TIMER_CHAN); /* unmask full irq */ + REG_TCU_TSCR = (1 << JZ_TIMER_CHAN); /* enable timer clock */ + REG_TCU_TESR = (1 << JZ_TIMER_CHAN); /* start counting up */ + + jz_timer_setup(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-apus.c linux-2.6.24.3-20100304/arch/mips/jz4750/board-apus.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-apus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/board-apus.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,64 @@ +/* + * linux/arch/mips/jz4750/board-apus.c + * + * JZ4750 APUS board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ +} + +static void apus_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + __gpio_as_pcm(); +} + +void __init jz_board_setup(void) +{ + printk("JZ4750 APUS board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = apus_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-fuwa.c linux-2.6.24.3-20100304/arch/mips/jz4750/board-fuwa.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-fuwa.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/board-fuwa.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,105 @@ +/* + * linux/arch/mips/jz4750/board-fuwa.c + * + * JZ4750 FUWA board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned char slash[] = "\\|/-"; +// static volatile unsigned char *p = (unsigned char *)0xb6000058; + static volatile unsigned char *p = (unsigned char *)0xb6000016; + static unsigned int count = 0; + *p = slash[count++]; + count &= 3; +} + +static void fuwa_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Initialize SDRAM pins + */ + + /* PORT A: D0 ~ D31 */ + REG_GPIO_PXFUNS(0) = 0xffffffff; + REG_GPIO_PXSELC(0) = 0xffffffff; + + /* PORT B: A0 ~ A16, DCS#, RAS#, CAS#, CKE#, RDWE#, CKO#, WE0# */ + REG_GPIO_PXFUNS(1) = 0x81f9ffff; + REG_GPIO_PXSELC(1) = 0x81f9ffff; + + /* PORT C: WE1#, WE2#, WE3# */ + REG_GPIO_PXFUNS(2) = 0x07000000; + REG_GPIO_PXSELC(2) = 0x07000000; + + + /* + * Initialize UART0 pins + */ + + /* PORT D: TXD/RXD */ + REG_GPIO_PXFUNS(3) = 0x06000000; + REG_GPIO_PXSELS(3) = 0x06000000; + + + /* + * Initialize LED pins + */ + __gpio_as_lcd_18bit(); + + /* CS2# */ + REG_GPIO_PXFUNS(1) = 0x04000000; + REG_GPIO_PXSELC(1) = 0x04000000; + + __gpio_as_pcm(); +} + +void __init jz_board_setup(void) +{ + printk("JZ4750 FUWA board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = fuwa_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-slt50.c linux-2.6.24.3-20100304/arch/mips/jz4750/board-slt50.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/board-slt50.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/board-slt50.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,64 @@ +/* + * linux/arch/mips/jz4750/board-apus.c + * + * JZ4750 APUS board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ +} + +static void apus_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + __gpio_as_pcm(); +} + +void __init jz_board_setup(void) +{ + printk("JZ4750 SLT_50 board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = apus_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/cpufreq.c linux-2.6.24.3-20100304/arch/mips/jz4750/cpufreq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/cpufreq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/cpufreq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,601 @@ +/* + * linux/arch/mips/jz4750/cpufreq.c + * + * cpufreq driver for JZ4750 + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ + "cpufreq-jz4750", msg) + +#undef CHANGE_PLL + +#define PLL_UNCHANGED 0 +#define PLL_GOES_UP 1 +#define PLL_GOES_DOWN 2 + +#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000)) + +/* Saved the boot-time parameters */ +static struct { + /* SDRAM parameters */ + unsigned int mclk; /* memory clock, KHz */ + unsigned int tras; /* RAS pulse width, cycles of mclk */ + unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ + unsigned int tpc; /* RAS Precharge time, cycles of mclk */ + unsigned int trwl; /* Write Precharge Time, cycles of mclk */ + unsigned int trc; /* RAS Cycle Time, cycles of mclk */ + unsigned int rtcor; /* Refresh Time Constant */ + unsigned int sdram_initialized; + + /* LCD parameters */ + unsigned int lcd_clk; /* LCD clock, Hz */ + unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ + unsigned int lcd_clks_initialized; +} boot_config; + +struct jz4750_freq_percpu_info { + struct cpufreq_frequency_table table[7]; +}; + +static struct jz4750_freq_percpu_info jz4750_freq_table; + +/* + * This contains the registers value for an operating point. + * If only part of a register needs to change then there is + * a mask value for that register. + * When going to a new operating point the current register + * value is ANDed with the ~mask and ORed with the new value. + */ +struct dpm_regs { + u32 cpccr; /* Clock Freq Control Register */ + u32 cpccr_mask; /* Clock Freq Control Register mask */ + u32 cppcr; /* PLL1 Control Register */ + u32 cppcr_mask; /* PLL1 Control Register mask */ + u32 pll_up_flag; /* New PLL freq is higher than current or not */ +}; + +extern jz_clocks_t jz_clocks; + +static void jz_update_clocks(void) +{ + /* Next clocks must be updated if we have changed + * the PLL or divisors. + */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); +} + +static void +jz_init_boot_config(void) +{ + if (!boot_config.lcd_clks_initialized) { + /* the first time to scale pll */ + boot_config.lcd_clk = __cpm_get_lcdclk(); + boot_config.lcdpix_clk = __cpm_get_pixclk(); + boot_config.lcd_clks_initialized = 1; + } + + if (!boot_config.sdram_initialized) { + /* the first time to scale frequencies */ + unsigned int dmcr, rtcor; + unsigned int tras, rcd, tpc, trwl, trc; + + dmcr = REG_EMC_DMCR; + rtcor = REG_EMC_RTCOR; + + tras = (dmcr >> 13) & 0x7; + rcd = (dmcr >> 11) & 0x3; + tpc = (dmcr >> 8) & 0x7; + trwl = (dmcr >> 5) & 0x3; + trc = (dmcr >> 2) & 0x7; + + boot_config.mclk = __cpm_get_mclk() / 1000; + boot_config.tras = tras + 4; + boot_config.rcd = rcd + 1; + boot_config.tpc = tpc + 1; + boot_config.trwl = trwl + 1; + boot_config.trc = trc * 2 + 1; + boot_config.rtcor = rtcor; + + boot_config.sdram_initialized = 1; + } +} + +static void jz_update_dram_rtcor(unsigned int new_mclk) +{ + unsigned int rtcor; + + new_mclk /= 1000; + rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; + rtcor--; + + if (rtcor < 1) rtcor = 1; + if (rtcor > 255) rtcor = 255; + + REG_EMC_RTCOR = rtcor; + REG_EMC_RTCNT = rtcor; +} + +static void jz_update_dram_dmcr(unsigned int new_mclk) +{ + unsigned int dmcr; + unsigned int tras, rcd, tpc, trwl, trc; + unsigned int valid_time, new_time; /* ns */ + + new_mclk /= 1000; + tras = boot_config.tras * new_mclk / boot_config.mclk; + rcd = boot_config.rcd * new_mclk / boot_config.mclk; + tpc = boot_config.tpc * new_mclk / boot_config.mclk; + trwl = boot_config.trwl * new_mclk / boot_config.mclk; + trc = boot_config.trc * new_mclk / boot_config.mclk; + + /* Validation checking */ + valid_time = (boot_config.tras * 1000000) / boot_config.mclk; + new_time = (tras * 1000000) / new_mclk; + if (new_time < valid_time) tras += 1; + + valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; + new_time = (rcd * 1000000) / new_mclk; + if (new_time < valid_time) rcd += 1; + + valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; + new_time = (tpc * 1000000) / new_mclk; + if (new_time < valid_time) tpc += 1; + + valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; + new_time = (trwl * 1000000) / new_mclk; + if (new_time < valid_time) trwl += 1; + + valid_time = (boot_config.trc * 1000000) / boot_config.mclk; + new_time = (trc * 1000000) / new_mclk; + if (new_time < valid_time) trc += 2; + + tras = (tras < 4) ? 4: tras; + tras = (tras > 11) ? 11: tras; + tras -= 4; + + rcd = (rcd < 1) ? 1: rcd; + rcd = (rcd > 4) ? 4: rcd; + rcd -= 1; + + tpc = (tpc < 1) ? 1: tpc; + tpc = (tpc > 8) ? 8: tpc; + tpc -= 1; + + trwl = (trwl < 1) ? 1: trwl; + trwl = (trwl > 4) ? 4: trwl; + trwl -= 1; + + trc = (trc < 1) ? 1: trc; + trc = (trc > 15) ? 15: trc; + trc /= 2; + + dmcr = REG_EMC_DMCR; + + dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); + dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); + + REG_EMC_DMCR = dmcr; +} + +static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL + * and TRC of DMCR before changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } else { + /* We're going SLOWER: first update RTCOR value + * before changing the frequency. + */ + jz_update_dram_rtcor(new_mclk); + } +} + +static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so update RTCOR + * after changing the frequency + */ + jz_update_dram_rtcor(new_mclk); + } else { + /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL + * and TRC of DMCR after changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } +} + +static void jz_scale_divisors(struct dpm_regs *regs) +{ + unsigned int cpccr; + unsigned int cur_mclk, new_mclk; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~((unsigned long)regs->cpccr_mask); + cpccr |= regs->cpccr; + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + cur_mclk = __cpm_get_mclk(); + new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; + + /* Update some DRAM parameters before changing frequency */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} + +#ifdef CHANGE_PLL +/* Maintain the LCD clock and pixel clock */ +static void jz_scale_lcd_divisors(struct dpm_regs *regs) +{ + unsigned int new_pll, new_lcd_div, new_lcdpix_div; + unsigned int cpccr; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + if (!boot_config.lcd_clks_initialized) return; + + new_pll = __cpm_get_pllout(); + new_lcd_div = new_pll / boot_config.lcd_clk; + new_lcdpix_div = new_pll / boot_config.lcdpix_clk; + + if (new_lcd_div < 1) + new_lcd_div = 1; + if (new_lcd_div > 16) + new_lcd_div = 16; + + if (new_lcdpix_div < 1) + new_lcdpix_div = 1; + if (new_lcdpix_div > 512) + new_lcdpix_div = 512; + +// REG_CPM_CPCCR2 = new_lcdpix_div - 1; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~CPM_CPCCR_LDIV_MASK; + cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT); + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); +} + +static void jz_scale_pll(struct dpm_regs *regs) +{ + unsigned int cppcr; + unsigned int cur_mclk, new_mclk, new_pll; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + int od[] = {1, 2, 2, 4}; + + cppcr = REG_CPM_CPPCR; + cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK); + regs->cppcr &= ~CPM_CPPCR_PLLEN; + cppcr |= (regs->cppcr | 0xff); + + /* Update some DRAM parameters before changing frequency */ + new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]); + cur_mclk = __cpm_get_mclk(); + new_mclk = new_pll / div[(REG_CPM_CPCCR>>16) & 0xf]; + + /* + * Update some SDRAM parameters + */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* + * Update PLL, align code to cache line. + */ + cppcr |= CPM_CPPCR_PLLEN; + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPPCR), "r" (cppcr)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} +#endif + +static void jz4750_transition(struct dpm_regs *regs) +{ + /* + * Get and save some boot-time conditions. + */ + jz_init_boot_config(); + +#ifdef CHANGE_PLL + /* + * Disable LCD before scaling pll. + * LCD and LCD pixel clocks should not be changed even if the PLL + * output frequency has been changed. + */ + REG_LCD_CTRL &= ~LCD_CTRL_ENA; + + /* + * Stop module clocks before scaling PLL + */ + __cpm_stop_eth(); + __cpm_stop_aic(1); + __cpm_stop_aic(2); +#endif + + /* ... add more as necessary */ + + if (regs->pll_up_flag == PLL_GOES_UP) { + /* the pll frequency is going up, so change dividors first */ + jz_scale_divisors(regs); +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + } + else if (regs->pll_up_flag == PLL_GOES_DOWN) { + /* the pll frequency is going down, so change pll first */ +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + jz_scale_divisors(regs); + } + else { + /* the pll frequency is unchanged, so change divisors only */ + jz_scale_divisors(regs); + } + +#ifdef CHANGE_PLL + /* + * Restart module clocks before scaling PLL + */ + __cpm_start_eth(); + __cpm_start_aic(1); + __cpm_start_aic(2); + + /* ... add more as necessary */ + + /* Scale the LCD divisors after scaling pll */ + if (regs->pll_up_flag != PLL_UNCHANGED) { + jz_scale_lcd_divisors(regs); + } + + /* Enable LCD controller */ + REG_LCD_CTRL &= ~LCD_CTRL_DIS; + REG_LCD_CTRL |= LCD_CTRL_ENA; +#endif + + /* Update system clocks */ + jz_update_clocks(); +} + +extern unsigned int idle_times; +static unsigned int jz4750_freq_get(unsigned int cpu) +{ + return (__cpm_get_cclk() / 1000); +} + +static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) +{ + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; + int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ + unsigned int div_of_cclk, new_freq, i; + + regs->pll_up_flag = PLL_UNCHANGED; + regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK; + + new_freq = jz4750_freq_table.table[index].frequency; + + do { + div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); + } while (div_of_cclk==0); + + if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { + for(i = 1; i<4; i++) { + div[i] = 3; + } + } else { + for(i = 1; i<4; i++) { + div[i] = 2; + } + } + + for(i = 0; i<4; i++) { + div[i] *= div_of_cclk; + } + + dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); + + regs->cpccr = + (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | + (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | + (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | + (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT); + + return div_of_cclk; +} + +static void jz4750_set_cpu_divider_index(unsigned int cpu, unsigned int index) +{ + unsigned long divisor, old_divisor; + struct cpufreq_freqs freqs; + struct dpm_regs regs; + + old_divisor = __cpm_get_pllout() / __cpm_get_cclk(); + divisor = index_to_divisor(index, ®s); + + freqs.old = __cpm_get_cclk() / 1000; + freqs.new = __cpm_get_pllout() / (1000 * divisor); + freqs.cpu = cpu; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (old_divisor != divisor) + jz4750_transition(®s); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + +static int jz4750_freq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int new_index = 0; + + if (cpufreq_frequency_table_target(policy, + &jz4750_freq_table.table[0], + target_freq, relation, &new_index)) + return -EINVAL; + + jz4750_set_cpu_divider_index(policy->cpu, new_index); + + dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR); + + return 0; +} + +static int jz4750_freq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &jz4750_freq_table.table[0]); +} + +static int __init jz4750_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + + struct cpufreq_frequency_table *table = &jz4750_freq_table.table[0]; + unsigned int MAX_FREQ; + + dprintk(KERN_INFO "Jz4750 cpufreq driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.min_freq = MAX_FREQ/8; + policy->cpuinfo.max_freq = MAX_FREQ; + policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ + + table[0].index = 0; + table[0].frequency = MAX_FREQ/8; + table[1].index = 1; + table[1].frequency = MAX_FREQ/6; + table[2].index = 2; + table[2].frequency = MAX_FREQ/4; + table[3].index = 3; + table[3].frequency = MAX_FREQ/3; + table[4].index = 4; + table[4].frequency = MAX_FREQ/2; + table[5].index = 5; + table[5].frequency = MAX_FREQ; + table[6].index = 6; + table[6].frequency = CPUFREQ_TABLE_END; + +#ifdef CONFIG_CPU_FREQ_STAT_DETAILS + cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */ +#endif + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static struct cpufreq_driver cpufreq_jz4750_driver = { +// .flags = CPUFREQ_STICKY, + .init = jz4750_cpufreq_driver_init, + .verify = jz4750_freq_verify, + .target = jz4750_freq_target, + .get = jz4750_freq_get, + .name = "jz4750", +}; + +static int __init jz4750_cpufreq_init(void) +{ + return cpufreq_register_driver(&cpufreq_jz4750_driver); +} + +static void __exit jz4750_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cpufreq_jz4750_driver); +} + +module_init(jz4750_cpufreq_init); +module_exit(jz4750_cpufreq_exit); + +MODULE_AUTHOR("Regen "); +MODULE_DESCRIPTION("cpufreq driver for Jz4750"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/dma.c linux-2.6.24.3-20100304/arch/mips/jz4750/dma.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/dma.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,854 @@ +/* + * linux/arch/mips/jz4750/dma.c + * + * Support functions for the JZ4750 internal DMA channels. + * No-descriptor transfer only. + * Descriptor transfer should also call jz_request_dma() to get a free + * channel and call jz_free_dma() to free the channel. And driver should + * build the DMA descriptor and setup the DMA channel by itself. + * + * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `jz_request_dma()' and `jz_free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from jz_request_dma(). + */ + +struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = { + {dev_id:DMA_ID_BCH_ENC,}, /* DMAC0 channel 0, reserved for BCH */ + {dev_id:-1,}, /* DMAC0 channel 1 */ + {dev_id:-1,}, /* DMAC0 channel 2 */ + {dev_id:-1,}, /* DMAC0 channel 3 */ + {dev_id:-1,}, /* DMAC0 channel 4 */ + {dev_id:-1,}, /* DMAC0 channel 5 */ + {dev_id:-1,}, /* DMAC1 channel 0 */ + {dev_id:-1,}, /* DMAC1 channel 1 */ + {dev_id:-1,}, /* DMAC1 channel 2 */ + {dev_id:-1,}, /* DMAC1 channel 3 */ + {dev_id:-1,}, /* DMAC1 channel 4 */ + {dev_id:-1,}, /* DMAC1 channel 5 */ +}; + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; + unsigned int dma_source; +} dma_dev_table[DMA_ID_MAX] = { + {0, DMA_AUTOINIT, DMAC_DRSR_RS_EXT}, /* External request with DREQn */ + {0x18000000, DMA_AUTOINIT, DMAC_DRSR_RS_NAND}, /* NAND request */ + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_ENC}, + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_DEC}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO}, +// {CPHYSADDR(TSSI_FIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_TSSIIN}, + {CPHYSADDR(UART3_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT}, + {CPHYSADDR(UART3_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART3IN}, + {CPHYSADDR(UART2_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT}, + {CPHYSADDR(UART2_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART2IN}, + {CPHYSADDR(UART1_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT}, + {CPHYSADDR(UART1_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART1IN}, + {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, + {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI0OUT}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI0IN}, + {CPHYSADDR(AIC_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, + {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, + {CPHYSADDR(MSC_TXFIFO(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC0OUT}, + {CPHYSADDR(MSC_RXFIFO(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC0IN}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU}, + {SADC_TSDAT, DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SADC},/* Touch Screen Data Register */ + {CPHYSADDR(MSC_TXFIFO(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC1OUT}, /* SSC1 TX */ + {CPHYSADDR(MSC_RXFIFO(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC1IN}, /* SSC1 RX */ + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI1OUT}, + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI1IN}, + {CPHYSADDR(PCM_DP), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_PMOUT}, + {CPHYSADDR(PCM_DP), DMA_16BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_PMIN}, + {}, +}; + + +int jz_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct jz_dma_chan *chan; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_jz_dma_channel(unsigned int dmanr) +{ + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return; + chan = &jz_dma_table[dmanr]; + + printk("DMA%d Registers:\n", dmanr); + printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR(chan->io/HALF_DMA_NUM)); + printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); + printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr)); + printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); + printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); + printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); + printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr)); + printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr)); + printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR(chan->io/HALF_DMA_NUM)); +} + + +/** + * jz_request_dma - dynamically allcate an idle DMA channel to return + * @dev_id: the specified dma device id or DMA_ID_RAW_SET + * @dev_str: the specified dma device string name + * @irqhandler: the irq handler, or NULL + * @irqflags: the irq handler flags + * @irq_dev_id: the irq handler device id for shared irq + * + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + * +*/ +/*int jz_request_dma(int dev_id, const char *dev_str, + void (*irqhandler)(int, void *, struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id) +*/ + +int jz_request_dma(int dev_id, const char *dev_str, + irqreturn_t (*irqhandler)(int, void *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct jz_dma_chan *chan; + int i, ret, chan0; + + if (dev_id < 0 || dev_id >= DMA_ID_MAX) + return -EINVAL; + + /* Because of a bug in DMA controller of jz4750, which causes auto + request and device request can't be allocated in a same DMA + controller, all device requests should be put in the second DMA + controller + */ + if (dev_id > DMA_ID_AUTO) + chan0 = 6; + else + chan0 = 0; + + for (i = chan0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) /* no free channel */ + return -ENODEV; + + /* we got a free channel */ + chan = &jz_dma_table[i]; + + if (irqhandler) { + chan->irq = IRQ_DMA_0 + i; // allocate irq number + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = -1; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = -1; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = i; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + chan->source = dma_dev_table[dev_id].dma_source; + + if (i < 6) + REG_DMAC_DMACKE(0) = 1 << i; + else + REG_DMAC_DMACKE(1) = 1 << (i - 6); + + return i; +} + +void jz_free_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = -1; + chan->irq_dev = NULL; + chan->dev_id = -1; +} + +void jz_set_dma_dest_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_DWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_DWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_DWDH_32; + break; + } +} + +void jz_set_dma_src_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_SWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_SWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_SWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_SWDH_32; + break; + } +} + +void jz_set_dma_block_size(int dmanr, int nbyte) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DS_MASK; + switch (nbyte) { + case 1: + chan->mode |= DMAC_DCMD_DS_8BIT; + break; + case 2: + chan->mode |= DMAC_DCMD_DS_16BIT; + break; + case 4: + chan->mode |= DMAC_DCMD_DS_32BIT; + break; + case 16: + chan->mode |= DMAC_DCMD_DS_16BYTE; + break; + case 32: + chan->mode |= DMAC_DCMD_DS_32BYTE; + break; + } +} + +unsigned int jz_get_dma_command(int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + return chan->mode; +} + +/** + * jz_set_dma_mode - do the raw settings for the specified DMA channel + * @dmanr: the specified DMA channel + * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE + * @dma_mode: dma raw mode + * @dma_source: dma raw request source + * @fifo_addr: dma raw device fifo address + * + * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call + * jz_set_dma_mode() rather than set_dma_mode() if you work with + * and external request dma device. + * + * NOTE: Don not dynamically allocate dma channel if one external request + * dma device will occupy this channel. +*/ +int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, + unsigned int dma_mode, unsigned int dma_source, + unsigned int fifo_addr) +{ + int dev_id, i; + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return -ENODEV; + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) + return -ENODEV; + + chan = &jz_dma_table[dmanr]; + dev_id = chan->dev_id; + if (dev_id > 0) { + printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", + __FUNCTION__, dmanr); + return -ENODEV; + } + + /* clone it from the dynamically allocated. */ + if (i != dmanr) { + chan->irq = jz_dma_table[i].irq; + chan->irq_dev = jz_dma_table[i].irq_dev; + chan->dev_str = jz_dma_table[i].dev_str; + jz_dma_table[i].irq = 0; + jz_dma_table[i].irq_dev = NULL; + jz_dma_table[i].dev_id = -1; + } + chan->dev_id = DMA_ID_RAW_SET; + chan->io = dmanr; + chan->fifo_addr = fifo_addr; + chan->mode = dma_mode; + chan->source = dma_source; + + set_dma_mode(dmanr, dma_mode); + + return dmanr; +} + +void enable_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); + REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */ + __dmac_enable_channel(dmanr); + if (chan->irq) + __dmac_channel_enable_irq(dmanr); +} + +#define DMA_DISABLE_POLL 0x10000 + +void disable_dma(unsigned int dmanr) +{ + int i; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + if (!__dmac_channel_enabled(dmanr)) + return; + + for (i = 0; i < DMA_DISABLE_POLL; i++) + if (__dmac_channel_transmit_end_detected(dmanr)) + break; +#if 0 + if (i == DMA_DISABLE_POLL) + printk(KERN_INFO "disable_dma: poll expired!\n"); +#endif + + __dmac_disable_channel(dmanr); + if (chan->irq) + __dmac_channel_disable_irq(dmanr); +} + +/* Note: DMA_MODE_MASK is simulated by sw */ +void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else { + printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + } + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; +} + +void set_dma_addr(unsigned int dmanr, unsigned int phyaddr) +{ + unsigned int mode; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + mode = chan->mode & DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + REG_DMAC_DSAR(chan->io) = chan->fifo_addr; + REG_DMAC_DTAR(chan->io) = phyaddr; + } else if (mode == DMA_MODE_WRITE) { + REG_DMAC_DSAR(chan->io) = phyaddr; + REG_DMAC_DTAR(chan->io) = chan->fifo_addr; + } else + printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); +} + +void set_dma_count(unsigned int dmanr, unsigned int bytecnt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + int dma_ds[] = {4, 1, 2, 16, 32}; + unsigned int ds; + + if (!chan) + return; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count +} + +unsigned int get_dma_residue(unsigned int dmanr) +{ + unsigned int count, ds; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + count = REG_DMAC_DTCR(chan->io); + count = count * dma_ds[ds]; + + return count; +} + +void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case AFMT_U8: + /* burst mode : 32BIT */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_8BIT_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_8BIT_TX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + + break; + case AFMT_S16_LE: + /* burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; + //chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case 8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case 16: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +//#define JZ4750_DMAC_TEST_ENABLE +#undef JZ4750_DMAC_TEST_ENABLE + +#ifdef JZ4750_DMAC_TEST_ENABLE + +/* + * DMA test: external address <--> external address + */ +#define TEST_DMA_SIZE 16*1024 + +static jz_dma_desc *dma_desc; + +static int dma_chan; +static dma_addr_t dma_desc_phys_addr; +static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr; + +static int dma_check_result(void *src, void *dst, int size) +{ + unsigned int addr1, addr2, i, err = 0; + + addr1 = (unsigned int)src; + addr2 = (unsigned int)dst; + + for (i = 0; i < size; i += 4) { + if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) { + err++; + printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2); + } + addr1 += 4; + addr2 += 4; + } + printk("check DMA result err=%d\n", err); + return err; +} + +static irqreturn_t jz4750_dma_irq(int irq, void *dev_id) +{ + printk("jz4750_dma_irq %d\n", irq); + + + if (__dmac_channel_transmit_halt_detected(dma_chan)) { + printk("DMA HALT\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + __dmac_channel_clear_transmit_halt(dma_chan); + } + + if (__dmac_channel_address_error_detected(dma_chan)) { + printk("DMA ADDR ERROR\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + REG_DMAC_DSAR(dma_chan) = 0; /* clear source address register */ + REG_DMAC_DTAR(dma_chan) = 0; /* clear target address register */ + __dmac_channel_clear_address_error(dma_chan); + } + + if (__dmac_channel_descriptor_invalid_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA DESC INVALID\n"); + __dmac_channel_clear_descriptor_invalid(dma_chan); + } + + if (__dmac_channel_count_terminated_detected(dma_chan)) { + printk("DMA CT\n"); + __dmac_channel_clear_count_terminated(dma_chan); + } + + if (__dmac_channel_transmit_end_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA TT\n"); + __dmac_channel_clear_transmit_end(dma_chan); + dump_jz_dma_channel(dma_chan); + dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE); + } + + return IRQ_HANDLED; +} + +void dma_nodesc_test(void) +{ + unsigned int addr, i; + + printk("dma_nodesc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Init DMA module */ + printk("Starting DMA\n"); + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0; + REG_DMAC_DCCSR(dma_chan) = 0; + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; + REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; + REG_DMAC_DTCR(dma_chan) = 512; + REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */ + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +void dma_desc_test(void) +{ + unsigned int next, addr, i; + static jz_dma_desc *desc; + + printk("dma_desc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Allocate DMA descriptors */ + dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0); + dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc); + + printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr); + + /* Setup DMA descriptors */ + desc = dma_desc; + next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr; /* DMA target address */ + desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE; + desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */ + desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */ + + dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc))); + + /* Setup DMA descriptor address */ + REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr; + + /* Setup request source */ + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + + /* Setup DMA channel control/status register */ + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */ + + /* Enable DMA */ + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; + + /* DMA doorbell set -- start DMA now ... */ + REG_DMAC_DMADBSR(dma_chan/HALF_DMA_NUM) = 1 << dma_chan; + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +#endif + +//EXPORT_SYMBOL_NOVERS(jz_dma_table); +EXPORT_SYMBOL(jz_dma_table); +EXPORT_SYMBOL(jz_request_dma); +EXPORT_SYMBOL(jz_free_dma); +EXPORT_SYMBOL(jz_set_dma_src_width); +EXPORT_SYMBOL(jz_set_dma_dest_width); +EXPORT_SYMBOL(jz_set_dma_block_size); +EXPORT_SYMBOL(jz_set_dma_mode); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(jz_set_oss_dma); +EXPORT_SYMBOL(jz_set_alsa_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(dump_jz_dma_channel); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/i2c.c linux-2.6.24.3-20100304/arch/mips/jz4750/i2c.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/i2c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/i2c.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,273 @@ +/* + * linux/arch/mips/jz4750/i2c.c + * + * Jz4750 I2C routines. + * + * Copyright (C) 2005,2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include + +#include + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (!__i2c_received_ack() && timeout) + timeout--; + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +#ifdef CONFIG_JZ_TPANEL_ATA2508 +static int i2c_put_data_nack(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (timeout--); + return 0; +} +#endif + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else + return -ETIMEDOUT; +} + +/* + * I2C interface + */ +void i2c_open(void) +{ + __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */ + __i2c_enable(); +} + +void i2c_close(void) +{ + udelay(300); /* wait for STOP goes over. */ + __i2c_disable(); +} + +void i2c_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.extalclk, i2cclk); +} + +int i2c_lseek(unsigned char device, unsigned char offset) +{ + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(offset) < 0) + goto address_err; + return 0; + device_err: + printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device); + __i2c_send_stop(); + return -ENODEV; + address_err: + printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device); + __i2c_send_stop(); + return -EREMOTEIO; +} + +int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int timeout = 5; + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; + if (i2c_put_data(address) < 0) + goto address_err; + + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_READ ) < 0) + goto device_rerr; + __i2c_send_ack(); /* Master sends ACK for continue reading */ + while (cnt) { + if (cnt == 1) { + if (i2c_get_data(buf, 0) < 0) + break; + } else { + if (i2c_get_data(buf, 1) < 0) + break; + } + cnt--; + buf++; + } + + __i2c_send_stop(); + return count - cnt; + device_rerr: + device_werr: + address_err: + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + +int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + unsigned char tmpaddr; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = count; + tmpbuf = (unsigned char *)buf; + tmpaddr = address; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; +#ifdef CONFIG_JZ_TPANEL_ATA2508 + if (address == 0xff) { + if (i2c_put_data_nack(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data_nack(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } + else { + + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } +#else + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } +#endif + __i2c_send_stop(); + return count - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + + W_timeout: + printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +EXPORT_SYMBOL(i2c_open); +EXPORT_SYMBOL(i2c_close); +EXPORT_SYMBOL(i2c_setclk); +EXPORT_SYMBOL(i2c_read); +EXPORT_SYMBOL(i2c_write); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/irq.c linux-2.6.24.3-20100304/arch/mips/jz4750/irq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/irq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,299 @@ +/* + * linux/arch/mips/jz4750/irq.c + * + * JZ4750 interrupt routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * INTC irq type + */ + +static void enable_intc_irq(unsigned int irq) +{ + __intc_unmask_irq(irq); +} + +static void disable_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); +} + +static void mask_and_ack_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); + __intc_ack_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_intc_irq(irq); + } +} + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static struct irq_chip intc_irq_type = { + .typename = "INTC", + .startup = startup_intc_irq, + .shutdown = shutdown_intc_irq, + .enable = enable_intc_irq, + .disable = disable_intc_irq, + .ack = mask_and_ack_intc_irq, + .end = end_intc_irq, +}; + +/* + * GPIO irq type + */ + +static void enable_gpio_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if (irq < (IRQ_GPIO_0 + 32)) { + intc_irq = IRQ_GPIO0; + } + else if (irq < (IRQ_GPIO_0 + 64)) { + intc_irq = IRQ_GPIO1; + } + else if (irq < (IRQ_GPIO_0 + 96)) { + intc_irq = IRQ_GPIO2; + } + else if (irq < (IRQ_GPIO_0 + 128)) { + intc_irq = IRQ_GPIO3; + } + else if (irq < (IRQ_GPIO_0 + 160)) { + intc_irq = IRQ_GPIO4; + } + else { + intc_irq = IRQ_GPIO5; + } + + enable_intc_irq(intc_irq); + __gpio_unmask_irq(irq - IRQ_GPIO_0); +} + +static void disable_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); +} + +static void mask_and_ack_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); + __gpio_ack_irq(irq - IRQ_GPIO_0); +} + +static void end_gpio_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_gpio_irq(irq); + } +} + +static unsigned int startup_gpio_irq(unsigned int irq) +{ + enable_gpio_irq(irq); + return 0; +} + +static void shutdown_gpio_irq(unsigned int irq) +{ + disable_gpio_irq(irq); +} + +static struct irq_chip gpio_irq_type = { + .typename = "GPIO", + .startup = startup_gpio_irq, + .shutdown = shutdown_gpio_irq, + .enable = enable_gpio_irq, + .disable = disable_gpio_irq, + .ack = mask_and_ack_gpio_irq, + .end = end_gpio_irq, +}; + +/* + * DMA irq type + */ + +static void enable_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return; + } + __intc_unmask_irq(intc_irq); + __dmac_channel_enable_irq(irq - IRQ_DMA_0); +} + +static void disable_dma_irq(unsigned int irq) +{ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void mask_and_ack_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return ; + } + __intc_ack_irq(intc_irq); + __dmac_channel_ack_irq(irq-IRQ_DMA_0); /* needed?? add 20080506, Wolfgang */ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void end_dma_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_dma_irq(irq); + } +} + +static unsigned int startup_dma_irq(unsigned int irq) +{ + enable_dma_irq(irq); + return 0; +} + +static void shutdown_dma_irq(unsigned int irq) +{ + disable_dma_irq(irq); +} + +static struct irq_chip dma_irq_type = { + .typename = "DMA", + .startup = startup_dma_irq, + .shutdown = shutdown_dma_irq, + .enable = enable_dma_irq, + .disable = disable_dma_irq, + .ack = mask_and_ack_dma_irq, + .end = end_dma_irq, +}; + +//---------------------------------------------------------------------- + +void __init arch_init_irq(void) +{ + int i; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + /* Set up INTC irq + */ + for (i = 0; i < 32; i++) { + disable_intc_irq(i); + irq_desc[i].chip = &intc_irq_type; + } + + /* Set up DMAC irq + */ + for (i = 0; i < NUM_DMA; i++) { + disable_dma_irq(IRQ_DMA_0 + i); + irq_desc[IRQ_DMA_0 + i].chip = &dma_irq_type; + } + + /* Set up GPIO irq + */ + for (i = 0; i < NUM_GPIO; i++) { + disable_gpio_irq(IRQ_GPIO_0 + i); + irq_desc[IRQ_GPIO_0 + i].chip = &gpio_irq_type; + } +} + +static int plat_real_irq(int irq) +{ + switch (irq) { + case IRQ_GPIO0: + irq = __gpio_group_irq(0) + IRQ_GPIO_0; + break; + case IRQ_GPIO1: + irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32; + break; + case IRQ_GPIO2: + irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64; + break; + case IRQ_GPIO3: + irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96; + break; + case IRQ_GPIO4: + irq = __gpio_group_irq(4) + IRQ_GPIO_0 + 128; + break; + case IRQ_GPIO5: + irq = __gpio_group_irq(5) + IRQ_GPIO_0 + 160; + break; + case IRQ_DMAC0: + case IRQ_DMAC1: + irq = __dmac_get_irq() + IRQ_DMA_0; + break; + } + + return irq; +} + +asmlinkage void plat_irq_dispatch(void) +{ + int irq = 0; + static unsigned long intc_ipr = 0; + + intc_ipr |= REG_INTC_IPR; + + if (!intc_ipr) return; + + irq = ffs(intc_ipr) - 1; + intc_ipr &= ~(1< + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include + +/* OHCI (USB full speed host controller) */ +static struct resource jz_usb_ohci_resources[] = { + [0] = { + .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap + .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UHC, + .end = IRQ_UHC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct platform_device jz_usb_ohci_device = { + .name = "jz-ohci", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_ohci_resources), + .resource = jz_usb_ohci_resources, +}; + +/*** LCD controller ***/ +static struct resource jz_lcd_resources[] = { + [0] = { + .start = CPHYSADDR(LCD_BASE), + .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_lcd_dmamask = ~(u32)0; + +static struct platform_device jz_lcd_device = { + .name = "jz-lcd", + .id = 0, + .dev = { + .dma_mask = &jz_lcd_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_lcd_resources), + .resource = jz_lcd_resources, +}; + +/* UDC (USB gadget controller) */ +static struct resource jz_usb_gdt_resources[] = { + [0] = { + .start = CPHYSADDR(UDC_BASE), + .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UDC, + .end = IRQ_UDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device jz_usb_gdt_device = { + .name = "jz-udc", + .id = 0, + .dev = { + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_gdt_resources), + .resource = jz_usb_gdt_resources, +}; + +/** MMC/SD controller **/ +static struct resource jz_mmc_resources[] = { + [0] = { + .start = CPHYSADDR(MSC_BASE), + .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MSC0, + .end = IRQ_MSC0, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_mmc_dmamask = ~(u32)0; + +static struct platform_device jz_mmc_device = { + .name = "jz-mmc", + .id = 0, + .dev = { + .dma_mask = &jz_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_mmc_resources), + .resource = jz_mmc_resources, +}; + + +/** I2C controller **/ +static struct resource jz_i2c_resources[] = { + [0] = { + .start = CPHYSADDR(I2C_BASE), + .end = CPHYSADDR(I2C_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, +#if 0 + [1] = { + .start = IRQ_I2C, + .end = IRQ_I2C, + .flags = IORESOURCE_IRQ, + } +#endif +}; + +static u64 jz_i2c_dmamask = ~(u32)0; +static struct platform_device jz_i2c_device = { + .name = "jz_i2c", + .id = 0, + .dev = { + .dma_mask = &jz_i2c_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_i2c_resources), + .resource = jz_i2c_resources, +}; + + + +/* All */ +static struct platform_device *jz_platform_devices[] __initdata = { + &jz_usb_ohci_device, + &jz_lcd_device, + &jz_usb_gdt_device, + &jz_mmc_device, + &jz_i2c_device, + +}; + +static int __init jz_platform_init(void) +{ + return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices)); +} + +arch_initcall(jz_platform_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/pm.c linux-2.6.24.3-20100304/arch/mips/jz4750/pm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/pm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/pm.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,492 @@ +/* + * linux/arch/mips/jz4750/common/pm.c + * + * JZ4750 Power Management Routines + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + +#define GPIO_PORT_NUM 6 + +/* + * __gpio_as_sleep set all pins to pull-disable, and set all pins as input + * except sdram and the pins which can be used as CS1_N to CS4_N for chip select. + */ +#if 0 +#define __gpio_as_sleep() \ +do { \ + REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \ + REG_GPIO_PXSELC(1) = ~0x03ff7fff; \ + REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \ + REG_GPIO_PXPES(1) = 0xffffffff; \ + REG_GPIO_PXFUNC(2) = ~0x01e00000; \ + REG_GPIO_PXSELC(2) = ~0x01e00000; \ + REG_GPIO_PXDIRC(2) = ~0x01e00000; \ + REG_GPIO_PXPES(2) = 0xffffffff; \ + REG_GPIO_PXFUNC(3) = 0xffffffff; \ + REG_GPIO_PXSELC(3) = 0xffffffff; \ + REG_GPIO_PXDIRC(3) = 0xffffffff; \ + REG_GPIO_PXPES(3) = 0xffffffff; \ + REG_GPIO_PXFUNC(4) = 0xffffffff; \ + REG_GPIO_PXSELC(4) = 0xffffffff; \ + REG_GPIO_PXDIRC(4) = 0xffffffff; \ + REG_GPIO_PXPES(4) = 0xffffffff; \ + REG_GPIO_PXFUNC(5) = 0xffffffff; \ + REG_GPIO_PXSELC(5) = 0xffffffff; \ + REG_GPIO_PXDIRC(5) = 0xffffffff; \ + REG_GPIO_PXPES(5) = 0xffffffff; \ +} while (0) +#endif + +#if 1 +#define __gpio_as_sleep() \ +do { \ + REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \ + REG_GPIO_PXSELC(1) = ~0x03ff7fff; \ + REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \ + REG_GPIO_PXPES(1) = 0xffffffff; \ + REG_GPIO_PXFUNC(2) = ~0x01e00000; \ + REG_GPIO_PXSELC(2) = ~0x01e00000; \ + REG_GPIO_PXDIRC(2) = ~0x01e00000; \ + REG_GPIO_PXPES(2) = 0xffffffff; \ + REG_GPIO_PXFUNC(3) = 0xffffffff; \ + REG_GPIO_PXSELC(3) = 0xffffffff; \ + REG_GPIO_PXDIRC(3) = 0xffffffff; \ + REG_GPIO_PXPEC(3) = 0xffffffff; \ + REG_GPIO_PXFUNC(4) = 0xffffffff; \ + REG_GPIO_PXSELC(4) = 0xffffffff; \ + REG_GPIO_PXDIRC(4) = 0xffffffff; \ + REG_GPIO_PXPES(4) = 0xffffffff; \ + REG_GPIO_PXFUNC(5) = 0xffffffff; \ + REG_GPIO_PXSELC(5) = 0xffffffff; \ + REG_GPIO_PXDIRC(5) = 0xffffffff; \ + REG_GPIO_PXPES(5) = 0xffffffff; \ +} while (0) +#endif + + +static int jz_pm_do_hibernate(void) +{ + printk("Put CPU into hibernate mode.\n"); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* + * RTC Wakeup or 1Hz interrupt can be enabled or disabled + * through RTC driver's ioctl (linux/driver/char/rtc_jz.c). + */ + + /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT); + + /* Set reset pin low-level assertion time after wakeup: must > 60ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */ + + /* Scratch pad register to be reserved */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HSPR = 0x12345678; + + /* clear wakeup status register */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWRSR = 0x0; + + /* Put CPU to power down mode */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HCR = RTC_HCR_PD; + + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + while(1); + + /* We can't get here */ + return 0; +} + +/* NOTES: + * 1: Pins that are floated (NC) should be set as input and pull-enable. + * 2: Pins that are pull-up or pull-down by outside should be set as input + * and pull-disable. + * 3: Pins that are connected to a chip except sdram and nand flash + * should be set as input and pull-disable, too. + */ +static void jz_board_do_sleep(unsigned long *ptr) +{ + unsigned char i; + + /* Print messages of GPIO registers for debug */ + for(i=0;i + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG 1 +#undef DEBUG + + +struct proc_dir_entry *proc_jz_root; + + +/* + * EMC Modules + */ +static int emc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4); + len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4); + len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); + len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); + len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); + return len; +} + +/* + * Power Manager Module + */ +static int pmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned long lcr = REG_CPM_LCR; + unsigned long clkgr = REG_CPM_CLKGR; + + len += sprintf (page+len, "Low Power Mode : %s\n", + ((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ? + "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ? + "SLEEP" : "HIBERNATE")); + len += sprintf (page+len, "Doze Mode : %s\n", + (lcr & CPM_LCR_DOZE_ON) ? "on" : "off"); + if (lcr & CPM_LCR_DOZE_ON) + len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); + len += sprintf (page+len, "IPU : %s\n", + (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); + len += sprintf (page+len, "DMAC : %s\n", + (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); + len += sprintf (page+len, "UHC : %s\n", + (clkgr & CPM_CLKGR_UHC) ? "stopped" : "running"); + len += sprintf (page+len, "UDC : %s\n", + (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); + len += sprintf (page+len, "LCD : %s\n", + (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); + len += sprintf (page+len, "CIM : %s\n", + (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); + len += sprintf (page+len, "SADC : %s\n", + (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); + len += sprintf (page+len, "MSC0 : %s\n", + (clkgr & CPM_CLKGR_MSC0) ? "stopped" : "running"); + len += sprintf (page+len, "MSC1 : %s\n", + (clkgr & CPM_CLKGR_MSC1) ? "stopped" : "running"); + len += sprintf (page+len, "AIC1 : %s\n", + (clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running"); + len += sprintf (page+len, "AIC2 : %s\n", + (clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running"); + len += sprintf (page+len, "SSI0 : %s\n", + (clkgr & CPM_CLKGR_SSI0) ? "stopped" : "running"); + len += sprintf (page+len, "SSI1 : %s\n", + (clkgr & CPM_CLKGR_SSI1) ? "stopped" : "running"); + len += sprintf (page+len, "I2C : %s\n", + (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); + len += sprintf (page+len, "RTC : %s\n", + (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); + len += sprintf (page+len, "TCU : %s\n", + (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); + len += sprintf (page+len, "UART1 : %s\n", + (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); + len += sprintf (page+len, "UART0 : %s\n", + (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); + return len; +} + +static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * Clock Generation Module + */ +#define TO_MHZ(x) (x/1000000),(x%1000000)/10000 +#define TO_KHZ(x) (x/1000),(x%1000)/10 + +static int cgm_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ + unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr); + len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr); + len += sprintf (page+len, "PLL : %s\n", + (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); + len += sprintf (page+len, "m:n:o : %d:%d:%d\n", + __cpm_get_pllm() + 2, + __cpm_get_plln() + 2, + od[__cpm_get_pllod()] + ); + len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n", + div[__cpm_get_cdiv()], + div[__cpm_get_hdiv()], + div[__cpm_get_mdiv()], + div[__cpm_get_pdiv()] + ); + len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout())); + len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk())); + len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk())); + len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk())); + len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk())); + len += sprintf (page+len, "LCDCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_lcdclk())); + len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk())); + len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk())); + len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk())); + len += sprintf (page+len, "MSC0CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(0))); + len += sprintf (page+len, "MSC1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(1))); + len += sprintf (page+len, "EXTALCLK0 : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk0())); + len += sprintf (page+len, "EXTALCLK(by CPM): %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk())); + len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk())); + + return len; +} + +static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16); + return count; +} + + +/* USAGE: + * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages. + * echo FF > /proc/jz/ipu // 255, free all buffer + * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx + * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l) + * echo 0 > /proc/jz/ipu // debug, print ipu_buf + * od -X /proc/jz/ipu // read mem addr + */ + +typedef struct _ipu_buf { + unsigned int addr; /* phys addr */ + unsigned int page_shift; +} ipu_buf_t; + +#define IPU_BUF_MAX 4 /* 4 buffers */ + +static struct _ipu_buf ipu_buf[IPU_BUF_MAX]; +static int ipu_buf_cnt = 0; +static unsigned char g_asid=0; + +extern void local_flush_tlb_all(void); + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") +void show_tlb(void) +{ +#define ASID_MASK 0xFF + + unsigned long flags; + unsigned int old_ctx; + unsigned int entry; + unsigned int entrylo0, entrylo1, entryhi; + unsigned int pagemask; + + local_irq_save(flags); + + /* Save old context */ + old_ctx = (read_c0_entryhi() & 0xff); + + printk("TLB content:\n"); + entry = 0; + while(entry < 32) { + write_c0_index(entry); + BARRIER; + tlb_read(); + BARRIER; + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); + pagemask = read_c0_pagemask(); + printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); + printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); + printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); + + printk("\t\tpagemask=0x%08x", pagemask); + printk("\tentryhi=0x%08x\n", entryhi); + printk("\t\tentrylo0=0x%08x", entrylo0); + printk("\tentrylo1=0x%08x\n", entrylo1); + + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + + local_irq_restore(flags); +} + +static void ipu_add_wired_entry(unsigned long pid, + unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + struct task_struct *g, *p; + + /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */ + entrylo0 = entrylo0 >> 6; + entrylo0 |= 0x6 | (0 << 3); + /*entrylo0 |= 0x6 | (1 << 3);*/ + + do_each_thread(g, p) { + if (p->pid == pid ) + g_asid = p->mm->context[0]; + } while_each_thread(g, p); + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + entryhi &= ~0xff; /* new add, 20070906 */ + entryhi |= g_asid; /* new add, 20070906 */ +// entryhi |= old_ctx; /* new add, 20070906 */ + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +#if defined(DEBUG) + printk("\nold_ctx=%03d\n", old_ctx); + + show_tlb(); +#endif +} + +static void ipu_del_wired_entry( void ) +{ + unsigned long flags; + unsigned long wired; + + local_irq_save(flags); + wired = read_c0_wired(); + if (wired) { + write_c0_wired(0); + } + local_irq_restore(flags); +} + +static inline void ipu_buf_get( unsigned int page_shift ) +{ + unsigned char * virt_addr; + int i; + for ( i=0; i< IPU_BUF_MAX; ++i ) { + if ( ipu_buf[i].addr == 0 ) { + break; + } + } + + if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) { + printk("Error, no free ipu buffer.\n"); + return ; + } + + virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift); + + if ( virt_addr ) { + ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr); + ipu_buf[ipu_buf_cnt].page_shift = page_shift; + + for (i = 0; i < (1<= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */ + printk("no free buffer.\n"); + *pint = 0; + } + else + *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */ + len += sizeof(unsigned int); + +#if defined(DEBUG) + show_tlb(); +#endif + return len; + +} + +static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val ; + int cnt,i; + char buf[12]; + unsigned long pid, entrylo0, entrylo1, entryhi, pagemask; +#if defined(DEBUG) + printk("ipu write count=%u\n", count); +#endif + if (count == 41) { + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*0, 8); + pid = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*1, 8); + entrylo0 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*2, 8); + entrylo1 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*3, 8); + entryhi = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*4, 8); + pagemask = simple_strtoul(buf, 0, 16); + +#if defined(DEBUG) + printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n", + pid, entrylo0, entrylo1, entryhi, pagemask); +#endif + ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask); + return 41; + } else if ( count <= 9 ) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer, 8); + val = simple_strtoul(buf, 0, 16); + } else if (count == 44) { + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer, 10); + pid = simple_strtoul(buf, 0, 16); + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 11, 10); + entryhi = simple_strtoul(buf, 0, 16);//vaddr + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 22, 10); + entrylo0 = simple_strtoul(buf, 0, 16);//paddr + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 33, 10); + pagemask = simple_strtoul(buf, 0, 16); + pagemask = 0x3ff << 13; /* Fixed to 4MB page size */ + //pagemask = 0xfff << 13; /* Fixed to 16MB page size */ + + ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask); + return 44; + } else if (count == 12) { + printk("\necho release tlb > /proc/jz/ipu\n"); + ipu_del_wired_entry(); + return 12; + } else { + printk("ipu write count error, count=%d\n.", (unsigned int)count); + return -1; + } + + /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */ + if ( val == 0 ) { /* debug, print ipu_buf info */ + for ( cnt=0; cnt /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages + * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx + * echo FF > /proc/jz/ipu // FF, free all buffers + * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer + */ + +//#define DEBUG_IMEM 1 + +#define IMEM_MAX_ORDER 12 /* max 2^10 * 4096 = 4MB */ + +static unsigned int jz_imem_base; /* physical base address of ipu memory */ + +static unsigned int allocated_phys_addr = 0; + +/* + * Allocated buffer list + */ +typedef struct imem_list { + unsigned int phys_start; /* physical start addr */ + unsigned int phys_end; /* physical end addr */ + struct imem_list *next; +} imem_list_t; + +static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */ + +#ifdef DEBUG_IMEM +static void dump_imem_list(void) +{ + struct imem_list *imem; + + printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head); + imem = imem_list_head; + while (imem) { + printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next); + imem = imem->next; + } +} +#endif + +/* allocate 2^order pages inside the 4MB memory */ +static int imem_alloc(unsigned int order) +{ + int alloc_ok = 0; + unsigned int start, end; + unsigned int size = (1 << order) * PAGE_SIZE; + struct imem_list *imem, *imemn, *imemp; + + allocated_phys_addr = 0; + + start = jz_imem_base; + end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + imem = imem_list_head; + while (imem) { + if ((imem->phys_start - start) >= size) { + /* we got a valid address range */ + alloc_ok = 1; + break; + } + + start = imem->phys_end + 1; + imem = imem->next; + } + + if (!alloc_ok) { + if ((end - start) >= size) + alloc_ok = 1; + } + + if (alloc_ok) { + end = start + size - 1; + allocated_phys_addr = start; + + /* add to imem_list, up sorted by phys_start */ + imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); + if (!imemn) { + return -ENOMEM; + } + imemn->phys_start = start; + imemn->phys_end = end; + imemn->next = NULL; + + if (!imem_list_head) + imem_list_head = imemn; + else { + imem = imemp = imem_list_head; + while (imem) { + if (start < imem->phys_start) { + break; + } + + imemp = imem; + imem = imem->next; + } + + if (imem == imem_list_head) { + imem_list_head = imemn; + imemn->next = imem; + } + else { + imemn->next = imemp->next; + imemp->next = imemn; + } + } + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif + return 0; +} + +static void imem_free(unsigned int phys_addr) +{ + struct imem_list *imem, *imemp; + + imem = imemp = imem_list_head; + while (imem) { + if (phys_addr == imem->phys_start) { + if (imem == imem_list_head) { + imem_list_head = imem->next; + } + else { + imemp->next = imem->next; + } + + kfree(imem); + break; + } + + imemp = imem; + imem = imem->next; + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +static void imem_free_all(void) +{ + struct imem_list *imem; + + imem = imem_list_head; + while (imem) { + kfree(imem); + imem = imem->next; + } + + imem_list_head = NULL; + + allocated_phys_addr = 0; + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +/* + * Return the allocated buffer address and the max order of free buffer + */ +static int imem_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int start_addr, end_addr, max_order, max_size; + struct imem_list *imem; + + unsigned int *tmp = (unsigned int *)(page + len); + + start_addr = jz_imem_base; + end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + if (!imem_list_head) + max_size = end_addr - start_addr; + else { + max_size = 0; + imem = imem_list_head; + while (imem) { + if (max_size < (imem->phys_start - start_addr)) + max_size = imem->phys_start - start_addr; + + start_addr = imem->phys_end + 1; + imem = imem->next; + } + + if (max_size < (end_addr - start_addr)) + max_size = end_addr - start_addr; + } + + if (max_size > 0) { + max_order = get_order(max_size); + if (((1 << max_order) * PAGE_SIZE) > max_size) + max_order--; + } + else { + max_order = 0xffffffff; /* No any free buffer */ + } + + *tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */ + *tmp = max_order; /* max order of current free buffers */ + + len += 2 * sizeof(unsigned int); + + return len; +} + +static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val; + + val = simple_strtoul(buffer, 0, 16); + + if (val == 0xff) { + /* free all memory */ + imem_free_all(); + ipu_del_wired_entry(); + } else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) { + /* allocate 2^val pages */ + imem_alloc(val); + } else { + /* free buffer which phys_addr is val */ + imem_free(val); + } + + return count; +} + +/* + * /proc/jz/xxx entry + * + */ +static int __init jz_proc_init(void) +{ + struct proc_dir_entry *res; + unsigned int virt_addr, i; + + proc_jz_root = proc_mkdir("jz", 0); + + /* External Memory Controller */ + res = create_proc_entry("emc", 0644, proc_jz_root); + if (res) { + res->read_proc = emc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* Power Management Controller */ + res = create_proc_entry("pmc", 0644, proc_jz_root); + if (res) { + res->read_proc = pmc_read_proc; + res->write_proc = pmc_write_proc; + res->data = NULL; + } + + /* Clock Generation Module */ + res = create_proc_entry("cgm", 0644, proc_jz_root); + if (res) { + res->read_proc = cgm_read_proc; + res->write_proc = cgm_write_proc; + res->data = NULL; + } + + /* Image process unit */ + res = create_proc_entry("ipu", 0644, proc_jz_root); + if (res) { + res->read_proc = ipu_read_proc; + res->write_proc = ipu_write_proc; + res->data = NULL; + } + + /* udc hotplug */ + res = create_proc_entry("udc", 0644, proc_jz_root); + if (res) { + res->read_proc = udc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* mmc hotplug */ + res = create_proc_entry("mmc", 0644, proc_jz_root); + if (res) { + res->read_proc = mmc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* show tlb */ + res = create_proc_entry("tlb", 0644, proc_jz_root); + if (res) { + res->read_proc = tlb_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* + * Reserve a 4MB memory for IPU on JZ4750. + */ + jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER); + if (jz_imem_base) { + /* imem (IPU memory management) */ + res = create_proc_entry("imem", 0644, proc_jz_root); + if (res) { + res->read_proc = imem_read_proc; + res->write_proc = imem_write_proc; + res->data = NULL; + } + + /* Set page reserved */ + virt_addr = jz_imem_base; + for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) { + SetPageReserved(virt_to_page((void *)virt_addr)); + virt_addr += PAGE_SIZE; + } + + /* Convert to physical address */ + jz_imem_base = virt_to_phys((void *)jz_imem_base); + + printk("Total %dMB memory at 0x%x was reserved for IPU\n", + (unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base); + } else + printk("NOT enough memory for imem\n"); + + return 0; +} + +__initcall(jz_proc_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/prom.c linux-2.6.24.3-20100304/arch/mips/jz4750/prom.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/prom.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,198 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, supports YAMON and U-Boot. + * + * Copyright 2000, 2001, 2006 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +int prom_argc; +char **prom_argv, **prom_envp; + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + if (prom_argc > 1) + *cp = '\0'; + +} + + +char *prom_getenv(char *envname) +{ +#if 0 + /* + * Return a pointer to the given environment variable. + * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". + */ + + char **env = prom_envp; + int i = strlen(envname); + int yamon = (*env && strchr(*env, '=') == NULL); + + while (*env) { + if (yamon) { + if (strcmp(envname, *env++) == 0) + return *env; + } else { + if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; + } + env++; + } +#endif + return NULL; +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machtype = MACH_INGENIC_JZ4750; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +/* used by early printk */ +void prom_putchar(char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART0_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART0_BASE + OFF_TDR); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +const char *get_system_type(void) +{ + return "JZ4750"; +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/reset.c linux-2.6.24.3-20100304/arch/mips/jz4750/reset.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/reset.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,46 @@ +/* + * linux/arch/mips/jz4750/reset.c + * + * JZ4750 reset routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void jz_restart(char *command) +{ + printk("Restarting after 4 ms\n"); + REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN; + REG_WDT_TCNT = 0; + REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */ + REG_TCU_TSCR = TCU_TSCR_WDTSC; /* enable wdt clock */ + REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */ + while (1); +} + +void jz_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void jz_power_off(void) +{ + jz_halt(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/setup.c linux-2.6.24.3-20100304/arch/mips/jz4750/setup.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/setup.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,197 @@ +/* + * linux/arch/mips/jz4750/common/setup.c + * + * JZ4750 common setup routines. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PC_KEYB +#include +#endif + +jz_clocks_t jz_clocks; + +extern char * __init prom_getcmdline(void); +extern void __init jz_board_setup(void); +extern void jz_restart(char *); +extern void jz_halt(void); +extern void jz_power_off(void); +extern void jz_time_init(void); + +static void __init sysclocks_setup(void) +{ +#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.lcdclk = __cpm_get_lcdclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); + jz_clocks.extalclk = __cpm_get_extalclk(); + jz_clocks.rtcclk = __cpm_get_rtcclk(); +#else + +#define FPGACLK 8000000 + + jz_clocks.cclk = FPGACLK; + jz_clocks.hclk = FPGACLK; + jz_clocks.pclk = FPGACLK; + jz_clocks.mclk = FPGACLK; + jz_clocks.lcdclk = FPGACLK; + jz_clocks.pixclk = FPGACLK; + jz_clocks.i2sclk = FPGACLK; + jz_clocks.usbclk = FPGACLK; + jz_clocks.mscclk = FPGACLK; + jz_clocks.extalclk = FPGACLK; + jz_clocks.rtcclk = FPGACLK; +#endif + + printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n", + (jz_clocks.cclk + 500000) / 1000000, + (jz_clocks.hclk + 500000) / 1000000, + (jz_clocks.pclk + 500000) / 1000000, + (jz_clocks.mclk + 500000) / 1000000); +} + +static void __init soc_cpm_setup(void) +{ + /* Start all module clocks + */ + __cpm_start_all(); + + /* Enable CKO to external memory */ + __cpm_enable_cko(); + + /* CPU enters IDLE mode when executing 'wait' instruction */ + __cpm_idle_mode(); + + /* Setup system clocks */ + sysclocks_setup(); +} + +static void __init soc_harb_setup(void) +{ +// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ +} + +static void __init soc_emc_setup(void) +{ +} + +static void __init soc_dmac_setup(void) +{ + __dmac_enable_module(0); + __dmac_enable_module(1); +} + +static void __init jz_soc_setup(void) +{ + soc_cpm_setup(); + soc_harb_setup(); + soc_emc_setup(); + soc_dmac_setup(); +} + +static void __init jz_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */ + memset(&s, 0, sizeof(s)); + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = SERIAL_IO_MEM; + s.regshift = 2; + s.uartclk = jz_clocks.extalclk ; + + s.line = 0; + s.membase = (u8 *)UART0_BASE; + s.irq = IRQ_UART0; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS0 setup failed!\n"); + } + + s.line = 1; + s.membase = (u8 *)UART1_BASE; + s.irq = IRQ_UART1; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS1 setup failed!\n"); + } + + s.line = 2; + s.membase = (u8 *)UART2_BASE; + s.irq = IRQ_UART2; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS2 setup failed!\n"); + } + + s.line = 3; + s.membase = (u8 *)UART3_BASE; + s.irq = IRQ_UART3; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS3 setup failed!\n"); + } +#endif +} + +void __init plat_mem_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + + /* IO/MEM resources. Which will be the addtion value in `inX' and + * `outX' macros defined in asm/io.h */ + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x00000000; + iomem_resource.end = 0xffffffff; + + _machine_restart = jz_restart; + _machine_halt = jz_halt; + pm_power_off = jz_power_off; + + jz_soc_setup(); + jz_serial_setup(); + jz_board_setup(); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/time.c linux-2.6.24.3-20100304/arch/mips/jz4750/time.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750/time.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,156 @@ +/* + * linux/arch/mips/jz4750/time.c + * + * Setting up the clock on the JZ4750 boards. + * + * Copyright (C) 2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include + +#include +#include + +/* This is for machines which generate the exact clock. */ + +#define JZ_TIMER_IRQ IRQ_TCU0 + +#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */ + +static struct clocksource clocksource_jz; /* Jz clock source */ +static struct clock_event_device jz_clockevent_device; /* Jz clock event */ + +void (*jz_timer_callback)(void); + +static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */ + + if (jz_timer_callback) + jz_timer_callback(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction jz_irqaction = { + .handler = jz_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .name = "jz-timerirq", +}; + + +cycle_t jz_get_cycles(void) +{ + /* convert jiffes to jz timer cycles */ + return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_OSTCNT); +} + +static struct clocksource clocksource_jz = { + .name = "jz_clocksource", + .rating = 300, + .read = jz_get_cycles, + .mask = 0xFFFFFFFF, + .shift = 10, + .flags = CLOCK_SOURCE_WATCHDOG, +}; + +static int __init jz_clocksource_init(void) +{ + clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); + clocksource_register(&clocksource_jz); + return 0; +} + +static int jz_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + return 0; +} + +static void jz_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device jz_clockevent_device = { + .name = "jz-clockenvent", + .features = CLOCK_EVT_FEAT_PERIODIC, +// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */ + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + .rating = 300, + .irq = JZ_TIMER_IRQ, + .set_mode = jz_set_mode, + .set_next_event = jz_set_next_event, +}; + +static void __init jz_clockevent_init(void) +{ + struct clock_event_device *cd = &jz_clockevent_device; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); +} + +static void __init jz_timer_setup(void) +{ + jz_clocksource_init(); /* init jz clock source */ + jz_clockevent_init(); /* init jz clock event */ + + /* + * Make irqs happen for the system timer + */ + jz_irqaction.dev_id = &jz_clockevent_device; + setup_irq(JZ_TIMER_IRQ, &jz_irqaction); +} + + +void __init plat_time_init(void) +{ + unsigned int latch; + + /* Init timer */ + latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ; + + REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN; + REG_TCU_OSTCNT = 0; + REG_TCU_OSTDR = latch; + + REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */ + REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */ + REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */ + + jz_timer_setup(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/board-cetus.c linux-2.6.24.3-20100304/arch/mips/jz4750d/board-cetus.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/board-cetus.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/board-cetus.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,72 @@ +/* + * linux/arch/mips/jz4750d/board-cetus.c + * + * JZ4750D CETUS board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned char slash[] = "\\|/-"; +// static volatile unsigned char *p = (unsigned char *)0xb6000058; + static volatile unsigned char *p = (unsigned char *)0xb6000016; + static unsigned int count = 0; + *p = slash[count++]; + count &= 3; +} + +static void cetus_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750d/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Initialize SDRAM pins + */ +} + +void __init jz_board_setup(void) +{ + printk("JZ4750D CETUS board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = cetus_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/board-fuwa1.c linux-2.6.24.3-20100304/arch/mips/jz4750d/board-fuwa1.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/board-fuwa1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/board-fuwa1.c 2010-03-03 19:05:01.000000000 -0800 @@ -0,0 +1,72 @@ +/* + * linux/arch/mips/jz4750d/board-fuwa1.c + * + * JZ4750D FUWA1 board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned char slash[] = "\\|/-"; +// static volatile unsigned char *p = (unsigned char *)0xb6000058; + static volatile unsigned char *p = (unsigned char *)0xb6000016; + static unsigned int count = 0; + *p = slash[count++]; + count &= 3; +} + +static void fuwa1_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750d/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Initialize SDRAM pins + */ +} + +void __init jz_board_setup(void) +{ + printk("JZ4750D FUWA1 board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = fuwa1_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/cpufreq.c linux-2.6.24.3-20100304/arch/mips/jz4750d/cpufreq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/cpufreq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/cpufreq.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,598 @@ +/* + * linux/arch/mips/jz4750d/cpufreq.c + * + * cpufreq driver for JZ4750D + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ + "cpufreq-jz4750d", msg) + +#undef CHANGE_PLL + +#define PLL_UNCHANGED 0 +#define PLL_GOES_UP 1 +#define PLL_GOES_DOWN 2 + +#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000)) + +/* Saved the boot-time parameters */ +static struct { + /* SDRAM parameters */ + unsigned int mclk; /* memory clock, KHz */ + unsigned int tras; /* RAS pulse width, cycles of mclk */ + unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ + unsigned int tpc; /* RAS Precharge time, cycles of mclk */ + unsigned int trwl; /* Write Precharge Time, cycles of mclk */ + unsigned int trc; /* RAS Cycle Time, cycles of mclk */ + unsigned int rtcor; /* Refresh Time Constant */ + unsigned int sdram_initialized; + + /* LCD parameters */ + unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ + unsigned int lcd_clks_initialized; +} boot_config; + +struct jz4750d_freq_percpu_info { + struct cpufreq_frequency_table table[7]; +}; + +static struct jz4750d_freq_percpu_info jz4750d_freq_table; + +/* + * This contains the registers value for an operating point. + * If only part of a register needs to change then there is + * a mask value for that register. + * When going to a new operating point the current register + * value is ANDed with the ~mask and ORed with the new value. + */ +struct dpm_regs { + u32 cpccr; /* Clock Freq Control Register */ + u32 cpccr_mask; /* Clock Freq Control Register mask */ + u32 cppcr; /* PLL1 Control Register */ + u32 cppcr_mask; /* PLL1 Control Register mask */ + u32 pll_up_flag; /* New PLL freq is higher than current or not */ +}; + +extern jz_clocks_t jz_clocks; + +static void jz_update_clocks(void) +{ + /* Next clocks must be updated if we have changed + * the PLL or divisors. + */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); +} + +static void +jz_init_boot_config(void) +{ + if (!boot_config.lcd_clks_initialized) { + /* the first time to scale pll */ + boot_config.lcdpix_clk = __cpm_get_pixclk(); + boot_config.lcd_clks_initialized = 1; + } + + if (!boot_config.sdram_initialized) { + /* the first time to scale frequencies */ + unsigned int dmcr, rtcor; + unsigned int tras, rcd, tpc, trwl, trc; + + dmcr = REG_EMC_DMCR; + rtcor = REG_EMC_RTCOR; + + tras = (dmcr >> 13) & 0x7; + rcd = (dmcr >> 11) & 0x3; + tpc = (dmcr >> 8) & 0x7; + trwl = (dmcr >> 5) & 0x3; + trc = (dmcr >> 2) & 0x7; + + boot_config.mclk = __cpm_get_mclk() / 1000; + boot_config.tras = tras + 4; + boot_config.rcd = rcd + 1; + boot_config.tpc = tpc + 1; + boot_config.trwl = trwl + 1; + boot_config.trc = trc * 2 + 1; + boot_config.rtcor = rtcor; + + boot_config.sdram_initialized = 1; + } +} + +static void jz_update_dram_rtcor(unsigned int new_mclk) +{ + unsigned int rtcor; + + new_mclk /= 1000; + rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; + rtcor--; + + if (rtcor < 1) rtcor = 1; + if (rtcor > 255) rtcor = 255; + + REG_EMC_RTCOR = rtcor; + REG_EMC_RTCNT = rtcor; +} + +static void jz_update_dram_dmcr(unsigned int new_mclk) +{ + unsigned int dmcr; + unsigned int tras, rcd, tpc, trwl, trc; + unsigned int valid_time, new_time; /* ns */ + + new_mclk /= 1000; + tras = boot_config.tras * new_mclk / boot_config.mclk; + rcd = boot_config.rcd * new_mclk / boot_config.mclk; + tpc = boot_config.tpc * new_mclk / boot_config.mclk; + trwl = boot_config.trwl * new_mclk / boot_config.mclk; + trc = boot_config.trc * new_mclk / boot_config.mclk; + + /* Validation checking */ + valid_time = (boot_config.tras * 1000000) / boot_config.mclk; + new_time = (tras * 1000000) / new_mclk; + if (new_time < valid_time) tras += 1; + + valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; + new_time = (rcd * 1000000) / new_mclk; + if (new_time < valid_time) rcd += 1; + + valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; + new_time = (tpc * 1000000) / new_mclk; + if (new_time < valid_time) tpc += 1; + + valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; + new_time = (trwl * 1000000) / new_mclk; + if (new_time < valid_time) trwl += 1; + + valid_time = (boot_config.trc * 1000000) / boot_config.mclk; + new_time = (trc * 1000000) / new_mclk; + if (new_time < valid_time) trc += 2; + + tras = (tras < 4) ? 4: tras; + tras = (tras > 11) ? 11: tras; + tras -= 4; + + rcd = (rcd < 1) ? 1: rcd; + rcd = (rcd > 4) ? 4: rcd; + rcd -= 1; + + tpc = (tpc < 1) ? 1: tpc; + tpc = (tpc > 8) ? 8: tpc; + tpc -= 1; + + trwl = (trwl < 1) ? 1: trwl; + trwl = (trwl > 4) ? 4: trwl; + trwl -= 1; + + trc = (trc < 1) ? 1: trc; + trc = (trc > 15) ? 15: trc; + trc /= 2; + + dmcr = REG_EMC_DMCR; + + dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); + dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); + + REG_EMC_DMCR = dmcr; +} + +static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL + * and TRC of DMCR before changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } else { + /* We're going SLOWER: first update RTCOR value + * before changing the frequency. + */ + jz_update_dram_rtcor(new_mclk); + } +} + +static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so update RTCOR + * after changing the frequency + */ + jz_update_dram_rtcor(new_mclk); + } else { + /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL + * and TRC of DMCR after changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } +} + +static void jz_scale_divisors(struct dpm_regs *regs) +{ + unsigned int cpccr; + unsigned int cur_mclk, new_mclk; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~((unsigned long)regs->cpccr_mask); + cpccr |= regs->cpccr; + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + cur_mclk = __cpm_get_mclk(); + new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; + + /* Update some DRAM parameters before changing frequency */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} + +#ifdef CHANGE_PLL +/* Maintain the LCD clock and pixel clock */ +static void jz_scale_lcd_divisors(struct dpm_regs *regs) +{ + unsigned int new_pll, new_lcd_div, new_lcdpix_div; + unsigned int cpccr; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + if (!boot_config.lcd_clks_initialized) return; + + new_pll = __cpm_get_pllout(); + new_lcd_div = new_pll / boot_config.lcd_clk; + new_lcdpix_div = new_pll / boot_config.lcdpix_clk; + + if (new_lcd_div < 1) + new_lcd_div = 1; + if (new_lcd_div > 16) + new_lcd_div = 16; + + if (new_lcdpix_div < 1) + new_lcdpix_div = 1; + if (new_lcdpix_div > 512) + new_lcdpix_div = 512; + +// REG_CPM_CPCCR2 = new_lcdpix_div - 1; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~CPM_CPCCR_LDIV_MASK; + cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT); + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); +} + +static void jz_scale_pll(struct dpm_regs *regs) +{ + unsigned int cppcr; + unsigned int cur_mclk, new_mclk, new_pll; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + int od[] = {1, 2, 2, 4}; + + cppcr = REG_CPM_CPPCR; + cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK); + regs->cppcr &= ~CPM_CPPCR_PLLEN; + cppcr |= (regs->cppcr | 0xff); + + /* Update some DRAM parameters before changing frequency */ + new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]); + cur_mclk = __cpm_get_mclk(); + new_mclk = new_pll / div[(REG_CPM_CPCCR>>16) & 0xf]; + + /* + * Update some SDRAM parameters + */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* + * Update PLL, align code to cache line. + */ + cppcr |= CPM_CPPCR_PLLEN; + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPPCR), "r" (cppcr)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} +#endif + +static void jz4750d_transition(struct dpm_regs *regs) +{ + /* + * Get and save some boot-time conditions. + */ + jz_init_boot_config(); + +#ifdef CHANGE_PLL + /* + * Disable LCD before scaling pll. + * LCD and LCD pixel clocks should not be changed even if the PLL + * output frequency has been changed. + */ + REG_LCD_CTRL &= ~LCD_CTRL_ENA; + + /* + * Stop module clocks before scaling PLL + */ + __cpm_stop_eth(); + __cpm_stop_aic(1); + __cpm_stop_aic(2); +#endif + + /* ... add more as necessary */ + + if (regs->pll_up_flag == PLL_GOES_UP) { + /* the pll frequency is going up, so change dividors first */ + jz_scale_divisors(regs); +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + } + else if (regs->pll_up_flag == PLL_GOES_DOWN) { + /* the pll frequency is going down, so change pll first */ +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + jz_scale_divisors(regs); + } + else { + /* the pll frequency is unchanged, so change divisors only */ + jz_scale_divisors(regs); + } + +#ifdef CHANGE_PLL + /* + * Restart module clocks before scaling PLL + */ + __cpm_start_eth(); + __cpm_start_aic(1); + __cpm_start_aic(2); + + /* ... add more as necessary */ + + /* Scale the LCD divisors after scaling pll */ + if (regs->pll_up_flag != PLL_UNCHANGED) { + jz_scale_lcd_divisors(regs); + } + + /* Enable LCD controller */ + REG_LCD_CTRL &= ~LCD_CTRL_DIS; + REG_LCD_CTRL |= LCD_CTRL_ENA; +#endif + + /* Update system clocks */ + jz_update_clocks(); +} + +extern unsigned int idle_times; +static unsigned int jz4750d_freq_get(unsigned int cpu) +{ + return (__cpm_get_cclk() / 1000); +} + +static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) +{ + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; + int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ + unsigned int div_of_cclk, new_freq, i; + + regs->pll_up_flag = PLL_UNCHANGED; + regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK; + + new_freq = jz4750d_freq_table.table[index].frequency; + + do { + div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); + } while (div_of_cclk==0); + + if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { + for(i = 1; i<4; i++) { + div[i] = 3; + } + } else { + for(i = 1; i<4; i++) { + div[i] = 2; + } + } + + for(i = 0; i<4; i++) { + div[i] *= div_of_cclk; + } + + dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); + + regs->cpccr = + (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | + (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | + (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | + (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT); + + return div_of_cclk; +} + +static void jz4750d_set_cpu_divider_index(unsigned int cpu, unsigned int index) +{ + unsigned long divisor, old_divisor; + struct cpufreq_freqs freqs; + struct dpm_regs regs; + + old_divisor = __cpm_get_pllout() / __cpm_get_cclk(); + divisor = index_to_divisor(index, ®s); + + freqs.old = __cpm_get_cclk() / 1000; + freqs.new = __cpm_get_pllout() / (1000 * divisor); + freqs.cpu = cpu; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (old_divisor != divisor) + jz4750d_transition(®s); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + +static int jz4750d_freq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int new_index = 0; + + if (cpufreq_frequency_table_target(policy, + &jz4750d_freq_table.table[0], + target_freq, relation, &new_index)) + return -EINVAL; + + jz4750d_set_cpu_divider_index(policy->cpu, new_index); + + dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR); + + return 0; +} + +static int jz4750d_freq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &jz4750d_freq_table.table[0]); +} + +static int __init jz4750d_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + + struct cpufreq_frequency_table *table = &jz4750d_freq_table.table[0]; + unsigned int MAX_FREQ; + + dprintk(KERN_INFO "Jz4750d cpufreq driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.min_freq = MAX_FREQ/8; + policy->cpuinfo.max_freq = MAX_FREQ; + policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ + + table[0].index = 0; + table[0].frequency = MAX_FREQ/8; + table[1].index = 1; + table[1].frequency = MAX_FREQ/6; + table[2].index = 2; + table[2].frequency = MAX_FREQ/4; + table[3].index = 3; + table[3].frequency = MAX_FREQ/3; + table[4].index = 4; + table[4].frequency = MAX_FREQ/2; + table[5].index = 5; + table[5].frequency = MAX_FREQ; + table[6].index = 6; + table[6].frequency = CPUFREQ_TABLE_END; + +#ifdef CONFIG_CPU_FREQ_STAT_DETAILS + cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */ +#endif + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static struct cpufreq_driver cpufreq_jz4750d_driver = { +// .flags = CPUFREQ_STICKY, + .init = jz4750d_cpufreq_driver_init, + .verify = jz4750d_freq_verify, + .target = jz4750d_freq_target, + .get = jz4750d_freq_get, + .name = "jz4750d", +}; + +static int __init jz4750d_cpufreq_init(void) +{ + return cpufreq_register_driver(&cpufreq_jz4750d_driver); +} + +static void __exit jz4750d_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cpufreq_jz4750d_driver); +} + +module_init(jz4750d_cpufreq_init); +module_exit(jz4750d_cpufreq_exit); + +MODULE_AUTHOR("Regen "); +MODULE_DESCRIPTION("cpufreq driver for Jz4750d"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/dma.c linux-2.6.24.3-20100304/arch/mips/jz4750d/dma.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/dma.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,822 @@ +/* + * linux/arch/mips/jz4750d/dma.c + * + * Support functions for the JZ4750D internal DMA channels. + * No-descriptor transfer only. + * Descriptor transfer should also call jz_request_dma() to get a free + * channel and call jz_free_dma() to free the channel. And driver should + * build the DMA descriptor and setup the DMA channel by itself. + * + * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `jz_request_dma()' and `jz_free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from jz_request_dma(). + */ + +struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = { + {dev_id:DMA_ID_BCH_ENC,}, /* DMAC0 channel 0, reserved for BCH */ + {dev_id:-1,}, /* DMAC0 channel 1 */ + {dev_id:-1,}, /* DMAC0 channel 2 */ + {dev_id:-1,}, /* DMAC0 channel 3 */ + {dev_id:-1,}, /* DMAC1 channel 0 */ + {dev_id:-1,}, /* DMAC1 channel 1 */ + {dev_id:-1,}, /* DMAC1 channel 2 */ + {dev_id:-1,}, /* DMAC1 channel 3 */ +}; + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; + unsigned int dma_source; +} dma_dev_table[DMA_ID_MAX] = { + {0, DMA_AUTOINIT, DMAC_DRSR_RS_EXT}, /* External request with DREQn */ + {0x18000000, DMA_AUTOINIT, DMAC_DRSR_RS_NAND}, /* NAND request */ + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_ENC}, + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_DEC}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO}, +// {CPHYSADDR(TSSI_FIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_TSSIIN}, + {CPHYSADDR(UART3_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT}, + {CPHYSADDR(UART3_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART3IN}, + {CPHYSADDR(UART2_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT}, + {CPHYSADDR(UART2_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART2IN}, + {CPHYSADDR(UART1_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT}, + {CPHYSADDR(UART1_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART1IN}, + {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, + {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI0OUT}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI0IN}, + {CPHYSADDR(AIC_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, + {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, + {CPHYSADDR(MSC_TXFIFO(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC0OUT}, + {CPHYSADDR(MSC_RXFIFO(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC0IN}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU}, + {SADC_TSDAT, DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SADC},/* Touch Screen Data Register */ + {CPHYSADDR(MSC_TXFIFO(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC1OUT}, /* SSC1 TX */ + {CPHYSADDR(MSC_RXFIFO(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC1IN}, /* SSC1 RX */ + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI1OUT}, + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI1IN}, + {CPHYSADDR(PCM_DP), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_PMOUT}, + {CPHYSADDR(PCM_DP), DMA_16BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_PMIN}, + {}, +}; + + +int jz_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct jz_dma_chan *chan; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_jz_dma_channel(unsigned int dmanr) +{ + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return; + chan = &jz_dma_table[dmanr]; + + printk("DMA%d Registers:\n", dmanr); + printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR(chan->io/HALF_DMA_NUM)); + printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); + printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr)); + printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); + printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); + printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); + printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr)); + printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr)); + printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR(chan->io/HALF_DMA_NUM)); +} + + +/** + * jz_request_dma - dynamically allcate an idle DMA channel to return + * @dev_id: the specified dma device id or DMA_ID_RAW_SET + * @dev_str: the specified dma device string name + * @irqhandler: the irq handler, or NULL + * @irqflags: the irq handler flags + * @irq_dev_id: the irq handler device id for shared irq + * + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + * +*/ +/*int jz_request_dma(int dev_id, const char *dev_str, + void (*irqhandler)(int, void *, struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id) +*/ + +int jz_request_dma(int dev_id, const char *dev_str, + irqreturn_t (*irqhandler)(int, void *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct jz_dma_chan *chan; + int i, ret; + + if (dev_id < 0 || dev_id >= DMA_ID_MAX) + return -EINVAL; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) /* no free channel */ + return -ENODEV; + + /* we got a free channel */ + chan = &jz_dma_table[i]; + + if (irqhandler) { + chan->irq = IRQ_DMA_0 + i; // allocate irq number + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = -1; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = -1; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = i; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + chan->source = dma_dev_table[dev_id].dma_source; + + if (i < HALF_DMA_NUM) + REG_DMAC_DMACKE(0) = 1 << i; + else + REG_DMAC_DMACKE(1) = 1 << (i - HALF_DMA_NUM); + + return i; +} + +void jz_free_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = -1; + chan->irq_dev = NULL; + chan->dev_id = -1; +} + +void jz_set_dma_dest_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_DWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_DWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_DWDH_32; + break; + } +} + +void jz_set_dma_src_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_SWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_SWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_SWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_SWDH_32; + break; + } +} + +void jz_set_dma_block_size(int dmanr, int nbyte) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DS_MASK; + switch (nbyte) { + case 1: + chan->mode |= DMAC_DCMD_DS_8BIT; + break; + case 2: + chan->mode |= DMAC_DCMD_DS_16BIT; + break; + case 4: + chan->mode |= DMAC_DCMD_DS_32BIT; + break; + case 16: + chan->mode |= DMAC_DCMD_DS_16BYTE; + break; + case 32: + chan->mode |= DMAC_DCMD_DS_32BYTE; + break; + } +} + +unsigned int jz_get_dma_command(int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + return chan->mode; +} + +/** + * jz_set_dma_mode - do the raw settings for the specified DMA channel + * @dmanr: the specified DMA channel + * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE + * @dma_mode: dma raw mode + * @dma_source: dma raw request source + * @fifo_addr: dma raw device fifo address + * + * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call + * jz_set_dma_mode() rather than set_dma_mode() if you work with + * and external request dma device. + * + * NOTE: Don not dynamically allocate dma channel if one external request + * dma device will occupy this channel. +*/ +int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, + unsigned int dma_mode, unsigned int dma_source, + unsigned int fifo_addr) +{ + int dev_id, i; + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return -ENODEV; + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) + return -ENODEV; + + chan = &jz_dma_table[dmanr]; + dev_id = chan->dev_id; + if (dev_id > 0) { + printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", + __FUNCTION__, dmanr); + return -ENODEV; + } + + /* clone it from the dynamically allocated. */ + if (i != dmanr) { + chan->irq = jz_dma_table[i].irq; + chan->irq_dev = jz_dma_table[i].irq_dev; + chan->dev_str = jz_dma_table[i].dev_str; + jz_dma_table[i].irq = 0; + jz_dma_table[i].irq_dev = NULL; + jz_dma_table[i].dev_id = -1; + } + chan->dev_id = DMA_ID_RAW_SET; + chan->io = dmanr; + chan->fifo_addr = fifo_addr; + chan->mode = dma_mode; + chan->source = dma_source; + + set_dma_mode(dmanr, dma_mode); + + return dmanr; +} + +void enable_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); + REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */ + __dmac_enable_channel(dmanr); + if (chan->irq) + __dmac_channel_enable_irq(dmanr); +} + +#define DMA_DISABLE_POLL 0x10000 + +void disable_dma(unsigned int dmanr) +{ + int i; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + if (!__dmac_channel_enabled(dmanr)) + return; + + for (i = 0; i < DMA_DISABLE_POLL; i++) + if (__dmac_channel_transmit_end_detected(dmanr)) + break; +#if 0 + if (i == DMA_DISABLE_POLL) + printk(KERN_INFO "disable_dma: poll expired!\n"); +#endif + + __dmac_disable_channel(dmanr); + if (chan->irq) + __dmac_channel_disable_irq(dmanr); +} + +/* Note: DMA_MODE_MASK is simulated by sw */ +void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else { + printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + } + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; +} + +void set_dma_addr(unsigned int dmanr, unsigned int phyaddr) +{ + unsigned int mode; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + mode = chan->mode & DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + REG_DMAC_DSAR(chan->io) = chan->fifo_addr; + REG_DMAC_DTAR(chan->io) = phyaddr; + } else if (mode == DMA_MODE_WRITE) { + REG_DMAC_DSAR(chan->io) = phyaddr; + REG_DMAC_DTAR(chan->io) = chan->fifo_addr; + } else + printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); +} + +void set_dma_count(unsigned int dmanr, unsigned int bytecnt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + int dma_ds[] = {4, 1, 2, 16, 32}; + unsigned int ds; + + if (!chan) + return; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count +} + +unsigned int get_dma_residue(unsigned int dmanr) +{ + unsigned int count, ds; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + count = REG_DMAC_DTCR(chan->io); + count = count * dma_ds[ds]; + + return count; +} + +void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case AFMT_U8: + /* burst mode : 32BIT */ + break; + case AFMT_S16_LE: + /* burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; + //chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case 8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case 16: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +//#define JZ4750D_DMAC_TEST_ENABLE +#undef JZ4750D_DMAC_TEST_ENABLE + +#ifdef JZ4750D_DMAC_TEST_ENABLE + +/* + * DMA test: external address <--> external address + */ +#define TEST_DMA_SIZE 16*1024 + +static jz_dma_desc *dma_desc; + +static int dma_chan; +static dma_addr_t dma_desc_phys_addr; +static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr; + +static int dma_check_result(void *src, void *dst, int size) +{ + unsigned int addr1, addr2, i, err = 0; + + addr1 = (unsigned int)src; + addr2 = (unsigned int)dst; + + for (i = 0; i < size; i += 4) { + if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) { + err++; + printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2); + } + addr1 += 4; + addr2 += 4; + } + printk("check DMA result err=%d\n", err); + return err; +} + +static irqreturn_t jz4750d_dma_irq(int irq, void *dev_id) +{ + printk("jz4750d_dma_irq %d\n", irq); + + + if (__dmac_channel_transmit_halt_detected(dma_chan)) { + printk("DMA HALT\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + __dmac_channel_clear_transmit_halt(dma_chan); + } + + if (__dmac_channel_address_error_detected(dma_chan)) { + printk("DMA ADDR ERROR\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + REG_DMAC_DSAR(dma_chan) = 0; /* clear source address register */ + REG_DMAC_DTAR(dma_chan) = 0; /* clear target address register */ + __dmac_channel_clear_address_error(dma_chan); + } + + if (__dmac_channel_descriptor_invalid_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA DESC INVALID\n"); + __dmac_channel_clear_descriptor_invalid(dma_chan); + } + + if (__dmac_channel_count_terminated_detected(dma_chan)) { + printk("DMA CT\n"); + __dmac_channel_clear_count_terminated(dma_chan); + } + + if (__dmac_channel_transmit_end_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA TT\n"); + __dmac_channel_clear_transmit_end(dma_chan); + dump_jz_dma_channel(dma_chan); + dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE); + } + + return IRQ_HANDLED; +} + +void dma_nodesc_test(void) +{ + unsigned int addr, i; + + printk("dma_nodesc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750d_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Init DMA module */ + printk("Starting DMA\n"); + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0; + REG_DMAC_DCCSR(dma_chan) = 0; + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; + REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; + REG_DMAC_DTCR(dma_chan) = 512; + REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */ + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +void dma_desc_test(void) +{ + unsigned int next, addr, i; + static jz_dma_desc *desc; + + printk("dma_desc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750d_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Allocate DMA descriptors */ + dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0); + dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc); + + printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr); + + /* Setup DMA descriptors */ + desc = dma_desc; + next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr; /* DMA target address */ + desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE; + desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */ + desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */ + + dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc))); + + /* Setup DMA descriptor address */ + REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr; + + /* Setup request source */ + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + + /* Setup DMA channel control/status register */ + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */ + + /* Enable DMA */ + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; + + /* DMA doorbell set -- start DMA now ... */ + REG_DMAC_DMADBSR(dma_chan/HALF_DMA_NUM) = 1 << dma_chan; + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +#endif + +//EXPORT_SYMBOL_NOVERS(jz_dma_table); +EXPORT_SYMBOL(jz_dma_table); +EXPORT_SYMBOL(jz_request_dma); +EXPORT_SYMBOL(jz_free_dma); +EXPORT_SYMBOL(jz_set_dma_src_width); +EXPORT_SYMBOL(jz_set_dma_dest_width); +EXPORT_SYMBOL(jz_set_dma_block_size); +EXPORT_SYMBOL(jz_set_dma_mode); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(jz_set_oss_dma); +EXPORT_SYMBOL(jz_set_alsa_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(dump_jz_dma_channel); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/i2c.c linux-2.6.24.3-20100304/arch/mips/jz4750d/i2c.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/i2c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/i2c.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,273 @@ +/* + * linux/arch/mips/jz4750d/i2c.c + * + * Jz4750D I2C routines. + * + * Copyright (C) 2005,2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include + +#include + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (!__i2c_received_ack() && timeout) + timeout--; + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +#ifdef CONFIG_JZ_TPANEL_ATA2508 +static int i2c_put_data_nack(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (timeout--); + return 0; +} +#endif + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else + return -ETIMEDOUT; +} + +/* + * I2C interface + */ +void i2c_open(void) +{ + __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */ + __i2c_enable(); +} + +void i2c_close(void) +{ + udelay(300); /* wait for STOP goes over. */ + __i2c_disable(); +} + +void i2c_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.extalclk, i2cclk); +} + +int i2c_lseek(unsigned char device, unsigned char offset) +{ + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(offset) < 0) + goto address_err; + return 0; + device_err: + printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device); + __i2c_send_stop(); + return -ENODEV; + address_err: + printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device); + __i2c_send_stop(); + return -EREMOTEIO; +} + +int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int timeout = 5; + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; + if (i2c_put_data(address) < 0) + goto address_err; + + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_READ ) < 0) + goto device_rerr; + __i2c_send_ack(); /* Master sends ACK for continue reading */ + while (cnt) { + if (cnt == 1) { + if (i2c_get_data(buf, 0) < 0) + break; + } else { + if (i2c_get_data(buf, 1) < 0) + break; + } + cnt--; + buf++; + } + + __i2c_send_stop(); + return count - cnt; + device_rerr: + device_werr: + address_err: + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + +int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + unsigned char tmpaddr; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = count; + tmpbuf = (unsigned char *)buf; + tmpaddr = address; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; +#ifdef CONFIG_JZ_TPANEL_ATA2508 + if (address == 0xff) { + if (i2c_put_data_nack(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data_nack(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } + else { + + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } +#else + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } +#endif + __i2c_send_stop(); + return count - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + + W_timeout: + printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +EXPORT_SYMBOL(i2c_open); +EXPORT_SYMBOL(i2c_close); +EXPORT_SYMBOL(i2c_setclk); +EXPORT_SYMBOL(i2c_read); +EXPORT_SYMBOL(i2c_write); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/irq.c linux-2.6.24.3-20100304/arch/mips/jz4750d/irq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/irq.c 2010-03-03 19:05:01.000000000 -0800 @@ -0,0 +1,299 @@ +/* + * linux/arch/mips/jz4750d/irq.c + * + * JZ4750D interrupt routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * INTC irq type + */ + +static void enable_intc_irq(unsigned int irq) +{ + __intc_unmask_irq(irq); +} + +static void disable_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); +} + +static void mask_and_ack_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); + __intc_ack_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_intc_irq(irq); + } +} + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static struct irq_chip intc_irq_type = { + .typename = "INTC", + .startup = startup_intc_irq, + .shutdown = shutdown_intc_irq, + .enable = enable_intc_irq, + .disable = disable_intc_irq, + .ack = mask_and_ack_intc_irq, + .end = end_intc_irq, +}; + +/* + * GPIO irq type + */ + +static void enable_gpio_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if (irq < (IRQ_GPIO_0 + 32)) { + intc_irq = IRQ_GPIO0; + } + else if (irq < (IRQ_GPIO_0 + 64)) { + intc_irq = IRQ_GPIO1; + } + else if (irq < (IRQ_GPIO_0 + 96)) { + intc_irq = IRQ_GPIO2; + } + else if (irq < (IRQ_GPIO_0 + 128)) { + intc_irq = IRQ_GPIO3; + } + else if (irq < (IRQ_GPIO_0 + 160)) { + intc_irq = IRQ_GPIO4; + } + else { + intc_irq = IRQ_GPIO5; + } + + enable_intc_irq(intc_irq); + __gpio_unmask_irq(irq - IRQ_GPIO_0); +} + +static void disable_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); +} + +static void mask_and_ack_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); + __gpio_ack_irq(irq - IRQ_GPIO_0); +} + +static void end_gpio_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_gpio_irq(irq); + } +} + +static unsigned int startup_gpio_irq(unsigned int irq) +{ + enable_gpio_irq(irq); + return 0; +} + +static void shutdown_gpio_irq(unsigned int irq) +{ + disable_gpio_irq(irq); +} + +static struct irq_chip gpio_irq_type = { + .typename = "GPIO", + .startup = startup_gpio_irq, + .shutdown = shutdown_gpio_irq, + .enable = enable_gpio_irq, + .disable = disable_gpio_irq, + .ack = mask_and_ack_gpio_irq, + .end = end_gpio_irq, +}; + +/* + * DMA irq type + */ + +static void enable_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return; + } + __intc_unmask_irq(intc_irq); + __dmac_channel_enable_irq(irq - IRQ_DMA_0); +} + +static void disable_dma_irq(unsigned int irq) +{ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void mask_and_ack_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return ; + } + __intc_ack_irq(intc_irq); + __dmac_channel_ack_irq(irq-IRQ_DMA_0); /* needed?? add 20080506, Wolfgang */ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void end_dma_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_dma_irq(irq); + } +} + +static unsigned int startup_dma_irq(unsigned int irq) +{ + enable_dma_irq(irq); + return 0; +} + +static void shutdown_dma_irq(unsigned int irq) +{ + disable_dma_irq(irq); +} + +static struct irq_chip dma_irq_type = { + .typename = "DMA", + .startup = startup_dma_irq, + .shutdown = shutdown_dma_irq, + .enable = enable_dma_irq, + .disable = disable_dma_irq, + .ack = mask_and_ack_dma_irq, + .end = end_dma_irq, +}; + +//---------------------------------------------------------------------- + +void __init arch_init_irq(void) +{ + int i; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + /* Set up INTC irq + */ + for (i = 0; i < 32; i++) { + disable_intc_irq(i); + irq_desc[i].chip = &intc_irq_type; + } + + /* Set up DMAC irq + */ + for (i = 0; i < NUM_DMA; i++) { + disable_dma_irq(IRQ_DMA_0 + i); + irq_desc[IRQ_DMA_0 + i].chip = &dma_irq_type; + } + + /* Set up GPIO irq + */ + for (i = 0; i < NUM_GPIO; i++) { + disable_gpio_irq(IRQ_GPIO_0 + i); + irq_desc[IRQ_GPIO_0 + i].chip = &gpio_irq_type; + } +} + +static int plat_real_irq(int irq) +{ + switch (irq) { + case IRQ_GPIO0: + irq = __gpio_group_irq(0) + IRQ_GPIO_0; + break; + case IRQ_GPIO1: + irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32; + break; + case IRQ_GPIO2: + irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64; + break; + case IRQ_GPIO3: + irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96; + break; + case IRQ_GPIO4: + irq = __gpio_group_irq(4) + IRQ_GPIO_0 + 128; + break; + case IRQ_GPIO5: + irq = __gpio_group_irq(5) + IRQ_GPIO_0 + 160; + break; + case IRQ_DMAC0: + case IRQ_DMAC1: + irq = __dmac_get_irq() + IRQ_DMA_0; + break; + } + + return irq; +} + +asmlinkage void plat_irq_dispatch(void) +{ + int irq = 0; + static unsigned long intc_ipr = 0; + + intc_ipr |= REG_INTC_IPR; + + if (!intc_ipr) return; + + irq = ffs(intc_ipr) - 1; + intc_ipr &= ~(1< + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include +#if 0 +/* OHCI (USB full speed host controller) */ +static struct resource jz_usb_ohci_resources[] = { + [0] = { + .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap + .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UHC, + .end = IRQ_UHC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct platform_device jz_usb_ohci_device = { + .name = "jz-ohci", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_ohci_resources), + .resource = jz_usb_ohci_resources, +}; +#endif +/*** LCD controller ***/ +static struct resource jz_lcd_resources[] = { + [0] = { + .start = CPHYSADDR(LCD_BASE), + .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_lcd_dmamask = ~(u32)0; + +static struct platform_device jz_lcd_device = { + .name = "jz-lcd", + .id = 0, + .dev = { + .dma_mask = &jz_lcd_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_lcd_resources), + .resource = jz_lcd_resources, +}; + +/* UDC (USB gadget controller) */ +static struct resource jz_usb_gdt_resources[] = { + [0] = { + .start = CPHYSADDR(UDC_BASE), + .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UDC, + .end = IRQ_UDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device jz_usb_gdt_device = { + .name = "jz-udc", + .id = 0, + .dev = { + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_gdt_resources), + .resource = jz_usb_gdt_resources, +}; + +/** MMC/SD controller **/ +static struct resource jz_mmc_resources[] = { + [0] = { + .start = CPHYSADDR(MSC_BASE), + .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MSC0, + .end = IRQ_MSC0, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_mmc_dmamask = ~(u32)0; + +static struct platform_device jz_mmc_device = { + .name = "jz-mmc", + .id = 0, + .dev = { + .dma_mask = &jz_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_mmc_resources), + .resource = jz_mmc_resources, +}; + +/* All */ +static struct platform_device *jz_platform_devices[] __initdata = { +// &jz_usb_ohci_device, + &jz_lcd_device, + &jz_usb_gdt_device, + &jz_mmc_device, +}; + +static int __init jz_platform_init(void) +{ + return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices)); +} + +arch_initcall(jz_platform_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/pm.c linux-2.6.24.3-20100304/arch/mips/jz4750d/pm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/pm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/pm.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,461 @@ +/* + * linux/arch/mips/jz4750d/common/pm.c + * + * JZ4750D Power Management Routines + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + +#define GPIO_PORT_NUM 6 + +/* + * __gpio_as_sleep set all pins to pull-disable, and set all pins as input + * except sdram and the pins which can be used as CS1_N to CS4_N for chip select. + */ +#define __gpio_as_sleep() \ +do { \ + REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \ + REG_GPIO_PXSELC(1) = ~0x03ff7fff; \ + REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \ + REG_GPIO_PXPES(1) = 0xffffffff; \ + REG_GPIO_PXFUNC(2) = ~0x01e00000; \ + REG_GPIO_PXSELC(2) = ~0x01e00000; \ + REG_GPIO_PXDIRC(2) = ~0x01e00000; \ + REG_GPIO_PXPES(2) = 0xffffffff; \ + REG_GPIO_PXFUNC(3) = 0xffffffff; \ + REG_GPIO_PXSELC(3) = 0xffffffff; \ + REG_GPIO_PXDIRC(3) = 0xffffffff; \ + REG_GPIO_PXPES(3) = 0xffffffff; \ + REG_GPIO_PXFUNC(4) = 0xffffffff; \ + REG_GPIO_PXSELC(4) = 0xffffffff; \ + REG_GPIO_PXDIRC(4) = 0xffffffff; \ + REG_GPIO_PXPES(4) = 0xffffffff; \ + REG_GPIO_PXFUNC(5) = 0xffffffff; \ + REG_GPIO_PXSELC(5) = 0xffffffff; \ + REG_GPIO_PXDIRC(5) = 0xffffffff; \ + REG_GPIO_PXPES(5) = 0xffffffff; \ +} while (0) + +static int jz_pm_do_hibernate(void) +{ + printk("Put CPU into hibernate mode.\n"); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* + * RTC Wakeup or 1Hz interrupt can be enabled or disabled + * through RTC driver's ioctl (linux/driver/char/rtc_jz.c). + */ + + /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT); + + /* Set reset pin low-level assertion time after wakeup: must > 60ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */ + + /* Scratch pad register to be reserved */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HSPR = 0x12345678; + + /* clear wakeup status register */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWRSR = 0x0; + + /* Put CPU to power down mode */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HCR = RTC_HCR_PD; + + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + while(1); + + /* We can't get here */ + return 0; +} + +/* NOTES: + * 1: Pins that are floated (NC) should be set as input and pull-enable. + * 2: Pins that are pull-up or pull-down by outside should be set as input + * and pull-disable. + * 3: Pins that are connected to a chip except sdram and nand flash + * should be set as input and pull-disable, too. + */ +static void jz_board_do_sleep(unsigned long *ptr) +{ + unsigned char i; + + /* Print messages of GPIO registers for debug */ + for(i=0;i + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG 1 +#undef DEBUG + + +struct proc_dir_entry *proc_jz_root; + + +/* + * EMC Modules + */ +static int emc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4); + len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4); + len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); + len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); + len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); + return len; +} + +/* + * Power Manager Module + */ +static int pmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned long lcr = REG_CPM_LCR; + unsigned long clkgr = REG_CPM_CLKGR; + + len += sprintf (page+len, "Low Power Mode : %s\n", + ((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ? + "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ? + "SLEEP" : "HIBERNATE")); + len += sprintf (page+len, "Doze Mode : %s\n", + (lcr & CPM_LCR_DOZE_ON) ? "on" : "off"); + if (lcr & CPM_LCR_DOZE_ON) + len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); + len += sprintf (page+len, "AUX_CPU : %s\n", + (clkgr & CPM_CLKGR_AUX_CPU) ? "stopped" : "running"); + len += sprintf (page+len, "AHB1 : %s\n", + (clkgr & CPM_CLKGR_AHB1) ? "stopped" : "running"); + len += sprintf (page+len, "IDCT : %s\n", + (clkgr & CPM_CLKGR_IDCT) ? "stopped" : "running"); + len += sprintf (page+len, "DB : %s\n", + (clkgr & CPM_CLKGR_DB) ? "stopped" : "running"); + len += sprintf (page+len, "ME : %s\n", + (clkgr & CPM_CLKGR_ME) ? "stopped" : "running"); + len += sprintf (page+len, "MC : %s\n", + (clkgr & CPM_CLKGR_MC) ? "stopped" : "running"); + len += sprintf (page+len, "TVE : %s\n", + (clkgr & CPM_CLKGR_TVE) ? "stopped" : "running"); + len += sprintf (page+len, "TSSI : %s\n", + (clkgr & CPM_CLKGR_TSSI) ? "stopped" : "running"); + len += sprintf (page+len, "IPU : %s\n", + (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); + len += sprintf (page+len, "DMAC : %s\n", + (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); + len += sprintf (page+len, "UDC : %s\n", + (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); + len += sprintf (page+len, "LCD : %s\n", + (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); + len += sprintf (page+len, "CIM : %s\n", + (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); + len += sprintf (page+len, "SADC : %s\n", + (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); + len += sprintf (page+len, "MSC0 : %s\n", + (clkgr & CPM_CLKGR_MSC0) ? "stopped" : "running"); + len += sprintf (page+len, "MSC1 : %s\n", + (clkgr & CPM_CLKGR_MSC1) ? "stopped" : "running"); + len += sprintf (page+len, "SSI : %s\n", + (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running"); + len += sprintf (page+len, "I2C : %s\n", + (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); + len += sprintf (page+len, "RTC : %s\n", + (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); + len += sprintf (page+len, "TCU : %s\n", + (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); + len += sprintf (page+len, "UART1 : %s\n", + (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); + len += sprintf (page+len, "UART0 : %s\n", + (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); + return len; +} + +static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * Clock Generation Module + */ +#define TO_MHZ(x) (x/1000000),(x%1000000)/10000 +#define TO_KHZ(x) (x/1000),(x%1000)/10 + +static int cgm_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ + unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr); + len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr); + len += sprintf (page+len, "PLL : %s\n", + (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); + len += sprintf (page+len, "m:n:o : %d:%d:%d\n", + __cpm_get_pllm() + 2, + __cpm_get_plln() + 2, + od[__cpm_get_pllod()] + ); + len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n", + div[__cpm_get_cdiv()], + div[__cpm_get_hdiv()], + div[__cpm_get_mdiv()], + div[__cpm_get_pdiv()] + ); + len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout())); + len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk())); + len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk())); + len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk())); + len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk())); + len += sprintf (page+len, "H1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_h1clk())); + len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk())); + len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk())); + len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk())); + len += sprintf (page+len, "MSC0CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(0))); + len += sprintf (page+len, "MSC1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(1))); + len += sprintf (page+len, "EXTALCLK0 : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk0())); + len += sprintf (page+len, "EXTALCLK(by CPM): %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk())); + len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk())); + + return len; +} + +static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16); + return count; +} + + +/* USAGE: + * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages. + * echo FF > /proc/jz/ipu // 255, free all buffer + * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx + * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l) + * echo 0 > /proc/jz/ipu // debug, print ipu_buf + * od -X /proc/jz/ipu // read mem addr + */ + +typedef struct _ipu_buf { + unsigned int addr; /* phys addr */ + unsigned int page_shift; +} ipu_buf_t; + +#define IPU_BUF_MAX 4 /* 4 buffers */ + +static struct _ipu_buf ipu_buf[IPU_BUF_MAX]; +static int ipu_buf_cnt = 0; +static unsigned char g_asid=0; + +extern void local_flush_tlb_all(void); + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") +void show_tlb(void) +{ +#define ASID_MASK 0xFF + + unsigned long flags; + unsigned int old_ctx; + unsigned int entry; + unsigned int entrylo0, entrylo1, entryhi; + unsigned int pagemask; + + local_irq_save(flags); + + /* Save old context */ + old_ctx = (read_c0_entryhi() & 0xff); + + printk("TLB content:\n"); + entry = 0; + while(entry < 32) { + write_c0_index(entry); + BARRIER; + tlb_read(); + BARRIER; + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); + pagemask = read_c0_pagemask(); + printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); + printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); + printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); + + printk("\t\tpagemask=0x%08x", pagemask); + printk("\tentryhi=0x%08x\n", entryhi); + printk("\t\tentrylo0=0x%08x", entrylo0); + printk("\tentrylo1=0x%08x\n", entrylo1); + + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + + local_irq_restore(flags); +} + +static void ipu_add_wired_entry(unsigned long pid, + unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + struct task_struct *g, *p; + + /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */ + entrylo0 = entrylo0 >> 6; + entrylo0 |= 0x6 | (0 << 3); + + do_each_thread(g, p) { + if (p->pid == pid ) + g_asid = p->mm->context[0]; + } while_each_thread(g, p); + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + entryhi &= ~0xff; /* new add, 20070906 */ + entryhi |= g_asid; /* new add, 20070906 */ +// entryhi |= old_ctx; /* new add, 20070906 */ + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +#if defined(DEBUG) + printk("\nold_ctx=%03d\n", old_ctx); + + show_tlb(); +#endif +} + +static void ipu_del_wired_entry( void ) +{ + unsigned long flags; + unsigned long wired; + + local_irq_save(flags); + wired = read_c0_wired(); + if ( wired > 0 ) { + write_c0_wired(wired - 1); + } + local_irq_restore(flags); +} + +static inline void ipu_buf_get( unsigned int page_shift ) +{ + unsigned char * virt_addr; + int i; + for ( i=0; i< IPU_BUF_MAX; ++i ) { + if ( ipu_buf[i].addr == 0 ) { + break; + } + } + + if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) { + printk("Error, no free ipu buffer.\n"); + return ; + } + + virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift); + + if ( virt_addr ) { + ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr); + ipu_buf[ipu_buf_cnt].page_shift = page_shift; + + for (i = 0; i < (1<= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */ + printk("no free buffer.\n"); + *pint = 0; + } + else + *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */ + len += sizeof(unsigned int); + +#if defined(DEBUG) + show_tlb(); +#endif + return len; + +} + +static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val ; + int cnt,i; + char buf[12]; + unsigned long pid, entrylo0, entrylo1, entryhi, pagemask; +#if defined(DEBUG) + printk("ipu write count=%u\n", count); +#endif + if (count == 41) { + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*0, 8); + pid = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*1, 8); + entrylo0 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*2, 8); + entrylo1 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*3, 8); + entryhi = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) + buf[i]=0; + strncpy(buf, buffer+8*4, 8); + pagemask = simple_strtoul(buf, 0, 16); + +#if defined(DEBUG) + printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n", + pid, entrylo0, entrylo1, entryhi, pagemask); +#endif + ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask); + return 41; + } else if ( count <= 9 ) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer, 8); + val = simple_strtoul(buf, 0, 16); + } else if (count == 44) { + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer, 10); + pid = simple_strtoul(buf, 0, 16); + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 11, 10); + entryhi = simple_strtoul(buf, 0, 16);//vaddr + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 22, 10); + entrylo0 = simple_strtoul(buf, 0, 16);//paddr + + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 33, 10); + pagemask = simple_strtoul(buf, 0, 16); + //pagemask = 0x3ff << 13; /* Fixed to 4MB page size */ + pagemask = 0xfff << 13; /* Fixed to 16MB page size */ + + ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask); + return 44; + } else if (count == 12) { + printk("\necho release tlb > /proc/jz/ipu\n"); + ipu_del_wired_entry(); + return 12; + } else { + printk("ipu write count error, count=%d\n.", (unsigned int)count); + return -1; + } + + /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */ + if ( val == 0 ) { /* debug, print ipu_buf info */ + for ( cnt=0; cnt /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages + * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx + * echo FF > /proc/jz/ipu // FF, free all buffers + * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer + */ + +//#define DEBUG_IMEM 1 + +#define IMEM0_MAX_ORDER 12 /* max 2^12 * 4096 = 16MB */ +static unsigned int jz_imem0_base; /* physical base address of ipu memory */ +static unsigned int allocated_phys_addr0 = 0; + +/* + * Allocated buffer list + */ +typedef struct imem_list { + unsigned int phys_start; /* physical start addr */ + unsigned int phys_end; /* physical end addr */ + struct imem_list *next; +} imem_list_t; + +static struct imem_list *imem0_list_head = NULL; /* up sorted by phys_start */ + +#define IMEM1_MAX_ORDER 11 /* max 2^11 * 4096 = 8MB */ +static unsigned int jz_imem1_base; /* physical base address of ipu memory */ +static unsigned int allocated_phys_addr1 = 0; +static struct imem_list *imem1_list_head = NULL; /* up sorted by phys_start */ + +#ifdef DEBUG_IMEM +static void dump_imem_list(void) +{ + struct imem_list *imem; + + printk("*** dump_imem_list 0x%x ***\n", (u32)imem0_list_head); + imem = imem0_list_head; + while (imem) { + printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next); + imem = imem->next; + } + + + printk("*** dump_imem_list 0x%x ***\n", (u32)imem1_list_head); + imem = imem1_list_head; + while (imem) { + printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next); + imem = imem->next; + } + +} +#endif + +/* allocate 2^order pages inside the 4MB memory */ + +static int imem0_alloc(unsigned int order) +{ + int alloc_ok = 0; + unsigned int start, end; + unsigned int size = (1 << order) * PAGE_SIZE; + struct imem_list *imem, *imemn, *imemp; + + allocated_phys_addr0 = 0; + + start = jz_imem0_base; + end = start + (1 << IMEM0_MAX_ORDER) * PAGE_SIZE; + + imem = imem0_list_head; + while (imem) { + if ((imem->phys_start - start) >= size) { + /* we got a valid address range */ + alloc_ok = 1; + break; + } + + start = imem->phys_end + 1; + imem = imem->next; + } + + if (!alloc_ok) { + if ((end - start) >= size) + alloc_ok = 1; + } + + if (alloc_ok) { + end = start + size - 1; + allocated_phys_addr0 = start; + + /* add to imem_list, up sorted by phys_start */ + imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); + if (!imemn) { + return -ENOMEM; + } + imemn->phys_start = start; + imemn->phys_end = end; + imemn->next = NULL; + + if (!imem0_list_head) + imem0_list_head = imemn; + else { + imem = imemp = imem0_list_head; + while (imem) { + if (start < imem->phys_start) { + break; + } + + imemp = imem; + imem = imem->next; + } + + if (imem == imem0_list_head) { + imem0_list_head = imemn; + imemn->next = imem; + } + else { + imemn->next = imemp->next; + imemp->next = imemn; + } + } + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif + return 0; +} + +/* allocate 2^order pages inside the 4MB memory */ +static int imem1_alloc(unsigned int order) +{ + int alloc_ok = 0; + unsigned int start, end; + unsigned int size = (1 << order) * PAGE_SIZE; + struct imem_list *imem, *imemn, *imemp; + + allocated_phys_addr1 = 0; + + start = jz_imem1_base; + end = start + (1 << IMEM1_MAX_ORDER) * PAGE_SIZE; + + imem = imem1_list_head; + while (imem) { + if ((imem->phys_start - start) >= size) { + /* we got a valid address range */ + alloc_ok = 1; + break; + } + + start = imem->phys_end + 1; + imem = imem->next; + } + + if (!alloc_ok) { + if ((end - start) >= size) + alloc_ok = 1; + } + + if (alloc_ok) { + end = start + size - 1; + allocated_phys_addr1 = start; + + /* add to imem_list, up sorted by phys_start */ + imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); + if (!imemn) { + return -ENOMEM; + } + imemn->phys_start = start; + imemn->phys_end = end; + imemn->next = NULL; + + if (!imem1_list_head) + imem1_list_head = imemn; + else { + imem = imemp = imem1_list_head; + while (imem) { + if (start < imem->phys_start) { + break; + } + + imemp = imem; + imem = imem->next; + } + + if (imem == imem1_list_head) { + imem1_list_head = imemn; + imemn->next = imem; + } + else { + imemn->next = imemp->next; + imemp->next = imemn; + } + } + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif + return 0; +} + + +static void imem_free(unsigned int phys_addr) +{ + struct imem_list *imem, *imemp; + + imem = imemp = imem0_list_head; + while (imem) { + if (phys_addr == imem->phys_start) { + if (imem == imem0_list_head) { + imem0_list_head = imem->next; + } + else { + imemp->next = imem->next; + } + + kfree(imem); + break; + } + + imemp = imem; + imem = imem->next; + } + + + imem = imemp = imem1_list_head; + while (imem) { + if (phys_addr == imem->phys_start) { + if (imem == imem1_list_head) { + imem1_list_head = imem->next; + } + else { + imemp->next = imem->next; + } + + kfree(imem); + break; + } + + imemp = imem; + imem = imem->next; + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +static void imem_free_all(void) +{ + struct imem_list *imem; + + imem = imem0_list_head; + while (imem) { + kfree(imem); + imem = imem->next; + } + + imem0_list_head = NULL; + + allocated_phys_addr0 = 0; + + + + imem = imem1_list_head; + while (imem) { + kfree(imem); + imem = imem->next; + } + + imem1_list_head = NULL; + + allocated_phys_addr1 = 0; + + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +/* + * Return the allocated buffer address and the max order of free buffer + */ +static int imem0_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int start_addr, end_addr, max_order, max_size; + struct imem_list *imem; + + unsigned int *tmp = (unsigned int *)(page + len); + + start_addr = jz_imem0_base; + end_addr = start_addr + (1 << IMEM0_MAX_ORDER) * PAGE_SIZE; + + if (!imem0_list_head) + max_size = end_addr - start_addr; + else { + max_size = 0; + imem = imem0_list_head; + while (imem) { + if (max_size < (imem->phys_start - start_addr)) + max_size = imem->phys_start - start_addr; + + start_addr = imem->phys_end + 1; + imem = imem->next; + } + + if (max_size < (end_addr - start_addr)) + max_size = end_addr - start_addr; + } + + if (max_size > 0) { + max_order = get_order(max_size); + if (((1 << max_order) * PAGE_SIZE) > max_size) + max_order--; + } + else { + max_order = 0xffffffff; /* No any free buffer */ + } + + *tmp++ = allocated_phys_addr0; /* address allocated by 'echo n > /proc/jz/imem' */ + *tmp = max_order; /* max order of current free buffers */ + + len += 2 * sizeof(unsigned int); + + return len; +} + +static int imem0_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val; + + val = simple_strtoul(buffer, 0, 16); + + if (val == 0xff) { + /* free all memory */ + imem_free_all(); + ipu_del_wired_entry(); + } else if ((val >= 0) && (val <= IMEM0_MAX_ORDER)) { + /* allocate 2^val pages */ + imem0_alloc(val); + } else { + /* free buffer which phys_addr is val */ + imem_free(val); + } + + return count; +} + +/* + * Return the allocated buffer address and the max order of free buffer + */ +static int imem1_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int start_addr, end_addr, max_order, max_size; + struct imem_list *imem; + + unsigned int *tmp = (unsigned int *)(page + len); + + start_addr = jz_imem1_base; + end_addr = start_addr + (1 << IMEM1_MAX_ORDER) * PAGE_SIZE; + + if (!imem1_list_head) + max_size = end_addr - start_addr; + else { + max_size = 0; + imem = imem1_list_head; + while (imem) { + if (max_size < (imem->phys_start - start_addr)) + max_size = imem->phys_start - start_addr; + + start_addr = imem->phys_end + 1; + imem = imem->next; + } + + if (max_size < (end_addr - start_addr)) + max_size = end_addr - start_addr; + } + + if (max_size > 0) { + max_order = get_order(max_size); + if (((1 << max_order) * PAGE_SIZE) > max_size) + max_order--; + } + else { + max_order = 0xffffffff; /* No any free buffer */ + } + + *tmp++ = allocated_phys_addr1; /* address allocated by 'echo n > /proc/jz/imem' */ + *tmp = max_order; /* max order of current free buffers */ + + len += 2 * sizeof(unsigned int); + + return len; +} + +static int imem1_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val; + + val = simple_strtoul(buffer, 0, 16); + + if (val == 0xff) { + /* free all memory */ + imem_free_all(); + ipu_del_wired_entry(); + } else if ((val >= 0) && (val <= IMEM1_MAX_ORDER)) { + /* allocate 2^val pages */ + imem1_alloc(val); + } else { + /* free buffer which phys_addr is val */ + imem_free(val); + } + + return count; +} + +/* + * /proc/jz/xxx entry + * + */ +static int __init jz_proc_init(void) +{ + struct proc_dir_entry *res; + unsigned int virt_addr, i; + + proc_jz_root = proc_mkdir("jz", 0); + + /* External Memory Controller */ + res = create_proc_entry("emc", 0644, proc_jz_root); + if (res) { + res->read_proc = emc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* Power Management Controller */ + res = create_proc_entry("pmc", 0644, proc_jz_root); + if (res) { + res->read_proc = pmc_read_proc; + res->write_proc = pmc_write_proc; + res->data = NULL; + } + + /* Clock Generation Module */ + res = create_proc_entry("cgm", 0644, proc_jz_root); + if (res) { + res->read_proc = cgm_read_proc; + res->write_proc = cgm_write_proc; + res->data = NULL; + } + + /* Image process unit */ + res = create_proc_entry("ipu", 0644, proc_jz_root); + if (res) { + res->read_proc = ipu_read_proc; + res->write_proc = ipu_write_proc; + res->data = NULL; + } + + /* udc hotplug */ + res = create_proc_entry("udc", 0644, proc_jz_root); + if (res) { + res->read_proc = udc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* mmc hotplug */ + res = create_proc_entry("mmc", 0644, proc_jz_root); + if (res) { + res->read_proc = mmc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* + * Reserve a 16MB memory for IPU on JZ4750D. + */ + jz_imem0_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM0_MAX_ORDER); + if (jz_imem0_base) { + /* imem (IPU memory management) */ + res = create_proc_entry("imem", 0644, proc_jz_root); + if (res) { + res->read_proc = imem0_read_proc; + res->write_proc = imem0_write_proc; + res->data = NULL; + } + + /* Set page reserved */ + virt_addr = jz_imem0_base; + for (i = 0; i < (1 << IMEM0_MAX_ORDER); i++) { + SetPageReserved(virt_to_page((void *)virt_addr)); + virt_addr += PAGE_SIZE; + } + + /* Convert to physical address */ + jz_imem0_base = virt_to_phys((void *)jz_imem0_base); + + printk("Total %dMB memory at 0x%x was reserved for IPU\n", + (unsigned int)((1 << IMEM0_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem0_base); + } else + printk("NOT enough memory for imem\n"); + + + jz_imem1_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM1_MAX_ORDER); + if (jz_imem1_base) { + /* imem (IPU memory management) */ + res = create_proc_entry("imem1", 0644, proc_jz_root); + if (res) { + res->read_proc = imem1_read_proc; + res->write_proc = imem1_write_proc; + res->data = NULL; + } + + /* Set page reserved */ + virt_addr = jz_imem1_base; + for (i = 0; i < (1 << IMEM1_MAX_ORDER); i++) { + SetPageReserved(virt_to_page((void *)virt_addr)); + virt_addr += PAGE_SIZE; + } + + /* Convert to physical address */ + jz_imem1_base = virt_to_phys((void *)jz_imem1_base); + + printk("Total %dMB memory1 at 0x%x was reserved for IPU\n", + (unsigned int)((1 << IMEM1_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem1_base); + } else + printk("NOT enough memory for imem1\n"); + return 0; +} + +__initcall(jz_proc_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/prom.c linux-2.6.24.3-20100304/arch/mips/jz4750d/prom.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/prom.c 2010-03-03 19:05:01.000000000 -0800 @@ -0,0 +1,198 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, supports YAMON and U-Boot. + * + * Copyright 2000, 2001, 2006 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +int prom_argc; +char **prom_argv, **prom_envp; + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + if (prom_argc > 1) + *cp = '\0'; + +} + + +char *prom_getenv(char *envname) +{ +#if 0 + /* + * Return a pointer to the given environment variable. + * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". + */ + + char **env = prom_envp; + int i = strlen(envname); + int yamon = (*env && strchr(*env, '=') == NULL); + + while (*env) { + if (yamon) { + if (strcmp(envname, *env++) == 0) + return *env; + } else { + if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; + } + env++; + } +#endif + return NULL; +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machtype = MACH_INGENIC_JZ4750D; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +/* used by early printk */ +void prom_putchar(char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART1_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART1_BASE + OFF_TDR); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +const char *get_system_type(void) +{ + return "JZ4750D"; +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/reset.c linux-2.6.24.3-20100304/arch/mips/jz4750d/reset.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/reset.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,46 @@ +/* + * linux/arch/mips/jz4750/reset.c + * + * JZ4750 reset routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void jz_restart(char *command) +{ + printk("Restarting after 4 ms\n"); + REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN; + REG_WDT_TCNT = 0; + REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */ + REG_TCU_TSCR = TCU_TSCR_WDTSC; /* enable wdt clock */ + REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */ + while (1); +} + +void jz_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void jz_power_off(void) +{ + jz_halt(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/setup.c linux-2.6.24.3-20100304/arch/mips/jz4750d/setup.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/setup.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,199 @@ +/* + * linux/arch/mips/jz4750d/common/setup.c + * + * JZ4750D common setup routines. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PC_KEYB +#include +#endif + +jz_clocks_t jz_clocks; + +extern char * __init prom_getcmdline(void); +extern void __init jz_board_setup(void); +extern void jz_restart(char *); +extern void jz_halt(void); +extern void jz_power_off(void); +extern void jz_time_init(void); + +static void __init sysclocks_setup(void) +{ +#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.h1clk = __cpm_get_h1clk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); + jz_clocks.extalclk = __cpm_get_extalclk(); + jz_clocks.rtcclk = __cpm_get_rtcclk(); +#else + +#define FPGACLK 8000000 + + jz_clocks.cclk = FPGACLK; + jz_clocks.hclk = FPGACLK; + jz_clocks.pclk = FPGACLK; + jz_clocks.mclk = FPGACLK; + jz_clocks.h1clk = FPGACLK; + jz_clocks.pixclk = FPGACLK; + jz_clocks.i2sclk = FPGACLK; + jz_clocks.usbclk = FPGACLK; + jz_clocks.mscclk = FPGACLK; + jz_clocks.extalclk = FPGACLK; + jz_clocks.rtcclk = FPGACLK; +#endif + + printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n", + (jz_clocks.cclk + 500000) / 1000000, + (jz_clocks.hclk + 500000) / 1000000, + (jz_clocks.pclk + 500000) / 1000000, + (jz_clocks.mclk + 500000) / 1000000); +} + +static void __init soc_cpm_setup(void) +{ + /* Start all module clocks + */ + __cpm_start_all(); + + /* Enable CKO to external memory */ + __cpm_enable_cko(); + + /* CPU enters IDLE mode when executing 'wait' instruction */ + __cpm_idle_mode(); + + /* Setup system clocks */ + sysclocks_setup(); +} + +static void __init soc_harb_setup(void) +{ +// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ +} + +static void __init soc_emc_setup(void) +{ +} + +static void __init soc_dmac_setup(void) +{ + __dmac_enable_module(0); + __dmac_enable_module(1); +} + +static void __init jz_soc_setup(void) +{ + soc_cpm_setup(); + soc_harb_setup(); + soc_emc_setup(); + soc_dmac_setup(); +} + +static void __init jz_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */ + memset(&s, 0, sizeof(s)); + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = SERIAL_IO_MEM; + s.regshift = 2; + s.uartclk = jz_clocks.extalclk ; + + s.line = 0; + s.membase = (u8 *)UART0_BASE; + s.irq = IRQ_UART0; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS0 setup failed!\n"); + } + + s.line = 1; + s.membase = (u8 *)UART1_BASE; + s.irq = IRQ_UART1; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS1 setup failed!\n"); + } + + s.line = 2; + s.membase = (u8 *)UART2_BASE; + s.irq = IRQ_UART2; + + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS2 setup failed!\n"); + } +/* + s.line = 3; + s.membase = (u8 *)UART3_BASE; + s.irq = IRQ_UART3; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS3 setup failed!\n"); + } +*/ +#endif +} + +void __init plat_mem_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + + /* IO/MEM resources. Which will be the addtion value in `inX' and + * `outX' macros defined in asm/io.h */ + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x00000000; + iomem_resource.end = 0xffffffff; + + _machine_restart = jz_restart; + _machine_halt = jz_halt; + pm_power_off = jz_power_off; + + jz_soc_setup(); + jz_serial_setup(); + jz_board_setup(); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/time.c linux-2.6.24.3-20100304/arch/mips/jz4750d/time.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750d/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750d/time.c 2010-03-03 19:05:02.000000000 -0800 @@ -0,0 +1,156 @@ +/* + * linux/arch/mips/jz4750d/time.c + * + * Setting up the clock on the JZ4750D boards. + * + * Copyright (C) 2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include + +#include +#include + +/* This is for machines which generate the exact clock. */ + +#define JZ_TIMER_IRQ IRQ_TCU0 + +#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */ + +static struct clocksource clocksource_jz; /* Jz clock source */ +static struct clock_event_device jz_clockevent_device; /* Jz clock event */ + +void (*jz_timer_callback)(void); + +static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */ + + if (jz_timer_callback) + jz_timer_callback(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction jz_irqaction = { + .handler = jz_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .name = "jz-timerirq", +}; + + +cycle_t jz_get_cycles(void) +{ + /* convert jiffes to jz timer cycles */ + return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_OSTCNT); +} + +static struct clocksource clocksource_jz = { + .name = "jz_clocksource", + .rating = 300, + .read = jz_get_cycles, + .mask = 0xFFFFFFFF, + .shift = 10, + .flags = CLOCK_SOURCE_WATCHDOG, +}; + +static int __init jz_clocksource_init(void) +{ + clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); + clocksource_register(&clocksource_jz); + return 0; +} + +static int jz_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + return 0; +} + +static void jz_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device jz_clockevent_device = { + .name = "jz-clockenvent", + .features = CLOCK_EVT_FEAT_PERIODIC, +// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */ + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + .rating = 300, + .irq = JZ_TIMER_IRQ, + .set_mode = jz_set_mode, + .set_next_event = jz_set_next_event, +}; + +static void __init jz_clockevent_init(void) +{ + struct clock_event_device *cd = &jz_clockevent_device; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); +} + +static void __init jz_timer_setup(void) +{ + jz_clocksource_init(); /* init jz clock source */ + jz_clockevent_init(); /* init jz clock event */ + + /* + * Make irqs happen for the system timer + */ + jz_irqaction.dev_id = &jz_clockevent_device; + setup_irq(JZ_TIMER_IRQ, &jz_irqaction); +} + + +void __init plat_time_init(void) +{ + unsigned int latch; + + /* Init timer */ + latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ; + + REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN; + REG_TCU_OSTCNT = 0; + REG_TCU_OSTDR = latch; + + REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */ + REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */ + REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */ + + jz_timer_setup(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/board-f4750l.c linux-2.6.24.3-20100304/arch/mips/jz4750l/board-f4750l.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/board-f4750l.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/board-f4750l.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,72 @@ +/* + * linux/arch/mips/jz4750l/board-f4750l.c + * + * JZ4750L F4750L board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + static unsigned char slash[] = "\\|/-"; +// static volatile unsigned char *p = (unsigned char *)0xb6000058; + static volatile unsigned char *p = (unsigned char *)0xb6000016; + static unsigned int count = 0; + *p = slash[count++]; + count &= 3; +} + +static void f4750l_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750l/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Initialize SDRAM pins + */ +} + +void __init jz_board_setup(void) +{ + printk("JZ4750L F4750L board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = f4750l_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/board-volans.c linux-2.6.24.3-20100304/arch/mips/jz4750l/board-volans.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/board-volans.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/board-volans.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,67 @@ +/* + * linux/arch/mips/jz4750l/board-volans.c + * + * JZ4750L VOLANS board setup routines. + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void (*jz_timer_callback)(void); + +static void dancing(void) +{ + +} + +static void volans_timer_callback(void) +{ + static unsigned long count = 0; + + if ((++count) % 50 == 0) { + dancing(); + count = 0; + } +} + +static void __init board_cpm_setup(void) +{ + /* Stop unused module clocks here. + * We have started all module clocks at arch/mips/jz4750l/setup.c. + */ +} + +static void __init board_gpio_setup(void) +{ + /* + * Initialize SDRAM pins + */ +} + +void __init jz_board_setup(void) +{ + printk("JZ4750L VOLANS board setup\n"); + + board_cpm_setup(); + board_gpio_setup(); + + jz_timer_callback = volans_timer_callback; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/cpufreq.c linux-2.6.24.3-20100304/arch/mips/jz4750l/cpufreq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/cpufreq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/cpufreq.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,598 @@ +/* + * linux/arch/mips/jz4750l/cpufreq.c + * + * cpufreq driver for JZ4750L + * + * Copyright (c) 2006-2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ + "cpufreq-jz4750l", msg) + +#undef CHANGE_PLL + +#define PLL_UNCHANGED 0 +#define PLL_GOES_UP 1 +#define PLL_GOES_DOWN 2 + +#define PLL_WAIT_500NS (500*(__cpm_get_cclk()/1000000000)) + +/* Saved the boot-time parameters */ +static struct { + /* SDRAM parameters */ + unsigned int mclk; /* memory clock, KHz */ + unsigned int tras; /* RAS pulse width, cycles of mclk */ + unsigned int rcd; /* RAS to CAS Delay, cycles of mclk */ + unsigned int tpc; /* RAS Precharge time, cycles of mclk */ + unsigned int trwl; /* Write Precharge Time, cycles of mclk */ + unsigned int trc; /* RAS Cycle Time, cycles of mclk */ + unsigned int rtcor; /* Refresh Time Constant */ + unsigned int sdram_initialized; + + /* LCD parameters */ + unsigned int lcdpix_clk; /* LCD Pixel clock, Hz */ + unsigned int lcd_clks_initialized; +} boot_config; + +struct jz4750l_freq_percpu_info { + struct cpufreq_frequency_table table[7]; +}; + +static struct jz4750l_freq_percpu_info jz4750l_freq_table; + +/* + * This contains the registers value for an operating point. + * If only part of a register needs to change then there is + * a mask value for that register. + * When going to a new operating point the current register + * value is ANDed with the ~mask and ORed with the new value. + */ +struct dpm_regs { + u32 cpccr; /* Clock Freq Control Register */ + u32 cpccr_mask; /* Clock Freq Control Register mask */ + u32 cppcr; /* PLL1 Control Register */ + u32 cppcr_mask; /* PLL1 Control Register mask */ + u32 pll_up_flag; /* New PLL freq is higher than current or not */ +}; + +extern jz_clocks_t jz_clocks; + +static void jz_update_clocks(void) +{ + /* Next clocks must be updated if we have changed + * the PLL or divisors. + */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); +} + +static void +jz_init_boot_config(void) +{ + if (!boot_config.lcd_clks_initialized) { + /* the first time to scale pll */ + boot_config.lcdpix_clk = __cpm_get_pixclk(); + boot_config.lcd_clks_initialized = 1; + } + + if (!boot_config.sdram_initialized) { + /* the first time to scale frequencies */ + unsigned int dmcr, rtcor; + unsigned int tras, rcd, tpc, trwl, trc; + + dmcr = REG_EMC_DMCR; + rtcor = REG_EMC_RTCOR; + + tras = (dmcr >> 13) & 0x7; + rcd = (dmcr >> 11) & 0x3; + tpc = (dmcr >> 8) & 0x7; + trwl = (dmcr >> 5) & 0x3; + trc = (dmcr >> 2) & 0x7; + + boot_config.mclk = __cpm_get_mclk() / 1000; + boot_config.tras = tras + 4; + boot_config.rcd = rcd + 1; + boot_config.tpc = tpc + 1; + boot_config.trwl = trwl + 1; + boot_config.trc = trc * 2 + 1; + boot_config.rtcor = rtcor; + + boot_config.sdram_initialized = 1; + } +} + +static void jz_update_dram_rtcor(unsigned int new_mclk) +{ + unsigned int rtcor; + + new_mclk /= 1000; + rtcor = boot_config.rtcor * new_mclk / boot_config.mclk; + rtcor--; + + if (rtcor < 1) rtcor = 1; + if (rtcor > 255) rtcor = 255; + + REG_EMC_RTCOR = rtcor; + REG_EMC_RTCNT = rtcor; +} + +static void jz_update_dram_dmcr(unsigned int new_mclk) +{ + unsigned int dmcr; + unsigned int tras, rcd, tpc, trwl, trc; + unsigned int valid_time, new_time; /* ns */ + + new_mclk /= 1000; + tras = boot_config.tras * new_mclk / boot_config.mclk; + rcd = boot_config.rcd * new_mclk / boot_config.mclk; + tpc = boot_config.tpc * new_mclk / boot_config.mclk; + trwl = boot_config.trwl * new_mclk / boot_config.mclk; + trc = boot_config.trc * new_mclk / boot_config.mclk; + + /* Validation checking */ + valid_time = (boot_config.tras * 1000000) / boot_config.mclk; + new_time = (tras * 1000000) / new_mclk; + if (new_time < valid_time) tras += 1; + + valid_time = (boot_config.rcd * 1000000) / boot_config.mclk; + new_time = (rcd * 1000000) / new_mclk; + if (new_time < valid_time) rcd += 1; + + valid_time = (boot_config.tpc * 1000000) / boot_config.mclk; + new_time = (tpc * 1000000) / new_mclk; + if (new_time < valid_time) tpc += 1; + + valid_time = (boot_config.trwl * 1000000) / boot_config.mclk; + new_time = (trwl * 1000000) / new_mclk; + if (new_time < valid_time) trwl += 1; + + valid_time = (boot_config.trc * 1000000) / boot_config.mclk; + new_time = (trc * 1000000) / new_mclk; + if (new_time < valid_time) trc += 2; + + tras = (tras < 4) ? 4: tras; + tras = (tras > 11) ? 11: tras; + tras -= 4; + + rcd = (rcd < 1) ? 1: rcd; + rcd = (rcd > 4) ? 4: rcd; + rcd -= 1; + + tpc = (tpc < 1) ? 1: tpc; + tpc = (tpc > 8) ? 8: tpc; + tpc -= 1; + + trwl = (trwl < 1) ? 1: trwl; + trwl = (trwl > 4) ? 4: trwl; + trwl -= 1; + + trc = (trc < 1) ? 1: trc; + trc = (trc > 15) ? 15: trc; + trc /= 2; + + dmcr = REG_EMC_DMCR; + + dmcr &= ~(EMC_DMCR_TRAS_MASK | EMC_DMCR_RCD_MASK | EMC_DMCR_TPC_MASK | EMC_DMCR_TRWL_MASK | EMC_DMCR_TRC_MASK); + dmcr |= ((tras << EMC_DMCR_TRAS_BIT) | (rcd << EMC_DMCR_RCD_BIT) | (tpc << EMC_DMCR_TPC_BIT) | (trwl << EMC_DMCR_TRWL_BIT) | (trc << EMC_DMCR_TRC_BIT)); + + REG_EMC_DMCR = dmcr; +} + +static void jz_update_dram_prev(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so first update TRAS, RCD, TPC, TRWL + * and TRC of DMCR before changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } else { + /* We're going SLOWER: first update RTCOR value + * before changing the frequency. + */ + jz_update_dram_rtcor(new_mclk); + } +} + +static void jz_update_dram_post(unsigned int cur_mclk, unsigned int new_mclk) +{ + /* No risk, no fun: run with interrupts on! */ + if (new_mclk > cur_mclk) { + /* We're going FASTER, so update RTCOR + * after changing the frequency + */ + jz_update_dram_rtcor(new_mclk); + } else { + /* We're going SLOWER: so update TRAS, RCD, TPC, TRWL + * and TRC of DMCR after changing the frequency. + */ + jz_update_dram_dmcr(new_mclk); + } +} + +static void jz_scale_divisors(struct dpm_regs *regs) +{ + unsigned int cpccr; + unsigned int cur_mclk, new_mclk; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~((unsigned long)regs->cpccr_mask); + cpccr |= regs->cpccr; + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + cur_mclk = __cpm_get_mclk(); + new_mclk = __cpm_get_pllout() / div[(cpccr & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; + + /* Update some DRAM parameters before changing frequency */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} + +#ifdef CHANGE_PLL +/* Maintain the LCD clock and pixel clock */ +static void jz_scale_lcd_divisors(struct dpm_regs *regs) +{ + unsigned int new_pll, new_lcd_div, new_lcdpix_div; + unsigned int cpccr; + unsigned int tmp = 0, wait = PLL_WAIT_500NS; + + if (!boot_config.lcd_clks_initialized) return; + + new_pll = __cpm_get_pllout(); + new_lcd_div = new_pll / boot_config.lcd_clk; + new_lcdpix_div = new_pll / boot_config.lcdpix_clk; + + if (new_lcd_div < 1) + new_lcd_div = 1; + if (new_lcd_div > 16) + new_lcd_div = 16; + + if (new_lcdpix_div < 1) + new_lcdpix_div = 1; + if (new_lcdpix_div > 512) + new_lcdpix_div = 512; + +// REG_CPM_CPCCR2 = new_lcdpix_div - 1; + + cpccr = REG_CPM_CPCCR; + cpccr &= ~CPM_CPCCR_LDIV_MASK; + cpccr |= ((new_lcd_div - 1) << CPM_CPCCR_LDIV_BIT); + cpccr |= CPM_CPCCR_CE; /* update immediately */ + + /* update register to change the clocks. + * align this code to a cache line. + */ + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "li %3,0\n\t" + "1:\n\t" + "bne %3,%2,1b\n\t" + "addi %3, 1\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPCCR), "r" (cpccr), "r" (wait), "r" (tmp)); +} + +static void jz_scale_pll(struct dpm_regs *regs) +{ + unsigned int cppcr; + unsigned int cur_mclk, new_mclk, new_pll; + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + int od[] = {1, 2, 2, 4}; + + cppcr = REG_CPM_CPPCR; + cppcr &= ~(regs->cppcr_mask | CPM_CPPCR_PLLS | CPM_CPPCR_PLLEN | CPM_CPPCR_PLLST_MASK); + regs->cppcr &= ~CPM_CPPCR_PLLEN; + cppcr |= (regs->cppcr | 0xff); + + /* Update some DRAM parameters before changing frequency */ + new_pll = JZ_EXTAL * ((cppcr>>23)+2) / ((((cppcr>>18)&0x1f)+2) * od[(cppcr>>16)&0x03]); + cur_mclk = __cpm_get_mclk(); + new_mclk = new_pll / div[(REG_CPM_CPCCR>>16) & 0xf]; + + /* + * Update some SDRAM parameters + */ + jz_update_dram_prev(cur_mclk, new_mclk); + + /* + * Update PLL, align code to cache line. + */ + cppcr |= CPM_CPPCR_PLLEN; + __asm__ __volatile__( + ".set noreorder\n\t" + ".align 5\n" + "sw %1,0(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set reorder\n\t" + : + : "r" (CPM_CPPCR), "r" (cppcr)); + + /* Update some other DRAM parameters after changing frequency */ + jz_update_dram_post(cur_mclk, new_mclk); +} +#endif + +static void jz4750l_transition(struct dpm_regs *regs) +{ + /* + * Get and save some boot-time conditions. + */ + jz_init_boot_config(); + +#ifdef CHANGE_PLL + /* + * Disable LCD before scaling pll. + * LCD and LCD pixel clocks should not be changed even if the PLL + * output frequency has been changed. + */ + REG_LCD_CTRL &= ~LCD_CTRL_ENA; + + /* + * Stop module clocks before scaling PLL + */ + __cpm_stop_eth(); + __cpm_stop_aic(1); + __cpm_stop_aic(2); +#endif + + /* ... add more as necessary */ + + if (regs->pll_up_flag == PLL_GOES_UP) { + /* the pll frequency is going up, so change dividors first */ + jz_scale_divisors(regs); +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + } + else if (regs->pll_up_flag == PLL_GOES_DOWN) { + /* the pll frequency is going down, so change pll first */ +#ifdef CHANGE_PLL + jz_scale_pll(regs); +#endif + jz_scale_divisors(regs); + } + else { + /* the pll frequency is unchanged, so change divisors only */ + jz_scale_divisors(regs); + } + +#ifdef CHANGE_PLL + /* + * Restart module clocks before scaling PLL + */ + __cpm_start_eth(); + __cpm_start_aic(1); + __cpm_start_aic(2); + + /* ... add more as necessary */ + + /* Scale the LCD divisors after scaling pll */ + if (regs->pll_up_flag != PLL_UNCHANGED) { + jz_scale_lcd_divisors(regs); + } + + /* Enable LCD controller */ + REG_LCD_CTRL &= ~LCD_CTRL_DIS; + REG_LCD_CTRL |= LCD_CTRL_ENA; +#endif + + /* Update system clocks */ + jz_update_clocks(); +} + +extern unsigned int idle_times; +static unsigned int jz4750l_freq_get(unsigned int cpu) +{ + return (__cpm_get_cclk() / 1000); +} + +static unsigned int index_to_divisor(unsigned int index, struct dpm_regs *regs) +{ + int n2FR[33] = { + 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, + 9 + }; + int div[4] = {1, 2, 2, 2}; /* divisors of I:S:P:M */ + unsigned int div_of_cclk, new_freq, i; + + regs->pll_up_flag = PLL_UNCHANGED; + regs->cpccr_mask = CPM_CPCCR_CDIV_MASK | CPM_CPCCR_HDIV_MASK | CPM_CPCCR_PDIV_MASK | CPM_CPCCR_MDIV_MASK; + + new_freq = jz4750l_freq_table.table[index].frequency; + + do { + div_of_cclk = __cpm_get_pllout() / (1000 * new_freq); + } while (div_of_cclk==0); + + if(div_of_cclk == 1 || div_of_cclk == 2 || div_of_cclk == 4) { + for(i = 1; i<4; i++) { + div[i] = 3; + } + } else { + for(i = 1; i<4; i++) { + div[i] = 2; + } + } + + for(i = 0; i<4; i++) { + div[i] *= div_of_cclk; + } + + dprintk("divisors of I:S:P:M = %d:%d:%d:%d\n", div[0], div[1], div[2], div[3]); + + regs->cpccr = + (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | + (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | + (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | + (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT); + + return div_of_cclk; +} + +static void jz4750l_set_cpu_divider_index(unsigned int cpu, unsigned int index) +{ + unsigned long divisor, old_divisor; + struct cpufreq_freqs freqs; + struct dpm_regs regs; + + old_divisor = __cpm_get_pllout() / __cpm_get_cclk(); + divisor = index_to_divisor(index, ®s); + + freqs.old = __cpm_get_cclk() / 1000; + freqs.new = __cpm_get_pllout() / (1000 * divisor); + freqs.cpu = cpu; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (old_divisor != divisor) + jz4750l_transition(®s); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +} + +static int jz4750l_freq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int new_index = 0; + + if (cpufreq_frequency_table_target(policy, + &jz4750l_freq_table.table[0], + target_freq, relation, &new_index)) + return -EINVAL; + + jz4750l_set_cpu_divider_index(policy->cpu, new_index); + + dprintk("new frequency is %d KHz (REG_CPM_CPCCR:0x%x)\n", __cpm_get_cclk() / 1000, REG_CPM_CPCCR); + + return 0; +} + +static int jz4750l_freq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &jz4750l_freq_table.table[0]); +} + +static int __init jz4750l_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + + struct cpufreq_frequency_table *table = &jz4750l_freq_table.table[0]; + unsigned int MAX_FREQ; + + dprintk(KERN_INFO "Jz4750l cpufreq driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = MAX_FREQ = __cpm_get_cclk() / 1000; /* in kHz. Current and max frequency is determined by u-boot */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + policy->cpuinfo.min_freq = MAX_FREQ/8; + policy->cpuinfo.max_freq = MAX_FREQ; + policy->cpuinfo.transition_latency = 100000; /* in 10^(-9) s = nanoseconds */ + + table[0].index = 0; + table[0].frequency = MAX_FREQ/8; + table[1].index = 1; + table[1].frequency = MAX_FREQ/6; + table[2].index = 2; + table[2].frequency = MAX_FREQ/4; + table[3].index = 3; + table[3].frequency = MAX_FREQ/3; + table[4].index = 4; + table[4].frequency = MAX_FREQ/2; + table[5].index = 5; + table[5].frequency = MAX_FREQ; + table[6].index = 6; + table[6].frequency = CPUFREQ_TABLE_END; + +#ifdef CONFIG_CPU_FREQ_STAT_DETAILS + cpufreq_frequency_table_get_attr(table, policy->cpu); /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */ +#endif + + return cpufreq_frequency_table_cpuinfo(policy, table); +} + +static struct cpufreq_driver cpufreq_jz4750l_driver = { +// .flags = CPUFREQ_STICKY, + .init = jz4750l_cpufreq_driver_init, + .verify = jz4750l_freq_verify, + .target = jz4750l_freq_target, + .get = jz4750l_freq_get, + .name = "jz4750l", +}; + +static int __init jz4750l_cpufreq_init(void) +{ + return cpufreq_register_driver(&cpufreq_jz4750l_driver); +} + +static void __exit jz4750l_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cpufreq_jz4750l_driver); +} + +module_init(jz4750l_cpufreq_init); +module_exit(jz4750l_cpufreq_exit); + +MODULE_AUTHOR("Regen "); +MODULE_DESCRIPTION("cpufreq driver for Jz4750l"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/dma.c linux-2.6.24.3-20100304/arch/mips/jz4750l/dma.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/dma.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/dma.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,822 @@ +/* + * linux/arch/mips/jz4750l/dma.c + * + * Support functions for the JZ4750L internal DMA channels. + * No-descriptor transfer only. + * Descriptor transfer should also call jz_request_dma() to get a free + * channel and call jz_free_dma() to free the channel. And driver should + * build the DMA descriptor and setup the DMA channel by itself. + * + * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `jz_request_dma()' and `jz_free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from jz_request_dma(). + */ + +struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = { + {dev_id:DMA_ID_BCH_ENC,}, /* DMAC0 channel 0, reserved for BCH */ + {dev_id:-1,}, /* DMAC0 channel 1 */ + {dev_id:-1,}, /* DMAC0 channel 2 */ + {dev_id:-1,}, /* DMAC0 channel 3 */ + {dev_id:-1,}, /* DMAC1 channel 0 */ + {dev_id:-1,}, /* DMAC1 channel 1 */ + {dev_id:-1,}, /* DMAC1 channel 2 */ + {dev_id:-1,}, /* DMAC1 channel 3 */ +}; + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; + unsigned int dma_source; +} dma_dev_table[DMA_ID_MAX] = { + {0, DMA_AUTOINIT, DMAC_DRSR_RS_EXT}, /* External request with DREQn */ + {0x18000000, DMA_AUTOINIT, DMAC_DRSR_RS_NAND}, /* NAND request */ + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_ENC}, + {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_DEC}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO}, +// {CPHYSADDR(TSSI_FIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_TSSIIN}, + {CPHYSADDR(UART3_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT}, + {CPHYSADDR(UART3_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART3IN}, + {CPHYSADDR(UART2_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT}, + {CPHYSADDR(UART2_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART2IN}, + {CPHYSADDR(UART1_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT}, + {CPHYSADDR(UART1_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART1IN}, + {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT}, + {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI0OUT}, + {CPHYSADDR(SSI_DR(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI0IN}, + {CPHYSADDR(AIC_DR), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT}, + {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN}, + {CPHYSADDR(MSC_TXFIFO(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC0OUT}, + {CPHYSADDR(MSC_RXFIFO(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC0IN}, + {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU}, + {SADC_TSDAT, DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SADC},/* Touch Screen Data Register */ + {CPHYSADDR(MSC_TXFIFO(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC1OUT}, /* SSC1 TX */ + {CPHYSADDR(MSC_RXFIFO(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC1IN}, /* SSC1 RX */ + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI1OUT}, + {CPHYSADDR(SSI_DR(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI1IN}, + {CPHYSADDR(PCM_DP), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_PMOUT}, + {CPHYSADDR(PCM_DP), DMA_16BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_PMIN}, + {}, +}; + + +int jz_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct jz_dma_chan *chan; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_jz_dma_channel(unsigned int dmanr) +{ + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return; + chan = &jz_dma_table[dmanr]; + + printk("DMA%d Registers:\n", dmanr); + printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR(chan->io/HALF_DMA_NUM)); + printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr)); + printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr)); + printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr)); + printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr)); + printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr)); + printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr)); + printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr)); + printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR(chan->io/HALF_DMA_NUM)); +} + + +/** + * jz_request_dma - dynamically allcate an idle DMA channel to return + * @dev_id: the specified dma device id or DMA_ID_RAW_SET + * @dev_str: the specified dma device string name + * @irqhandler: the irq handler, or NULL + * @irqflags: the irq handler flags + * @irq_dev_id: the irq handler device id for shared irq + * + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + * +*/ +/*int jz_request_dma(int dev_id, const char *dev_str, + void (*irqhandler)(int, void *, struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id) +*/ + +int jz_request_dma(int dev_id, const char *dev_str, + irqreturn_t (*irqhandler)(int, void *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct jz_dma_chan *chan; + int i, ret; + + if (dev_id < 0 || dev_id >= DMA_ID_MAX) + return -EINVAL; + + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) /* no free channel */ + return -ENODEV; + + /* we got a free channel */ + chan = &jz_dma_table[i]; + + if (irqhandler) { + chan->irq = IRQ_DMA_0 + i; // allocate irq number + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = -1; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = -1; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = i; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + chan->source = dma_dev_table[dev_id].dma_source; + + if (i < HALF_DMA_NUM) + REG_DMAC_DMACKE(0) = 1 << i; + else + REG_DMAC_DMACKE(1) = 1 << (i - HALF_DMA_NUM); + + return i; +} + +void jz_free_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = -1; + chan->irq_dev = NULL; + chan->dev_id = -1; +} + +void jz_set_dma_dest_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_DWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_DWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_DWDH_32; + break; + } +} + +void jz_set_dma_src_width(int dmanr, int nbit) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_SWDH_MASK; + switch (nbit) { + case 8: + chan->mode |= DMAC_DCMD_SWDH_8; + break; + case 16: + chan->mode |= DMAC_DCMD_SWDH_16; + break; + case 32: + chan->mode |= DMAC_DCMD_SWDH_32; + break; + } +} + +void jz_set_dma_block_size(int dmanr, int nbyte) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode &= ~DMAC_DCMD_DS_MASK; + switch (nbyte) { + case 1: + chan->mode |= DMAC_DCMD_DS_8BIT; + break; + case 2: + chan->mode |= DMAC_DCMD_DS_16BIT; + break; + case 4: + chan->mode |= DMAC_DCMD_DS_32BIT; + break; + case 16: + chan->mode |= DMAC_DCMD_DS_16BYTE; + break; + case 32: + chan->mode |= DMAC_DCMD_DS_32BYTE; + break; + } +} + +unsigned int jz_get_dma_command(int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + return chan->mode; +} + +/** + * jz_set_dma_mode - do the raw settings for the specified DMA channel + * @dmanr: the specified DMA channel + * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE + * @dma_mode: dma raw mode + * @dma_source: dma raw request source + * @fifo_addr: dma raw device fifo address + * + * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call + * jz_set_dma_mode() rather than set_dma_mode() if you work with + * and external request dma device. + * + * NOTE: Don not dynamically allocate dma channel if one external request + * dma device will occupy this channel. +*/ +int jz_set_dma_mode(unsigned int dmanr, unsigned int mode, + unsigned int dma_mode, unsigned int dma_source, + unsigned int fifo_addr) +{ + int dev_id, i; + struct jz_dma_chan *chan; + + if (dmanr > MAX_DMA_NUM) + return -ENODEV; + for (i = 0; i < MAX_DMA_NUM; i++) { + if (jz_dma_table[i].dev_id < 0) + break; + } + if (i == MAX_DMA_NUM) + return -ENODEV; + + chan = &jz_dma_table[dmanr]; + dev_id = chan->dev_id; + if (dev_id > 0) { + printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n", + __FUNCTION__, dmanr); + return -ENODEV; + } + + /* clone it from the dynamically allocated. */ + if (i != dmanr) { + chan->irq = jz_dma_table[i].irq; + chan->irq_dev = jz_dma_table[i].irq_dev; + chan->dev_str = jz_dma_table[i].dev_str; + jz_dma_table[i].irq = 0; + jz_dma_table[i].irq_dev = NULL; + jz_dma_table[i].dev_id = -1; + } + chan->dev_id = DMA_ID_RAW_SET; + chan->io = dmanr; + chan->fifo_addr = fifo_addr; + chan->mode = dma_mode; + chan->source = dma_source; + + set_dma_mode(dmanr, dma_mode); + + return dmanr; +} + +void enable_dma(unsigned int dmanr) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR); + REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */ + __dmac_enable_channel(dmanr); + if (chan->irq) + __dmac_channel_enable_irq(dmanr); +} + +#define DMA_DISABLE_POLL 0x10000 + +void disable_dma(unsigned int dmanr) +{ + int i; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + if (!__dmac_channel_enabled(dmanr)) + return; + + for (i = 0; i < DMA_DISABLE_POLL; i++) + if (__dmac_channel_transmit_end_detected(dmanr)) + break; +#if 0 + if (i == DMA_DISABLE_POLL) + printk(KERN_INFO "disable_dma: poll expired!\n"); +#endif + + __dmac_disable_channel(dmanr); + if (chan->irq) + __dmac_channel_disable_irq(dmanr); +} + +/* Note: DMA_MODE_MASK is simulated by sw */ +void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else { + printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + } + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; +} + +void set_dma_addr(unsigned int dmanr, unsigned int phyaddr) +{ + unsigned int mode; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + mode = chan->mode & DMA_MODE_MASK; + if (mode == DMA_MODE_READ) { + REG_DMAC_DSAR(chan->io) = chan->fifo_addr; + REG_DMAC_DTAR(chan->io) = phyaddr; + } else if (mode == DMA_MODE_WRITE) { + REG_DMAC_DSAR(chan->io) = phyaddr; + REG_DMAC_DTAR(chan->io) = chan->fifo_addr; + } else + printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n"); +} + +void set_dma_count(unsigned int dmanr, unsigned int bytecnt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + int dma_ds[] = {4, 1, 2, 16, 32}; + unsigned int ds; + + if (!chan) + return; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count +} + +unsigned int get_dma_residue(unsigned int dmanr) +{ + unsigned int count, ds; + int dma_ds[] = {4, 1, 2, 16, 32}; + struct jz_dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT; + count = REG_DMAC_DTCR(chan->io); + count = count * dma_ds[ds]; + + return count; +} + +void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case AFMT_U8: + /* burst mode : 32BIT */ + break; + case AFMT_S16_LE: + /* burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE; + //chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt) +{ + struct jz_dma_chan *chan = get_dma_chan(dmanr); + + if (!chan) + return; + + switch (audio_fmt) { + case 8: + /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */ + break; + case 16: + /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */ + if (mode == DMA_MODE_READ) { + chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_DAI; + chan->mode &= ~DMAC_DCMD_SAI; + } else if (mode == DMA_MODE_WRITE) { + chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE; + chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI); + mode &= DMA_MODE_MASK; + chan->mode |= DMAC_DCMD_SAI; + chan->mode &= ~DMAC_DCMD_DAI; + } else + printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n"); + + REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK; + REG_DMAC_DRSR(chan->io) = chan->source; + break; + } +} + +//#define JZ4750L_DMAC_TEST_ENABLE +#undef JZ4750L_DMAC_TEST_ENABLE + +#ifdef JZ4750L_DMAC_TEST_ENABLE + +/* + * DMA test: external address <--> external address + */ +#define TEST_DMA_SIZE 16*1024 + +static jz_dma_desc *dma_desc; + +static int dma_chan; +static dma_addr_t dma_desc_phys_addr; +static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr; + +static int dma_check_result(void *src, void *dst, int size) +{ + unsigned int addr1, addr2, i, err = 0; + + addr1 = (unsigned int)src; + addr2 = (unsigned int)dst; + + for (i = 0; i < size; i += 4) { + if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) { + err++; + printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2); + } + addr1 += 4; + addr2 += 4; + } + printk("check DMA result err=%d\n", err); + return err; +} + +static irqreturn_t jz4750l_dma_irq(int irq, void *dev_id) +{ + printk("jz4750l_dma_irq %d\n", irq); + + + if (__dmac_channel_transmit_halt_detected(dma_chan)) { + printk("DMA HALT\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + __dmac_channel_clear_transmit_halt(dma_chan); + } + + if (__dmac_channel_address_error_detected(dma_chan)) { + printk("DMA ADDR ERROR\n"); + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + REG_DMAC_DSAR(dma_chan) = 0; /* clear source address register */ + REG_DMAC_DTAR(dma_chan) = 0; /* clear target address register */ + __dmac_channel_clear_address_error(dma_chan); + } + + if (__dmac_channel_descriptor_invalid_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA DESC INVALID\n"); + __dmac_channel_clear_descriptor_invalid(dma_chan); + } + + if (__dmac_channel_count_terminated_detected(dma_chan)) { + printk("DMA CT\n"); + __dmac_channel_clear_count_terminated(dma_chan); + } + + if (__dmac_channel_transmit_end_detected(dma_chan)) { + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + printk("DMA TT\n"); + __dmac_channel_clear_transmit_end(dma_chan); + dump_jz_dma_channel(dma_chan); + dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE); + } + + return IRQ_HANDLED; +} + +void dma_nodesc_test(void) +{ + unsigned int addr, i; + + printk("dma_nodesc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750l_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Init DMA module */ + printk("Starting DMA\n"); + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0; + REG_DMAC_DCCSR(dma_chan) = 0; + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; + REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; + REG_DMAC_DTCR(dma_chan) = 512; + REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */ + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +void dma_desc_test(void) +{ + unsigned int next, addr, i; + static jz_dma_desc *desc; + + printk("dma_desc_test\n"); + + /* Request DMA channel and setup irq handler */ + dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4750l_dma_irq, + IRQF_DISABLED, NULL); + if (dma_chan < 0) { + printk("Setup irq failed\n"); + return; + } + + printk("Requested DMA channel = %d\n", dma_chan); + + /* Allocate DMA buffers */ + dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */ + + dma_src_phys_addr = CPHYSADDR(dma_src_addr); + dma_dst_phys_addr = CPHYSADDR(dma_dst_addr); + + printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n", + dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr); + + /* Prepare data for source buffer */ + addr = (unsigned int)dma_src_addr; + for (i = 0; i < TEST_DMA_SIZE; i += 4) { + *(volatile unsigned int *)addr = addr; + addr += 4; + } + dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE); + + /* Init target buffer */ + memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE); + dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE); + + /* Allocate DMA descriptors */ + dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0); + dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc); + + printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr); + + /* Setup DMA descriptors */ + desc = dma_desc; + next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr; /* DMA target address */ + desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK; + desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */ + desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */ + + desc++; + next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4; + + desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE; + desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */ + desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */ + desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */ + + dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc))); + + /* Setup DMA descriptor address */ + REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr; + + /* Setup request source */ + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO; + + /* Setup DMA channel control/status register */ + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */ + + /* Enable DMA */ + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; + + /* DMA doorbell set -- start DMA now ... */ + REG_DMAC_DMADBSR(dma_chan/HALF_DMA_NUM) = 1 << dma_chan; + + printk("DMA started. IMR=%08x\n", REG_INTC_IMR); + /* wait a long time, ensure transfer end */ + printk("wait 3s...\n"); + mdelay(3000); /* wait 3s */ + + REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + /* free buffers */ + printk("free DMA buffers\n"); + free_pages(dma_src_addr, 2); + free_pages(dma_dst_addr, 2); + + if (dma_desc) + free_pages((unsigned int)dma_desc, 0); + + /* free dma */ + jz_free_dma(dma_chan); +} + +#endif + +//EXPORT_SYMBOL_NOVERS(jz_dma_table); +EXPORT_SYMBOL(jz_dma_table); +EXPORT_SYMBOL(jz_request_dma); +EXPORT_SYMBOL(jz_free_dma); +EXPORT_SYMBOL(jz_set_dma_src_width); +EXPORT_SYMBOL(jz_set_dma_dest_width); +EXPORT_SYMBOL(jz_set_dma_block_size); +EXPORT_SYMBOL(jz_set_dma_mode); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(jz_set_oss_dma); +EXPORT_SYMBOL(jz_set_alsa_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(dump_jz_dma_channel); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/i2c.c linux-2.6.24.3-20100304/arch/mips/jz4750l/i2c.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/i2c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/i2c.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,279 @@ +/* + * linux/arch/mips/jz4750l/i2c.c + * + * Jz4750L I2C routines. + * + * Copyright (C) 2005,2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include + +#include + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (!__i2c_received_ack() && timeout) + timeout--; + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +#ifdef CONFIG_JZ_TPANEL_ATA2508 +static int i2c_put_data_nack(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0); + while (!__i2c_transmit_ended()); + while (timeout--); + return 0; +} +#endif + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else + return -ETIMEDOUT; +} + +/* + * I2C interface + */ +void i2c_open(void) +{ + __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */ + __i2c_enable(); +} + +void i2c_close(void) +{ + udelay(300); /* wait for STOP goes over. */ + __i2c_disable(); +} + +void i2c_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.extalclk, i2cclk); +} + +int i2c_lseek(unsigned char device, unsigned char offset) +{ + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + if (i2c_put_data(offset) < 0) + goto address_err; + return 0; + device_err: + printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device); + __i2c_send_stop(); + return -ENODEV; + address_err: + printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device); + __i2c_send_stop(); + return -EREMOTEIO; +} + +int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int timeout = 5; + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; +#ifndef CONFIG_TOUCHSCREEN_AK4183 + if (i2c_put_data(address) < 0) + goto address_err; +#endif + + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_READ ) < 0) + goto device_rerr; + __i2c_send_ack(); /* Master sends ACK for continue reading */ + while (cnt) { + if (cnt == 1) { + if (i2c_get_data(buf, 0) < 0) + break; + } else { + if (i2c_get_data(buf, 1) < 0) + break; + } + cnt--; + buf++; + } +#ifdef CONFIG_TOUCHSCREEN_AK4183 + __i2c_send_nack(); +#endif + __i2c_send_stop(); + return count - cnt; + device_rerr: + device_werr: + address_err: + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + +int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count) +{ + int cnt = count; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + unsigned char tmpaddr; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = count; + tmpbuf = (unsigned char *)buf; + tmpaddr = address; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; +#ifdef CONFIG_JZ_TPANEL_ATA2508 + if (address == 0xff) { + if (i2c_put_data_nack(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data_nack(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } + else { + + if (i2c_put_data(tmpaddr) < 0) + goto address_err; + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + } +#else +#ifndef CONFIG_TOUCHSCREEN_AK4183 + if (i2c_put_data(tmpaddr) < 0) + goto address_err; +#endif + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + tmpaddr += 8; + goto start_write_page; + } + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } +#endif + __i2c_send_stop(); + return count - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + + W_timeout: + printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +EXPORT_SYMBOL(i2c_open); +EXPORT_SYMBOL(i2c_close); +EXPORT_SYMBOL(i2c_setclk); +EXPORT_SYMBOL(i2c_read); +EXPORT_SYMBOL(i2c_write); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/irq.c linux-2.6.24.3-20100304/arch/mips/jz4750l/irq.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/irq.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,299 @@ +/* + * linux/arch/mips/jz4750l/irq.c + * + * JZ4750L interrupt routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * INTC irq type + */ + +static void enable_intc_irq(unsigned int irq) +{ + __intc_unmask_irq(irq); +} + +static void disable_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); +} + +static void mask_and_ack_intc_irq(unsigned int irq) +{ + __intc_mask_irq(irq); + __intc_ack_irq(irq); +} + +static void end_intc_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_intc_irq(irq); + } +} + +static unsigned int startup_intc_irq(unsigned int irq) +{ + enable_intc_irq(irq); + return 0; +} + +static void shutdown_intc_irq(unsigned int irq) +{ + disable_intc_irq(irq); +} + +static struct irq_chip intc_irq_type = { + .typename = "INTC", + .startup = startup_intc_irq, + .shutdown = shutdown_intc_irq, + .enable = enable_intc_irq, + .disable = disable_intc_irq, + .ack = mask_and_ack_intc_irq, + .end = end_intc_irq, +}; + +/* + * GPIO irq type + */ + +static void enable_gpio_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if (irq < (IRQ_GPIO_0 + 32)) { + intc_irq = IRQ_GPIO0; + } + else if (irq < (IRQ_GPIO_0 + 64)) { + intc_irq = IRQ_GPIO1; + } + else if (irq < (IRQ_GPIO_0 + 96)) { + intc_irq = IRQ_GPIO2; + } + else if (irq < (IRQ_GPIO_0 + 128)) { + intc_irq = IRQ_GPIO3; + } + else if (irq < (IRQ_GPIO_0 + 160)) { + intc_irq = IRQ_GPIO4; + } + else { + intc_irq = IRQ_GPIO5; + } + + enable_intc_irq(intc_irq); + __gpio_unmask_irq(irq - IRQ_GPIO_0); +} + +static void disable_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); +} + +static void mask_and_ack_gpio_irq(unsigned int irq) +{ + __gpio_mask_irq(irq - IRQ_GPIO_0); + __gpio_ack_irq(irq - IRQ_GPIO_0); +} + +static void end_gpio_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_gpio_irq(irq); + } +} + +static unsigned int startup_gpio_irq(unsigned int irq) +{ + enable_gpio_irq(irq); + return 0; +} + +static void shutdown_gpio_irq(unsigned int irq) +{ + disable_gpio_irq(irq); +} + +static struct irq_chip gpio_irq_type = { + .typename = "GPIO", + .startup = startup_gpio_irq, + .shutdown = shutdown_gpio_irq, + .enable = enable_gpio_irq, + .disable = disable_gpio_irq, + .ack = mask_and_ack_gpio_irq, + .end = end_gpio_irq, +}; + +/* + * DMA irq type + */ + +static void enable_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return; + } + __intc_unmask_irq(intc_irq); + __dmac_channel_enable_irq(irq - IRQ_DMA_0); +} + +static void disable_dma_irq(unsigned int irq) +{ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void mask_and_ack_dma_irq(unsigned int irq) +{ + unsigned int intc_irq; + + if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */ + intc_irq = IRQ_DMAC0; + else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */ + intc_irq = IRQ_DMAC1; + else { + printk("%s, unexpected dma irq #%d\n", __FILE__, irq); + return ; + } + __intc_ack_irq(intc_irq); + __dmac_channel_ack_irq(irq-IRQ_DMA_0); /* needed?? add 20080506, Wolfgang */ + __dmac_channel_disable_irq(irq - IRQ_DMA_0); +} + +static void end_dma_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + enable_dma_irq(irq); + } +} + +static unsigned int startup_dma_irq(unsigned int irq) +{ + enable_dma_irq(irq); + return 0; +} + +static void shutdown_dma_irq(unsigned int irq) +{ + disable_dma_irq(irq); +} + +static struct irq_chip dma_irq_type = { + .typename = "DMA", + .startup = startup_dma_irq, + .shutdown = shutdown_dma_irq, + .enable = enable_dma_irq, + .disable = disable_dma_irq, + .ack = mask_and_ack_dma_irq, + .end = end_dma_irq, +}; + +//---------------------------------------------------------------------- + +void __init arch_init_irq(void) +{ + int i; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + /* Set up INTC irq + */ + for (i = 0; i < 32; i++) { + disable_intc_irq(i); + irq_desc[i].chip = &intc_irq_type; + } + + /* Set up DMAC irq + */ + for (i = 0; i < NUM_DMA; i++) { + disable_dma_irq(IRQ_DMA_0 + i); + irq_desc[IRQ_DMA_0 + i].chip = &dma_irq_type; + } + + /* Set up GPIO irq + */ + for (i = 0; i < NUM_GPIO; i++) { + disable_gpio_irq(IRQ_GPIO_0 + i); + irq_desc[IRQ_GPIO_0 + i].chip = &gpio_irq_type; + } +} + +static int plat_real_irq(int irq) +{ + switch (irq) { + case IRQ_GPIO0: + irq = __gpio_group_irq(0) + IRQ_GPIO_0; + break; + case IRQ_GPIO1: + irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32; + break; + case IRQ_GPIO2: + irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64; + break; + case IRQ_GPIO3: + irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96; + break; + case IRQ_GPIO4: + irq = __gpio_group_irq(4) + IRQ_GPIO_0 + 128; + break; + case IRQ_GPIO5: + irq = __gpio_group_irq(5) + IRQ_GPIO_0 + 160; + break; + case IRQ_DMAC0: + case IRQ_DMAC1: + irq = __dmac_get_irq() + IRQ_DMA_0; + break; + } + + return irq; +} + +asmlinkage void plat_irq_dispatch(void) +{ + int irq = 0; + static unsigned long intc_ipr = 0; + + intc_ipr |= REG_INTC_IPR; + + if (!intc_ipr) return; + + irq = ffs(intc_ipr) - 1; + intc_ipr &= ~(1< + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include +#if 0 +/* OHCI (USB full speed host controller) */ +static struct resource jz_usb_ohci_resources[] = { + [0] = { + .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap + .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UHC, + .end = IRQ_UHC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct platform_device jz_usb_ohci_device = { + .name = "jz-ohci", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_ohci_resources), + .resource = jz_usb_ohci_resources, +}; +#endif +/*** LCD controller ***/ +static struct resource jz_lcd_resources[] = { + [0] = { + .start = CPHYSADDR(LCD_BASE), + .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_lcd_dmamask = ~(u32)0; + +static struct platform_device jz_lcd_device = { + .name = "jz-lcd", + .id = 0, + .dev = { + .dma_mask = &jz_lcd_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_lcd_resources), + .resource = jz_lcd_resources, +}; + +/* UDC (USB gadget controller) */ +static struct resource jz_usb_gdt_resources[] = { + [0] = { + .start = CPHYSADDR(UDC_BASE), + .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_UDC, + .end = IRQ_UDC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device jz_usb_gdt_device = { + .name = "jz-udc", + .id = 0, + .dev = { + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_usb_gdt_resources), + .resource = jz_usb_gdt_resources, +}; + +/** MMC/SD controller **/ +static struct resource jz_mmc_resources[] = { + [0] = { + .start = CPHYSADDR(MSC_BASE), + .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MSC0, + .end = IRQ_MSC0, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 jz_mmc_dmamask = ~(u32)0; + +static struct platform_device jz_mmc_device = { + .name = "jz-mmc", + .id = 0, + .dev = { + .dma_mask = &jz_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(jz_mmc_resources), + .resource = jz_mmc_resources, +}; + +/* All */ +static struct platform_device *jz_platform_devices[] __initdata = { +// &jz_usb_ohci_device, + &jz_lcd_device, + &jz_usb_gdt_device, + &jz_mmc_device, +}; + +static int __init jz_platform_init(void) +{ + return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices)); +} + +arch_initcall(jz_platform_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/pm.c linux-2.6.24.3-20100304/arch/mips/jz4750l/pm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/pm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/pm.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,461 @@ +/* + * linux/arch/mips/jz4750l/common/pm.c + * + * JZ4750L Power Management Routines + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + +#define GPIO_PORT_NUM 6 + +/* + * __gpio_as_sleep set all pins to pull-disable, and set all pins as input + * except sdram and the pins which can be used as CS1_N to CS4_N for chip select. + */ +#define __gpio_as_sleep() \ +do { \ + REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \ + REG_GPIO_PXSELC(1) = ~0x03ff7fff; \ + REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \ + REG_GPIO_PXPES(1) = 0xffffffff; \ + REG_GPIO_PXFUNC(2) = ~0x01e00000; \ + REG_GPIO_PXSELC(2) = ~0x01e00000; \ + REG_GPIO_PXDIRC(2) = ~0x01e00000; \ + REG_GPIO_PXPES(2) = 0xffffffff; \ + REG_GPIO_PXFUNC(3) = 0xffffffff; \ + REG_GPIO_PXSELC(3) = 0xffffffff; \ + REG_GPIO_PXDIRC(3) = 0xffffffff; \ + REG_GPIO_PXPES(3) = 0xffffffff; \ + REG_GPIO_PXFUNC(4) = 0xffffffff; \ + REG_GPIO_PXSELC(4) = 0xffffffff; \ + REG_GPIO_PXDIRC(4) = 0xffffffff; \ + REG_GPIO_PXPES(4) = 0xffffffff; \ + REG_GPIO_PXFUNC(5) = 0xffffffff; \ + REG_GPIO_PXSELC(5) = 0xffffffff; \ + REG_GPIO_PXDIRC(5) = 0xffffffff; \ + REG_GPIO_PXPES(5) = 0xffffffff; \ +} while (0) + +static int jz_pm_do_hibernate(void) +{ + printk("Put CPU into hibernate mode.\n"); + + /* Mask all interrupts */ + REG_INTC_IMSR = 0xffffffff; + + /* + * RTC Wakeup or 1Hz interrupt can be enabled or disabled + * through RTC driver's ioctl (linux/driver/char/rtc_jz.c). + */ + + /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT); + + /* Set reset pin low-level assertion time after wakeup: must > 60ms */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */ + + /* Scratch pad register to be reserved */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HSPR = 0x12345678; + + /* clear wakeup status register */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HWRSR = 0x0; + + /* Put CPU to power down mode */ + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + REG_RTC_HCR = RTC_HCR_PD; + + while (!(REG_RTC_RCR & RTC_RCR_WRDY)); + while(1); + + /* We can't get here */ + return 0; +} + +/* NOTES: + * 1: Pins that are floated (NC) should be set as input and pull-enable. + * 2: Pins that are pull-up or pull-down by outside should be set as input + * and pull-disable. + * 3: Pins that are connected to a chip except sdram and nand flash + * should be set as input and pull-disable, too. + */ +static void jz_board_do_sleep(unsigned long *ptr) +{ + unsigned char i; + + /* Print messages of GPIO registers for debug */ + for(i=0;i + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DEBUG 1 +#undef DEBUG + + +struct proc_dir_entry *proc_jz_root; + + +/* + * EMC Modules + */ +static int emc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf (page+len, "SMCR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SMCR0, REG_EMC_SMCR1, REG_EMC_SMCR2, REG_EMC_SMCR3, REG_EMC_SMCR4); + len += sprintf (page+len, "SACR(0-5): 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", REG_EMC_SACR0, REG_EMC_SACR1, REG_EMC_SACR2, REG_EMC_SACR3, REG_EMC_SACR4); + len += sprintf (page+len, "DMCR: 0x%08x\n", REG_EMC_DMCR); + len += sprintf (page+len, "RTCSR: 0x%04x\n", REG_EMC_RTCSR); + len += sprintf (page+len, "RTCOR: 0x%04x\n", REG_EMC_RTCOR); + return len; +} + +/* + * Power Manager Module + */ +static int pmc_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned long lcr = REG_CPM_LCR; + unsigned long clkgr = REG_CPM_CLKGR; + + len += sprintf (page+len, "Low Power Mode : %s\n", + ((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_IDLE)) ? + "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == (CPM_LCR_LPM_SLEEP)) ? + "SLEEP" : "HIBERNATE")); + len += sprintf (page+len, "Doze Mode : %s\n", + (lcr & CPM_LCR_DOZE_ON) ? "on" : "off"); + if (lcr & CPM_LCR_DOZE_ON) + len += sprintf (page+len, " duty : %d\n", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)); + len += sprintf (page+len, "AUX_CPU : %s\n", + (clkgr & CPM_CLKGR_AUX_CPU) ? "stopped" : "running"); + len += sprintf (page+len, "AHB1 : %s\n", + (clkgr & CPM_CLKGR_AHB1) ? "stopped" : "running"); + len += sprintf (page+len, "IDCT : %s\n", + (clkgr & CPM_CLKGR_IDCT) ? "stopped" : "running"); + len += sprintf (page+len, "DB : %s\n", + (clkgr & CPM_CLKGR_DB) ? "stopped" : "running"); + len += sprintf (page+len, "ME : %s\n", + (clkgr & CPM_CLKGR_ME) ? "stopped" : "running"); + len += sprintf (page+len, "MC : %s\n", + (clkgr & CPM_CLKGR_MC) ? "stopped" : "running"); + len += sprintf (page+len, "TVE : %s\n", + (clkgr & CPM_CLKGR_TVE) ? "stopped" : "running"); + len += sprintf (page+len, "TSSI : %s\n", + (clkgr & CPM_CLKGR_TSSI) ? "stopped" : "running"); + len += sprintf (page+len, "IPU : %s\n", + (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running"); + len += sprintf (page+len, "DMAC : %s\n", + (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running"); + len += sprintf (page+len, "UDC : %s\n", + (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running"); + len += sprintf (page+len, "LCD : %s\n", + (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running"); + len += sprintf (page+len, "CIM : %s\n", + (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running"); + len += sprintf (page+len, "SADC : %s\n", + (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running"); + len += sprintf (page+len, "MSC0 : %s\n", + (clkgr & CPM_CLKGR_MSC0) ? "stopped" : "running"); + len += sprintf (page+len, "MSC1 : %s\n", + (clkgr & CPM_CLKGR_MSC1) ? "stopped" : "running"); + len += sprintf (page+len, "SSI : %s\n", + (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running"); + len += sprintf (page+len, "I2C : %s\n", + (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running"); + len += sprintf (page+len, "RTC : %s\n", + (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running"); + len += sprintf (page+len, "TCU : %s\n", + (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running"); + len += sprintf (page+len, "UART1 : %s\n", + (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running"); + len += sprintf (page+len, "UART0 : %s\n", + (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running"); + return len; +} + +static int pmc_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CLKGR = simple_strtoul(buffer, 0, 16); + return count; +} + +/* + * Clock Generation Module + */ +#define TO_MHZ(x) (x/1000000),(x%1000000)/10000 +#define TO_KHZ(x) (x/1000),(x%1000)/10 + +static int cgm_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */ + unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */ + unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + unsigned int od[4] = {1, 2, 2, 4}; + + len += sprintf (page+len, "CPPCR : 0x%08x\n", cppcr); + len += sprintf (page+len, "CPCCR : 0x%08x\n", cpccr); + len += sprintf (page+len, "PLL : %s\n", + (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF"); + len += sprintf (page+len, "m:n:o : %d:%d:%d\n", + __cpm_get_pllm() + 2, + __cpm_get_plln() + 2, + od[__cpm_get_pllod()] + ); + len += sprintf (page+len, "C:H:M:P : %d:%d:%d:%d\n", + div[__cpm_get_cdiv()], + div[__cpm_get_hdiv()], + div[__cpm_get_mdiv()], + div[__cpm_get_pdiv()] + ); + len += sprintf (page+len, "PLL Freq : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pllout())); + len += sprintf (page+len, "CCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_cclk())); + len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_hclk())); + len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mclk())); + len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_pclk())); + len += sprintf (page+len, "H1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_h1clk())); + len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(__cpm_get_pixclk())); + len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_i2sclk())); + len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_usbclk())); + len += sprintf (page+len, "MSC0CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(0))); + len += sprintf (page+len, "MSC1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(1))); + len += sprintf (page+len, "EXTALCLK0 : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk0())); + len += sprintf (page+len, "EXTALCLK(by CPM): %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk())); + len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_rtcclk())); + + return len; +} + +static int cgm_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + REG_CPM_CPCCR = simple_strtoul(buffer, 0, 16); + return count; +} + + +/* USAGE: + * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages. + * echo FF > /proc/jz/ipu // 255, free all buffer + * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx + * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l) + * echo 0 > /proc/jz/ipu // debug, print ipu_buf + * od -X /proc/jz/ipu // read mem addr + */ + +typedef struct _ipu_buf { + unsigned int addr; /* phys addr */ + unsigned int page_shift; +} ipu_buf_t; + +#define IPU_BUF_MAX 4 /* 4 buffers */ + +static struct _ipu_buf ipu_buf[IPU_BUF_MAX]; +static int ipu_buf_cnt = 0; +static unsigned char g_asid=0; + +extern void local_flush_tlb_all(void); + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") +void show_tlb(void) +{ +#define ASID_MASK 0xFF + + unsigned long flags; + unsigned int old_ctx; + unsigned int entry; + unsigned int entrylo0, entrylo1, entryhi; + unsigned int pagemask; + + local_irq_save(flags); + + /* Save old context */ + old_ctx = (read_c0_entryhi() & 0xff); + + printk("TLB content:\n"); + entry = 0; + while(entry < 32) { + write_c0_index(entry); + BARRIER; + tlb_read(); + BARRIER; + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); + pagemask = read_c0_pagemask(); + printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); + printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); + printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); + + printk("\t\tpagemask=0x%08x", pagemask); + printk("\tentryhi=0x%08x\n", entryhi); + printk("\t\tentrylo0=0x%08x", entrylo0); + printk("\tentrylo1=0x%08x\n", entrylo1); + + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + + local_irq_restore(flags); +} + +static void ipu_add_wired_entry(unsigned long pid, + unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + struct task_struct *g, *p; + + /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */ + wired = read_c0_wired(); + if (wired) return; + + do_each_thread(g, p) { + if (p->pid == pid ) + g_asid = p->mm->context[0]; + } while_each_thread(g, p); + + + local_irq_save(flags); + + entrylo0 = entrylo0 >> 6; /* PFN */ + entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */ + + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + entryhi &= ~0xff; /* new add, 20070906 */ + entryhi |= g_asid; /* new add, 20070906 */ +// entryhi |= old_ctx; /* new add, 20070906 */ + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +#if defined(DEBUG) + printk("\nold_ctx=%03d\n", old_ctx); + + show_tlb(); +#endif +} + +static void ipu_del_wired_entry( void ) +{ + unsigned long flags; + unsigned long wired; + + local_irq_save(flags); + wired = read_c0_wired(); + if ( wired > 0 ) { + write_c0_wired(wired - 1); + } + local_irq_restore(flags); +} + +static inline void ipu_buf_get( unsigned int page_shift ) +{ + unsigned char * virt_addr; + int i; + for ( i=0; i< IPU_BUF_MAX; ++i ) { + if ( ipu_buf[i].addr == 0 ) { + break; + } + } + + if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) { + printk("Error, no free ipu buffer.\n"); + return ; + } + + virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift); + + if ( virt_addr ) { + ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr); + ipu_buf[ipu_buf_cnt].page_shift = page_shift; + + for (i = 0; i < (1<= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */ + printk("no free buffer.\n"); + *pint = 0; + } + else + *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */ + len += sizeof(unsigned int); + +#if defined(DEBUG) + show_tlb(); +#endif + return len; + +} + +static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val ; + int cnt,i; + char buf[12]; + unsigned long pid, entrylo0, entrylo1, entryhi, pagemask; +#if defined(DEBUG) + printk("ipu write count=%u\n", count); +#endif + if (count == (8*5+1)) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*0, 8); + pid = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*1, 8); + entrylo0 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*2, 8); + entrylo1 = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*3, 8); + entryhi = simple_strtoul(buf, 0, 16); + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer+8*4, 8); + pagemask = simple_strtoul(buf, 0, 16); + +#if defined(DEBUG) + printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n", + pid, entrylo0, entrylo1, entryhi, pagemask); +#endif + ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask); + return 41; + } + else if ( count <= 8+1 ) { + for (i=0;i<12;i++) buf[i]=0; + strncpy(buf, buffer, 8); + val = simple_strtoul(buf, 0, 16); + } else if (count == 44) { + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer, 10); + pid = simple_strtoul(buf, 0, 16); + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 11, 10); + entryhi = simple_strtoul(buf, 0, 16);//vaddr + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 22, 10); + entrylo0 = simple_strtoul(buf, 0, 16);//paddr + for (i = 0; i < 12; i++) + buf[i] = 0; + strncpy(buf, buffer + 33, 10); + pagemask = simple_strtoul(buf, 0, 16); + pagemask = 0x3ff << 13; /* Fixed to 4MB page size */ + ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask); + return 44; + } else { + printk("ipu write count error, count=%d\n.", (unsigned int)count); + return -1; + } + + /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */ + if ( val == 0 ) { /* debug, print ipu_buf info */ + for ( cnt=0; cnt /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages + * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx + * echo FF > /proc/jz/ipu // FF, free all buffers + * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer + */ + +//#define DEBUG_IMEM 1 + +#define IMEM_MAX_ORDER 10 /* max 2^10 * 4096 = 4MB */ + +static unsigned int jz_imem_base; /* physical base address of ipu memory */ + +static unsigned int allocated_phys_addr = 0; + +/* + * Allocated buffer list + */ +typedef struct imem_list { + unsigned int phys_start; /* physical start addr */ + unsigned int phys_end; /* physical end addr */ + struct imem_list *next; +} imem_list_t; + +static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */ + +#ifdef DEBUG_IMEM +static void dump_imem_list(void) +{ + struct imem_list *imem; + + printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head); + imem = imem_list_head; + while (imem) { + printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next); + imem = imem->next; + } +} +#endif + +/* allocate 2^order pages inside the 4MB memory */ +static int imem_alloc(unsigned int order) +{ + int alloc_ok = 0; + unsigned int start, end; + unsigned int size = (1 << order) * PAGE_SIZE; + struct imem_list *imem, *imemn, *imemp; + + allocated_phys_addr = 0; + + start = jz_imem_base; + end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + imem = imem_list_head; + while (imem) { + if ((imem->phys_start - start) >= size) { + /* we got a valid address range */ + alloc_ok = 1; + break; + } + + start = imem->phys_end + 1; + imem = imem->next; + } + + if (!alloc_ok) { + if ((end - start) >= size) + alloc_ok = 1; + } + + if (alloc_ok) { + end = start + size - 1; + allocated_phys_addr = start; + + /* add to imem_list, up sorted by phys_start */ + imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); + if (!imemn) { + return -ENOMEM; + } + imemn->phys_start = start; + imemn->phys_end = end; + imemn->next = NULL; + + if (!imem_list_head) + imem_list_head = imemn; + else { + imem = imemp = imem_list_head; + while (imem) { + if (start < imem->phys_start) { + break; + } + + imemp = imem; + imem = imem->next; + } + + if (imem == imem_list_head) { + imem_list_head = imemn; + imemn->next = imem; + } + else { + imemn->next = imemp->next; + imemp->next = imemn; + } + } + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif + return 0; +} + +static void imem_free(unsigned int phys_addr) +{ + struct imem_list *imem, *imemp; + + imem = imemp = imem_list_head; + while (imem) { + if (phys_addr == imem->phys_start) { + if (imem == imem_list_head) { + imem_list_head = imem->next; + } + else { + imemp->next = imem->next; + } + + kfree(imem); + break; + } + + imemp = imem; + imem = imem->next; + } + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +static void imem_free_all(void) +{ + struct imem_list *imem; + + imem = imem_list_head; + while (imem) { + kfree(imem); + imem = imem->next; + } + + imem_list_head = NULL; + + allocated_phys_addr = 0; + +#ifdef DEBUG_IMEM + dump_imem_list(); +#endif +} + +/* + * Return the allocated buffer address and the max order of free buffer + */ +static int imem_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + unsigned int start_addr, end_addr, max_order, max_size; + struct imem_list *imem; + + unsigned int *tmp = (unsigned int *)(page + len); + + start_addr = jz_imem_base; + end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; + + if (!imem_list_head) + max_size = end_addr - start_addr; + else { + max_size = 0; + imem = imem_list_head; + while (imem) { + if (max_size < (imem->phys_start - start_addr)) + max_size = imem->phys_start - start_addr; + + start_addr = imem->phys_end + 1; + imem = imem->next; + } + + if (max_size < (end_addr - start_addr)) + max_size = end_addr - start_addr; + } + + if (max_size > 0) { + max_order = get_order(max_size); + if (((1 << max_order) * PAGE_SIZE) > max_size) + max_order--; + } + else { + max_order = 0xffffffff; /* No any free buffer */ + } + + *tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */ + *tmp = max_order; /* max order of current free buffers */ + + len += 2 * sizeof(unsigned int); + + return len; +} + +static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + unsigned int val; + + val = simple_strtoul(buffer, 0, 16); + + if (val == 0xff) { + /* free all memory */ + imem_free_all(); + } + else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) { + /* allocate 2^val pages */ + imem_alloc(val); + } + else { + /* free buffer which phys_addr is val */ + imem_free(val); + } + + return count; +} + +/* + * /proc/jz/xxx entry + * + */ +static int __init jz_proc_init(void) +{ + struct proc_dir_entry *res; + unsigned int virt_addr, i; + + proc_jz_root = proc_mkdir("jz", 0); + + /* External Memory Controller */ + res = create_proc_entry("emc", 0644, proc_jz_root); + if (res) { + res->read_proc = emc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* Power Management Controller */ + res = create_proc_entry("pmc", 0644, proc_jz_root); + if (res) { + res->read_proc = pmc_read_proc; + res->write_proc = pmc_write_proc; + res->data = NULL; + } + + /* Clock Generation Module */ + res = create_proc_entry("cgm", 0644, proc_jz_root); + if (res) { + res->read_proc = cgm_read_proc; + res->write_proc = cgm_write_proc; + res->data = NULL; + } + + /* Image process unit */ + res = create_proc_entry("ipu", 0644, proc_jz_root); + if (res) { + res->read_proc = ipu_read_proc; + res->write_proc = ipu_write_proc; + res->data = NULL; + } + + /* udc hotplug */ + res = create_proc_entry("udc", 0644, proc_jz_root); + if (res) { + res->read_proc = udc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* mmc hotplug */ + res = create_proc_entry("mmc", 0644, proc_jz_root); + if (res) { + res->read_proc = mmc_read_proc; + res->write_proc = NULL; + res->data = NULL; + } + + /* + * Reserve a 4MB memory for IPU on JZ4750L. + */ + jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER); + if (jz_imem_base) { + /* imem (IPU memory management) */ + res = create_proc_entry("imem", 0644, proc_jz_root); + if (res) { + res->read_proc = imem_read_proc; + res->write_proc = imem_write_proc; + res->data = NULL; + } + + /* Set page reserved */ + virt_addr = jz_imem_base; + for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) { + SetPageReserved(virt_to_page((void *)virt_addr)); + virt_addr += PAGE_SIZE; + } + + /* Convert to physical address */ + jz_imem_base = virt_to_phys((void *)jz_imem_base); + + printk("Total %dMB memory at 0x%x was reserved for IPU\n", + (unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base); + } + + return 0; +} + +__initcall(jz_proc_init); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/prom.c linux-2.6.24.3-20100304/arch/mips/jz4750l/prom.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/prom.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,198 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, supports YAMON and U-Boot. + * + * Copyright 2000, 2001, 2006 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* #define DEBUG_CMDLINE */ + +int prom_argc; +char **prom_argv, **prom_envp; + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + if (prom_argc > 1) + *cp = '\0'; + +} + + +char *prom_getenv(char *envname) +{ +#if 0 + /* + * Return a pointer to the given environment variable. + * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". + */ + + char **env = prom_envp; + int i = strlen(envname); + int yamon = (*env && strchr(*env, '=') == NULL); + + while (*env) { + if (yamon) { + if (strcmp(envname, *env++) == 0) + return *env; + } else { + if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; + } + env++; + } +#endif + return NULL; +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machtype = MACH_INGENIC_JZ4750L; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +/* used by early printk */ +void prom_putchar(char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART1_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART1_BASE + OFF_TDR); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +const char *get_system_type(void) +{ + return "JZ4750L"; +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/reset.c linux-2.6.24.3-20100304/arch/mips/jz4750l/reset.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/reset.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,46 @@ +/* + * linux/arch/mips/jz4750/reset.c + * + * JZ4750 reset routines. + * + * Copyright (c) 2006-2007 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void jz_restart(char *command) +{ + printk("Restarting after 4 ms\n"); + REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN; + REG_WDT_TCNT = 0; + REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */ + REG_TCU_TSCR = TCU_TSCR_WDTSC; /* enable wdt clock */ + REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */ + while (1); +} + +void jz_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void jz_power_off(void) +{ + jz_halt(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/setup.c linux-2.6.24.3-20100304/arch/mips/jz4750l/setup.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/setup.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,199 @@ +/* + * linux/arch/mips/jz4750l/common/setup.c + * + * JZ4750L common setup routines. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PC_KEYB +#include +#endif + +jz_clocks_t jz_clocks; + +extern char * __init prom_getcmdline(void); +extern void __init jz_board_setup(void); +extern void jz_restart(char *); +extern void jz_halt(void); +extern void jz_power_off(void); +extern void jz_time_init(void); + +static void __init sysclocks_setup(void) +{ +#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */ + jz_clocks.cclk = __cpm_get_cclk(); + jz_clocks.hclk = __cpm_get_hclk(); + jz_clocks.pclk = __cpm_get_pclk(); + jz_clocks.mclk = __cpm_get_mclk(); + jz_clocks.h1clk = __cpm_get_h1clk(); + jz_clocks.pixclk = __cpm_get_pixclk(); + jz_clocks.i2sclk = __cpm_get_i2sclk(); + jz_clocks.usbclk = __cpm_get_usbclk(); + jz_clocks.mscclk = __cpm_get_mscclk(0); + jz_clocks.extalclk = __cpm_get_extalclk(); + jz_clocks.rtcclk = __cpm_get_rtcclk(); +#else + +#define FPGACLK 8000000 + + jz_clocks.cclk = FPGACLK; + jz_clocks.hclk = FPGACLK; + jz_clocks.pclk = FPGACLK; + jz_clocks.mclk = FPGACLK; + jz_clocks.h1clk = FPGACLK; + jz_clocks.pixclk = FPGACLK; + jz_clocks.i2sclk = FPGACLK; + jz_clocks.usbclk = FPGACLK; + jz_clocks.mscclk = FPGACLK; + jz_clocks.extalclk = FPGACLK; + jz_clocks.rtcclk = FPGACLK; +#endif + + printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n", + (jz_clocks.cclk + 500000) / 1000000, + (jz_clocks.hclk + 500000) / 1000000, + (jz_clocks.pclk + 500000) / 1000000, + (jz_clocks.mclk + 500000) / 1000000); +} + +static void __init soc_cpm_setup(void) +{ + /* Start all module clocks + */ + __cpm_start_all(); + + /* Enable CKO to external memory */ + __cpm_enable_cko(); + + /* CPU enters IDLE mode when executing 'wait' instruction */ + __cpm_idle_mode(); + + /* Setup system clocks */ + sysclocks_setup(); +} + +static void __init soc_harb_setup(void) +{ +// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */ +// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */ +} + +static void __init soc_emc_setup(void) +{ +} + +static void __init soc_dmac_setup(void) +{ + __dmac_enable_module(0); + __dmac_enable_module(1); +} + +static void __init jz_soc_setup(void) +{ + soc_cpm_setup(); + soc_harb_setup(); + soc_emc_setup(); + soc_dmac_setup(); +} + +static void __init jz_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */ + memset(&s, 0, sizeof(s)); + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + s.iotype = SERIAL_IO_MEM; + s.regshift = 2; + s.uartclk = jz_clocks.extalclk ; + + s.line = 0; + s.membase = (u8 *)UART0_BASE; + s.irq = IRQ_UART0; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS0 setup failed!\n"); + } + + s.line = 1; + s.membase = (u8 *)UART1_BASE; + s.irq = IRQ_UART1; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS1 setup failed!\n"); + } + + s.line = 2; + s.membase = (u8 *)UART2_BASE; + s.irq = IRQ_UART2; + + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS2 setup failed!\n"); + } +/* + s.line = 3; + s.membase = (u8 *)UART3_BASE; + s.irq = IRQ_UART3; + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial ttyS3 setup failed!\n"); + } +*/ +#endif +} + +void __init plat_mem_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + + /* IO/MEM resources. Which will be the addtion value in `inX' and + * `outX' macros defined in asm/io.h */ + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x00000000; + iomem_resource.end = 0xffffffff; + + _machine_restart = jz_restart; + _machine_halt = jz_halt; + pm_power_off = jz_power_off; + + jz_soc_setup(); + jz_serial_setup(); + jz_board_setup(); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/time.c linux-2.6.24.3-20100304/arch/mips/jz4750l/time.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/jz4750l/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/jz4750l/time.c 2010-03-03 19:05:07.000000000 -0800 @@ -0,0 +1,156 @@ +/* + * linux/arch/mips/jz4750l/time.c + * + * Setting up the clock on the JZ4750L boards. + * + * Copyright (C) 2008 Ingenic Semiconductor Inc. + * Author: + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include +#include +#include +#include + +#include +#include + +/* This is for machines which generate the exact clock. */ + +#define JZ_TIMER_IRQ IRQ_TCU0 + +#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */ + +static struct clocksource clocksource_jz; /* Jz clock source */ +static struct clock_event_device jz_clockevent_device; /* Jz clock event */ + +void (*jz_timer_callback)(void); + +static irqreturn_t jz_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */ + + if (jz_timer_callback) + jz_timer_callback(); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction jz_irqaction = { + .handler = jz_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, + .name = "jz-timerirq", +}; + + +cycle_t jz_get_cycles(void) +{ + /* convert jiffes to jz timer cycles */ + return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_OSTCNT); +} + +static struct clocksource clocksource_jz = { + .name = "jz_clocksource", + .rating = 300, + .read = jz_get_cycles, + .mask = 0xFFFFFFFF, + .shift = 10, + .flags = CLOCK_SOURCE_WATCHDOG, +}; + +static int __init jz_clocksource_init(void) +{ + clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift); + clocksource_register(&clocksource_jz); + return 0; +} + +static int jz_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + return 0; +} + +static void jz_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device jz_clockevent_device = { + .name = "jz-clockenvent", + .features = CLOCK_EVT_FEAT_PERIODIC, +// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */ + + /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + .rating = 300, + .irq = JZ_TIMER_IRQ, + .set_mode = jz_set_mode, + .set_next_event = jz_set_next_event, +}; + +static void __init jz_clockevent_init(void) +{ + struct clock_event_device *cd = &jz_clockevent_device; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of_cpu(cpu); + clockevents_register_device(cd); +} + +static void __init jz_timer_setup(void) +{ + jz_clocksource_init(); /* init jz clock source */ + jz_clockevent_init(); /* init jz clock event */ + + /* + * Make irqs happen for the system timer + */ + jz_irqaction.dev_id = &jz_clockevent_device; + setup_irq(JZ_TIMER_IRQ, &jz_irqaction); +} + + +void __init plat_time_init(void) +{ + unsigned int latch; + + /* Init timer */ + latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ; + + REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN; + REG_TCU_OSTCNT = 0; + REG_TCU_OSTDR = latch; + + REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */ + REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */ + REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */ + + jz_timer_setup(); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/Kconfig linux-2.6.24.3-20100304/arch/mips/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/Kconfig 2010-03-03 19:05:06.000000000 -0800 @@ -16,6 +16,107 @@ prompt "System type" default SGI_IP22 +config JZ4730_PMP + bool "Ingenic JZ4730 PMP board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4730 + +config JZ4740_PAVO + bool "Ingenic JZ4740 PAVO board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4740 + +config JZ4740_LEO + bool "Ingenic JZ4740 LEO board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4740 + +config JZ4740_LYRA + bool "Ingenic JZ4740 LYRA board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4740 + +config JZ4725_DIPPER + bool "Ingenic JZ4725 DIPPER board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4740 + select SOC_JZ4725 + +config JZ4720_VIRGO + bool "Ingenic JZ4720 VIRGO board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4740 + select SOC_JZ4720 + +config JZ4750_FUWA + bool "Ingenic JZ4750 FUWA board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750 + select JZ_FPGA + +config JZ4750D_FUWA1 + bool "Ingenic JZ4750d FUWA1 board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750D + select JZ_FPGA + +config JZ4750_APUS + bool "Ingenic JZ4750 APUS board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750 + +config JZ4750D_CETUS + bool "Ingenic JZ4750d CETUS board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750D + +config JZ4750L_F4750L + bool "Ingenic JZ4750L FPGA board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750L + select JZ_FPGA + +config JZ4750L_VOLANS + bool "Ingenic JZ4725B VOLANS board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4750L + config MACH_ALCHEMY bool "Alchemy processor based machines" @@ -701,6 +802,52 @@ endmenu +##################################################### +# Ingenic SOC series +##################################################### + +config SOC_JZ4730 + bool + select JZSOC + +config SOC_JZ4740 + bool + select JZSOC + +config SOC_JZ4725 + bool + select JZSOC + +config SOC_JZ4720 + bool + select JZSOC + +config SOC_JZ4750 + bool + select JZSOC + +config SOC_JZ4750D + bool + select JZSOC + +config SOC_JZ4750L + bool + select JZSOC + +config JZ_FPGA + bool + +config JZSOC + bool + select JZRISC + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + +config JZRISC + bool + +#################################################### + config RWSEM_GENERIC_SPINLOCK bool default y @@ -1770,6 +1917,14 @@ source "kernel/time/Kconfig" +# the value of (max order + 1) +config FORCE_MAX_ZONEORDER + prompt "MAX_ZONEORDER" + int + default "12" + help + The max memory that can be allocated = 4KB * 2^(CONFIG_FORCE_MAX_ZONEORDER - 1) + # # Timer Interrupt Frequency Configuration # @@ -2046,6 +2201,23 @@ endmenu +menu "CPU Frequency scaling" + +config CPU_FREQ_JZ + tristate "CPUfreq driver for JZ CPUs" + depends on JZSOC + default n + help + This enables the CPUfreq driver for JZ CPUs. + + If in doubt, say N. + +if (CPU_FREQ_JZ) +source "drivers/cpufreq/Kconfig" +endif + +endmenu + menu "Power management options" source "kernel/power/Kconfig" diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/kernel/cpu-probe.c linux-2.6.24.3-20100304/arch/mips/kernel/cpu-probe.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/kernel/cpu-probe.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/kernel/cpu-probe.c 2010-03-03 19:05:04.000000000 -0800 @@ -160,6 +160,7 @@ case CPU_25KF: case CPU_PR4450: case CPU_BCM3302: + case CPU_JZRISC: cpu_wait = r4k_wait; break; @@ -802,6 +803,22 @@ } } +static inline void cpu_probe_ingenic(struct cpuinfo_mips *c) +{ + decode_configs(c); + c->options &= ~MIPS_CPU_COUNTER; /* JZRISC does not implement the CP0 counter. */ + switch (c->processor_id & 0xff00) { + case PRID_IMP_JZRISC: + c->cputype = CPU_JZRISC; + c->isa_level = MIPS_CPU_ISA_M32R1; + c->tlbsize = 32; + break; + default: + panic("Unknown Ingenic Processor ID!"); + break; + } +} + const char *__cpu_name[NR_CPUS]; /* @@ -880,6 +897,7 @@ case CPU_BCM4710: name = "Broadcom BCM4710"; break; case CPU_PR4450: name = "Philips PR4450"; break; case CPU_LOONGSON2: name = "ICT Loongson-2"; break; + case CPU_JZRISC: name = "Ingenic JZRISC"; break; default: BUG(); } @@ -919,6 +937,10 @@ case PRID_COMP_PHILIPS: cpu_probe_philips(c); break; + case PRID_COMP_INGENIC: + case 0xd80000: // used on fpga + cpu_probe_ingenic(c); + break; default: c->cputype = CPU_UNKNOWN; } diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/kernel/entry.S linux-2.6.24.3-20100304/arch/mips/kernel/entry.S --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/kernel/entry.S 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/kernel/entry.S 2010-03-03 19:05:04.000000000 -0800 @@ -38,6 +38,11 @@ FEXPORT(__ret_from_irq) LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER + bnez t0, resume_userspace + nop + LONG_L t0, PT_STATUS(sp) # returning to kernel mode? + srl t0, t0, 27 + andi t0, t0, 1 beqz t0, resume_kernel resume_userspace: diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/Makefile linux-2.6.24.3-20100304/arch/mips/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/Makefile 2010-03-03 19:05:06.000000000 -0800 @@ -159,6 +159,45 @@ # # +# Commond Ingenic JZ4730 series +# +core-$(CONFIG_SOC_JZ4730) += arch/mips/jz4730/ +cflags-$(CONFIG_SOC_JZ4730) += -Iinclude/asm-mips/mach-jz4730 +load-$(CONFIG_SOC_JZ4730) += 0xffffffff80010000 + +# +# Commond Ingenic JZ4740 series +# + +core-$(CONFIG_SOC_JZ4740) += arch/mips/jz4740/ +cflags-$(CONFIG_SOC_JZ4740) += -Iinclude/asm-mips/mach-jz4740 +load-$(CONFIG_SOC_JZ4740) += 0xffffffff80010000 + +# +# Commond Ingenic JZ4750 series +# + +core-$(CONFIG_SOC_JZ4750) += arch/mips/jz4750/ +cflags-$(CONFIG_SOC_JZ4750) += -Iinclude/asm-mips/mach-jz4750 +load-$(CONFIG_SOC_JZ4750) += 0xffffffff80010000 + +# +# Commond Ingenic JZ4750d series +# + +core-$(CONFIG_SOC_JZ4750D) += arch/mips/jz4750d/ +cflags-$(CONFIG_SOC_JZ4750D) += -Iinclude/asm-mips/mach-jz4750d +load-$(CONFIG_SOC_JZ4750D) += 0xffffffff80010000 + +# +# Commond Ingenic JZ4750L series +# + +core-$(CONFIG_SOC_JZ4750L) += arch/mips/jz4750l/ +cflags-$(CONFIG_SOC_JZ4750L) += -Iinclude/asm-mips/mach-jz4750l +load-$(CONFIG_SOC_JZ4750L) += 0xffffffff80010000 + +# # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. # core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/ @@ -670,6 +709,12 @@ all: $(all-y) +uImage: $(vmlinux-32) + +@$(call makeboot,$@) + +zImage: $(vmlinux-32) + +@$(call makeboot,$@) + vmlinux.bin: $(vmlinux-32) +@$(call makeboot,$@) @@ -694,12 +739,13 @@ archclean: @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/boot/compressed @$(MAKE) $(clean)=arch/mips/lasat define archhelp - echo ' vmlinux.ecoff - ECOFF boot image' - echo ' vmlinux.bin - Raw binary boot image' - echo ' vmlinux.srec - SREC boot image' + echo ' uImage - u-boot format image (arch/$(ARCH)/boot/uImage)' + echo ' zImage - Compressed binary image (arch/$(ARCH)/boot/compressed/zImage)' + echo ' vmlinux.bin - Uncompressed binary image (arch/$(ARCH)/boot/vmlinux.bin)' echo echo ' These will be default as apropriate for a configured platform.' endef diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/cache.c linux-2.6.24.3-20100304/arch/mips/mm/cache.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/cache.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/mm/cache.c 2010-03-03 19:05:08.000000000 -0800 @@ -47,6 +47,8 @@ void (*_dma_cache_inv)(unsigned long start, unsigned long size); EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); #endif /* CONFIG_DMA_NONCOHERENT */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/c-r4k.c linux-2.6.24.3-20100304/arch/mips/mm/c-r4k.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/c-r4k.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/mm/c-r4k.c 2010-03-03 19:05:08.000000000 -0800 @@ -874,6 +874,36 @@ c->dcache.waybit = 0; break; + case CPU_JZRISC: + config1 = read_c0_config1(); + config1 = (config1 >> 22) & 0x07; + if (config1 == 0x07) + config1 = 10; + else + config1 = config1 + 11; + config1 += 2; + icache_size = (1 << config1); + c->icache.linesz = 32; + c->icache.ways = 4; + c->icache.waybit = __ffs(icache_size / c->icache.ways); + + config1 = read_c0_config1(); + config1 = (config1 >> 13) & 0x07; + if (config1 == 0x07) + config1 = 10; + else + config1 = config1 + 11; + config1 += 2; + dcache_size = (1 << config1); + c->dcache.linesz = 32; + c->dcache.ways = 4; + c->dcache.waybit = __ffs(dcache_size / c->dcache.ways); + + c->dcache.flags = 0; + c->options |= MIPS_CPU_PREFETCH; + + break; + default: if (!(config & MIPS_CONF_M)) panic("Don't know how to probe P-caches on this cpu."); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/tlbex.c linux-2.6.24.3-20100304/arch/mips/mm/tlbex.c --- /home/stdev/development/source/02os/linux-2.6.24.3/arch/mips/mm/tlbex.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/arch/mips/mm/tlbex.c 2010-03-03 19:05:08.000000000 -0800 @@ -981,6 +981,11 @@ tlbw(p); break; + case CPU_JZRISC: + tlbw(p); + i_nop(p); + break; + default: panic("No TLB refill handler yet (CPU type: %d)", current_cpu_data.cputype); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/Changelog linux-2.6.24.3-20100304/Changelog --- /home/stdev/development/source/02os/linux-2.6.24.3/Changelog 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/Changelog 2010-03-03 19:05:42.000000000 -0800 @@ -0,0 +1,426 @@ +2009.04.22 +* Which mode a partition works with, cpu mode or dma mode, could be determined by the + value of cpu_mode in partition_info[] in drivers/mtd/nand/jz47xx_nand.c + Update Files: + include/linux/mtd/partitions.h + include/mtd/mtd-abi.h + include/asm-mips/mach-jz4750/ops.h + drivers/mtd/nand/jz4750_nand.c + drivers/mtd/nand/nand_base.c + drivers/mtd/mtdpart.c + drivers/mtd/mtdcore.c + +* Vmalloc instead of kmalloc a block cache for mtdblock-jz when the partition works + in cpu mode. + Update Files: + drivers/mtd/mtdblock-jz.c + + +2009.04.17 +* Allocate a block cache for every partitions which works over mtdblock-jz early + in nand_base.c if CONFIG_ALLOCATE_MTDBLOCK_JZ_ERALY defined. + Update Files: + drivers/mtd/nand/nand_base.c + drivers/mtd/mtdblock-jz.c + drivers/mtd/nand/jz4740_nand.c + drivers/mtd/nand/jz4750_nand.c + +* The eccpos in nand_oob_64 was changed to 24 when using 4-bit BCH to conform with + the eccpos of nand_oob_128 when using 8-bit BCH. + Update Files: + drivers/mtd/nand/nand_base.c + +* set CONFIG_PREEMPT_NONE=y to make the speed of UDC using NAND highly. And set + CONFIG_MTD_HW_BCH_8BIT=y for 4KB pagesize NAND. + Update Files: + arch/mips/configs/apus_defconfig + + + +2009.04.11 +* Whether a partition works over mtdblock-jz or not could be determined by the + value of mtdblock_jz_invalid in partition_info[] in drivers/mtd/nand/jz47xx_nand.c + + Update Files: + drivers/mtd/nand/jz4740_nand.c + drivers/mtd/nand/jz4750_nand.c + include/linux/mtd/partitions.h + include/mtd/mtd-abi.h + drivers/mtd/mtdpart.c + drivers/mtd/mtdblock-jz.c + + +2009.03.30 +* Set ECCPOS of 4K page nand to 28. (For 4750, only set 4bit BCH ECCPOS to 28) + Modify nand partitions of PAVO & APUS. + + Update Files: + drivers/mtd/nand/nand_base.c + drivers/mtd/nand/jz4740_nand.c + drivers/mtd/nand/jz4750_nand.c + + +2009.02.17 +* Modify oss driver to support jz4750 i2s codec. + Update Files: + sound/oss/Kconfig + sound/oss/Makefile + sound/oss/jz_i2s.c + Add Files: + sound/oss/jzdlv.h + sound/oss/jzdlv.c + +2008.12.08 +* Power management is supported for jz4750. + Update Files: + arch/mips/jz4750/pm.c + drivers/char/jzchar/poweroff.c + +2008.12.04 +* Whether NAND multiple planes operation for one partition is used or not could be + determined by the value of use_planes in partition_info[] in drivers/mtd/nand/jz47xx_nand.c + Updated files: + include/linux/mtd/partitions.h + drivers/mtd/nand/nand_base.c + drivers/mtd/nand/jz4740_nand.c + drivers/mtd/mtdpart.c +* Supported 4KB page size nand with 2 planes + Update Files: + include/linux/mtd/nand.h + drivers/mtd/nand/nand_base.c + fs/yaffs2/utils/mkyaffs2image.c + drivers/mtd/mtd-utils/nandwrite_mlc.c + + +2008.11.07 +* The ubi was modified to support MTD of 64bit. + Updated file: + drivers/mtd/ubi/io.c +* The ubi and ubifs were modified by changing vmalloc and vfree to kmalloc and kfree + to provide DMA buffer for NAND driver. But the NAND driver will use DMA buffer in + itself instead of in ubi and ubifs when CONFIG_MTD_NAND_DMABUF is defined. + Updated files: + drivers/mtd/ubi/build.c + drivers/mtd/ubi/cdev.c + drivers/mtd/ubi/gluebi.c + drivers/mtd/ubi/misc.c + drivers/mtd/ubi/scan.c + drivers/mtd/ubi/ubiblk.c + drivers/mtd/ubi/upd.c + drivers/mtd/ubi/vtbl.c + fs/ubifs/build.c + fs/ubifs/log.c + fs/ubifs/lpt.c + fs/ubifs/lpt_commit.c + fs/ubifs/orphan.c + fs/ubifs/recovery.c + fs/ubifs/replay.c + fs/ubifs/super.c + + +2008.10.31 +* Converted MTD from 32bit to 64bit to support the NAND larger than 4GB, and yaffs2 was + modified accordingly. + Updated file: + include/mtd/mtd-abi.h + include/linux/mtd/mtd.h + include/linux/mtd/partitions.h + include/linux/mtd/nand.h + drivers/mtd/mtdcore.c + drivers/mtd/mtdchar.c + drivers/mtd/mtdpart.c + drivers/mtd/mtdblock-jz.c + drivers/mtd/nand/nand_base.c + drivers/mtd/nand/nand_bbt.c + drivers/mtd/mtd-utils/include/mtd/mtd-abi.h + drivers/mtd/mtd-utils/flash_eraseall.c + drivers/mtd/mtd-utils/nandwrite_mlc.c + drivers/mtd/mtd-utils/nandwrite.c + fs/yaffs2/yaffs_fs.c + fs/yaffs2/yaffs_mtdif.c + fs/yaffs2/yaffs_mtdif2.c + +2008.10.29 +* Modified yaffs2 utils mkyaffs2image to support writting 4KB pagesize NAND. NAND layout + is (0 - raw(512B pagesize), 1 - nand_oob_64(2KB pagesize), 2 - nand_oob_128(4KB pagesize)). + + Updated file: + fs/yaffs2/utils/mkyaffs2image.c + +2008.10.27 +* Supported multiply chip selecting for NAND flash. + Updated files: + include/linux/mtd/nand.h + drivers/mtd/nand/nand_base.c + drivers/mtd/nand/jz4750_nand.c + drivers/mtd/nand/jz4740_nand.c + +2008.10.23 +* Modified yaffs2 utils mkyaffs2image to enable writing soft reed-solomn ECC for + yaffs2 file system information in oob area of MLC nand, getting CONFIG_YAFFS_ECC_RS + from .config, so when CONFIG_YAFFS_ECC_RS is changed, mkyaffs2image should be built + again. + Updated files: + fs/yaffs2/yaffs_ecc.c + fs/yaffs2/utils/Makefile + Added files: + fs/yaffs2/utils/ssfdc_rs_ecc.c + fs/yaffs2/utils/ssfdc_rs_ecc.h + +2008.09.26 + +* Fixed a fatal bug for mplayer, which may cause some files cannot be played and + the system is crashed. + Updated file: arch/mips/jz4740/proc.c + +2008.08.30 +* For jz4750, DMA clock for each channel should be enabled before using the channel. + So REG_DMAC_DMACKE and __dmac_channel_enable_clk(n) were added. + Updated files: + include/asm-mips/mach-jz4750/regs.h + include/asm-mips/mach-jz4750/ops.h + Regen, + +2008.08.19 +* Modify jzfb_mmap() for cacheable framebuffer access. + Updated files: + drivers/video/jzlcd.c + drivers/video/jz4740_slcd.c + drivers/video/jz4750_lcd.c + +2008.08.15 +* Modify ipu interface to toggle PID of MPlayer in TLB. +* Modify OSS ioctl function to play movie with mono channel better. + Update Files: + arch/mips/jz4740/proc.c + sound/oss/jz_i2s.c + Richard Feng, + +2008.08.04 +* Check whether the free block is erased before erasing it, 'unsigned int' instead of + 'unsigned short' was used to store block number, and heap sort for lifetime after + erasing a block was replaced by another faster method. + Update File: + drivers/mtd/mtdblock-jz.uu + +* Cache read was used in nand_read_page_hwecc_rs() for Jz4740. + Update File: + drivers/mtd/nand/nand_base.c + +* Faster timing in REG_EMC_SMCR1 whose value is 0x09221200 was used. + Update File: + drivers/mtd/nand/jz4740_nand.c + + Regen, + +2008.07.21 +* Supported 4KB page size nand + Update File: + drivers/mtd/nand/nand_base.c + include/linux/mtd/nand.h + include/mtd/mtd-abi.h + drivers/mtd/mtd-utils/include/mtd/mtd-abi.h + Regen, + +2008.07.18 +* Soft reed solomon ECC was supported for yaffs2 information which is 16 bytes in nand + oob, and it should be used for MLC nand. + Update File: + fs/yaffs2/yaffs_ecc.c + fs/yaffs2/yaffs_ecc.h + fs/yaffs2/yaffs_fs.c + fs/yaffs2/yaffs_packedtags2.c + Regen, + +2008.07.10 +* Added support to generate any frequency baud rate of uart for both Jz4740 and Jz4750. + Update File: + drivers/serial/8250.c + Regen, + +2008.07.03 +* Modified Jz4750's INTC, CIM, TSSI, macros. + Update Files: + include/asm-mips/mach-jz4750/regs.h + include/asm-mips/mach-jz4750/ops.h + +2008.06.24 +* Combined Jz4750 SLCD Controller support into drivers/video/jz4750_lcd.c. +* drivers/video/jz4750_lcd.c, now support: LCD Controller, Slcd Controller, TVE. +* And add smart lcd panel TRULY_TFT_GG1P0319LTSW_W support. + Update Files: + drivers/video/Kconfig + drivers/video/jz4750_lcd.h + drivers/video/jz4750_lcd.c + Wolfgang Wang, + +2008.06.20 +* Add Jz4750 LCDC and TVE driver. + Update Files: + arch/asm-mips/mach-jz4750/regs.h + arch/asm-mips/mach-jz4750/ops.h + drivers/video/Kconfig + drivers/video/Makefile + Add Files: + drivers/video/jz4750_lcd.h + drivers/video/jz4750_lcd.c + drivers/video/jz4750_tve.h + drivers/video/jz4750_tve.c + +2008.06.12 +* Modified CONFIG_FB_JZXXX macros, rename drivers/video/jzslcd.x to drivers/video/jz4740_slcd.x + Update Files: + drivers/video/Kconfig + drivers/video/Makefile + arch/mips/configs/dipper_defconfig + arch/mips/configs/leo_defconfig + arch/mips/configs/lyra_defconfig + arch/mips/configs/pavo_defconfig + arch/mips/configs/virgo_defconfig + + +2008.06.10 +* Add jz_clocksource, upgrade the system time's accuracy from 10ms to about 1(or 2) us. + but the system timer remained 10ms. + Files modified: + arch/mips/jz4730/time.c + arch/mips/jz4740/time.c + arch/mips/jz4750/time.c + + +2008.05.31 + +* Updated UBIFS. + +2008.05.30 + +* Added JZ4720 virgo board support. + +2008.05.29 + +* Added definition of CONFIG_SOC_JZ4725 and CONFIG_SOC_JZ4720. +* Added selection of 4-bit/1-bit data bus for MMC/SD card driver. +* Added dipper_defconfig for JZ4725 DIPPER board. + +2008.05.29: + +* Modified sound/oss/jz_i2s.c to increase the sound buffer. +* Modified pavo_defconfig to select the oss sound driver by default. +* Fixed jzlcd.h for jz4730 pmp. +* Modified jzcs8900a.c to not test the chip ID. + +2008.05.22: + +* jzcs8900a.c: fixed the bug of "No network devices available". + +2008.05.13: + +* Rewrote all of the UBI and UBIFS codes. + +2008.05.07: +* Add GPIO group E group F irq, DMAC1 irq. Add SSI1 macros. + + +2008.05.06: + +* Modified MMC/SD driver jz_mmc.c to support PM callback. + +2008.05.04: + +* Fixed a bug of mtdblock-jz.uu of using the badblock_table. + +2008.04.26: + +* Patch jz4740_nand.c to optimize the RS correction algorithm. + +2008.04.24 +* Jzlcd driver add Framebuffer Rotate support. + Update files: + drivers/video/Kconfig + drivers/video/jzlcd.h + drivers/video/jzlcd.c + + +2008.04.21: +* Modified LCD_CFG_MODE_INTER_CCIR656 define + #define LCD_CFG_MODE_INTER_CCIR656 (5 << LCD_CFG_MODE_BIT) + should be ==>> + #define LCD_CFG_MODE_INTER_CCIR656 (6 << LCD_CFG_MODE_BIT) + Update files: + include/asm-mips/mach-jz4730/regs.h + include/asm-mips/mach-jz4740/regs.h + include/asm-mips/mach-jz4750/regs.h + +2008.04.14: + +* Modify drivers/video/jzslcd.c to suport Smart LCD switches between + always refresh and event-driven refresh . + +2008.04.01: + +* Support multi-framebuffers, update files: + drivers/video/Kconfig, add: CONFIG_JZLCD_FRAMEBUFFER_MAX=1 + drivers/video/jzlcd.h + drivers/video/jzlcd.c + arch/mips/configs/pavo_defconfig, add: CONFIG_JZLCD_FRAMEBUFFER_MAX=1 + + +2008.03.29: + +* Modified sound/soc/jz4740/jz4740-i2s.c to support 32KHz PCM sample. + +2008.03.28 + +* Ported new mtd-utils and mkfs.ubifs. + +2008.03.27 + +* board_fuwa.h, change GPIO_DISP_OFF_N to GPD25. +* Added lyra_defconfig for JZ4740 LYRA (MP4) board. + +2008.03.24: + +* Added jzslcd.c for Smart LCD framebuffer driver. +* Modified rtc_jz.c to use some functions in rtc library instead of our function. + +* Added jz_keypad.c and gpio_keys.c for scan keypad drivers. + +2008.03.19: + +* Added block-jz.c to support block device layer on top of ubi. + + +2008.03.17: + +* Modified jz4740_udc.c to enable the suspend irq when host unloads us. + +* pavo_defconfig: select CONFIG_WIRELESS_EXT, CONFIG_PNP and CONFIG_SERIAL_8250_PNP. + + +2008.03.14: + +* Modified jz_ts.c jz_ts.h and sadc.c to release CPU by interrupt mode instead of pio mode. + + +2008.03.13: + +* Fixed a bug in jz4740_udc.c and jz4730_udc.c during rmmod the driver. + + +2008.03.10: + +* Modified jz_i2s.c to fix the jz_audio_release(). + +2008.03.08: + +* Fixed udc_hotplug.c to avoid the "unexpected IRQ". +* Fixed jz4740/cpufreq.c of calculating the new_mclk. + +2008.03.05: + +* Modified drivers/video/console/fbcon.c by adding fb_flashcursor selection. + + +2008.03.04: + +* Initial release. diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/crypto/Kconfig linux-2.6.24.3-20100304/crypto/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/crypto/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/crypto/Kconfig 2010-03-03 19:05:42.000000000 -0800 @@ -502,6 +502,14 @@ Authenc: Combined mode wrapper for IPsec. This is required for IPSec. +config CRYPTO_LZO + tristate "LZO compression algorithm" + select CRYPTO_ALGAPI + select LZO_COMPRESS + select LZO_DECOMPRESS + help + This is the LZO algorithm. + source "drivers/crypto/Kconfig" endif # if CRYPTO diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/crypto/lzo.c linux-2.6.24.3-20100304/crypto/lzo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/crypto/lzo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/crypto/lzo.c 2010-03-03 19:05:42.000000000 -0800 @@ -0,0 +1,106 @@ +/* + * Cryptographic API. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include + +struct lzo_ctx { + void *lzo_comp_mem; +}; + +static int lzo_init(struct crypto_tfm *tfm) +{ + struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS); + if (!ctx->lzo_comp_mem) + return -ENOMEM; + + return 0; +} + +static void lzo_exit(struct crypto_tfm *tfm) +{ + struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); + + vfree(ctx->lzo_comp_mem); +} + +static int lzo_compress(struct crypto_tfm *tfm, const u8 *src, + unsigned int slen, u8 *dst, unsigned int *dlen) +{ + struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); + size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ + int err; + + err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx->lzo_comp_mem); + + if (err != LZO_E_OK) + return -EINVAL; + + *dlen = tmp_len; + return 0; +} + +static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src, + unsigned int slen, u8 *dst, unsigned int *dlen) +{ + int err; + size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ + + err = lzo1x_decompress_safe(src, slen, dst, &tmp_len); + + if (err != LZO_E_OK) + return -EINVAL; + + *dlen = tmp_len; + return 0; + +} + +static struct crypto_alg alg = { + .cra_name = "lzo", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_ctxsize = sizeof(struct lzo_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_init = lzo_init, + .cra_exit = lzo_exit, + .cra_u = { .compress = { + .coa_compress = lzo_compress, + .coa_decompress = lzo_decompress } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LZO Compression Algorithm"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/crypto/Makefile linux-2.6.24.3-20100304/crypto/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/crypto/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/crypto/Makefile 2010-03-03 19:05:42.000000000 -0800 @@ -51,6 +51,7 @@ obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o +obj-$(CONFIG_CRYPTO_LZO) += lzo.o obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/crypto/tcrypt.c linux-2.6.24.3-20100304/crypto/tcrypt.c --- /home/stdev/development/source/02os/linux-2.6.24.3/crypto/tcrypt.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/crypto/tcrypt.c 2010-03-03 19:05:42.000000000 -0800 @@ -78,7 +78,7 @@ "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", "seed", NULL + "camellia", "seed", "lzo", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -800,7 +800,8 @@ crypto_free_hash(tfm); } -static void test_deflate(void) +static void test_comp(char *algo, struct comp_testvec *ctemplate, + struct comp_testvec *dtemplate, int ctcount, int dtcount) { unsigned int i; char result[COMP_BUF_SIZE]; @@ -808,25 +809,26 @@ struct comp_testvec *tv; unsigned int tsize; - printk("\ntesting deflate compression\n"); + printk("\ntesting %s compression\n", algo); - tsize = sizeof (deflate_comp_tv_template); + tsize = sizeof(struct comp_testvec); + tsize *= ctcount; if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } - memcpy(tvmem, deflate_comp_tv_template, tsize); + memcpy(tvmem, ctemplate, tsize); tv = (void *)tvmem; - tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { - printk("failed to load transform for deflate\n"); + printk("failed to load transform for %s\n", algo); return; } - for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) { + for (i = 0; i < ctcount; i++) { int ilen, ret, dlen = COMP_BUF_SIZE; printk("test %u:\n", i + 1); @@ -845,19 +847,20 @@ ilen, dlen); } - printk("\ntesting deflate decompression\n"); + printk("\ntesting %s decompression\n", algo); - tsize = sizeof (deflate_decomp_tv_template); + tsize = sizeof(struct comp_testvec); + tsize *= dtcount; if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } - memcpy(tvmem, deflate_decomp_tv_template, tsize); + memcpy(tvmem, dtemplate, tsize); tv = (void *)tvmem; - for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) { + for (i = 0; i < dtcount; i++) { int ilen, ret, dlen = COMP_BUF_SIZE; printk("test %u:\n", i + 1); @@ -1057,7 +1060,11 @@ test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS); test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); - test_deflate(); + test_comp("deflate", deflate_comp_tv_template, + deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS, + DEFLATE_DECOMP_TEST_VECTORS); + test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template, + LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS); test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS); test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); @@ -1167,7 +1174,9 @@ break; case 13: - test_deflate(); + test_comp("deflate", deflate_comp_tv_template, + deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS, + DEFLATE_DECOMP_TEST_VECTORS); break; case 14: @@ -1292,6 +1301,11 @@ CAMELLIA_CBC_DEC_TEST_VECTORS); break; + case 33: + test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template, + LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS); + break; + case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/crypto/tcrypt.h linux-2.6.24.3-20100304/crypto/tcrypt.h --- /home/stdev/development/source/02os/linux-2.6.24.3/crypto/tcrypt.h 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/crypto/tcrypt.h 2010-03-03 19:05:42.000000000 -0800 @@ -4408,6 +4408,88 @@ }; /* + * LZO test vectors (null-terminated strings). + */ +#define LZO_COMP_TEST_VECTORS 2 +#define LZO_DECOMP_TEST_VECTORS 2 + +static struct comp_testvec lzo_comp_tv_template[] = { + { + .inlen = 70, + .outlen = 46, + .input = "Join us now and share the software " + "Join us now and share the software ", + .output = { 0x00, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x20, 0x75, + 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x70, 0x01, 0x01, 0x4a, 0x6f, 0x69, 0x6e, + 0x3d, 0x88, 0x00, 0x11, 0x00, 0x00 }, + }, { + .inlen = 159, + .outlen = 133, + .input = "This document describes a compression method based on the LZO " + "compression algorithm. This document defines the application of " + "the LZO algorithm used in UBIFS.", + .output = { 0x00, 0x2b, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x62, + 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x4c, 0x5a, 0x4f, 0x2b, + 0x8c, 0x00, 0x0d, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x20, 0x20, 0x54, + 0x68, 0x69, 0x73, 0x2a, 0x54, 0x01, 0x02, 0x66, + 0x69, 0x6e, 0x65, 0x73, 0x94, 0x06, 0x05, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x76, + 0x0a, 0x6f, 0x66, 0x88, 0x02, 0x60, 0x09, 0x27, + 0xf0, 0x00, 0x0c, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x55, 0x42, 0x49, 0x46, + 0x53, 0x2e, 0x11, 0x00, 0x00 }, + }, +}; + +static struct comp_testvec lzo_decomp_tv_template[] = { + { + .inlen = 133, + .outlen = 159, + .input = { 0x00, 0x2b, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x62, + 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x4c, 0x5a, 0x4f, 0x2b, + 0x8c, 0x00, 0x0d, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x20, 0x20, 0x54, + 0x68, 0x69, 0x73, 0x2a, 0x54, 0x01, 0x02, 0x66, + 0x69, 0x6e, 0x65, 0x73, 0x94, 0x06, 0x05, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x76, + 0x0a, 0x6f, 0x66, 0x88, 0x02, 0x60, 0x09, 0x27, + 0xf0, 0x00, 0x0c, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x55, 0x42, 0x49, 0x46, + 0x53, 0x2e, 0x11, 0x00, 0x00 }, + .output = "This document describes a compression method based on the LZO " + "compression algorithm. This document defines the application of " + "the LZO algorithm used in UBIFS.", + }, { + .inlen = 46, + .outlen = 70, + .input = { 0x00, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x20, 0x75, + 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x70, 0x01, 0x01, 0x4a, 0x6f, 0x69, 0x6e, + 0x3d, 0x88, 0x00, 0x11, 0x00, 0x00 }, + .output = "Join us now and share the software " + "Join us now and share the software ", + }, +}; + +/* * Michael MIC test vectors from IEEE 802.11i */ #define MICHAEL_MIC_TEST_VECTORS 6 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ak4182.c linux-2.6.24.3-20100304/drivers/char/jzchar/ak4182.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ak4182.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/ak4182.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,657 @@ +/* + * ak4182.c using national microwire protocol + * + * Touch screen driver interface to the AK4182A . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "jz_ts.h" +#include "ak4182.h" + +#define TS_PIN GPIO_TS_PENIRQ +#define TS_IRQ (IRQ_GPIO_0 + TS_PIN) + +static int samples = 5; +static int first_time = 0; +static unsigned long last_x, last_y, last_p; + +static int adcsync = 0; + +static struct ak4182 *ak; + +extern unsigned int (*codec_read_battery)(void); + +/*------------------JzSoc SSI configure----------------*/ +static void ak4182_ssi_reset(void) +{ + REG_SSI_CR0 = 0x0000; + REG_SSI_CR1 = 0x00007960; + REG_SSI_SR = 0x00000098; + REG_SSI_ITR = 0x0000; + REG_SSI_ICR = 0x00; + REG_SSI_GR = 0x0000; + + __ssi_disable(); + __ssi_flush_fifo(); + __ssi_clear_errors(); + __ssi_select_ce(); +} + +static void ak4182_ssi_enable(void) +{ + __ssi_enable(); +} + +#ifdef CONFIG_PM +static void ak4182_ssi_disable(void) +{ + __ssi_disable(); +} +#endif + +static void ak4182_ssi_set_trans_mode_format(void) +{ + __ssi_microwire_format(); + __ssi_set_msb(); + __ssi_set_microwire_command_length(8); + __ssi_set_frame_length(12); +} + +static void ak4182_ssi_set_clk_div_ratio(int dev_clk, int ssi_clk) +{ + __ssi_set_clk(dev_clk, ssi_clk); +} + +static void ak4182_ssi_set_normal_mode(void) +{ + __ssi_normal_mode(); +} + +static void ak4182_ssi_set_IRQ(void) +{ + __ssi_disable_tx_intr(); + __ssi_disable_rx_intr(); +} + +/*------------------ AK4182 routines ------------------*/ +static inline void ak4182_reg_write(unsigned short val) +{ + __ssi_transmit_data(val); +} + +static inline unsigned int ak4182_reg_read(void) +{ + unsigned int val; + val = __ssi_receive_data(); + return val; +} + +static unsigned int ak4182_adc_read(int cmd_code, int sync) +{ + unsigned int val, timeout = 10000; + unsigned int status,valid1,valid2,dataentry; + + ak4182_reg_write(cmd_code); + udelay(2);//wait 2 D_CLK + for (;;) { + status =0; + status = REG_SSI_SR; + valid1 = (status>>7) & 1; + valid2 = (status>>6) & 1; + if( valid1==1 && valid2==0 )//SSI transfer is finished + { + //Receive FIFO data entry number + dataentry = val = 0; + dataentry = (status>>8) & 0x1F; + if( dataentry > 5 ) + { + printk("R-FIFO entry=%d,SSI transfer is wrong!\n",dataentry); + while(dataentry > 0) + { + ak4182_reg_read(); + dataentry--; + } + return 0; + } + while(dataentry > 0) + { + val = ak4182_reg_read(); + dataentry--; + } + return val; + } + + if (--timeout == 0) + break; + udelay(1); + } + return 0; +} + + +//enable pen down IRQ +static void ak4182_enable_irq(void) +{ + unsigned long flags; + + spin_lock_irqsave(&ak->lock, flags); + __gpio_unmask_irq(TS_PIN); + spin_unlock_irqrestore(&ak->lock, flags); +} + +//disable pen down IRQ +static void ak4182_disable_irq(void) +{ + unsigned long flags; + + spin_lock_irqsave(&ak->lock, flags); + __gpio_mask_irq(TS_PIN); +// spin_unlock_irqrestore(&ucb->lock, flags); + spin_unlock_irqrestore(&ak->lock, flags); +} +/* + * Switch to X position mode and measure Y plate. We switch the plate + * configuration in pressure mode, then switch to position mode. This + * gives a faster response time. Even so, we need to wait about 55us + * for things to stabilise. + */ +static inline unsigned int ak4182_ts_read_xpos(void) +{ + return ak4182_adc_read(0xD0, adcsync);//X-axis,0xD0 for 12bit,0xD8 for 8bit +} + + +/* + * Switch to pressure mode, and read pressure. We don't need to wait + * here, since both plates are being driven. + */ +static inline unsigned int ak4182_ts_read_pressure(void) +{ + unsigned int z1,z2,xpos,pressureval=0;//300 Om + //Z1 pressure + z1 = ak4182_adc_read(0xB0, adcsync);//0xB0 for 12bit,0xB8 for 8bit + if(z1>0) + { + //Z2 pressure + z2 = ak4182_adc_read(0xC0, adcsync);//0xC0 for 12bit,0xC8 for 8bit + if(z2>z1) + { + xpos = ak4182_ts_read_xpos(); + pressureval = (300*xpos*(z2-z1))/(4096*z1); + } + } + + return pressureval; +} + + +/* + * Switch to Y position mode and measure X plate. We switch the plate + * configuration in pressure mode, then switch to position mode. This + * gives a faster response time. Even so, we need to wait about 55us + * for things to stabilise. + */ +static inline unsigned int ak4182_ts_read_ypos(void) +{ + return ak4182_adc_read(0x90, adcsync);//Y-axis,0x90 for 12bit,0x98 for 8bit +} + +/*------------------------------------------------------------ + * Read the battery voltage + */ + +unsigned int ak4182_read_battery(void) +{ + unsigned int v; + int bat_val[5]; + int total = 0, max_bat, min_bat; + + v = ak4182_adc_read(0xA7, adcsync); + v = ak4182_adc_read(0xA7, adcsync); + for(v = 0;v <= 4;v++) + bat_val[v] = ak4182_adc_read(0xA7, adcsync); + + ak4182_adc_read(0xA4, adcsync); + max_bat = min_bat = bat_val[0]; + for(v = 0;v <= 4;v++) { + total += bat_val[v]; + if(bat_val[v] > max_bat) + max_bat = bat_val[v]; + if(bat_val[v] < min_bat) + min_bat = bat_val[v]; + } + total = total - max_bat - min_bat; + v = total / 3; + return v; +} + +/*------------------ Calibrate samples -------------------*/ + +#define DIFF(a,b) ((a>b)?(a-b):(b-a)) + +static int calibrate_samples(void *xbuf, void *ybuf, void *pbuf, int count) +{ + unsigned long *xp = (unsigned long *)xbuf; + unsigned long *yp = (unsigned long *)ybuf; + unsigned long *pp = (unsigned long *)pbuf; + unsigned long x_cal = 0, y_cal = 0, p_cal = 0, tmp; + int ignored, i, j; + int valid = 0; + + /* throw away the max cases */ + tmp = xp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (xp[i] > tmp) { + tmp = xp[i]; + ignored = i; + } + }//find the max val + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + xp[j++] = xp[i]; + }//shift val and delete the max val + + tmp = yp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (yp[i] > tmp) { + tmp = yp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + yp[j++] = yp[i]; + } + + tmp = pp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (pp[i] > tmp) { + tmp = pp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + pp[j++] = pp[i]; + } + + /* throw away the min cases */ + + count -= 1; // decrement by 1 + + tmp = xp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (xp[i] < tmp) { + tmp = xp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + xp[j++] = xp[i]; + } + + tmp = yp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (yp[i] < tmp) { + tmp = yp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + yp[j++] = yp[i]; + } + + tmp = pp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (pp[i] < tmp) { + tmp = pp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + pp[j++] = pp[i]; + } + + count -= 1; // decrement by 1 + + /* calculate the average of the rest */ + for (i = 0; i < count; i++) { + x_cal += xp[i]; + y_cal += yp[i]; + p_cal += pp[i]; + } + x_cal /= count; + y_cal /= count; + p_cal /= count; + + if (first_time) { + first_time = 0; + last_x = x_cal; + last_y = y_cal; + last_p = p_cal; + valid = 1; + } + else { + if ((DIFF(x_cal, last_x) > 100) || + (DIFF(y_cal, last_y) > 100)) + valid = 0; + else + valid = 1; + } + + //printk("x_cal=%d y_cal=%d p_cal=%d valid=%d\n", x_cal, y_cal, p_cal, valid); + + if (valid) { + *xp = last_x = x_cal; + *yp = last_y = y_cal; + *pp = last_p = p_cal; + } + + return valid; +} + + +#define TSMAXX 945 +#define TSMAXY 830 +#define TSMINX 90 +#define TSMINY 105 + +#define SCREEN_X 480 +#define SCREEN_Y 272 + +static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x ) +{ + + if (ts->minx) + { + if (x < ts->minx) x = ts->minx; + if (x > ts->maxx) x = ts->maxx; + + return (x - ts->minx) * SCREEN_X / (ts->maxx - ts->minx); + } + else + { + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return (x - TSMINX) * SCREEN_X / (TSMAXX - TSMINX); + } +} + +static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y) +{ + if (ts->miny) + { + if (y < ts->miny) y = ts->miny; + if (y > ts->maxy) y = ts->maxy; + + return (y - ts->miny) * SCREEN_Y / (ts->maxy - ts->miny); + } + else + { + if (y < TSMINY) y = TSMINY; + if (y > TSMAXY) y = TSMAXY; + + return (y - TSMINY) * SCREEN_Y / (TSMAXY - TSMINY); + } +} + +/*------------------ Common routines -------------------*/ + +void ts_enable_irq(void) +{ + /* interrupt mode */ + ak4182_enable_irq(); + enable_irq(TS_IRQ); +} + +void ts_disable_irq(void) +{ + ak4182_disable_irq(); + disable_irq(TS_IRQ); +} + +int ts_request_irq(u32 *irq, + irqreturn_t (*handler)(int, void *), + const char *devname, + void *dev_id) +{ + int retval; + + /* return the irq number */ + *irq = TS_IRQ; + /* initializate ssi for AK4182 */ + ak4182_ssi_reset(); + ak4182_ssi_set_trans_mode_format(); + ak4182_ssi_set_normal_mode(); + ak4182_ssi_set_clk_div_ratio(JZ_EXTAL, 200*1000);//DCLK is 1.5M Hz max + ak4182_ssi_set_IRQ(); + + ak4182_enable_irq(); + + /* enable gpio irq */ + __gpio_as_irq_fall_edge(TS_PIN); + + /* register irq handler */ + retval = request_irq(TS_IRQ, handler, IRQF_DISABLED, devname, dev_id); + ak4182_ssi_enable(); + udelay(10); + return retval; +} + +void ts_free_irq(struct jz_ts_t *ts) +{ + free_irq(ts->pendown_irq, ts); + //Close SSI mode + ak4182_ssi_reset(); +} + +void ts_irq_callback(void) +{ + /* clear interrupt status */ + __gpio_ack_irq(TS_PIN); + first_time = 1; // first time to acquire sample +} + +int PenIsDown(void) +{ + unsigned int p; + p = ak4182_ts_read_pressure(); + return (p > 100) ? 1 : 0; +} + +/* + * Acquire Raw pen coodinate data and compute touch screen + * pressure resistance. Hold spinlock when calling. + */ +int AcquireEvent(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned int x_raw[8], y_raw[8], p_raw[8]; + int valid, i; + + for (i = 0; i < samples; i++) { + x_raw[i] = ak4182_ts_read_xpos(); + } + for (i = 0; i < samples; i++) { + y_raw[i] = ak4182_ts_read_ypos(); + } + for (i = 0; i < samples; i++) { + p_raw[i] = ak4182_ts_read_pressure(); + } + + valid = calibrate_samples(x_raw, y_raw, p_raw, samples); + + if (valid) { + unsigned int x_scr, y_scr; + + if(ts->filter) { + x_scr = transform_to_screen_x(ts, x_raw[0]); + y_scr = transform_to_screen_y(ts, y_raw[0]); + + if (ts->prints) + printk("filter:x_raw:%d,y_raw:%d,x_tran:%d,y_tran:%d\n", x_raw[0], y_raw[0], x_scr, y_scr); + } + else { + x_scr = x_raw[0]; + y_scr = y_raw[0]; + + if (ts->prints) + printk("no filter:x_raw=%d y_raw=%d \n", x_raw[0], y_raw[0]); + } + + event->x = x_scr; + event->y = y_scr; + event->pressure = (u16)p_raw[0]; + event->status = PENDOWN; + return 1; + } + return 0; +} + +#ifdef CONFIG_PM + +/* + * Suspend the Touch pad. + */ +static int ak4182_suspend(struct ak4182 *ak , int state) +{ + ak4182_ssi_disable(); + + return 0; +} + +/* + * Resume the Touch panel. + */ +static int ak4182_resume(struct ak4182 *ak) +{ + /* initializate ssi for AK4182 */ + ak4182_ssi_reset(); + ak4182_ssi_set_trans_mode_format(); + ak4182_ssi_set_normal_mode(); + ak4182_ssi_set_clk_div_ratio(JZ_EXTAL, 200*1000);//DCLK is 1.5M Hz max + ak4182_ssi_set_IRQ(); + + ak4182_enable_irq(); + + ak4182_ssi_enable(); + + return 0; +} + +static int ak4182_pm_callback(struct pm_dev *pm_dev, pm_request_t rqst, void *data) +{ + int ret; + struct ak4182 *akinfo = pm_dev->data; + + if (!akinfo) + return -EINVAL; + + + switch (rqst) { + case PM_SUSPEND: + ret = ak4182_suspend(akinfo, (int)data); + break; + + case PM_RESUME: + ret = ak4182_resume(akinfo); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +#endif /* CONFIG_PM */ + + +/* + * Module init and exit + */ + +int __init ak4182_init(void) +{ + ak = kmalloc(sizeof(struct ak4182), GFP_KERNEL); + if (!ak) return -ENOMEM; + + memset(ak, 0, sizeof(struct ak4182)); + + codec_read_battery = ak4182_read_battery; + + spin_lock_init(&ak->lock); + sema_init(&ak->adc_sem, 1); + + //initialize AK4182 register + __gpio_clear_pin(73); + __gpio_as_output(73); + mdelay(2); + __gpio_set_pin(73); + __gpio_as_ssi(); + + ak4182_read_battery(); + +#ifdef CONFIG_PM + ak->pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ak4182_pm_callback); + if (ak->pmdev) + { + ak->pmdev->data = ak; + } +#endif + + printk("AK4182 touch screen driver initialized\n"); + + return 0; +} + +void ak4182_cleanup(void) +{ +} + +module_init(ak4182_init); +module_exit(ak4182_cleanup); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ak4182.h linux-2.6.24.3-20100304/drivers/char/jzchar/ak4182.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ak4182.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/ak4182.h 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,16 @@ +#ifndef __AK4182_H__ +#define __AK4182_H__ + +/* Device data structure */ + +struct ak4182 { + spinlock_t lock; + struct pm_dev *pmdev; + struct semaphore adc_sem; + u16 adc_cr; + u16 irq_fal_enbl; + u16 irq_ris_enbl; + int irq_enabled; +}; + +#endif /* __AK4182_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ata2508.c linux-2.6.24.3-20100304/drivers/char/jzchar/ata2508.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ata2508.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/ata2508.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,227 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define MP4_KEY_RST (32*3+3) +#define MP4_KEY_TINT (32*3+2) +#define MP4_KEY_SCL (32*3+1) +#define MP4_KEY_SDA (32*3+0) +#define MP4_TINT_IRQ (IRQ_GPIO_0 + MP4_KEY_TINT) + +#define ADDR_WARM_RESET 0xFF +#define ATA2508_SENSOR_MASK 0x1F + +const unsigned char init_data_burst[] = {//Address:0x0D-0x3E + 0x04, // BETA + 0x27, // AIC_WAIT + //0x32, // REF_DELAY + 0x16, // REF_DELAY + 0x02, // HYSTERESIS01 + 0x02, // HYSTERESIS1 + 0x02, // HYSTERESIS2 + 0x02, // HYSTERESIS3 + 0x02, // HYSTERESIS4 + 0x02, // HYSTERESIS51 + 0x02, // HYSTERESIS61 + 0x02, // HYSTERESIS7 + 0x02, // HYSTERESIS8 + 0x02, // HYSTERESIS9 + 0x02, // HYSTERESIS10 + 0x02, // HYSTERESIS11 + 0x64, // STRENGTH_THRESHOLD0 + 0x64, // STRENGTH_THRESHOLD1 + 0x64, // STRENGTH_THRESHOLD2 + 0x64, // STRENGTH_THRESHOLD3 + 0x64, // STRENGTH_THRESHOLD4 + 0x64, // STRENGTH_THRESHOLD5 + 0x64, // STRENGTH_THRESHOLD6 + 0x64, // STRENGTH_THRESHOLD7 + 0x64, // STRENGTH_THRESHOLD8 + 0x64, // STRENGTH_THRESHOLD9 + 0x64, // STRENGTH_THRESHOLD10 + 0x64, // STRENGTH_THRESHOLD11 + 0x0f, // Sampling Interval + 0xC8, // INTEGRATION TIME + 0x0f, // IDLE TIME + 0x00, // SIF_SETUP(RESERVED) + 0x01, // MODE + 0x00, // GPIO_REG_L + 0x00, // GPIO_REG_H + 0x00, // GPIO_CONFIGURATION_L + 0x00, // GPIO_CONFIGURATION_H + 0x00, // GPIO_DIR_L + 0x00, // GPIO_DIR_H + 0x0c, // CONTROL + 0x38, // INT_MASK + 0x00, // INT_CLEAR + 0xFF, // INT_edge + 0x02, // CONTROL_2 + 0xAF, // BEEP_TIME + 0x7F, // BEEP_FREQUENCY + 0x30, // CALIBRATION INTERVAL + 0x00, // EINT_ENABLE + 0x00, // EINT_POL + 0x00, // FILTER_PERIOD + 0x00, // FILTER_THRESHOLD +}; +const unsigned char init_data_alpha[] = {//Address:0x00-0x0C + 0x02, // APIS + 0x08, // ALPHA0 + 0x08, // ALPHA1 + 0x08, // ALPHA2 + 0x08, // ALPHA3 + 0x08, // ALPHA4 + 0x28, // ALPHA5 + 0x28, // ALPHA6 + 0x28, // ALPHA7 + 0x28, // ALPHA8 + 0x28, // ALPHA9 + 0x28, // ALPHA10 + 0x28, // ALPHA11 +}; +static unsigned int i2c_addr = 0x58; +static unsigned int i2c_clk = 100000; + +static void write_reg(u8 reg, u8 val) +{ + int ret; + i2c_open(); + i2c_setclk(i2c_clk); + ret = i2c_write(i2c_addr, &val, reg, 1); + i2c_close(); +} + +static u8 read_reg(u8 reg) +{ + u8 val; + + i2c_open(); + i2c_setclk(i2c_clk); + i2c_read(i2c_addr, &val, reg, 1); + i2c_close(); + return val; +} + +/* + * Interrupt handler + */ +static irqreturn_t mp4_tint_irq(int irq, void *dev_id) +{ + int key_num = 0; + u8 value0, value1; + + __gpio_ack_irq(MP4_KEY_TINT); + value0 = read_reg(0x75); + value1 = read_reg(0x76); + value0 &= ATA2508_SENSOR_MASK; + if (value0 == 0) { + printk("\nRelease key!\n"); + return IRQ_HANDLED; + } + while(value0 >> 1){ + value0 >>= 1; + key_num++; + } + + printk("\nPress key %d!\n", key_num); + return IRQ_HANDLED; +} + +static int __init init_ata2508(void) +{ + int i; + unsigned char data1; + int retval; + + __gpio_as_output(MP4_KEY_RST); + __gpio_set_pin(MP4_KEY_RST); + mdelay(100); + __gpio_clear_pin(MP4_KEY_RST); + mdelay(800); + __gpio_set_pin(MP4_KEY_RST); + __gpio_mask_irq(MP4_KEY_TINT); + + /*write registers*/ + for(i=0; i<13; i++) + { + data1 = init_data_alpha[i]; + write_reg(i, data1); + } + + for(i=13; i<63; i++) + { + data1 = init_data_burst[i-13]; + write_reg(i, data1); + } +#if 0 + for (i = 0; i < 63; i++) + { + data1 = read_reg(i); + printk("REG0x%02x = 0x%02x\n", i, data1); + } +#endif + + /* wait for 1 ms*/ + mdelay(1); +#if 0 + while(1) + { + data1 = read_reg(0x68); + printk("REG0x68 = %d\n", data1); + data1 = read_reg(0x75); + printk("REG0x75 = 0x%02x\n", data1); + data1 = read_reg(0x76); + printk("REG0x76 = 0x%02x\n", data1); + mdelay(2000); + } +#endif + data1 = read_reg(0x68); + printk("REG0x68 = %d\n", data1); + + /* to activate all the new settings, give a WARM RESET.*/ + write_reg(ADDR_WARM_RESET, 0x00); //ADDR_WARM_RESET=0xFF + + //printk("REG0x68 = %d\n", data1); + + /* wait for 1 ~ 10 ms.*/ + mdelay(10); + data1 = read_reg(0x68); + + /* Enable INT that connected to ATA2508's TINT.*/ + __gpio_as_irq_rise_edge(MP4_KEY_TINT); + + retval = request_irq(MP4_TINT_IRQ, mp4_tint_irq, + IRQF_DISABLED, "mp4_key_tint", NULL); + if (retval) { + printk("Could not get mp4 key irq %d\n", MP4_TINT_IRQ); + return retval; + } + + printk("MP4 touch panel register!\n"); + + return 0; +} + +static void __exit exit_ata2508(void) +{ + free_irq(MP4_TINT_IRQ, NULL); +} + +module_init(init_ata2508); +module_exit(exit_ata2508); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/cim.c linux-2.6.24.3-20100304/drivers/char/jzchar/cim.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/cim.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/cim.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,366 @@ +/* + * linux/drivers/char/jzchar/cim.c + * + * Camera Interface Module (CIM) driver for JzSOC + * This driver is independent of the camera sensor + * + * Copyright (C) 2005 JunZheng semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jzchars.h" + +#define CIM_NAME "cim" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("JzSOC Camera Interface Module driver"); +MODULE_LICENSE("GPL"); + +/* + * Define the Max Image Size + */ +#define MAX_IMAGE_WIDTH 640 +#define MAX_IMAGE_HEIGHT 480 +#define MAX_IMAGE_BPP 16 +#define MAX_FRAME_SIZE (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * MAX_IMAGE_BPP / 8) + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} img_param_t; + +typedef struct +{ + u32 cfg; + u32 ctrl; + u32 mclk; +} cim_config_t; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: img_param_t * +#define IOCTL_CIM_CONFIG 1 // arg type: cim_config_t * + +/* Actual image size, must less than max values */ +static int img_width = MAX_IMAGE_WIDTH, img_height = MAX_IMAGE_HEIGHT, img_bpp = MAX_IMAGE_BPP; + +/* + * CIM DMA descriptor + */ +struct cim_desc { + u32 nextdesc; /* Physical address of next desc */ + u32 framebuf; /* Physical address of frame buffer */ + u32 frameid; /* Frame ID */ + u32 dmacmd; /* DMA command */ +}; + +/* + * CIM device structure + */ +struct cim_device { + unsigned char *framebuf; + unsigned int frame_size; + unsigned int page_order; + wait_queue_head_t wait_queue; + struct cim_desc frame_desc __attribute__ ((aligned (16))); +}; + +// global +static struct cim_device *cim_dev; + +/*========================================================================== + * CIM init routines + *========================================================================*/ + +static void cim_config(cim_config_t *c) +{ + REG_CIM_CFG = c->cfg; + REG_CIM_CTRL = c->ctrl; + // Set the master clock output +#if defined(CONFIG_SOC_JZ4730) + __cim_set_master_clk(__cpm_get_sclk(), c->mclk); +#elif defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750) + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#else + __cim_set_master_clk(__cpm_get_sclk(), c->mclk); +#endif + // Enable sof, eof and stop interrupts + __cim_enable_sof_intr(); + __cim_enable_eof_intr(); + __cim_enable_stop_intr(); +} + +/*========================================================================== + * CIM start/stop operations + *========================================================================*/ + +static int cim_start_dma(char *ubuf) +{ + __cim_disable(); + + dma_cache_wback((unsigned long)cim_dev->framebuf, (2 ^ (cim_dev->page_order)) * 4096); + + // set the desc addr + __cim_set_da(virt_to_phys(&(cim_dev->frame_desc))); + + __cim_clear_state(); // clear state register + __cim_reset_rxfifo(); // resetting rxfifo + __cim_unreset_rxfifo(); + __cim_enable_dma(); // enable dma + + // start + __cim_enable(); + + // wait for interrupts + interruptible_sleep_on(&cim_dev->wait_queue); + + // copy frame data to user buffer + memcpy(ubuf, cim_dev->framebuf, cim_dev->frame_size); + + return cim_dev->frame_size; +} + +static void cim_stop(void) +{ + __cim_disable(); + __cim_clear_state(); +} + +/*========================================================================== + * Framebuffer allocation and destroy + *========================================================================*/ + +static void cim_fb_destroy(void) +{ + if (cim_dev->framebuf) { + free_pages((unsigned long)(cim_dev->framebuf), cim_dev->page_order); + cim_dev->framebuf = NULL; + } +} + +static int cim_fb_alloc(void) +{ + cim_dev->frame_size = img_width * img_height * (img_bpp/8); + cim_dev->page_order = get_order(cim_dev->frame_size); + + /* frame buffer */ + cim_dev->framebuf = (unsigned char *)__get_free_pages(GFP_KERNEL, cim_dev->page_order); + if ( !(cim_dev->framebuf) ) { + return -ENOMEM; + } + + cim_dev->frame_desc.nextdesc = virt_to_phys(&(cim_dev->frame_desc)); + cim_dev->frame_desc.framebuf = virt_to_phys(cim_dev->framebuf); + cim_dev->frame_desc.frameid = 0x52052018; + cim_dev->frame_desc.dmacmd = CIM_CMD_EOFINT | CIM_CMD_STOP | (cim_dev->frame_size >> 2); // stop after capturing a frame + + dma_cache_wback((unsigned long)(&(cim_dev->frame_desc)), 16); + + return 0; +} + +/*========================================================================== + * File operations + *========================================================================*/ + +static int cim_open(struct inode *inode, struct file *filp); +static int cim_release(struct inode *inode, struct file *filp); +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); + +static struct file_operations cim_fops = +{ + open: cim_open, + release: cim_release, + read: cim_read, + write: cim_write, + ioctl: cim_ioctl +}; + +static int cim_open(struct inode *inode, struct file *filp) +{ + try_module_get(THIS_MODULE); + return 0; +} + +static int cim_release(struct inode *inode, struct file *filp) +{ + cim_stop(); + + module_put(THIS_MODULE); + return 0; +} + +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + if (size < cim_dev->frame_size) + return -EINVAL; + + return cim_start_dma(buf); +} + +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("cim error: write is not implemented\n"); + return -1; +} + +static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case IOCTL_SET_IMG_PARAM: + { + img_param_t i; + + if (copy_from_user((void *)&i, (void *)arg, sizeof(img_param_t))) + return -EFAULT; + + img_width = i.width; + img_height = i.height; + img_bpp = i.bpp; + + if ((img_width * img_height * img_bpp/8) > MAX_FRAME_SIZE) { + /* realloc the buffer */ + cim_fb_destroy(); + if (cim_fb_alloc() < 0) + return -ENOMEM; + } + + cim_dev->frame_size = img_width * img_height * (img_bpp/8); + + cim_dev->frame_desc.dmacmd = CIM_CMD_EOFINT | CIM_CMD_STOP | (cim_dev->frame_size >> 2); // stop after capturing a frame + + dma_cache_wback((unsigned long)(&(cim_dev->frame_desc)), 16); + + break; + } + case IOCTL_CIM_CONFIG: + { + cim_config_t c; + + if (copy_from_user((void *)&c, (void *)arg, sizeof(cim_config_t))) + return -EFAULT; + + cim_config(&c); + + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return 0; +} + +/*========================================================================== + * Interrupt handler + *========================================================================*/ + +static irqreturn_t cim_irq_handler(int irq, void *dev_id) +{ + u32 state = REG_CIM_STATE; +#if 0 + if (state & CIM_STATE_DMA_EOF) { + wake_up_interruptible(&cim_dev->wait_queue); + } +#endif + if (state & CIM_STATE_DMA_STOP) { + // Got a frame, wake up wait routine + wake_up_interruptible(&cim_dev->wait_queue); + } + + // clear status flags + REG_CIM_STATE = 0; + return IRQ_HANDLED; +} + +/*========================================================================== + * Module init and exit + *========================================================================*/ + +static int __init cim_init(void) +{ + struct cim_device *dev; + int ret; + + /* allocate device */ + dev = kmalloc(sizeof(struct cim_device), GFP_KERNEL); + if (!dev) return -ENOMEM; + + /* record device */ + cim_dev = dev; + + /* allocate a frame buffer */ + if (cim_fb_alloc() < 0) { + kfree(dev); + return -ENOMEM; + } + + init_waitqueue_head(&dev->wait_queue); + + ret = jz_register_chrdev(CIM_MINOR, CIM_NAME, &cim_fops, dev); + if (ret < 0) { + cim_fb_destroy(); + kfree(dev); + return ret; + } + + if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED, + CIM_NAME, dev))) { + cim_fb_destroy(); + kfree(dev); + printk(KERN_ERR "CIM could not get IRQ"); + return ret; + } + + printk("JzSOC Camera Interface Module (CIM) driver registered\n"); + + return 0; +} + +static void __exit cim_exit(void) +{ + free_irq(IRQ_CIM, cim_dev); + jz_unregister_chrdev(CIM_MINOR, CIM_NAME); + cim_fb_destroy(); + kfree(cim_dev); +} + +module_init(cim_init); +module_exit(cim_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/cim.h linux-2.6.24.3-20100304/drivers/char/jzchar/cim.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/cim.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/cim.h 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,36 @@ +/* + * JzSOC CIM driver + * + * Copyright (C) 2005 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __CIM_H__ +#define __CIM_H__ + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} IMG_PARAM; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: IMG_PARAM * + +#endif /* __CIM_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jzchars.c linux-2.6.24.3-20100304/drivers/char/jzchar/jzchars.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jzchars.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jzchars.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,158 @@ +/* + * linux/drivers/char/jzchar/jzchars.c + * + * JzSOC char device family common layer. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "jzchars.h" + +LIST_HEAD(jz_char_devs); + +int jz_register_chrdev(unsigned char minor, const char *name, + struct file_operations *fops, void *private) +{ + struct list_head *p; + jz_char_dev_t *new; + list_for_each(p, &jz_char_devs) { + jz_char_dev_t *dev = (jz_char_dev_t *)p; + if (minor == dev->dev_minor) + return -EBUSY; + } + new = (jz_char_dev_t *)kmalloc(sizeof(jz_char_dev_t), GFP_KERNEL); + new->dev_minor = minor; + new->name = (char *)name; + new->fops = fops; + new->private = private; + list_add_tail((struct list_head *)new, &jz_char_devs); + return 0; +} + +int jz_unregister_chrdev(unsigned char minor, const char *name) +{ + struct list_head *p; + jz_char_dev_t *dev = NULL; + list_for_each(p, &jz_char_devs) { + jz_char_dev_t *one = (jz_char_dev_t *)p; + if (minor == one->dev_minor) { + dev = one; + break; + } + } + if (dev == NULL) + return -EINVAL; + list_del((struct list_head *)dev); + kfree(dev); + return 0; +} + +static ssize_t jz_char_read(struct file *, char *, size_t, loff_t *); +static ssize_t jz_char_write(struct file *, const char *, size_t, loff_t *); +static int jz_char_open(struct inode *, struct file *); +static int jz_char_release(struct inode *, struct file *); +static int jz_char_ioctl(struct inode *, struct file *, + unsigned int, unsigned long); + +static struct file_operations jz_char_fops = +{ + read: jz_char_read, + write: jz_char_write, + ioctl: jz_char_ioctl, + open: jz_char_open, + release: jz_char_release +}; + +static int __init jz_char_family_init(void) +{ + printk("JzSOC: char device family.\n"); + return register_chrdev(JZ_CHAR_MAJOR, "JzChar", &jz_char_fops); +} + +static void __exit jz_char_family_exit(void) +{ + printk("JzSOC: exit char device family.\n"); + unregister_chrdev(JZ_CHAR_MAJOR, "JzChar"); +} + +module_init(jz_char_family_init); +module_exit(jz_char_family_exit); + +static int jz_char_open(struct inode *inode, struct file *filp) +{ + jz_char_dev_t *dev = NULL; + unsigned int minor = iminor(inode); //minor extend to 20bit! + struct list_head *p; + list_for_each(p, &jz_char_devs) { + jz_char_dev_t *one = (jz_char_dev_t *)p; + if (one->dev_minor == minor) { + dev = one; + filp->private_data = dev; + return dev->fops->open(inode, filp); + } + } + printk("JzChar: No such device\n"); + return -EINVAL; +} + +static int jz_char_release(struct inode *inode, struct file *filp) +{ + jz_char_dev_t *dev = (jz_char_dev_t *)filp->private_data; + if (dev->fops->release) + return dev->fops->release(inode, filp); + return 0; +} + +static int jz_char_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + jz_char_dev_t *dev = (jz_char_dev_t *)filp->private_data; + if (dev->fops->ioctl) + return dev->fops->ioctl(inode, filp, cmd, arg); + return 0; +} + +static ssize_t jz_char_read(struct file *filp, char *buf, + size_t count, loff_t *ppos) +{ + jz_char_dev_t *dev = (jz_char_dev_t *)filp->private_data; + if (dev->fops->read) + return dev->fops->read(filp, buf, count, ppos); + return 0; +} + +static ssize_t jz_char_write(struct file *filp, const char *buf, + size_t count, loff_t *ppos) +{ + jz_char_dev_t *dev = (jz_char_dev_t *)filp->private_data; + if (dev->fops->write) + return dev->fops->write(filp, buf, count, ppos); + return 0; +} + +EXPORT_SYMBOL(jz_register_chrdev); +EXPORT_SYMBOL(jz_unregister_chrdev); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jzchars.h linux-2.6.24.3-20100304/drivers/char/jzchar/jzchars.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jzchars.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jzchars.h 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,47 @@ +#ifndef __JZ_CHARS_H__ +#define __JZ_CHARS_H__ + +#include +#include + +#define JZ_CHAR_MAJOR 238 + +#define UPRT_MINOR 0 // Micro printer +#define CIM_MINOR 1 // Camera interface module +#define TPANEL_MINOR 2 // Touchpanel +#define KEYPAD_MINOR 3 // Keypad +#define MEMCARD_MINOR 4 // Memory card +#define MAGCARD_MINOR 5 // Magcard +#define VFD_MINOR 6 // VFD +#define POWERFAIL_MINOR 7 // Powerfail +#define EJTAG_MINOR 8 // EJTAG emulation +#define REMR0_MINOR 9 // Remote output receive 0 +#define REMR1_MINOR 10 // Remote output receive 1 +#define USPI_MINOR 11 // Ultra-speed SPI device +#define SADC_MINOR 12 // SAR-ADC +#define SLCD_MINOR 13 // Smart LCD + +// 32 to 47 are reserved for SCC +#define SCC_MINOR 32 +// 48 to 63 are reserved for Camera sensor +#define SENSOR_MINOR 48 +// 64 to 71 are for EEPROM +#define EEPROM_MINOR_BASE 64 +// 72 for OWI +#define OW_MINOR 72 +// 73 for TCSM_MINOR +#define TCSM_MINOR 73 + +typedef struct { + struct list_head list; + char *name; + struct file_operations *fops; + void *private; + unsigned short dev_minor; +} jz_char_dev_t; + +extern int jz_register_chrdev(unsigned char minor, const char *name, + struct file_operations *fops, void * private); +extern int jz_unregister_chrdev(unsigned char minor, const char *name); + +#endif /* __JZ_CHARS_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ow.c linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ow.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ow.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ow.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,497 @@ +/* + * linux/drivers/char/jzchar/jz_ow.c + * + * One Wire Bus test driver + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jzchars.h" + +#define OW_CPU_READ_ROM 1 +#define OW_INTC_READ_ROM 1 +#define OW_CPU_SEARCH_ROM 0 +#define OW_INTC_SEARCH_ROM 0 + +#define OW_DEBUG 0 +#if OW_DEBUG +#define OWI_MAX 10 +static char CFG[OWI_MAX]; +static char CTL[OWI_MAX]; +static char STS[OWI_MAX]; +static char DAT[OWI_MAX]; +static char DIV[OWI_MAX]; +static void owi_register_dump(int i) +{ + CFG[i]= REG_OWI_CFG; + CTL[i]= REG_OWI_CTL; + STS[i]= REG_OWI_STS; + DAT[i]= REG_OWI_DAT; + DIV[i]= REG_OWI_DIV; +} +static void owi_register_print(int i) +{ + printk(" REG_OWI_CFG: 0x%08x\n", CFG[i]); + printk(" REG_OWI_CTL: 0x%08x\n", CTL[i]); + printk(" REG_OWI_STS: 0x%08x\n", STS[i]); + printk(" REG_OWI_DAT: 0x%08x\n", DAT[i]); + printk(" REG_OWI_DIV: 0x%08x\n", DIV[i]); +} +#endif + +static DECLARE_WAIT_QUEUE_HEAD (ow_wait_queue); + +/* + * fops routines + */ +static int ow_open(struct inode *inode, struct file *filp); +static int ow_release(struct inode *inode, struct file *filp); +static ssize_t ow_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t ow_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int ow_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +static void do_ow_rddata(void); +static void do_ow_wrdata(void); +static void do_ow_wr1rd(void); +static void do_ow_wr0(void); +static void do_ow_rst(void); + +static void do_interrupt_mode_test(void); +static void do_cpu_mode_test(void); + +static struct file_operations ow_fops = +{ + open: ow_open, + release: ow_release, + read: ow_read, + write: ow_write, + ioctl: ow_ioctl, +}; + +static int ow_open(struct inode *inode, struct file *filp) +{ + try_module_get(THIS_MODULE); + return 0; +} + +static int ow_release(struct inode *inode, struct file *filp) +{ + module_put(THIS_MODULE); + return 0; +} + +static ssize_t ow_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + printk("OW: read is not implemented\n"); + return -1; +} + +static ssize_t ow_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("ow: write is not implemented\n"); + return -1; +} + +static int ow_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + switch (cmd) { + + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return ret; +} + +static void do_ow_rddata(void) +{ + __owi_clr_sts(); + __owi_set_rddata(); + __owi_enable_ow_ops(); +} + +static void do_ow_wrdata(void) +{ + __owi_clr_sts(); + __owi_set_wrdata(); + __owi_enable_ow_ops(); +} + +static void do_ow_wr1rd(void) +{ + __owi_clr_sts(); + __owi_set_wr1rd(); + __owi_enable_ow_ops(); +} + +static void do_ow_wr0(void) +{ + __owi_clr_sts(); + __owi_set_wr0(); + __owi_enable_ow_ops(); +} + +static void do_ow_rst(void) +{ + __owi_clr_sts(); + __owi_set_rst(); + __owi_enable_ow_ops(); +} + +static irqreturn_t ow_interrupt(int irq, void *dev_id) +{ + __owi_clr_sts(); + wake_up(&ow_wait_queue); + + return IRQ_HANDLED; +} + +static void ow_intcm_read_rom(char *rom) +{ + int i; + + __owi_select_regular_mode(); + REG_OWI_DIV = 23; + __owi_clr_sts(); + __intc_unmask_irq(IRQ_OWI); + __owi_enable_all_interrupts(); + + do_ow_rst(); + sleep_on(&ow_wait_queue); + + REG_OWI_DAT = 0x33; + do_ow_wrdata(); + sleep_on(&ow_wait_queue); + + for(i=0; i<8; i++){ + do_ow_rddata(); + sleep_on(&ow_wait_queue); + rom[i] = REG_OWI_DAT; + } + __intc_mask_irq(IRQ_OWI); +} + +static void ow_intcm_search_rom(void) +{ + int i, j; + int normal, reverse; +#if 1 + unsigned char rom[8]={0x01, 0xf9, 0x35, 0x53, 0x11, 0x00, 0x00, 0x3e}; +#else + unsigned char rom[8]={0x01, 0xd8, 0x10, 0x02, 0x10, 0x00, 0x00, 0x22}; +#endif + __owi_select_regular_mode(); + REG_OWI_DIV = __cpm_get_extalclk()/1000000 - 1; + __owi_clr_sts(); + __intc_unmask_irq(IRQ_OWI); + __owi_enable_all_interrupts(); + + /* reset */ + do_ow_rst(); + sleep_on(&ow_wait_queue); + + /* send search ROM command */ + REG_OWI_DAT = 0xf0; + do_ow_wrdata(); + sleep_on(&ow_wait_queue); + + for( i=0; i<8; i++){ + for (j=0; j<8; j++){ + do_ow_wr1rd(); + sleep_on(&ow_wait_queue); + normal = ( __owi_get_rdst() !=0); + printk("normal: %d\n",normal); + + do_ow_wr1rd(); + sleep_on(&ow_wait_queue); + reverse = ( __owi_get_rdst() !=0); + printk("reverse: %d\n",reverse); + + if(normal ==1 && reverse ==1){ + printk("Search rom INTC mode: 11 NO device found\n"); + __intc_mask_irq(IRQ_OWI); + return; + } +#if 1 + if ( (rom[i]>>j) & 1 ){ + printk("write 1\n"); + do_ow_wr1rd(); + sleep_on(&ow_wait_queue); + } + else{ + printk("write 0\n"); + do_ow_wr0(); + sleep_on(&ow_wait_queue); + } + +#else + if(normal ==0 && reverse ==0){ + if (!((rom[i]>>j) & 1) ){ + printk("write 1\n"); + do_ow_wr1rd(); + sleep_on(&ow_wait_queue); + } + else{ + printk("write 0\n"); + do_ow_wr0(); + sleep_on(&ow_wait_queue); + } + }else{ + + if(normal ==0){ + printk("write 0\n"); + do_ow_wr0(); + sleep_on(&ow_wait_queue); + } + if(normal ==1){ + printk("write 1\n"); + do_ow_wr1rd(); + sleep_on(&ow_wait_queue); + } + } +#endif + + } + printk("\n\n"); + } + + printk("\nSearch rom INTC mode: device found SUCCESSFULLY\n"); + __intc_mask_irq(IRQ_OWI); + +} + +static void ow_cpum_read_rom(char *rom) +{ + int i; + + __owi_select_regular_mode(); + REG_OWI_DIV = __cpm_get_extalclk()/1000000 - 1; + __owi_clr_sts(); + __owi_disable_all_interrupts(); + + do_ow_rst(); + __owi_wait_ops_rdy(); + + if(!__owi_get_sts_pst()) + printk("read rom no device found\n"); + + REG_OWI_DAT = 0x33; + do_ow_wrdata(); + __owi_wait_ops_rdy(); + + for(i=0; i<8; i++){ + do_ow_rddata(); + __owi_wait_ops_rdy(); + rom[i] = REG_OWI_DAT; + } +} + + +static void ow_comm_bit(unsigned comm) +{ + int i; + for(i=0; i<8; i++){ + if ( comm & (1<>j) & 1 ){ + printk("write 1\n"); + do_ow_wr1rd(); + while(!__owi_get_sts_bit_rdy()) ; + } + else{ + printk("write 0\n"); + do_ow_wr0(); + while(!__owi_get_sts_bit_rdy()) ; + } + +#else + if(normal ==0 && reverse ==0){ + if (!((rom[i]>>j) & 1) ){ + printk("write 1\n"); + do_ow_wr1rd(); + while(!__owi_get_sts_bit_rdy()) ; + } + else{ + printk("write 0\n"); + do_ow_wr0(); + while(!__owi_get_sts_bit_rdy()) ; + } + }else{ + + if(normal ==0){ + printk("write 0\n"); + do_ow_wr0(); + while(!__owi_get_sts_bit_rdy()) ; + } + if(normal ==1){ + printk("write 1\n"); + do_ow_wr1rd(); + while(!__owi_get_sts_bit_rdy()) ; + } + } +#endif + + } + printk("\n\n"); + } + printk("\nSearch rom CPU mode: device found SUCCESSFULLY\n"); +} + +static void do_interrupt_mode_test(void) +{ + int ret, i; + unsigned char rom[8]; + + /* interrupt mode */ + ret = request_irq(IRQ_OWI, ow_interrupt, IRQF_DISABLED, + "JZ_OWI", NULL); + if(ret) + printk("failed irq \n"); + +#if OW_INTC_READ_ROM + ow_intcm_read_rom(rom); + printk("\n\nAfter intc mode read ROM ops: \n"); + printk("ROM: "); + for(i=0; i<8; i++) + printk("0x%02x,",rom[i]); +#endif + +#if OW_INTC_SEARCH_ROM + ow_intcm_search_rom(); +#endif + +} + +static void do_cpu_mode_test(void) +{ + +#if OW_CPU_READ_ROM + int i; + unsigned char rom[8]; + + ow_cpum_read_rom(rom); + printk("\n\nAfter CPU mode read ROM ops: \n"); + printk("ROM: "); + for(i=0; i<8; i++) + printk("0x%02x,",rom[i]); +#endif + +#if OW_CPU_SEARCH_ROM + ow_cpum_search_rom(); +#endif +} + +/* + * Module init and exit + */ +static int __init ow_init(void) +{ + int ret; + + ret = jz_register_chrdev(OW_MINOR, "ow", &ow_fops, NULL); + if (ret < 0) { + return ret; + } + __gpio_as_func1(153); + + REG_OWI_CFG=0; + REG_OWI_CTL=0; + REG_OWI_STS=0; + REG_OWI_DAT=0; + REG_OWI_DIV=0; + + do_interrupt_mode_test(); + do_cpu_mode_test(); + + printk("Ingenic OW driver registered\n"); + + return 0; +} + +static void __exit ow_exit(void) +{ + free_irq(IRQ_OWI, NULL); + jz_unregister_chrdev(OW_MINOR, "ow"); +} + +module_init(ow_init); +module_exit(ow_exit); + +MODULE_AUTHOR("Yurong Tan"); +MODULE_DESCRIPTION("One Wire Bus test Driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ts.c linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ts.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ts.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ts.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,443 @@ +/* + * jz_ts.c + * + * Touch screen driver for the Ingenic JZ47XX. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jz_ts.h" + +MODULE_AUTHOR("Peter Wei "); +MODULE_DESCRIPTION("Ingenic Touch Screen Driver"); +MODULE_LICENSE("GPL"); + +#define TS_NAME "jz-ts" +#define TS_MINOR 16 /* MAJOR: 10, MINOR: 16 */ +#define PFX TS_NAME + +//#define JZ_TS_DEBUG + +#ifdef JZ_TS_DEBUG +#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif +#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg) + +static struct jz_ts_t jz_ts; + +unsigned int (*codec_read_battery)(void) = NULL; + +// hold the spinlock before calling. +static void event_add(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + + // add this event to the event queue + ts->event_buf[ts->nextIn] = *event; + ts->nextIn = (ts->nextIn + 1) & (EVENT_BUFSIZE - 1); + if (ts->event_count < EVENT_BUFSIZE) { + ts->event_count++; + } else { + // throw out the oldest event + ts->nextOut = (ts->nextOut + 1) & (EVENT_BUFSIZE - 1); + } + + spin_unlock_irqrestore(&ts->lock, flags); + + // async notify + if (ts->fasync) + kill_fasync(&ts->fasync, SIGIO, POLL_IN); + // wake up any read call + if (waitqueue_active(&ts->wait)) + wake_up_interruptible(&ts->wait); +} + +static int event_pull(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&ts->lock, flags); + ret = ts->event_count; + if (ts->event_count) { + *event = ts->event_buf[ts->nextOut]; + ts->nextOut = (ts->nextOut + 1) & (EVENT_BUFSIZE - 1); + ts->event_count--; + } + spin_unlock_irqrestore(&ts->lock, flags); + + return ret; +} + +static int pen_is_down = 0; + +static irqreturn_t pendown_interrupt(int irq, void * dev_id) +{ + struct jz_ts_t* ts = &jz_ts; + struct ts_event event; + + dbg("pen down"); +#if defined(CONFIG_SOC_JZ4740) + if (ts->sleeping) { + ts->sleeping = 0; + ts_data_ready(); + return IRQ_HANDLED; + } +#endif + spin_lock(&ts->lock); + + if (ts->irq_enabled) { + ts->irq_enabled = 0; + } + else + ts->irq_enabled = 1; + + + if (pen_is_down) + pen_is_down = 0; + else + pen_is_down = 1; + + // callback routine to clear irq status + ts_irq_callback(); + + if ( (pen_is_down == 0)){ + del_timer(&ts->acq_timer); + spin_unlock(&ts->lock); + event.x = event.y = event.pressure = 0; + event.status = PENUP; + ts->first_read = 0; + event_add(ts, &event); + return IRQ_HANDLED; + } + + if ( (pen_is_down == 1)) + { + ts->acq_timer.expires = jiffies + HZ / 100; + del_timer(&ts->acq_timer); + ts->first_read = 1; + add_timer(&ts->acq_timer); + spin_unlock(&ts->lock); + } + return IRQ_HANDLED; +} + + +/* + * Raw X,Y,pressure acquisition timer function. It gets scheduled + * only while pen is down. Its duration between calls is the polling + * rate. + */ +static void +jz_acq_timer(unsigned long data) +{ + struct jz_ts_t *ts = (struct jz_ts_t *)data; + struct ts_event event; + int pen_was_down = ts->pen_is_down; + + spin_lock(&ts->lock); + + if (PenIsDown()) { + + ts->pen_is_down = 1; + + if (AcquireEvent(ts, &event)) // check event is valid or not? + event_add(ts, &event); + + // schedule next acquire + ts->acq_timer.expires = jiffies + HZ / 100; + del_timer(&ts->acq_timer); + add_timer(&ts->acq_timer); + } else { + + if (!ts->irq_enabled) { + ts->irq_enabled = 1; + } + ts->pen_is_down = 0; + if (pen_was_down) { + event.x = event.y = event.pressure = 0; + event.status = PENUP; + event_add(ts, &event); + } + } + + spin_unlock(&ts->lock); +} + +/* +++++++++++++ Read battery voltage routine ++++++++++++++*/ + +unsigned int jz_read_battery(void) +{ + unsigned int v = 0; + struct jz_ts_t *ts = &jz_ts; + + spin_lock(&ts->lock); + + if (codec_read_battery) + v = codec_read_battery(); + + spin_unlock(&ts->lock); + + return v; +} + +/* +++++++++++++ File operations ++++++++++++++*/ + +static int +jz_fasync(int fd, struct file *filp, int mode) +{ + struct jz_ts_t *ts = (struct jz_ts_t *)filp->private_data; + return fasync_helper(fd, filp, mode, &ts->fasync); +} + + +static unsigned int +jz_poll(struct file * filp, poll_table * wait) +{ + struct jz_ts_t* ts = (struct jz_ts_t*)filp->private_data; + poll_wait(filp, &ts->wait, wait); + if (ts->event_count) + return POLLIN | POLLRDNORM; + return 0; +} + +static ssize_t +jz_read(struct file * filp, char * buffer, size_t count, loff_t * ppos) +{ + DECLARE_WAITQUEUE(wait, current); + struct jz_ts_t* ts = (struct jz_ts_t*)filp->private_data; + char *ptr = buffer; + struct ts_event event; + int err = 0; + + dbg("jz_read"); + + add_wait_queue(&ts->wait, &wait); + while (count >= sizeof(struct ts_event)) { + err = -ERESTARTSYS; + if (signal_pending(current)) + break; + + + if (event_pull(ts, &event)) { + err = copy_to_user(ptr, &event, + sizeof(struct ts_event)); + if (err) + break; + ptr += sizeof(struct ts_event); + count -= sizeof(struct ts_event); + } else { + set_current_state(TASK_INTERRUPTIBLE); + err = -EAGAIN; + if (filp->f_flags & O_NONBLOCK) + break; + schedule(); + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&ts->wait, &wait); + + return ptr == buffer ? err : ptr - buffer; +} + + +static int +jz_open(struct inode * inode, struct file * filp) +{ + struct jz_ts_t *ts; + int retval; + + dbg("open ts device"); + filp->private_data = ts = &jz_ts; + + spin_lock(&ts->lock); + + ts->pen_is_down = 0; // start with pen up + ts->sleeping = 0; + // flush event queue + ts->nextIn = ts->nextOut = ts->event_count = 0; + + // Init acquisition timer function + init_timer(&ts->acq_timer); + ts->acq_timer.function = jz_acq_timer; + ts->acq_timer.data = (unsigned long)ts; + + ts->irq_enabled = 1; + + spin_unlock(&ts->lock); + + /* Since ts interrupt can happen immediately after request_irq, + * we wait until we've completed init of all relevent driver + * state variables. Now we grab the PenDown IRQ + */ + retval = ts_request_irq(&ts->pendown_irq, pendown_interrupt, TS_NAME, ts); + if (retval) { + err("unable to get PenDown IRQ %d", ts->pendown_irq); + return retval; + } + + try_module_get(THIS_MODULE); + return 0; +} + +static int +jz_release(struct inode * inode, struct file * filp) +{ + struct jz_ts_t* ts = (struct jz_ts_t*)filp->private_data; + + ts_free_irq(ts); + jz_fasync(-1, filp, 0); + del_timer_sync(&ts->acq_timer); + + module_put(THIS_MODULE); + return 0; +} + +static int jz_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) +{ + struct txy { + int minx; + int miny; + int maxx; + int maxy; + }; + + struct txy ch; + + /* + * Switch according to the ioctl called + */ + switch (ioctl_num) + { + case IOCTL_SET_MSG: + jz_ts.filter=1; + break; + case IOCTL_SET_NUM: + if (copy_from_user((void *)&ch, (void *)ioctl_param, sizeof(ch))) + return -EFAULT; + jz_ts.minx = ch.minx; + jz_ts.miny = ch.miny; + jz_ts.maxx = ch.maxx; + jz_ts.maxy = ch.maxy; + break; + } + + return 0; +} + +static struct file_operations ts_fops = { + owner: THIS_MODULE, + read: jz_read, + poll: jz_poll, + fasync: jz_fasync, + ioctl: jz_ioctl, + open: jz_open, + release: jz_release, +}; + +/* +++++++++++++ End File operations ++++++++++++++*/ + +static int __init minx_setup(char *str) +{ + int i; + + if (get_option(&str,&i)) jz_ts.minx = i; + jz_ts.filter=i; + return 1; +} + +__setup("ts_minx=", minx_setup); + +static int __init miny_setup(char *str) +{ + int i; + if (get_option(&str,&i)) jz_ts.miny = i; + return 1; +} + +__setup("ts_miny=", miny_setup); + +static int __init maxx_setup(char *str) +{ + int i; + if (get_option(&str,&i)) jz_ts.maxx = i; + return 1; +} + +__setup("ts_maxx=", maxx_setup); + +static int __init maxy_setup(char *str) +{ + int i; + if (get_option(&str,&i)) jz_ts.maxy = i; + return 1; +} + +__setup("ts_maxy=", maxy_setup); + +static int __init printraw_setup(char *str) +{ + if (str) + jz_ts.prints = 1; + + return 0; +} + +__setup("ts_debug", printraw_setup); + + +static struct miscdevice jz_ts_dev = { + minor: TS_MINOR, + name: TS_NAME, + fops: &ts_fops, +}; + +static int __init jzts_init_module(void) +{ + struct jz_ts_t *ts = &jz_ts; + int ret; + + if ((ret = misc_register(&jz_ts_dev)) < 0) { + err("can't register misc device"); + return ret; + } + +// memset(ts, 0, sizeof(struct jz_ts_t)); + init_waitqueue_head(&ts->wait); + spin_lock_init(&ts->lock); + + printk("Jz generic touch screen driver registered\n"); + + return 0; +} + +static void jzts_cleanup_module(void) +{ + misc_deregister(&jz_ts_dev); +} + +module_init(jzts_init_module); +module_exit(jzts_cleanup_module); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ts.h linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ts.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_ts.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jz_ts.h 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,54 @@ +#ifndef __JZ_TS_H__ +#define __JZ_TS_H__ + +/* + * IOCTL commands + */ +#define IOCTL_SET_MSG 0 +#define IOCTL_SET_NUM 1 + + +/* + * TS Event type + */ +struct ts_event { + u16 status; + u16 x; + u16 y; + u16 pressure; + u16 pad; +}; + +/* TS event status */ +#define PENUP 0x00 +#define PENDOWN 0x01 + +#define EVENT_BUFSIZE 64 // must be power of two + +struct jz_ts_t { + int pendown_irq; // IRQ of pendown interrupt + int pen_is_down; // 1 = pen is down, 0 = pen is up + int irq_enabled; + struct ts_event event_buf[EVENT_BUFSIZE];// The event queue + int nextIn, nextOut; + int event_count; + struct fasync_struct *fasync; // asynch notification + struct timer_list acq_timer; // Timer for triggering acquisitions + wait_queue_head_t wait; // read wait queue + spinlock_t lock; + int minx, miny, maxx, maxy; + int filter, prints; + int sleeping; + int first_read; +}; + +extern void ts_enable_irq(void); +extern void ts_disable_irq(void); +extern int ts_request_irq(u32 *irq,irqreturn_t (*handler)(int, void *), const char *devname, void *dev_id); +extern void ts_free_irq(struct jz_ts_t *ts); +extern int PenIsDown(void); +extern int AcquireEvent(struct jz_ts_t *ts, struct ts_event *event); +extern void ts_irq_callback(void); +extern void ts_data_ready(void); + +#endif /* __JZ_TS_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_tssi.c linux-2.6.24.3-20100304/drivers/char/jzchar/jz_tssi.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_tssi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jz_tssi.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,457 @@ +/* + * jz_tssi.c + * + * MPEG2-TS interface driver for the Ingenic JZ47XX. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jzchars.h" + +#include "jz_tssi.h" + + +MODULE_AUTHOR("Lucifer Liu "); +MODULE_DESCRIPTION("Ingenic MPEG2-TS interface Driver"); +MODULE_LICENSE("GPL"); + +#define TSSI_NAME "JZ MPEG2-TS SI" +#define TSSI_MINOR 204 /* MAJOR: 10, MINOR: 16 */ +#define TSSI_IRQ IRQ_TSSI +#define PFX TSSI_NAME +#define RING_BUF_NUM 100 + +#define USE_DMA +#define TRIG_PIN ( 32 * 2 + 15 ) +#define DMA_ID_TSSI 5 +//#define JZ_TSSI_DEBUG + +#ifdef JZ_TSSISI_DEBUG +#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif +#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg) + +static struct jz_tssi_t jz_tssi_g; +static struct jz_tssi_buf_ring_t jz_tssi_ring_g; +static int tssi_dma_reinit(int dma_chan, unsigned char *dma_buf, int size); + +static void print_reg( void ) +{ + printk("REG_TSSI_ENA %8x \n ", REG8( TSSI_ENA )); + printk("REG_TSSI_CFG %8x \n ", REG16( TSSI_CFG )); + printk("REG_TSSI_CTRL %8x \n ", REG8( TSSI_CTRL )); + printk("REG_TSSI_STAT %8x \n ", REG8( TSSI_STAT )); + printk("REG_TSSI_FIFO %8x \n ", REG32( TSSI_FIFO )); + printk("REG_TSSI_PEN %8x \n ", REG32( TSSI_PEN )); + printk("REG_TSSI_PID0 %8x \n ", REG32( TSSI_PID0 )); + printk("REG_TSSI_PID1 %8x \n ", REG32( TSSI_PID1 )); + printk("REG_TSSI_PID2 %8x \n ", REG32( TSSI_PID2 )); + printk("REG_TSSI_PID3 %8x \n ", REG32( TSSI_PID3 )); + printk("REG_TSSI_PID4 %8x \n ", REG32( TSSI_PID4 )); + printk("REG_TSSI_PID5 %8x \n ", REG32( TSSI_PID5 )); + printk("REG_TSSI_PID6 %8x \n ", REG32( TSSI_PID6 )); + printk("REG_TSSI_PID7 %8x \n ", REG32( TSSI_PID7 )); +} + +void dump_dma_channel(unsigned int dmanr) +{ + printk("DMA%d Registers:\n", dmanr); + printk(" DMACR = 0x%8x\n", REG_DMAC_DMACR(0)); + printk(" DSAR = 0x%8x\n", REG_DMAC_DSAR(dmanr)); + printk(" DTAR = 0x%8x\n", REG_DMAC_DTAR(dmanr)); + printk(" DTCR = 0x%8x\n", REG_DMAC_DTCR(dmanr)); + printk(" DRSR = 0x%8x\n", REG_DMAC_DRSR(dmanr)); + printk(" DCCSR = 0x%8x\n", REG_DMAC_DCCSR(dmanr)); + printk(" DCMD = 0x%8x\n", REG_DMAC_DCMD(dmanr)); + printk(" DDA = 0x%8x\n", REG_DMAC_DDA(dmanr)); + printk(" DMADBR = 0x%8x\n", REG_DMAC_DMADBR(1)); +} + +static int tssi_buf_init( struct jz_tssi_buf_ring_t * ring ) +{ + int i; + struct jz_tssi_buf * bp,* ap, *cp; + + ap = cp = bp = (struct jz_tssi_buf *)kmalloc( sizeof( struct jz_tssi_buf ) ,GFP_KERNEL ); //the first + if ( !bp ) { + printk("Can not malloc buffer! \n"); + return -1; + } + + for ( i = 0; i < RING_BUF_NUM; i ++ ) { + bp = ap; + bp->buf = (unsigned int *) kmalloc(MPEG2_TS_PACHAGE_SIZE / 4 * sizeof(unsigned int) ,GFP_KERNEL); + if ( !bp->buf ) { + printk("Can not malloc buffer! \n"); + return -1; + } + bp->index = i; + bp->pos = 0; + ap = (struct jz_tssi_buf *)kmalloc( sizeof( struct jz_tssi_buf ) ,GFP_KERNEL ); + if ( !ap ) { + printk("Can not malloc buffer! \n"); + return -1; + } + + bp->next = ap; //point to next ! + } + + bp->next = cp; //point loop to first! + ring->front = cp; + ring->rear = cp; + ring->fu_num = 0; + kfree(ap); + return 0; +} + +static void tssi_free_buf( struct jz_tssi_buf_ring_t * ring ) +{ + int i; + struct jz_tssi_buf * ap; + for ( i = 0; i < RING_BUF_NUM; i ++ ) + { + ap = ring->front; + ring->front = ring->front->next; + kfree( ap ); + } +} + +#if 0 +static void tssi_read_fifo(void *dev_id) +{ + struct jz_tssi_t* tssi = ( struct jz_tssi_t* )dev_id; + struct jz_tssi_buf_ring_t * ring = tssi->cur_buf; + struct jz_tssi_buf *buf = ring->rear; + int i; +#if 0 + if ( ring->fu_num > RING_BUF_NUM ) + { + printk("Ring buffer full ! %d \n",ring->fu_num); + return; + } +#endif + + for ( i = 0; i < 8 ; i ++ ) + { + ring->front->buf[ring->front->pos++] = REG_TSSI_FIFO; + } + + if ( ring->front->pos >= MPEG2_TS_PACHAGE_SIZE ) + { + ring->fu_num ++; + ring->front = ring->front->next; + ring->front->pos = 0; + } +} +#endif + +static void tssi_config_filting( void ) +{ + __tssi_soft_reset(); + __gpio_as_tssi(); + __tssi_disable_ovrn_irq(); //use dma ,no need irq + __tssi_disable_trig_irq(); + __tssi_set_tigger_num( 8 ); //trig is 4 word! +// __tssi_filter_enable(); + __tssi_clear_state(); + __tssi_filter_disable(); + __tssi_state_clear_overrun(); +// __tssi_clear_trig_irq_flag(); +#ifdef USE_DMA + __tssi_dma_enable(); +#else + __tssi_dma_disable(); +#endif + + __tssi_enable_ovrn_irq(); +// __tssi_enable_trig_irq(); + + //set config +// __tssi_set_bt_1(); + __tssi_set_wd_1(); + __tssi_set_data_use_data7(); + __tssi_set_data_pola_high(); +// __tssi_select_serail_mode(); + __tssi_select_paral_mode(); + __tssi_select_clk_fast(); + __tssi_select_clk_posi_edge(); + __tssi_select_frm_act_high(); + __tssi_select_str_act_high(); + __tssi_select_fail_act_high(); +// __tssi_select_fail_act_low(); + __tssi_disable_filte_pid0(); //we disable pid0 filter for ever! +} + +static void tssi_add_pid(int pid_num, int pid) +{ + unsigned int addr ; + int n = pid_num / 2, hl = pid_num % 2; + if ( hl ) //use high pid, pid1 + { + addr = TSSI_PID0 + ( n * 4 ); + REG32( addr ) |= ( (pid & 0x1fff) << 16 ); //13bit + REG_TSSI_PEN |= ( 1 << (16 + n) ); + } + else //use low pid, pid0 + { + addr = TSSI_PID0 + ( n * 4 ); + REG32( addr ) |= pid & 0x1fff; //13bit + REG_TSSI_PEN |= ( 1 << n ); + } +} + +static irqreturn_t tssi_dma_irq(int irq, void * dev_id) +{ + struct jz_tssi_t *tssi = (struct jz_tssi_t *)dev_id; + struct jz_tssi_buf_ring_t *buf = tssi->cur_buf; + + REG_DMAC_DCCSR(tssi->dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + + if (__dmac_channel_transmit_end_detected(tssi->dma_chan)) { + __dmac_channel_clear_transmit_end(tssi->dma_chan); + if ( buf->fu_num < RING_BUF_NUM ) + { + buf->front = buf->front->next; + REG_DMAC_DSAR(tssi->dma_chan) = CPHYSADDR(TSSI_FIFO); + REG_DMAC_DTAR(tssi->dma_chan) = CPHYSADDR((unsigned int)buf->front->buf); + REG_DMAC_DTCR(tssi->dma_chan) = MPEG2_TS_PACHAGE_SIZE / 32; + REG_DMAC_DCCSR(tssi->dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + buf->fu_num ++; + } + __tssi_clear_state(); + } + + if (__dmac_channel_transmit_halt_detected(tssi->dma_chan)) { + printk("DMA HALT\n"); + __dmac_channel_clear_transmit_halt(tssi->dma_chan); + } + + if (__dmac_channel_address_error_detected(tssi->dma_chan)) { + printk("DMA ADDR ERROR\n"); + __dmac_channel_clear_address_error(tssi->dma_chan); + } + + if (__dmac_channel_descriptor_invalid_detected(tssi->dma_chan)) { + printk("DMA DESC INVALID\n"); + __dmac_channel_clear_descriptor_invalid(tssi->dma_chan); + } + + if (__dmac_channel_count_terminated_detected(tssi->dma_chan)) { + printk("DMA CT\n"); + __dmac_channel_clear_count_terminated(tssi->dma_chan); + } + + return IRQ_HANDLED; +} + +static irqreturn_t tssi_interrupt(int irq, void * dev_id) +{ + __intc_mask_irq(TSSI_IRQ); +#if 1 + if ( REG_TSSI_STAT & TSSI_STAT_OVRN ) + { + printk("tssi over run occur! %x\n",REG8( TSSI_STAT )); + __tssi_clear_state(); + printk("clear ! %x\n",REG8( TSSI_STAT )); + } +#endif + if ( REG_TSSI_STAT & TSSI_STAT_TRIG ) + { + printk("tssi trig irq occur! \n"); + tssi_read_fifo( dev_id ); + } + + __intc_ack_irq(TSSI_IRQ); + __intc_unmask_irq(TSSI_IRQ); + return IRQ_HANDLED; +} + +static ssize_t jz_read(struct file * filp, char * buffer, size_t count, loff_t * ppos) +{ + jz_char_dev_t *adev = (jz_char_dev_t *)filp->private_data; + struct jz_tssi_t* tssi = (struct jz_tssi_t*)adev->private; + struct jz_tssi_buf_ring_t* ring = tssi->cur_buf; + + int i; + + count /= MPEG2_TS_PACHAGE_SIZE; + + if ( count > ring->fu_num ) + count = ring->fu_num; + + for ( i = 0; i < count; i ++ ) + { + memcpy( buffer + ( i * MPEG2_TS_PACHAGE_SIZE), + ring->rear->buf, MPEG2_TS_PACHAGE_SIZE ); + ring->rear->pos = 0; + ring->rear = ring->rear->next; + } + ring->fu_num -= count; + return count * MPEG2_TS_PACHAGE_SIZE; +} + +static int tssi_dma_reinit(int dma_chan, unsigned char *dma_buf, int size) +{ + static unsigned int dma_src_phys_addr, dma_dst_phys_addr; + REG_DMAC_DMACKE(0) = 0xff; + dma_src_phys_addr = CPHYSADDR(TSSI_FIFO); + dma_dst_phys_addr = CPHYSADDR((unsigned int)dma_buf); + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0; + REG_DMAC_DCCSR(dma_chan) = 0; + REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_TSSIIN; + REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr; + REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr; + REG_DMAC_DTCR(dma_chan) = size / 32; + REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE; + REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN; + REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */ + return 0; +} + +static int jz_open(struct inode * inode, struct file * filp) +{ + try_module_get(THIS_MODULE); + + __tssi_soft_reset(); + __intc_mask_irq(TSSI_IRQ); + tssi_config_filting(); + + return 0; +} + +static int jz_release(struct inode * inode, struct file * filp) +{ + __intc_mask_irq(TSSI_IRQ); + module_put(THIS_MODULE); + return 0; +} + +static int jz_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + jz_char_dev_t *adev = (jz_char_dev_t *)file->private_data; + struct jz_tssi_t* tssi = (struct jz_tssi_t*)adev->private; + + switch (cmd) + { + case IOCTL_TSSI_ENABLE : + __intc_ack_irq(TSSI_IRQ); + __intc_unmask_irq(TSSI_IRQ); + __tssi_enable(); + print_reg(); + + break; + case IOCTL_TSSI_DISABLE : + __tssi_disable(); + + break; + case IOCTL_TSSI_SOFTRESET : + __tssi_soft_reset(); + + break; + case IOCTL_TSSI_ENFILTER : + __tssi_filter_enable(); + break; + case IOCTL_TSSI_DEFILTER : + __tssi_filter_disable(); + break; + case IOCTL_TSSI_ADDPID : //add one pid to filter + if ( tssi->pid_num < 15 ) + { + tssi_add_pid(tssi->pid_num, arg); + tssi->pid_num ++ ; + } + break; + + case IOCTL_TSSI_FLUSHPID : //set all filting pid to false + REG_TSSI_PEN = 0x0; + REG_TSSI_PID0 = 0x0; + REG_TSSI_PID1 = 0x0; + REG_TSSI_PID2 = 0x0; + REG_TSSI_PID3 = 0x0; + REG_TSSI_PID4 = 0x0; + REG_TSSI_PID5 = 0x0; + REG_TSSI_PID6 = 0x0; + REG_TSSI_PID7 = 0x0; + break; + + case IOCTL_TSSI_INIT_DMA: + tssi_dma_reinit(tssi->dma_chan, tssi->cur_buf->front->buf, MPEG2_TS_PACHAGE_SIZE); + break; + case IOCTL_TSSI_DISABLE_DMA: + REG_DMAC_DCCSR(tssi->dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */ + break; + } + + return 0; +} + +static struct file_operations tssi_fops = { + owner: THIS_MODULE, + read: jz_read, + poll: NULL, + fasync: NULL, + ioctl: jz_ioctl, + open: jz_open, + release: jz_release, +}; + +static int __init jztssi_init_module(void) +{ + int retval; + struct jz_tssi_t *tssi = &jz_tssi_g; + + __cpm_start_tssi(); + __cpm_start_dmac(); + tssi_buf_init( &jz_tssi_ring_g ); + tssi->cur_buf = &jz_tssi_ring_g; + tssi->pid_num = 0; + retval = request_irq(TSSI_IRQ, tssi_interrupt, IRQF_DISABLED, TSSI_NAME, &jz_tssi_g); + + if (retval) { + printk("unable to get IRQ %d",TSSI_IRQ); + return retval; + } + + tssi->dma_chan = jz_request_dma(DMA_ID_TSSI, "tssi", tssi_dma_irq, + IRQF_DISABLED, &jz_tssi_g); + if ( tssi->dma_chan < 0 ) + { + printk("MPEG2-TS request irq fail! \n"); + return -1; + } + + jz_register_chrdev(TSSI_MINOR, TSSI_NAME, &tssi_fops, &jz_tssi_g); + + printk("Jz MPEG2-TS interface driver registered %x %d\n",&jz_tssi_g,tssi->dma_chan); + return 0; +} + +static void jztssi_cleanup_module(void) +{ + free_irq(TSSI_IRQ,0); + jz_free_dma(jz_tssi_g.dma_chan); + tssi_free_buf( &jz_tssi_ring_g ); + jz_unregister_chrdev(TSSI_MINOR, TSSI_NAME); +} + +module_init(jztssi_init_module); +module_exit(jztssi_cleanup_module); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_tssi.h linux-2.6.24.3-20100304/drivers/char/jzchar/jz_tssi.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/jz_tssi.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/jz_tssi.h 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,76 @@ +#ifndef __JZ_TSSI_H__ +#define __JZ_TSSI_H__ + +/* + * IOCTL commands + */ +#define IOCTL_TSSI_ENABLE 0x01 +#define IOCTL_TSSI_DISABLE 0x02 +#define IOCTL_TSSI_SOFTRESET 0x03 +#define IOCTL_TSSI_ENFILTER 0x04 +#define IOCTL_TSSI_DEFILTER 0x05 +#define IOCTL_TSSI_ADDPID 0x06 +#define IOCTL_TSSI_FLUSHPID 0x07 +#define IOCTL_TSSI_INIT_DMA 0x08 +#define IOCTL_TSSI_DISABLE_DMA 0x09 + +#if 0 +#define IOCTL_TSSI_SET_CFG 0x06 +#define IOCTL_TSSI_GET_CFG 0x07 +#define IOCTL_TSSI_ENIRQ_TRIG 0x08 +#define IOCTL_TSSI_DEIRQ_TRIG 0x09 +#define IOCTL_TSSI_ENIRQ_OVRN 0x0a +#define IOCTL_TSSI_DEIRQ_OVRN 0x0b +#define IOCTL_TSSI_ENPID0 0x0c +#define IOCTL_TSSI_DEPID0 0x0d +#define IOCTL_TSSI_ENPIDN 0x0e +#define IOCTL_TSSI_DEPIDN 0x0f +#define IOCTL_TSSI_SETPIDN 0x10 +#define IOCTL_TSSI_SET_TRIG 0x11 +#endif + +#define MAX_PID_NUM 15 +#define MPEG2_TS_PACHAGE_SIZE 19200 + +struct jz_tssi_cfg_t +{ + unsigned char wordorder; + unsigned char byteorder; + unsigned char dataploa; + unsigned char use0; + unsigned char clkch; + unsigned char mode; + unsigned char clkpola; + unsigned char frmpola; + unsigned char strpola; + unsigned char failpola; + unsigned char trignum; + + unsigned short pid; + unsigned char pid_index; //0 to 15 +}; + +struct jz_tssi_buf +{ + unsigned int *buf; + unsigned int pos; + unsigned int index; + struct jz_tssi_buf *next; +}; + +struct jz_tssi_buf_ring_t +{ + struct jz_tssi_buf *front; + struct jz_tssi_buf *rear; + unsigned int fu_num; +}; + +struct jz_tssi_t +{ + struct jz_tssi_cfg_t cur_config; + struct jz_tssi_buf_ring_t *cur_buf; + struct semaphore tssi_sem; + int dma_chan, pid_num; +}; + +#endif /* __JZ_TSSI_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/Kconfig linux-2.6.24.3-20100304/drivers/char/jzchar/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/Kconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/Kconfig 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,70 @@ +# +# JzSOC char devices configuration +# + +menu "JZSOC char device support" + depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D + +config JZCHAR + tristate 'JzSOC char device support' + +config JZ_CAMERA_SENSOR + bool + +config JZ_CIM + tristate 'JzSOC Camera Interface Module (CIM) support' + depends on JZCHAR + select JZ_CAMERA_SENSOR + +config JZ_TPANEL_ATA2508 + tristate 'JzSOC MPEG4 TOUCH PANEL ATA2508 support' + depends on JZCHAR + +#config JZ_TPANEL +# tristate 'JzSOC touchpanel driver support' +# depends on JZCHAR +# select JZ_SADC if SOC_JZ4740 +# select JZ_TPANEL_AK4182 if SOC_JZ4730 + +choice + prompt "Touch Panel ADC type" + depends on JZ_TPANEL + default JZ_SADC if SOC_JZ4740 || SOC_JZ4750 || SOC_JZ4750D + default JZ_TPANEL_AK4182 if SOC_JZ4730 + +config JZ_SADC + bool 'Select the JZ47XX internal SADC' + +config JZ_TPANEL_AK4182 + bool 'Select the AK4182 codec' + +config JZ_TPANEL_UCB1400 + bool 'Select the UCB1400 codec' + +config JZ_TPANEL_WM9712 + bool 'Select the WM9712 codec' + +endchoice + +config JZ_UDC_HOTPLUG + tristate 'JZ UDC hotplug driver support' + depends on JZCHAR + +config JZ_POWEROFF + tristate 'JZ board poweroff support' + depends on JZCHAR + +config JZ_OW + tristate 'JZ One-wire bus support' + depends on JZCHAR + +config JZ_TCSM + tristate 'JZ TCSM support' + depends on JZCHAR + +config JZ_TSSI + tristate 'JZ MPEG2-TS interface support' + depends on JZCHAR && (SOC_JZ4750 || SOC_JZ4750D) + +endmenu + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/Makefile linux-2.6.24.3-20100304/drivers/char/jzchar/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/Makefile 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,24 @@ +# +# Makefile for jzchar +# +obj-$(CONFIG_JZCHAR) += jzchars.o + +obj-$(CONFIG_JZ_SCC) += scc.o +obj-$(CONFIG_JZ_CIM) += cim.o +obj-$(CONFIG_JZ_TPANEL_ATA2508) += ata2508.o +obj-$(CONFIG_JZ_CAMERA_SENSOR) += sensor.o +obj-$(CONFIG_JZ_I2C_EEPROM) += eeprom.o +obj-$(CONFIG_JZ_EJTAG) += ejtag.o +obj-$(CONFIG_JZ_POWEROFF) += poweroff.o + +#obj-$(CONFIG_JZ_TPANEL) += jz_ts.o +obj-$(CONFIG_JZ_TPANEL_UCB1400) += ucb1400.o +obj-$(CONFIG_JZ_TPANEL_WM9712) += wm9712.o +obj-$(CONFIG_JZ_TPANEL_AK4182) += ak4182.o +obj-$(CONFIG_JZ_SADC) += sadc.o + +obj-$(CONFIG_JZ_SMART_LCD) += slcd.o +obj-$(CONFIG_JZ_UDC_HOTPLUG) += udc_hotplug.o +obj-$(CONFIG_JZ_OW) += jz_ow.o +obj-$(CONFIG_JZ_TCSM) += tcsm.o +obj-$(CONFIG_JZ_TSSI) += jz_tssi.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/poweroff.c linux-2.6.24.3-20100304/drivers/char/jzchar/poweroff.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/poweroff.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/poweroff.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,396 @@ +/* + * linux/drivers/char/jzchar/poweroff.c + * + * Power off handling. + * + * Copyright (C) 2005-2007 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jzchars.h" + +MODULE_AUTHOR("Jianli Wei "); +MODULE_DESCRIPTION("Poweroff handling"); +MODULE_LICENSE("GPL"); + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + +//#define USE_SUSPEND_HOTPLUG + +#ifdef CONFIG_SOC_JZ4730 +#define GPIO_PW_I 97 +#define GPIO_PW_O 66 +#define POWEROFF_PIN_DOWN 1 +#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_rise_edge(POWEROFF_PIN) +#define DO_SHUTDOWN_SYSTEM __gpio_clear_pin(GPIO_PW_O) +#define DO_SUSPEND jz_pm_suspend() + +#define GPIO_DISP_OFF_N 93 +#define __lcd_set_backlight_level(n) \ +do { \ + REG_PWM_DUT(0) = n; \ + REG_PWM_PER(0) = 7; \ + REG_PWM_CTR(0) = 0x81; \ +} while (0) +#define __lcd_close_backlight() \ +do { \ + __lcd_set_backlight_level(0); \ +} while (0) +#endif + +#ifdef CONFIG_SOC_JZ4740 +#define GPIO_PW_I 125 +#define POWEROFF_PIN_DOWN 0 +#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN) +#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate() +#define DO_SUSPEND { \ + jz_pm_sleep();\ + suspend_flag = 0;\ + SET_POWEROFF_PIN_AS_IRQ;\ + } + +#define GPIO_DISP_OFF_N 118 +#define GPIO_PWM 123 +#define __lcd_close_backlight() \ +do { \ +__gpio_as_output(GPIO_PWM); \ +__gpio_clear_pin(GPIO_PWM); \ +} while (0) +#endif + +#ifdef CONFIG_SOC_JZ4750 +#define GPIO_PW_I GPIO_WAKEUP +#define POWEROFF_PIN_DOWN 0 +#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN) +#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate() +#define DO_SUSPEND { \ + jz_pm_sleep();\ + suspend_flag = 0;\ + SET_POWEROFF_PIN_AS_IRQ;\ + } +#endif + +#ifdef CONFIG_SOC_JZ4750D +#define GPIO_PW_I GPIO_WAKEUP +#define POWEROFF_PIN_DOWN 0 +#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN) +#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate() +#define DO_SUSPEND { \ + jz_pm_sleep();\ + suspend_flag = 0;\ + SET_POWEROFF_PIN_AS_IRQ;\ + } +#endif + + +#define POWEROFF_PIN GPIO_PW_I +#define POWEROFF_IRQ (IRQ_GPIO_0 + POWEROFF_PIN) + +#define POWEROFF_PERIOD 1000 /* unit: ms */ +#define POWEROFF_DELAY 100 /* unit: ms */ + +static struct timer_list poweroff_timer; +static struct timer_list poweroff_delaytimer; +static struct work_struct suspend_work; + +static int poweroff_flag = 0; +static int suspend_flag = 0; +static int num_seconds = 0; + +#ifdef CONFIG_JZ_UDC_HOTPLUG +extern int jz_udc_active; +#endif + +extern void jz_pm_suspend(void); +extern int jz_pm_hibernate(void); +extern int jz_pm_sleep(void); + +static void poweroff_timer_routine(unsigned long dummy) +{ + if (__gpio_get_pin(POWEROFF_PIN) == POWEROFF_PIN_DOWN) { + if (++num_seconds > 3) + { + printk("\nShutdown system now ..\n"); + +#ifndef USE_SUSPEND_HOTPLUG + /* Turn off LCD to inform user that the system is shutting down. + * But the information of shutting down system will be shown + * by userspace program if hotplug is used. + */ + __lcd_close_backlight(); +#endif + + /* + * Wait until the power key is up, or the system will reset with + * power key down after entering hibernate. + */ + while(__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN); + + poweroff_flag = 1; + schedule_work(&suspend_work); /* inform user to poweroff */ + } + else { + del_timer(&poweroff_timer); + init_timer(&poweroff_timer); + poweroff_timer.expires = jiffies + POWEROFF_PERIOD/10; + poweroff_timer.data = 0; + poweroff_timer.function = poweroff_timer_routine; + add_timer(&poweroff_timer); + } + } + else + { + printk("\nSuspend system now ..\n"); + num_seconds = 0; + suspend_flag = 1; + poweroff_flag = 0; + schedule_work(&suspend_work); /* we are entering suspend */ + } +} + +static void poweroff_delaytimer_routine(unsigned long dummy) +{ + __gpio_as_input(POWEROFF_PIN); + if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN) { + if (suspend_flag) { + suspend_flag = 0; + del_timer(&poweroff_delaytimer); + SET_POWEROFF_PIN_AS_IRQ; + __gpio_unmask_irq(POWEROFF_PIN); + return; + } + del_timer(&poweroff_delaytimer); + del_timer(&poweroff_timer); + init_timer(&poweroff_timer); + poweroff_timer.expires = jiffies + POWEROFF_PERIOD/100; + poweroff_timer.data = 0; + poweroff_timer.function = poweroff_timer_routine; + add_timer(&poweroff_timer); + } + else { + del_timer(&poweroff_delaytimer); + SET_POWEROFF_PIN_AS_IRQ; + __gpio_unmask_irq(POWEROFF_PIN); + + printk("This is a dummy key\n"); + } +} + +/* + * Poweroff pin interrupt handler + */ +static irqreturn_t poweroff_irq(int irq, void *dev_id) +{ + __gpio_ack_irq(POWEROFF_PIN); + __gpio_mask_irq(POWEROFF_PIN); + __gpio_as_input(POWEROFF_PIN); +#ifdef CONFIG_JZ_UDC_HOTPLUG + if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN && jz_udc_active == 0){ +#else + if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN){ +#endif + del_timer(&poweroff_delaytimer); + init_timer(&poweroff_delaytimer); + poweroff_delaytimer.expires = jiffies + POWEROFF_DELAY/10; + poweroff_delaytimer.data = 0; + poweroff_delaytimer.function = poweroff_delaytimer_routine; + add_timer(&poweroff_delaytimer); + } + else { + +/* + * If it reaches here without jz_udc_active == 0, then it indicates POWEROFF_PIN was + * changed to WAKEUP key in pm.c for hand is not able to rise up so quickly, so the + * irq handler entered because of WAKEUP key not POWEROFF_PIN. + */ + +#ifdef CONFIG_JZ_UDC_HOTPLUG + if (jz_udc_active == 1) + printk("\nUSB is working; Operation is denied\n"); +#endif + SET_POWEROFF_PIN_AS_IRQ; + __gpio_unmask_irq(POWEROFF_PIN); + } + + return IRQ_HANDLED; +} + +#ifdef CONFIG_PM + +static struct pm_dev *poweroff_dev; + +static int poweroff_suspend(int *poweroff , int state) +{ + suspend_flag = 1; + poweroff_flag = 0; + + return 0; +} + +static int poweroff_resume(int *poweroff) +{ + suspend_flag = 0; + SET_POWEROFF_PIN_AS_IRQ; + __gpio_unmask_irq(POWEROFF_PIN); + + return 0; +} + +static int poweroff_pm_callback(struct pm_dev *pm_dev, pm_request_t rqst, void *data) +{ + int ret; + int *poweroff_info = pm_dev->data; + + if (!poweroff_info) + return -EINVAL; + + switch (rqst) { + case PM_SUSPEND: + ret = poweroff_suspend(poweroff_info, (int)data); + break; + case PM_RESUME: + ret = poweroff_resume(poweroff_info); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +#endif /* CONFIG_PM */ + +#ifdef USE_SUSPEND_HOTPLUG +static void run_sbin_hotplug(int state) +{ + int i; + char *argv[3], *envp[8]; + char media[64], slotnum[16]; + if (!uevent_helper[0]) + return; + + i = 0; + argv[i++] = uevent_helper; + //argv[i++] = "home/lhhuang/hotplug"; + + if ( poweroff_flag == 1 ) + argv[i++] = "poweroff"; + else + argv[i++] = "suspend"; + + argv[i] = 0; + + /* minimal command environment */ + i = 0; + envp[i++] = "HOME=/"; + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + + /* other stuff we want to pass to /sbin/hotplug */ + sprintf(slotnum, "SLOT=0"); + + if ( poweroff_flag == 1 ) + sprintf(media, "MEDIA=poweroff"); + else + sprintf(media, "MEDIA=suspend"); + + envp[i++] = slotnum; + envp[i++] = media; + + if (state) + envp[i++] = "ACTION=enter"; + else + envp[i++] = "ACTION=exit"; + + envp[i] = 0; + + dprintk("SUSPEND: hotplug path=%s state=%d\n", argv[0], state); + + SET_POWEROFF_PIN_AS_IRQ; + __gpio_unmask_irq(POWEROFF_PIN); /* set it because call hotplug with call_usermodehelper() \ + might failed, especially when using nfsroot */ + + call_usermodehelper (argv [0], argv, envp, -1); +} +#endif + +static void suspend_handler(struct work_struct *work) +{ +#ifdef USE_SUSPEND_HOTPLUG + int state = 1; + run_sbin_hotplug(state); +#else + if (poweroff_flag) { + dprintk("DO_SHUTDOWN_SYSTEM\n"); + DO_SHUTDOWN_SYSTEM; + } else { + dprintk("DO_SUSPEND\n"); + DO_SUSPEND; + } +#endif +} + +static int __init poweroff_init(void) +{ + int retval; + + retval = request_irq(POWEROFF_IRQ, poweroff_irq, + IRQF_DISABLED, "poweroff", NULL); + + SET_POWEROFF_PIN_AS_IRQ; + + if (retval) { + printk("Could not get poweroff irq %d\n", POWEROFF_IRQ); + return retval; + } + +#ifdef CONFIG_PM + poweroff_dev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, poweroff_pm_callback); + if (poweroff_dev) { + poweroff_dev->data = &poweroff_dev; + } +#endif + + INIT_WORK(&suspend_work, suspend_handler); + + return 0; +} + +static void __exit poweroff_exit(void) +{ + free_irq(POWEROFF_IRQ, NULL); +} + +module_init(poweroff_init); +module_exit(poweroff_exit); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/sadc.c linux-2.6.24.3-20100304/drivers/char/jzchar/sadc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/sadc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/sadc.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,580 @@ +/* + * linux/drivers/char/jzchar/sadc.c + * + * SAR-ADC driver for JZ4740. + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jzchars.h" +#include "jz_ts.h" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("JZ4740 SADC driver"); +MODULE_LICENSE("GPL"); + +#define SADC_NAME "sadc" +static DECLARE_WAIT_QUEUE_HEAD (sadc_wait_queue); + +struct sadc_device { + int mode; + int dma_chan; + char *ts_buf; + char *pbat_buf; +}; + +static struct sadc_device *sadc_dev; + +static int samples = 3; /* we sample 3 every time */ +static int first_time = 0; +static unsigned long last_x, last_y, last_p; + +typedef struct datasource { + u16 xbuf; + u16 ybuf; + u16 zbuf; +}datasource_t; + +static datasource_t data_s; +static unsigned int p; +static unsigned int old_x, old_y; +extern unsigned int (*codec_read_battery)(void); + +/* + * set adc clock to 12MHz/div. A/D works at freq between 500KHz to 6MHz. + */ +static void sadc_init_clock(int div) +{ + if (div < 2) div = 2; + if (div > 23) div = 23; +#if defined(CONFIG_SOC_JZ4740) + REG_SADC_CFG &= ~SADC_CFG_CLKDIV_MASK; + REG_SADC_CFG |= (div - 1) << SADC_CFG_CLKDIV_BIT; +#endif +#if defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + REG_SADC_ADCLK &= ~SADC_ADCLK_CLKDIV_MASK; + REG_SADC_ADCLK |= (div - 1) << SADC_ADCLK_CLKDIV_BIT; + REG_SADC_ADCLK &= ~SADC_ADCLK_CLKDIV_BIT; + REG_SADC_ADCLK |= 39 << SADC_ADCLK_CLKDIV_10_BIT; /* if div ==3,here is 39 */ +#endif +} + +void start_sadcin(void) +{ + REG_SADC_CTRL &= ~SADC_CTRL_SRDYM; /* enable interrupt */ + REG_SADC_ENA |= SADC_ENA_SADCINEN; +} + +void start_pbat_adc(void) +{ + REG_SADC_CFG |= SADC_CFG_PBAT_HIGH ; /* full baterry voltage >= 2.5V */ +// REG_SADC_CFG |= SADC_CFG_PBAT_LOW; /* full baterry voltage < 2.5V */ + + REG_SADC_ENA |= SADC_ENA_PBATEN; /* Enable pbat adc */ +} + +void start_ts_adc(void) +{ + REG_SADC_SAMETIME = 10; /* about 0.1 ms,you can change it */ + REG_SADC_WAITTIME = 2; /* about 0.02 ms,you can change it */ + + REG_SADC_CFG &= ~(SADC_CFG_TS_DMA | SADC_CFG_XYZ_MASK | SADC_CFG_SNUM_MASK); + REG_SADC_CFG |= (SADC_CFG_EXIN | SADC_CFG_XYZ | SADC_CFG_SNUM_3); + REG_SADC_CTRL |= (SADC_CTRL_TSRDYM|SADC_CTRL_PBATRDYM|SADC_CTRL_PENUM |SADC_CTRL_SRDYM); + REG_SADC_CTRL &= ~SADC_CTRL_PENDM; + REG_SADC_ENA |= SADC_ENA_TSEN; +} + +static int jz4740_adc_read(struct jz_ts_t *ts) +{ + struct datasource *ds = &data_s; + u32 xybuf,z; + + if (!(REG_SADC_STATE & SADC_STATE_TSRDY)) { + /* sleep */ + REG_SADC_CTRL &= ~SADC_CTRL_TSRDYM; + ts->sleeping = 1; + sleep_on(&sadc_wait_queue); + } + ts->sleeping = 0; + + xybuf = REG_SADC_TSDAT; + ds->xbuf = (xybuf>>16) & 0x0fff; + ds->ybuf = (xybuf)& 0x0fff; + z = REG_SADC_TSDAT; + ds->zbuf = z& 0x0fff; + REG_SADC_STATE &= ~SADC_STATE_TSRDY; + return 0; +} + +/*------------------------------------------------------------ + * Read the battery voltage + */ +unsigned int jz4740_read_battery(void) +{ + unsigned int v; + unsigned int timeout = 0x3ff; + u16 pbat; + + if(!(REG_SADC_STATE & SADC_STATE_PBATRDY) ==1) + start_pbat_adc(); + + while(!(REG_SADC_STATE & SADC_STATE_PBATRDY) && --timeout) + ; + + pbat = REG_SADC_BATDAT; + v = pbat & 0x0fff; + REG_SADC_STATE = SADC_STATE_PBATRDY; + return v; +} + +/*------------------ Calibrate samples -------------------*/ + +#define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a))) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +#if 0 +#define XM 36 /* XM and YM may be changed for your screen */ +#define YM 20 +static int calibrate_samples(void *xbuf, void *ybuf, void *pbuf, int count) +{ + unsigned long usd0,usd1,usd2; + int xMaxError = XM,yMaxError = YM; + int x_valid = 0,y_valid = 0,valid = 0; + unsigned long x_cal = 0, y_cal = 0, p_cal = 0; + unsigned long *xp = (unsigned long *)xbuf; + unsigned long *yp = (unsigned long *)ybuf; + unsigned long *pp = (unsigned long *)pbuf; + + usd0 = (xp[0] > xp[1]) ? (xp[0] - xp[1]) : (xp[1] - xp[0]); + usd1 = (xp[1] > xp[2]) ? (xp[1] - xp[2]) : (xp[2] - xp[1]); + usd2 = (xp[2] > xp[0]) ? (xp[2] - xp[0]) : (xp[0] - xp[2]); + + if ( usd0 < usd1) + x_cal = xp[0] + ((usd2 < usd0) ? xp[2] : xp[1]); + else + x_cal= xp[2] + ((usd2 < usd1) ? xp[0] : xp[1]); + x_cal >>= 1; + + if ( (usd0 < xMaxError) && (usd1 < xMaxError) && (usd2 < xMaxError) ) + x_valid = 1; + + usd0 = (yp[0] > yp[1]) ? (yp[0] - yp[1]) : (yp[1] - yp[0]); + usd1 = (yp[1] > yp[2]) ? (yp[1] - yp[2]) : (yp[2] - yp[1]); + usd2 = (yp[2] > yp[0]) ? (yp[2] - yp[0]) : (yp[0] - yp[2]); + + if ( usd0 < usd1) + y_cal = yp[0] + ((usd2 < usd0) ? yp[2] : yp[1]); + else + y_cal = yp[2] + ((usd2 < usd1) ? yp[0] : yp[1]); + + y_cal >>= 1; + + if ( (usd0 < yMaxError) && (usd1 < yMaxError) && (usd2 < yMaxError) ) + y_valid = 1; + + if( x_valid && y_valid) + valid = 1; + + usd0 = (pp[0] > pp[1]) ? (pp[0] - pp[1]) : (pp[1] - pp[0]); + usd1 = (pp[1] > pp[2]) ? (pp[1] - pp[2]) : (pp[2] - pp[1]); + usd2 = (pp[2] > pp[0]) ? (pp[2] - pp[0]) : (pp[0] - pp[2]); + + if ( usd0 < usd1) + p_cal = pp[0] + ((usd2 < usd0) ? pp[2] : pp[1]); + else + p_cal= pp[2] + ((usd2 < usd1) ? pp[0] : pp[1]); + + p_cal >>= 1; + + if (first_time) { + first_time = 0; + last_x = x_cal; + last_y = y_cal; + last_p = p_cal; + } + else{ + if ((DIFF(x_cal, last_x) > 50) || + (DIFF(y_cal, last_y) > 50)) + valid = 0; + else + valid = 1; + } + *xp = last_x = x_cal; + *yp = last_y = y_cal; + *pp = last_p = p_cal; + + return valid; +} +#endif + +static int calibrate_samples(void *xbuf, void *ybuf, void *pbuf, int count) +{ + unsigned long *xp = (unsigned long *)xbuf; + unsigned long *yp = (unsigned long *)ybuf; + unsigned long *pp = (unsigned long *)pbuf; + unsigned long x_cal = 0, y_cal = 0, p_cal = 0; + int i; + int valid = 1; + + /* calculate the average of the rest */ + for (i = 0; i < count; i++) { + x_cal += xp[i]; + y_cal += yp[i]; + p_cal += pp[i]; + } + x_cal /= count; + y_cal /= count; + p_cal /= count; + + if (first_time) { + first_time = 0; + last_x = x_cal; + last_y = y_cal; + last_p = p_cal; + } + else { + if ((DIFF(x_cal, last_x) > 50) || + (DIFF(y_cal, last_y) > 50)) + valid = 0; + else + valid = 1; + } + + *xp = last_x = x_cal; + *yp = last_y = y_cal; + *pp = last_p = p_cal; + + return valid; +} + +#define TSMAXX 945 +#define TSMAXY 830 +#define TSMINX 90 +#define TSMINY 105 + +#define SCREEN_X 480 +#define SCREEN_Y 272 + +static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x ) +{ + + if (ts->minx) + { + if (x < ts->minx) x = ts->minx; + if (x > ts->maxx) x = ts->maxx; + + return (x - ts->minx) * SCREEN_X / (ts->maxx - ts->minx); + } + else + { + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return (x - TSMINX) * SCREEN_X / (TSMAXX - TSMINX); + } +} + +static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y) +{ + if (ts->minx) + { + if (y < ts->minx) y = ts->miny; + if (y > ts->maxx) y = ts->maxy; + + return (y - ts->miny) * SCREEN_Y / (ts->maxy - ts->miny); + } + else + { + if (y < TSMINX) y = TSMINY; + if (y > TSMAXX) y = TSMAXY; + + return (y - TSMINY) * SCREEN_Y / (TSMAXY - TSMINY); + } +} + +/* + * File operations + */ +static int sadc_open(struct inode *inode, struct file *filp); +static int sadc_release(struct inode *inode, struct file *filp); +static ssize_t sadc_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t sadc_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int sadc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); + +static struct file_operations sadc_fops = +{ + open: sadc_open, + release: sadc_release, + read: sadc_read, + write: sadc_write, + ioctl: sadc_ioctl +}; + +static int sadc_open(struct inode *inode, struct file *filp) +{ + try_module_get(THIS_MODULE); + return 0; +} + +static int sadc_release(struct inode *inode, struct file *filp) +{ + module_put(THIS_MODULE); + return 0; +} + +static ssize_t sadc_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + return size; +} + +static ssize_t sadc_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + return size; +} + +static int sadc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return 0; +} + +/*------------------ Common routines -------------------*/ + +void ts_enable_irq(void) +{ + REG_SADC_CTRL &= ~SADC_CTRL_PENDM; +} + +void ts_disable_irq(void) +{ + REG_SADC_CTRL |= (SADC_CTRL_PENDM | SADC_CTRL_PENUM); +} + +void ts_free_irq(struct jz_ts_t *ts) +{ + free_irq(ts->pendown_irq, ts); +} + +void ts_data_ready(void) +{ + REG_SADC_CTRL |= SADC_CTRL_TSRDYM; + wake_up(&sadc_wait_queue); +} + +/* + * Interrupt handler + */ +void ts_irq_callback(void) +{ + u32 state; + + state = REG_SADC_STATE; + if (!(REG_SADC_CTRL&SADC_CTRL_PENDM)&&(REG_SADC_STATE & SADC_STATE_PEND)) { + REG_SADC_STATE = SADC_STATE_PEND; + REG_SADC_STATE = SADC_STATE_PENU; + REG_SADC_CTRL |= SADC_CTRL_PENDM; + REG_SADC_CTRL &= ~SADC_CTRL_PENUM; + p = 1; + } + + if (!(REG_SADC_CTRL&SADC_CTRL_PENUM)&&(REG_SADC_STATE & SADC_STATE_PENU)) { + REG_SADC_STATE = SADC_STATE_PENU; + REG_SADC_CTRL |= SADC_CTRL_PENUM; + REG_SADC_CTRL &= ~SADC_CTRL_PENDM; + p = 0; + } + + first_time = 1; // first time to acquire sample +} + +int PenIsDown(void) +{ + return p; +} + +int ts_request_irq(u32 *irq, + irqreturn_t (*handler)(int, void *), + const char *devname, + void *dev_id) +{ + int ret; + + /* return the irq number */ + *irq = IRQ_SADC; + ts_disable_irq(); + /* interrupt mode */ + ret = request_irq(IRQ_SADC, handler, IRQF_DISABLED, + devname, dev_id); + if(ret) + printk("failed irq \n"); + + start_ts_adc(); + return ret; +} + +/* + * Acquire Raw pen coodinate data and compute touch screen + * pressure resistance. Hold spinlock when calling. + */ +int AcquireEvent(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned int x_raw[8], y_raw[8], p_raw[8]; + int valid, i; + unsigned int avl_x, avl_y, diff_x, diff_y; + struct datasource *ds = &data_s; + avl_x = avl_y = 0; + + for (i = 0; i < samples; i++) { + if (jz4740_adc_read(ts)) { + return 0; + } + + x_raw[i] = ds->ybuf; + y_raw[i] = ds->xbuf; + p_raw[i] = ds->zbuf; + avl_x += x_raw[i]; + avl_y += y_raw[i]; +#if 0 + printk("x_raw=%x y_raw=%x z_raw=%x\n",x_raw[i],y_raw[i],p_raw[i]); +#endif + } + + avl_x /= samples; + avl_y /= samples; +#define MAX_DELTA 20 + valid = 1; + + for (i = 1; i < samples; i++) + { + if ((100 * DIFF(x_raw[i],x_raw[i-1])/MIN(x_raw[i],x_raw[i-1])) > MAX_DELTA) { + valid = 0; + break; + } + + if ((100 * DIFF(y_raw[i],y_raw[i-1])/MIN(y_raw[i],y_raw[i-1])) > MAX_DELTA) { + valid = 0; + break; + } + + if ((100 * DIFF(p_raw[i],p_raw[i-1])/MIN(p_raw[i],p_raw[i-1])) > MAX_DELTA) { + valid = 0; + break; + } + } + + if (valid) { + if (ts->first_read) { + ts->first_read = 0; + old_x = avl_x; + old_y = avl_y; + } + diff_x = DIFF(old_x, avl_x); + diff_y = DIFF(old_y, avl_y); + if (diff_x < 100 && diff_y < 100) { + old_x = avl_x; + old_y = avl_y; + } else + valid = 0; + } + if (valid) { + valid = calibrate_samples(x_raw, y_raw, p_raw, samples); + } + + if (valid) { + unsigned int x_scr, y_scr; + + if(ts->filter) { + x_scr = transform_to_screen_x(ts, x_raw[0]); + y_scr = transform_to_screen_y(ts, y_raw[0]); + + if (ts->prints) + printk("x_raw=%d y_raw=%d x_transform=%d y_transform=%d\n", x_raw[0], y_raw[0], x_scr, y_scr); + } + else { + x_scr = x_raw[0]; + y_scr = y_raw[0]; + + if (ts->prints) + printk("x_raw=%d y_raw=%d \n", x_raw[0], y_raw[0]); + } + + event->x = x_scr; + event->y = y_scr; + event->pressure = (u16)p_raw[0]; + event->status = PENDOWN; + return 1; + } + return 0; +} + +/* + * Module init and exit + */ +static int __init sadc_init(void) +{ + struct sadc_device *dev; + int ret; + + /* allocate device */ + dev = kmalloc(sizeof(struct sadc_device), GFP_KERNEL); + if (!dev) return -ENOMEM; + + sadc_dev = dev; + ret = jz_register_chrdev(SADC_MINOR, SADC_NAME, &sadc_fops, dev); + if (ret < 0) { + kfree(dev); + return ret; + } + + codec_read_battery = jz4740_read_battery; + sadc_init_clock(3); + + printk("JZ4740 SAR-ADC driver registered\n"); + return 0; +} + +static void __exit sadc_exit(void) +{ + struct sadc_device *dev = sadc_dev; + + free_irq(IRQ_SADC, dev); + jz_unregister_chrdev(SADC_MINOR, SADC_NAME); + kfree(dev); +} + +module_init(sadc_init); +module_exit(sadc_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/sensor.c linux-2.6.24.3-20100304/drivers/char/jzchar/sensor.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/sensor.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/sensor.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,182 @@ +/* + * linux/drivers/char/jzchar/sensor.c + * + * Common CMOS Camera Sensor Driver + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jzchars.h" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("Common CMOS Camera Sensor Driver"); +MODULE_LICENSE("GPL"); + +/* + * ioctl commands + */ +#define IOCTL_SET_ADDR 0 /* set i2c address */ +#define IOCTL_SET_CLK 1 /* set i2c clock */ +#define IOCTL_WRITE_REG 2 /* write sensor register */ +#define IOCTL_READ_REG 3 /* read sensor register */ + +/* + * i2c related + */ +static unsigned int i2c_addr = 0x42; +static unsigned int i2c_clk = 100000; + +static void write_reg(u8 reg, u8 val) +{ + i2c_open(); + i2c_setclk(i2c_clk); + i2c_write((i2c_addr >> 1), &val, reg, 1); + i2c_close(); +} + +static u8 read_reg(u8 reg) +{ + u8 val; + + i2c_open(); + i2c_setclk(i2c_clk); + i2c_read((i2c_addr >> 1), &val, reg, 1); + i2c_close(); + return val; +} + +/* + * fops routines + */ + +static int sensor_open(struct inode *inode, struct file *filp); +static int sensor_release(struct inode *inode, struct file *filp); +static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int sensor_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +static struct file_operations sensor_fops = +{ + open: sensor_open, + release: sensor_release, + read: sensor_read, + write: sensor_write, + ioctl: sensor_ioctl, +}; + +static int sensor_open(struct inode *inode, struct file *filp) +{ + try_module_get(THIS_MODULE); + return 0; +} + +static int sensor_release(struct inode *inode, struct file *filp) +{ + module_put(THIS_MODULE); + return 0; +} + +static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + printk("sensor: read is not implemented\n"); + return -1; +} + +static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("sensor: write is not implemented\n"); + return -1; +} + +static int sensor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case IOCTL_SET_ADDR: + if (copy_from_user(&i2c_addr, (void *)arg, 4)) + return -EFAULT; + break; + case IOCTL_SET_CLK: + if (copy_from_user(&i2c_clk, (void *)arg, 4)) + return -EFAULT; + break; + case IOCTL_WRITE_REG: + { + u8 regval[2]; + + if (copy_from_user(regval, (void *)arg, 2)) + return -EFAULT; + + write_reg(regval[0], regval[1]); + break; + } + case IOCTL_READ_REG: + { + u8 reg, val; + + if (copy_from_user(®, (void *)arg, 1)) + return -EFAULT; + + val = read_reg(reg); + + if (copy_to_user((void *)(arg + 1), &val, 1)) + return -EFAULT; + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return ret; +} + +/* + * Module init and exit + */ + +static int __init sensor_init(void) +{ + int ret; + + ret = jz_register_chrdev(SENSOR_MINOR, "sensor", &sensor_fops, NULL); + if (ret < 0) { + return ret; + } + + printk("Ingenic CMOS camera sensor driver registered\n"); + + return 0; +} + +static void __exit sensor_exit(void) +{ + jz_unregister_chrdev(SENSOR_MINOR, "sensor"); +} + +module_init(sensor_init); +module_exit(sensor_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/tcsm.c linux-2.6.24.3-20100304/drivers/char/jzchar/tcsm.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/tcsm.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/tcsm.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,123 @@ +/* + * linux/drivers/char/jzchar/tcsm.c + * + * Virtual device driver with tricky appoach to manage TCSM + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "jzchars.h" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("Virtual Driver of TCSM"); +MODULE_LICENSE("GPL"); + +/* + * fops routines + */ + +static int tcsm_open(struct inode *inode, struct file *filp); +static int tcsm_release(struct inode *inode, struct file *filp); +static ssize_t tcsm_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t tcsm_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int tcsm_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +static struct file_operations tcsm_fops = +{ + open: tcsm_open, + release: tcsm_release, + read: tcsm_read, + write: tcsm_write, + ioctl: tcsm_ioctl, +}; + +static int tcsm_open(struct inode *inode, struct file *filp) +{ + struct pt_regs *info = task_pt_regs(current); + + info->cp0_status &= ~0x10;// clear UM bit + info->cp0_status |= 0x08000000; // set RP bit a tricky + + return 0; +} + +static int tcsm_release(struct inode *inode, struct file *filp) +{ + struct pt_regs *info = task_pt_regs(current); + + info->cp0_status |= 0x10;// set UM bit + info->cp0_status &= ~0x08000000; // clear RP bit a tricky + + return 0; +} + +static ssize_t tcsm_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + printk("tcsm: read is not implemented\n"); + return -1; +} + +static ssize_t tcsm_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("tcsm: write is not implemented\n"); + return -1; +} + +static int tcsm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + printk("tcsm: ioctl is not implemented\n"); + return ret; +} + +/* + * Module init and exit + */ + +static int __init tcsm_init(void) +{ + int ret; + + ret = jz_register_chrdev(TCSM_MINOR, "tcsm", &tcsm_fops, NULL); + if (ret < 0) { + return ret; + } + + printk("Virtual Driver of TCSM registered\n"); + return 0; +} + +static void __exit tcsm_exit(void) +{ + jz_unregister_chrdev(TCSM_MINOR, "tcsm"); +} + +module_init(tcsm_init); +module_exit(tcsm_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ucb1400.c linux-2.6.24.3-20100304/drivers/char/jzchar/ucb1400.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ucb1400.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/ucb1400.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,585 @@ +/* + * ucb1400.c + * + * Touch screen driver interface to the UCB1400 codec. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jz_ts.h" +#include "ucb1400.h" + +#ifndef GPIO_TS_PENIRQ +#define GPIO_TS_PENIRQ 68 +#endif + +#define TS_PIN GPIO_TS_PENIRQ +#define TS_IRQ (IRQ_GPIO_0 + TS_PIN) + +static int samples = 5; /* we sample 5 every time, and throw away the max and min cases, then use the average of the other 3 samples */ +static int first_time = 0; +static unsigned long last_x, last_y, last_p; + +static int adcsync = 0; + +static unsigned int ucb_id = 0; +static struct ucb1400 *ucb; + +extern struct ac97_codec * find_ac97_codec(void); + +extern unsigned int (*codec_read_battery)(void); + +/*------------------ UCB1400 routines ------------------*/ + +static inline void ucb1400_reg_write(unsigned char reg, unsigned short val) +{ + struct ac97_codec *codec = find_ac97_codec(); + if (!codec) + return; + codec->codec_write(codec, reg, val); +} + +static inline unsigned int ucb1400_reg_read(unsigned char reg) +{ + struct ac97_codec *codec = find_ac97_codec(); + if (!codec) + return 0; + return codec->codec_read(codec, reg); +} + +static void ucb1400_adc_enable(void) +{ + down(&ucb->adc_sem); + + ucb->adc_cr |= UCB_ADC_ENA; + ucb1400_reg_write(UCB_ADC_CR, ucb->adc_cr); +} + +static unsigned int ucb1400_adc_read(int adc_channel, int sync) +{ + unsigned int val, timeout = 10000; + + if (sync) + adc_channel |= UCB_ADC_SYNC_ENA; + + ucb1400_reg_write(UCB_ADC_CR, ucb->adc_cr | adc_channel); + ucb1400_reg_write(UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START); + + for (;;) { + val = ucb1400_reg_read(UCB_ADC_DATA); + if (val & UCB_ADC_DAT_VAL) + break; + if (--timeout == 0) + break; + udelay(1); + } + + return UCB_ADC_DAT(val); +} + +static void ucb1400_adc_disable(void) +{ + ucb->adc_cr &= ~UCB_ADC_ENA; + ucb1400_reg_write(UCB_ADC_CR, ucb->adc_cr); + + up(&ucb->adc_sem); +} + +static void ucb1400_enable_irq(unsigned int idx, int edges) +{ + unsigned long flags; + + if (idx < 16) { + spin_lock_irqsave(&ucb->lock, flags); + + /* This prevents spurious interrupts on the UCB1400 */ + ucb1400_reg_write(UCB_IE_CLEAR, 1 << idx); + ucb1400_reg_write(UCB_IE_CLEAR, 0); + + if (edges & UCB_RISING) { + ucb->irq_ris_enbl |= 1 << idx; + ucb1400_reg_write(UCB_IE_RIS, ucb->irq_ris_enbl); + } + if (edges & UCB_FALLING) { + ucb->irq_fal_enbl |= 1 << idx; + ucb1400_reg_write(UCB_IE_FAL, ucb->irq_fal_enbl); + } + spin_unlock_irqrestore(&ucb->lock, flags); + } +} + +static void ucb1400_disable_irq(unsigned int idx, int edges) +{ + unsigned long flags; + + if (idx < 16) { + spin_lock_irqsave(&ucb->lock, flags); + + if (edges & UCB_RISING) { + ucb->irq_ris_enbl &= ~(1 << idx); + ucb1400_reg_write(UCB_IE_RIS, ucb->irq_ris_enbl); + } + if (edges & UCB_FALLING) { + ucb->irq_fal_enbl &= ~(1 << idx); + ucb1400_reg_write(UCB_IE_FAL, ucb->irq_fal_enbl); + } + spin_unlock_irqrestore(&ucb->lock, flags); + } +} + +/* + * Switch to interrupt mode. + */ +static inline void ucb1400_ts_mode_int(void) +{ + if (!ucb_id) { + ucb_id = ucb1400_reg_read(UCB_ID); + } + + if (ucb_id == UCB_ID_1400_BUGGY) + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | + UCB_TS_CR_MODE_INT); + else + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | + UCB_TS_CR_MODE_INT); +} + +/* + * Switch to pressure mode, and read pressure. We don't need to wait + * here, since both plates are being driven. + */ +static inline unsigned int ucb1400_ts_read_pressure(void) +{ + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + + return ucb1400_adc_read(UCB_ADC_INP_TSPY, adcsync); +} + +/* + * Switch to X position mode and measure Y plate. We switch the plate + * configuration in pressure mode, then switch to position mode. This + * gives a faster response time. Even so, we need to wait about 55us + * for things to stabilise. + */ +static inline unsigned int ucb1400_ts_read_xpos(void) +{ + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); + + udelay(55); + + return ucb1400_adc_read(UCB_ADC_INP_TSPY, adcsync); +} + +/* + * Switch to Y position mode and measure X plate. We switch the plate + * configuration in pressure mode, then switch to position mode. This + * gives a faster response time. Even so, we need to wait about 55us + * for things to stabilise. + */ +static inline unsigned int ucb1400_ts_read_ypos(void) +{ + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + ucb1400_reg_write(UCB_TS_CR, + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); + + udelay(55); + + return ucb1400_adc_read(UCB_ADC_INP_TSPX, adcsync); +} + +/*------------------------------------------------------------ + * Read the battery voltage + */ + +unsigned int ucb1400_read_battery(void) +{ + unsigned int v; + + ucb1400_adc_enable(); + + // read twice to reduce fault value + v = ucb1400_adc_read(UCB_ADC_INP_AD0, adcsync); + v = ucb1400_adc_read(UCB_ADC_INP_AD0, adcsync); + + ucb1400_adc_disable(); + +// printk("ucb1400_read_battery v=%d\n", v); + + return v; +} + +/*------------------ Calibrate samples -------------------*/ + +#define DIFF(a,b) ((a>b)?(a-b):(b-a)) + +static int calibrate_samples(void *xbuf, void *ybuf, void *pbuf, int count) +{ + unsigned long *xp = (unsigned long *)xbuf; + unsigned long *yp = (unsigned long *)ybuf; + unsigned long *pp = (unsigned long *)pbuf; + unsigned long x_cal = 0, y_cal = 0, p_cal = 0, tmp; + int ignored, i, j; + int valid = 0; + + /* throw away the max cases */ + tmp = xp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (xp[i] > tmp) { + tmp = xp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + xp[j++] = xp[i]; + } + + tmp = yp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (yp[i] > tmp) { + tmp = yp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + yp[j++] = yp[i]; + } + + tmp = pp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (pp[i] > tmp) { + tmp = pp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + pp[j++] = pp[i]; + } + + /* throw away the min cases */ + + count -= 1; // decrement by 1 + + tmp = xp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (xp[i] < tmp) { + tmp = xp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + xp[j++] = xp[i]; + } + + tmp = yp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (yp[i] < tmp) { + tmp = yp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + yp[j++] = yp[i]; + } + + tmp = pp[0]; + ignored = 0; + for (i = 1; i < count; i++) { + if (pp[i] < tmp) { + tmp = pp[i]; + ignored = i; + } + } + j = 0; + for (i = 0; i < count; i++) { + if (i == ignored) + continue; + pp[j++] = pp[i]; + } + + count -= 1; // decrement by 1 + + /* calculate the average of the rest */ + for (i = 0; i < count; i++) { + x_cal += xp[i]; + y_cal += yp[i]; + p_cal += pp[i]; + } + x_cal /= count; + y_cal /= count; + p_cal /= count; + + if (first_time) { + first_time = 0; + last_x = x_cal; + last_y = y_cal; + last_p = p_cal; + valid = 1; + } + else { + if ((DIFF(x_cal, last_x) > 50) || + (DIFF(y_cal, last_y) > 50)) + valid = 0; + else + valid = 1; + } + +// printk("x_cal=%d y_cal=%d p_cal=%d valid=%d\n", x_cal, y_cal, p_cal, valid); + + if (valid) { + *xp = last_x = x_cal; + *yp = last_y = y_cal; + *pp = last_p = p_cal; + } + + return valid; +} + + +#define TSMAXX 945 +#define TSMAXY 830 +#define TSMINX 90 +#define TSMINY 105 + +#define SCREEN_X 480 +#define SCREEN_Y 272 + +static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x ) +{ + + if (ts->minx) + { + if (x < ts->minx) x = ts->minx; + if (x > ts->maxx) x = ts->maxx; + + return (x - ts->minx) * SCREEN_X / (ts->maxx - ts->minx); + } + else + { + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return (x - TSMINX) * SCREEN_X / (TSMAXX - TSMINX); + } +} + +static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y) +{ + if (ts->minx) + { + if (y < ts->minx) y = ts->miny; + if (y > ts->maxx) y = ts->maxy; + + return (y - ts->miny) * SCREEN_Y / (ts->maxy - ts->miny); + } + else + { + if (y < TSMINX) y = TSMINY; + if (y > TSMAXX) y = TSMAXY; + + return (y - TSMINY) * SCREEN_Y / (TSMAXY - TSMINY); + } +} + +/*------------------ Common routines -------------------*/ + +void ts_enable_irq(void) +{ + /* interrupt mode */ + ucb1400_ts_mode_int(); + ucb1400_enable_irq(UCB_IRQ_TSPX, UCB_FALLING); + + enable_irq(TS_IRQ); +} + +void ts_disable_irq(void) +{ + ucb1400_disable_irq(UCB_IRQ_TSPX, UCB_FALLING); + disable_irq(TS_IRQ); +} + +int ts_request_irq(u32 *irq, + void (*handler)(int, void *, struct pt_regs *), + const char *devname, + void *dev_id) +{ + int retval; + + /* return the irq number */ + *irq = TS_IRQ; + + /* interrupt mode */ + ucb1400_ts_mode_int(); + ucb1400_enable_irq(UCB_IRQ_TSPX, UCB_FALLING); + + /* enable gpio irq */ + __gpio_as_irq_rise_edge(TS_PIN); + + /* register irq handler */ + retval = request_irq(TS_IRQ, handler, SA_INTERRUPT, devname, dev_id); + + return retval; +} + +void ts_free_irq(struct jz_ts_t *ts) +{ + free_irq(ts->pendown_irq, ts); +} + +void ts_irq_callback(void) +{ + /* clear interrupt status */ + ucb1400_reg_write(UCB_IE_CLEAR, ucb1400_reg_read(UCB_IE_STATUS)); + __gpio_ack_irq(TS_PIN); + + first_time = 1; // first time to acquire sample +} + +int PenIsDown(void) +{ + unsigned int p; + + ucb1400_adc_enable(); + p = ucb1400_ts_read_pressure(); + ucb1400_adc_disable(); + + return (p > 100) ? 1 : 0; +} + +/* + * Acquire Raw pen coodinate data and compute touch screen + * pressure resistance. Hold spinlock when calling. + */ +int AcquireEvent(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned int x_raw[8], y_raw[8], p_raw[8]; + int valid, i; + + /* Enable ADC */ + ucb1400_adc_enable(); + + for (i = 0; i < samples; i++) { + x_raw[i] = ucb1400_ts_read_xpos(); + } + for (i = 0; i < samples; i++) { + y_raw[i] = ucb1400_ts_read_ypos(); + } + for (i = 0; i < samples; i++) { + p_raw[i] = ucb1400_ts_read_pressure(); + } + + /* Disable ADC */ + ucb1400_adc_disable(); + + valid = calibrate_samples(x_raw, y_raw, p_raw, samples); + + if (valid) { + unsigned int x_scr, y_scr; + + if(ts->filter) { + x_scr = transform_to_screen_x(ts, x_raw[0]); + y_scr = transform_to_screen_y(ts, y_raw[0]); + + if (ts->prints) + printk("x_raw=%d y_raw=%d x_transform=%d y_transform=%d\n", x_raw[0], y_raw[0], x_scr, y_scr); + } + else { + x_scr = x_raw[0]; + y_scr = y_raw[0]; + + if (ts->prints) + printk("x_raw=%d y_raw=%d \n", x_raw[0], y_raw[0]); + } + + event->x = x_scr; + event->y = y_scr; + event->pressure = (u16)p_raw[0]; + event->status = PENDOWN; + return 1; + } + return 0; +} + +/* + * Module init and exit + */ + +int __init ucb1400_init(void) +{ + ucb = kmalloc(sizeof(struct ucb1400), GFP_KERNEL); + if (!ucb) return -ENOMEM; + + memset(ucb, 0, sizeof(struct ucb1400)); + + codec_read_battery = ucb1400_read_battery; + + spin_lock_init(&ucb->lock); + sema_init(&ucb->adc_sem, 1); + + return 0; +} + +void ucb1400_cleanup(void) +{ + kfree(ucb); +} + +module_init(ucb1400_init); +module_exit(ucb1400_cleanup); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ucb1400.h linux-2.6.24.3-20100304/drivers/char/jzchar/ucb1400.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/ucb1400.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/ucb1400.h 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,113 @@ +#ifndef __UCB1400_H__ +#define __UCB1400_H__ + +/* ucb1400 aclink register mappings */ + +#define UCB_IO_DATA 0x5a +#define UCB_IO_DIR 0x5c +#define UCB_IE_RIS 0x5e +#define UCB_IE_FAL 0x60 +#define UCB_IE_STATUS 0x62 +#define UCB_IE_CLEAR 0x62 +#define UCB_TS_CR 0x64 +#define UCB_ADC_CR 0x66 +#define UCB_ADC_DATA 0x68 +#define UCB_ID 0x7e /* 7c is mfr id, 7e part id (from aclink spec) */ + +#define UCB_ADC_DAT(x) ((x) & 0x3ff) + +/* register bits */ + +#define UCB_IO_0 (1 << 0) +#define UCB_IO_1 (1 << 1) +#define UCB_IO_2 (1 << 2) +#define UCB_IO_3 (1 << 3) +#define UCB_IO_4 (1 << 4) +#define UCB_IO_5 (1 << 5) +#define UCB_IO_6 (1 << 6) +#define UCB_IO_7 (1 << 7) +#define UCB_IO_8 (1 << 8) +#define UCB_IO_9 (1 << 9) + +#define UCB_IE_ADC (1 << 11) +#define UCB_IE_TSPX (1 << 12) +#define UCB_IE_TSMX (1 << 13) +#define UCB_IE_TCLIP (1 << 14) +#define UCB_IE_ACLIP (1 << 15) + +#define UCB_IRQ_TSPX 12 + +#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */ +#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */ + +#define UCB_TC_B_VOICE_ENA (1 << 3) +#define UCB_TC_B_CLIP (1 << 4) +#define UCB_TC_B_ATT (1 << 6) +#define UCB_TC_B_SIDE_ENA (1 << 11) +#define UCB_TC_B_MUTE (1 << 13) +#define UCB_TC_B_IN_ENA (1 << 14) +#define UCB_TC_B_OUT_ENA (1 << 15) + +#define UCB_AC_B_LOOP (1 << 8) +#define UCB_AC_B_MUTE (1 << 13) +#define UCB_AC_B_IN_ENA (1 << 14) +#define UCB_AC_B_OUT_ENA (1 << 15) + +#define UCB_TS_CR_TSMX_POW (1 << 0) +#define UCB_TS_CR_TSPX_POW (1 << 1) +#define UCB_TS_CR_TSMY_POW (1 << 2) +#define UCB_TS_CR_TSPY_POW (1 << 3) +#define UCB_TS_CR_TSMX_GND (1 << 4) +#define UCB_TS_CR_TSPX_GND (1 << 5) +#define UCB_TS_CR_TSMY_GND (1 << 6) +#define UCB_TS_CR_TSPY_GND (1 << 7) +#define UCB_TS_CR_MODE_INT (0 << 8) +#define UCB_TS_CR_MODE_PRES (1 << 8) +#define UCB_TS_CR_MODE_POS (2 << 8) +#define UCB_TS_CR_BIAS_ENA (1 << 11) +#define UCB_TS_CR_TSPX_LOW (1 << 12) +#define UCB_TS_CR_TSMX_LOW (1 << 13) + +#define UCB_ADC_SYNC_ENA (1 << 0) +#define UCB_ADC_VREFBYP_CON (1 << 1) +#define UCB_ADC_INP_TSPX (0 << 2) +#define UCB_ADC_INP_TSMX (1 << 2) +#define UCB_ADC_INP_TSPY (2 << 2) +#define UCB_ADC_INP_TSMY (3 << 2) +#define UCB_ADC_INP_AD0 (4 << 2) +#define UCB_ADC_INP_AD1 (5 << 2) +#define UCB_ADC_INP_AD2 (6 << 2) +#define UCB_ADC_INP_AD3 (7 << 2) +#define UCB_ADC_EXT_REF (1 << 5) +#define UCB_ADC_START (1 << 7) +#define UCB_ADC_ENA (1 << 15) + +#define UCB_ADC_DAT_VAL (1 << 15) + +#define UCB_ID_1200 0x1004 +#define UCB_ID_1300 0x1005 +#define UCB_ID_1400 0x4304 +#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */ + +#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) +#define UCB_MODE_AUD_OFF_CAN (1 << 13) + +/* + * Which edges of the IRQ do you want to control today? + */ +#define UCB_RISING (1 << 0) +#define UCB_FALLING (1 << 1) + +/* Device data structure */ + +struct ucb1400 { + spinlock_t lock; + struct pm_dev *pmdev; + struct semaphore adc_sem; + u16 adc_cr; + u16 irq_fal_enbl; + u16 irq_ris_enbl; + int irq_enabled; +}; + +#endif /* __UCB1400_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/udc_hotplug.c linux-2.6.24.3-20100304/drivers/char/jzchar/udc_hotplug.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/udc_hotplug.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/udc_hotplug.c 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,451 @@ +/* + * linux/drivers/char/jzchar/udc_hotplug.c + * + * New UDC hotplug driver. + * + * Copyright (C) 2007 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "jzchars.h" + +#ifndef GPIO_UDC_HOTPLUG +#define GPIO_UDC_HOTPLUG 86 +#endif + +#define UDC_HOTPLUG_PIN GPIO_UDC_HOTPLUG +#define UDC_HOTPLUG_IRQ (IRQ_GPIO_0 + UDC_HOTPLUG_PIN) + +#define dprintk(x,...) + +//simple meaning define +#define NOT_CONNECT 0 +#define YES_CONNECT 1 +#define MAX_GPIO_TIME 50 + +#define EVENT_USB_ADD 1 +#define EVENT_USB_REMOVE 2 +#define EVENT_POWER_ADD 3 +#define EVENT_POWER_REMOVE 4 +#define EVENT_POWER_TO_USB 5 +#define EVENT_USB_SUSPEND_POWER 6 + +struct udc_pnp_stat +{ + char cable_stat, old_cable_stat; + char protl_stat, old_protl_stat; + char object_stat1; + char object_stat2; +}; + +static struct udc_pnp_stat cur_pnp_stat; + +static struct file_operations cable_fops = { + owner: THIS_MODULE, +}; + +static struct miscdevice cable_dev= +{ + 231, + "udc_cable", + &cable_fops +}; + +static struct file_operations power_fops = { + owner: THIS_MODULE, +}; + +static struct miscdevice power_dev= +{ + 232, + "power_cable", + &power_fops +}; + +int jz_udc_active = 0; /* 0: Have no actions; 1: Have actions */ + +static int udc_pin_level; +static int udc_old_state; +static int udc_pin_time; + +static struct timer_list udc_long_timer, udc_gpio_timer; + +/* Kernel thread to deliver event to user space */ +static struct task_struct *kudcd_task; + +static void udc_gpio_timer_routine(unsigned long data) +{ + wake_up_process(kudcd_task); +} + +static void udc_long_timer_routine(unsigned long data) +{ + dprintk("udc_timer\n"); + if (jz_udc_active) + udc_old_state = 1; + if (!jz_udc_active && udc_old_state) //udc irq timeout! do suspend + { + dprintk("udc suspend!\n"); + udc_old_state = 0; + cur_pnp_stat.protl_stat = NOT_CONNECT; + del_timer(&udc_long_timer); + wake_up_process(kudcd_task); + return; + } + jz_udc_active = 0; + udc_long_timer.expires = jiffies + 3 * HZ; /* about 3 s */ + add_timer(&udc_long_timer); +} + +static int udc_get_pnp_stat(void) +{ + udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN); + udc_pin_time = 1; + + init_timer(&udc_gpio_timer); + del_timer(&udc_gpio_timer); + udc_gpio_timer.function = udc_gpio_timer_routine; + udc_gpio_timer.expires = jiffies + 1; /* about 10 ms */ + add_timer(&udc_gpio_timer); + + while(1) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + if (__gpio_get_pin(UDC_HOTPLUG_PIN) != udc_pin_level) + { + udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN); + udc_pin_time = 1; + dprintk("udc gpio detect restart! \n"); + } + + udc_pin_time ++; + if (udc_pin_time > MAX_GPIO_TIME) + break; + + del_timer(&udc_gpio_timer); + udc_gpio_timer.function = udc_gpio_timer_routine; + udc_gpio_timer.expires = jiffies + 1; /* about 10 ms */ + add_timer(&udc_gpio_timer); + } + + del_timer(&udc_gpio_timer); + if (__gpio_get_pin(UDC_HOTPLUG_PIN)) + return YES_CONNECT; + else + return NOT_CONNECT; +} + +static void udc_get_cable(void) +{ + u32 intr_usb; + + __intc_mask_irq(IRQ_UDC); + + /* Now enable PHY to start detect */ +#ifdef CONFIG_SOC_JZ4740 + REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; +#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE; +#endif + /* Clear IRQs */ + REG16(USB_REG_INTRINE) = 0; + REG16(USB_REG_INTROUTE) = 0; + REG8(USB_REG_INTRUSBE) = 0; + + /* disable UDC IRQs first */ + REG16(USB_REG_INTRINE) = 0; + REG16(USB_REG_INTROUTE) = 0; + REG8(USB_REG_INTRUSBE) = 0; + + /* Disable DMA */ + REG32(USB_REG_CNTL1) = 0; + REG32(USB_REG_CNTL2) = 0; + + /* Enable HS Mode */ + REG8(USB_REG_POWER) |= USB_POWER_HSENAB; + /* Enable soft connect */ + REG8(USB_REG_POWER) |= USB_POWER_SOFTCONN; + + dprintk("enable phy! %x %x %x %x %x\n", + REG8(USB_REG_POWER), + REG_CPM_SCR, + REG16(USB_REG_INTRINE), + REG16(USB_REG_INTROUTE), + REG8(USB_REG_INTRUSBE)); + + init_timer(&udc_gpio_timer); + del_timer(&udc_gpio_timer); + udc_gpio_timer.function = udc_gpio_timer_routine; + udc_gpio_timer.expires = jiffies + 11; /* about 100 ms */ + add_timer(&udc_gpio_timer); + /* Sleep a short time to see result */ + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + del_timer(&udc_gpio_timer); + intr_usb = REG8(USB_REG_INTRUSB); + if ((intr_usb & USB_INTR_RESET) || + (intr_usb & USB_INTR_RESUME) || + (intr_usb & USB_INTR_SUSPEND)) + { + cur_pnp_stat.protl_stat = YES_CONNECT; + dprintk("cable is usb! \n"); + } + else + { + cur_pnp_stat.protl_stat = NOT_CONNECT; + dprintk("cable is power! \n"); + } + + /* Detect finish ,clean every thing */ + /* Disconnect from usb */ + REG8(USB_REG_POWER) &= ~USB_POWER_SOFTCONN; + /* Disable the USB PHY */ +#ifdef CONFIG_SOC_JZ4740 + REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE; +#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE; +#endif + /* Clear IRQs */ + REG16(USB_REG_INTRINE) = 0; + REG16(USB_REG_INTROUTE) = 0; + REG8(USB_REG_INTRUSBE) = 0; + __intc_ack_irq(IRQ_UDC); + __intc_unmask_irq(IRQ_UDC); +} + +static void send_event_udev(int event) +{ + dprintk("Send udev message: cable=%d old=%d protl=%d old=%d \n", + cur_pnp_stat.cable_stat, + cur_pnp_stat.old_cable_stat, + cur_pnp_stat.protl_stat, + cur_pnp_stat.old_protl_stat); + + switch (event) + { + case EVENT_USB_ADD: + printk("usb cable insert! \n"); + misc_register(&cable_dev); + kobject_uevent(&cable_dev.this_device->kobj, KOBJ_ADD); + init_timer(&udc_long_timer); + del_timer(&udc_long_timer); + udc_long_timer.function = udc_long_timer_routine; + udc_long_timer.expires = jiffies + 3 * HZ; /* about 3 s */ + add_timer(&udc_long_timer); + break; + case EVENT_USB_REMOVE: + printk("usb cable remove! \n"); + kobject_uevent(&cable_dev.this_device->kobj, KOBJ_REMOVE); + misc_deregister(&cable_dev); + del_timer(&udc_long_timer); + break; + case EVENT_POWER_ADD: + printk("power cable insert! \n"); + misc_register(&power_dev); + kobject_uevent(&power_dev.this_device->kobj, KOBJ_ADD); + break; + case EVENT_POWER_REMOVE: + printk("power cable remove! \n"); + kobject_uevent(&power_dev.this_device->kobj, KOBJ_REMOVE); + misc_deregister(&power_dev); + break; + case EVENT_POWER_TO_USB: + printk("change power cable to usb! \n"); + kobject_uevent(&power_dev.this_device->kobj, KOBJ_REMOVE); + misc_deregister(&power_dev); + misc_register(&cable_dev); + kobject_uevent(&cable_dev.this_device->kobj, KOBJ_ADD); + break; + case EVENT_USB_SUSPEND_POWER: + printk("usb cable suspend! \n"); + printk("as power cable insert! \n"); + kobject_uevent(&cable_dev.this_device->kobj, KOBJ_REMOVE); + misc_deregister(&cable_dev); + misc_register(&power_dev); + kobject_uevent(&power_dev.this_device->kobj, KOBJ_ADD); + break; + }; +} + +static void udc_pnp_detect(void) +{ + if (cur_pnp_stat.cable_stat == YES_CONNECT) /* already connected! */ + { + if (udc_get_pnp_stat() == NOT_CONNECT) + { + dprintk("cable real out! \n"); + cur_pnp_stat.cable_stat = NOT_CONNECT; + cur_pnp_stat.protl_stat = NOT_CONNECT; + /* Deliver this event to user space in udev model */ + if (cur_pnp_stat.old_protl_stat) + send_event_udev(EVENT_USB_REMOVE); + else + send_event_udev(EVENT_POWER_REMOVE); + cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat; + cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat; + } + else + { + if (cur_pnp_stat.old_protl_stat != cur_pnp_stat.protl_stat) + { + send_event_udev(EVENT_USB_SUSPEND_POWER); + cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat; + cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat; + } + else //change power to cable + { +#if 0 //not support yet! + udc_get_cable(); + if (cur_pnp_stat.old_protl_stat != cur_pnp_stat.protl_stat) + send_event_udev(EVENT_POWER_TO_USB); + cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat; + cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat; +#endif + } + } + } + else + { + if (udc_get_pnp_stat() == YES_CONNECT) + { + dprintk("cable real in! \n"); + cur_pnp_stat.cable_stat = YES_CONNECT; + udc_get_cable(); + /* Deliver this event to user space in udev model */ + if (cur_pnp_stat.protl_stat) + send_event_udev(EVENT_USB_ADD); + else + send_event_udev(EVENT_POWER_ADD); + cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat; + cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat; + } + else + dprintk("cable false in! \n"); + + } +} + +static void udc_pnp_set_gpio(void) +{ + if (cur_pnp_stat.cable_stat == YES_CONNECT) + __gpio_as_irq_fall_edge(UDC_HOTPLUG_PIN); + else + __gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN); + + /* clear interrupt pending status */ + __gpio_ack_irq(UDC_HOTPLUG_PIN); + /* unmask interrupt */ + __gpio_unmask_irq(UDC_HOTPLUG_PIN); +} + +static int udc_pnp_thread(void *unused) +{ + printk(KERN_NOTICE "UDC starting pnp monitor thread\n"); + + while(1) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + dprintk("pnp thread wake up! \n"); + /* wake up here */ + udc_pnp_detect(); + /* Reset gpio state last */ + udc_pnp_set_gpio(); + } +} + +static irqreturn_t udc_pnp_irq(int irq, void *dev_id) +{ + printk("udc_pnp_irq----\n"); + /* clear interrupt pending status */ + __gpio_ack_irq(UDC_HOTPLUG_PIN); + /* mask interrupt */ + __gpio_mask_irq(UDC_HOTPLUG_PIN); + /* wake up pnp detect thread */ + wake_up_process(kudcd_task); + + return IRQ_HANDLED; +} + +/* + * Module init and exit + */ +static int __init udc_hotplug_init(void) +{ + int retval; + /* Init pnp stat first */ + cur_pnp_stat.cable_stat = NOT_CONNECT; + cur_pnp_stat.protl_stat = NOT_CONNECT; + cur_pnp_stat.old_cable_stat = NOT_CONNECT; + cur_pnp_stat.old_protl_stat = NOT_CONNECT; + cur_pnp_stat.object_stat1 = NOT_CONNECT; + cur_pnp_stat.object_stat2 = NOT_CONNECT; + udc_old_state = 0; + + /* create pnp thread and register IRQ */ + kudcd_task = kthread_run(udc_pnp_thread, NULL, "kudcd"); + if (IS_ERR(kudcd_task)) { + printk(KERN_ERR "jz_udc_hotplug: Failed to create system monitor thread.\n"); + return PTR_ERR(kudcd_task); + } + + retval = request_irq(UDC_HOTPLUG_IRQ, udc_pnp_irq, + IRQF_DISABLED, "udc_pnp", NULL); + if (retval) { + printk("Could not get udc hotplug irq %d\n", UDC_HOTPLUG_IRQ); + return retval; + } + + /* get current pin level */ + __gpio_disable_pull(UDC_HOTPLUG_PIN); + __gpio_as_input(UDC_HOTPLUG_PIN); + udelay(1); + udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN); + + if (udc_pin_level) { + dprintk("Cable already in! \n"); + /* Post a event */ + wake_up_process(kudcd_task); + } + else { + __gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN); + dprintk("Cable not in! \n"); + } + + printk("JZ UDC hotplug driver registered\n"); + + return 0; +} + +static void __exit udc_hotplug_exit(void) +{ + free_irq(UDC_HOTPLUG_IRQ, NULL); +} + +module_init(udc_hotplug_init); +module_exit(udc_hotplug_exit); + +EXPORT_SYMBOL(jz_udc_active); + +MODULE_AUTHOR("Lucifer "); +MODULE_DESCRIPTION("JzSOC OnChip udc hotplug driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/wm9712.c linux-2.6.24.3-20100304/drivers/char/jzchar/wm9712.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/wm9712.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/wm9712.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,334 @@ +/* + * wm9712.c + * + * Touch screen driver interface to the Wolfson WM9712 codec. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jz_ts.h" +#include "wm9712.h" + +#define POLL_TIMES 10 + +static int samples = 1; +static int inited = 0, started = 0; + +extern struct ac97_codec * find_ac97_codec(void); +extern int PenIsDown(void); + + +static inline void wm9712_reg_write(unsigned int reg, unsigned int val) +{ + struct ac97_codec *codec = find_ac97_codec(); + if (!codec) + return; + codec->codec_write(codec, reg, val); +} + +static inline unsigned int wm9712_reg_read(unsigned int reg) +{ + struct ac97_codec *codec = find_ac97_codec(); + if (!codec) + return 0; + return codec->codec_read(codec, reg); +} + +static unsigned int wm9712_adc_read(int adc_channel) +{ + unsigned int val; + + if (!PenIsDown()) + return 0; + + val = wm9712_reg_read(DIGI_REG1); + wm9712_reg_write(DIGI_REG1, val|adc_channel|DIGI_REG1_POLL); + + for (;;) { + if (wm9712_reg_read(0x54) & (1 << 12)) { + val = wm9712_reg_read(DIGI_READBACK); + break; + } + } + + /* stop the measure */ + wm9712_reg_write(DIGI_REG1, 0); + + return (val & 0x0fff); +} + +static struct timer_list pndn_timer; +static void (*irq_handler)(int, void *, struct pt_regs *) = NULL; + +void ts_irq_callback(void) +{ +#ifdef TS_IRQ + __gpio_ack_irq(TS_IRQ); +#else +#endif +} + +void ts_enable_irq(void) +{ + if (!inited) + return; +#ifdef TS_IRQ + enable_irq(TS_IRQ); +#else + pndn_timer.expires = jiffies + HZ/POLL_TIMES; + add_timer(&pndn_timer); +#endif +} + +void ts_disable_irq(void) +{ + if (!inited) + return; +#ifdef TS_IRQ + disable_irq(TS_IRQ); +#endif +} + +#ifndef TS_IRQ +static void pndn_detect(unsigned long data) +{ + if (PenIsDown()) { + if (!started) + return; + if (irq_handler) + irq_handler(NULL, data, NULL); + } else { + pndn_timer.expires = jiffies + HZ/POLL_TIMES; + add_timer(&pndn_timer); + } +} +#endif + +void ts_free_irq(struct jz_ts_t *ts) +{ +#ifdef TS_IRQ + free_irq(ts->pendown_irq, ts); +#else + started = 0; + del_timer_sync(&pndn_timer); +#endif +} + +int ts_request_irq(u32 *irq, + void (*handler)(int, void *, struct pt_regs *), + const char *devname, + void *dev_id) +{ + /* 4wire, Ip=400uA, Rpu=64Kohm/64, wake-up on pendown without + * reset, meassure on pen down. Do not use wait mode. + */ + started = 1; + if (!inited) { + wm9712_reg_write(DIGI_REG2, + DIGI_REG2_WIRE_4 | + DIGI_REG2_PIL_200uA | + (31 << DIGI_REG2_RPU_BIT) | + DIGI_REG2_PRP_ALLON | + DIGI_REG2_RPR_NWOR); + /* Polling mode and no measurement */ + wm9712_reg_write(DIGI_REG1, 0); + } + +#ifdef TS_IRQ + /* Generate irq request on PENDOWN pin, pendown cause the level high */ + wm9712_reg_write(0x56, wm9712_reg_read(0x56) & ~(1 << 3)); + wm9712_reg_write(0x4c, wm9712_reg_read(0x4c) & ~(1 << 3)); + + *irq = TS_IRQ; + return request_irq(TS_IRQ, handler, SA_INTERRUPT, devname, dev_id); +#else + if (!inited) { + irq_handler = handler; + init_timer(&pndn_timer); + pndn_timer.function = pndn_detect; + pndn_timer.data = (unsigned long)dev_id; + pndn_timer.expires = jiffies + HZ/POLL_TIMES; + add_timer(&pndn_timer); + inited = 1; + } else { + pndn_timer.expires = jiffies + HZ/POLL_TIMES; + add_timer(&pndn_timer); + } + return 0; +#endif +} + +int PenIsDown(void) +{ + if (wm9712_reg_read(DIGI_READBACK) & DIGI_READBACK_PNDN) + return 1; + return 0; +} + +#if defined(CONFIG_MIPS_JZ4730_GPS) +#define adj_data(r1, r2, r3, s) \ +do { \ + if (r1 < 0x90) \ + r1 = 0x90; \ + if (r2 < 0xed) \ + r2 = 0xed; \ + r1 = ((r1 - 0x90) * 240) / 3354; \ + r2 = ((r2 - 0xed) * 320) / 3671; \ + if (r1 > 239) \ + r1 = 239; \ + if (r2 > 319) \ + r2 = 319; \ + \ + *s = r2; \ + *(s+1) = 239 - r1; \ + *(s+2) = z_raw; \ +} while (0) +#endif + +#ifndef adj_data +#define adj_data(r1, r2, r3, s) +#endif + +static int read_adc(unsigned int *sdata) +{ + unsigned long x_raw=0, y_raw=0, z_raw=0, t, fail = 0; + int i; + + for (i=0; i 1) { + x_raw = (x_raw + (samples>>1)) / samples; + y_raw = (y_raw + (samples>>1)) / samples; + z_raw = (z_raw + (samples>>1)) / samples; + } + + adj_data (x_raw, y_raw, z_raw, sdata); + + return 1; +} + + +#define TSMAXX 945 +#define TSMAXY 830 +#define TSMINX 90 +#define TSMINY 105 + +#define SCREEN_X 480 +#define SCREEN_Y 272 + +static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x ) +{ + + if (ts->minx) + { + if (x < ts->minx) x = ts->minx; + if (x > ts->maxx) x = ts->maxx; + + return (x - ts->minx) * SCREEN_X / (ts->maxx - ts->minx); + } + else + { + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return (x - TSMINX) * SCREEN_X / (TSMAXX - TSMINX); + } +} + +static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y) +{ + if (ts->minx) + { + if (y < ts->minx) y = ts->miny; + if (y > ts->maxx) y = ts->maxy; + + return (y - ts->miny) * SCREEN_Y / (ts->maxy - ts->miny); + } + else + { + if (y < TSMINX) y = TSMINY; + if (y > TSMAXX) y = TSMAXY; + + return (y - TSMINY) * SCREEN_Y / (TSMAXY - TSMINY); + } +} + + +/* + * Acquire Raw pen coodinate data and compute touch screen + * pressure resistance. Hold spinlock when calling. + */ +int AcquireEvent(struct jz_ts_t *ts, struct ts_event *event) +{ + unsigned int s[3]; + unsigned int x_scr, y_scr; + if (!read_adc(s)) + return 0; + if(ts->filter) { + x_scr = transform_to_screen_x(ts, s[0]); + y_scr = transform_to_screen_y(ts, s[1]); + + if (ts->prints) + printk("x_raw=%d y_raw=%d x_transform=%d y_transform=%d\n", s[0], s[1], x_scr, y_scr); } + else { + x_scr = s[0]; + y_scr = s[1]; + + if (ts->prints) + printk("x_raw=%d y_raw=%d \n", s[0], s[1]); + } + event->x = x_scr; + event->y = y_scr; + event->pressure = (u16)s[2]; + event->status = PENDOWN; + return 1; +#if 0 + do_gettimeofday(&event->stamp); +#endif +} + +int __init wm9712_init(void) +{ + return 0; +} + +void wm9712_cleanup(void) +{ +} + +module_init(wm9712_init); +module_exit(wm9712_cleanup); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/wm9712.h linux-2.6.24.3-20100304/drivers/char/jzchar/wm9712.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/jzchar/wm9712.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/jzchar/wm9712.h 2010-03-03 19:03:58.000000000 -0800 @@ -0,0 +1,58 @@ +#ifndef __WM9712_H__ +#define __WM9712_H__ + +#define DIGI_REG1 0x76 +#define DIGI_REG2 0x78 +#define DIGI_READBACK 0x7A + +#define ADCSEL_BIT 12 +#define ADCSEL_MASK (7 << ADCSEL_BIT) +#define ADCSEL_NONE (0 << ADCSEL_BIT) +#define ADCSEL_XPOS (1 << ADCSEL_BIT) +#define ADCSEL_YPOS (2 << ADCSEL_BIT) +#define ADCSEL_PRESSURE (3 << ADCSEL_BIT) +#define ADCSEL_COMP1 (4 << ADCSEL_BIT) +#define ADCSEL_COMP2 (5 << ADCSEL_BIT) +#define ADCSEL_BMON (6 << ADCSEL_BIT) +#define ADCSEL_WIPER (7 << ADCSEL_BIT) + +#define DIGI_REG1_CTC (1 << 10) +#define DIGI_REG1_POLL (1 << 15) +#define DIGI_REG1_CR_BIT 8 +#define DIGI_REG1_CR_MASK (3 << DIGI_REG1_CR_BIT) +#define DIGI_REG1_COO (1 << 11) +#define DIGI_REG1_SLEN (1 << 3) +#define DIGI_REG1_SLT_BIT 0 +#define DIGI_REG1_SLT_MASK (7 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_5 (0 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_6 (1 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_7 (2 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_8 (3 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_9 (4 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_10 (5 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_11 (6 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_SLT_RES (7 << DIGI_REG1_SLT_BIT) +#define DIGI_REG1_DEL_BIT 4 +#define DIGI_REG1_DEL_MASK (0x0f << DIGI_REG1_DEL_BIT) + +#define DIGI_REG2_WIRE_5 (1 << 12) +#define DIGI_REG2_WIRE_4 (0 << 12) +#define DIGI_REG2_RPU_BIT 0 +#define DIGI_REG2_RPU_MASK (0x3f << DIGI_REG2_RPU_BIT) +#define DIGI_REG2_PIL_400uA (1 << 8) +#define DIGI_REG2_PIL_200uA (0 << 8) +#define DIGI_REG2_PRP_BIT 14 +#define DIGI_REG2_PRP_MASK (3 << DIGI_REG2_PRP_BIT) +#define DIGI_REG2_PRP_ALLOFF (0 << DIGI_REG2_PRP_BIT) +#define DIGI_REG2_PRP_WOP (1 << DIGI_REG2_PRP_BIT) +#define DIGI_REG2_PRP_NWOP (2 << DIGI_REG2_PRP_BIT) +#define DIGI_REG2_PRP_ALLON (3 << DIGI_REG2_PRP_BIT) +#define DIGI_REG2_RPR_WOR (0 << 13) +#define DIGI_REG2_RPR_NWOR (1 << 13) +#define DIGI_REG2_PDEN (1 << 11) +#define DIGI_REG2_WAIT (1 << 9) + +#define DIGI_READBACK_PNDN (1 << 15) + +#endif /* __WM9712_H__ */ + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/Kconfig linux-2.6.24.3-20100304/drivers/char/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/Kconfig 2010-03-03 19:03:57.000000000 -0800 @@ -731,6 +731,16 @@ To compile this driver as a module, choose M here: the module will be called rtc. +config RTC_PCF8563 + bool 'Philips PCF8563 Real Time Clock (I2C Bus)' + help + Philips PCF8563 Real Time Clock (I2C Bus) + +config RTC_JZ + bool 'Jz47XX On-Chip Real Time Clock' + help + Jz47XX On-Chip Real Time Clock + config JS_RTC tristate "Enhanced Real Time Clock Support" depends on SPARC32 && PCI @@ -1039,6 +1049,7 @@ default y source "drivers/s390/char/Kconfig" +source "drivers/char/jzchar/Kconfig" endmenu diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/Makefile linux-2.6.24.3-20100304/drivers/char/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/Makefile 2010-03-03 19:03:57.000000000 -0800 @@ -97,6 +97,10 @@ obj-$(CONFIG_GPIO_TB0219) += tb0219.o obj-$(CONFIG_TELCLOCK) += tlclk.o +obj-$(CONFIG_RTC_PCF8563) += rtc_pcf8563.o +obj-$(CONFIG_RTC_JZ) += rtc_jz.o +obj-$(CONFIG_JZCHAR) += jzchar/ + obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_AGP) += agp/ obj-$(CONFIG_DRM) += drm/ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_jz.c linux-2.6.24.3-20100304/drivers/char/rtc_jz.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_jz.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/rtc_jz.c 2010-03-03 19:03:55.000000000 -0800 @@ -0,0 +1,504 @@ +/* + * Jz OnChip Real Time Clock interface for Linux + * + * NOTE: we need to wait rtc write ready before read or write RTC registers. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* get the user-level API */ +#include +#include + +#include "rtc_jz.h" + + +char sbin_rtc_alarm_handler_path[] = "/sbin/rtcalarm"; +//call_usermodehelper(char *path, char **argv, char **envp, int wait) +//extern int call_usermodehelper(char *path, char **argv, char **envp); + +extern spinlock_t rtc_lock; + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + + +static void get_rtc_time (struct rtc_time *rtc_tm); +static int set_rtc_time (struct rtc_time *rtc_tm); +static void get_rtc_alm_time (struct rtc_time *alm_tm); +static int set_rtc_alm_time (struct rtc_time *alm_tm); + +static void set_rtc_irq_bit(int bit); +static void mask_rtc_irq_bit(int bit); + +static unsigned int rtc_status = 0; +static unsigned int epoch = 1900; + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + unsigned long lval; + struct rtc_time ltm; + + spin_lock_irq(&rtc_lock); + while ( !__rtc_write_ready() ) ; + lval = REG_RTC_RSR; + rtc_time_to_tm(lval, <m); + if(rtc_valid_tm(<m) == 0) { + /* is valid */ + rtc_tm->tm_sec = ltm.tm_sec; + rtc_tm->tm_min = ltm.tm_min; + rtc_tm->tm_hour = ltm.tm_hour; + rtc_tm->tm_mday = ltm.tm_mday; + rtc_tm->tm_wday = ltm.tm_wday; + rtc_tm->tm_mon = ltm.tm_mon; + rtc_tm->tm_year = ltm.tm_year; + } else { + printk("invlaid data / time!\n"); + } + spin_unlock_irq(&rtc_lock); +} + +static int set_rtc_time(struct rtc_time *rtc_tm) +{ + unsigned long lval; + + rtc_tm_to_time(rtc_tm, &lval); + + spin_lock_irq(&rtc_lock); + while ( !__rtc_write_ready() ) ; + REG_RTC_RSR = lval; + + spin_unlock_irq(&rtc_lock); + + return 0; + +} + +static void get_rtc_alm_time(struct rtc_time *alm_tm) +{ + unsigned long lval; + struct rtc_time altm; + + spin_lock_irq(&rtc_lock); + while ( !__rtc_write_ready() ) ; + lval = REG_RTC_RSAR; + rtc_time_to_tm(lval, &altm); + if(rtc_valid_tm(&altm) == 0) { + /* is valid */ + alm_tm->tm_sec = altm.tm_sec; + alm_tm->tm_min = altm.tm_min; + alm_tm->tm_hour = altm.tm_hour; + alm_tm->tm_mday = altm.tm_mday; + alm_tm->tm_wday = altm.tm_wday; + alm_tm->tm_mon = altm.tm_mon; + alm_tm->tm_year = altm.tm_year; + } else { + printk("invlaid data / time in Line:%d!\n",__LINE__); + } + spin_unlock_irq(&rtc_lock); +} + +static int set_rtc_alm_time(struct rtc_time *alm_tm) +{ + unsigned long lval; + + rtc_tm_to_time(alm_tm, &lval); + + spin_lock_irq(&rtc_lock); + while ( !__rtc_write_ready() ) ; + REG_RTC_RSAR = lval; + + while ( !__rtc_write_ready() ) ; /* set alarm function */ + if ( !((REG_RTC_RCR>>2) & 0x1) ) { + while ( !__rtc_write_ready() ) ; + __rtc_enable_alarm(); + } + + while ( !__rtc_write_ready() ) ; + if ( !(REG_RTC_RCR & RTC_RCR_AIE) ) { /* Enable alarm irq */ + __rtc_enable_alarm_irq(); + } + + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static void get_rtc_wakeup_alarm(struct rtc_wkalrm *wkalm) +{ + int enabled, pending; + + get_rtc_alm_time(&wkalm->time); + + spin_lock_irq(&rtc_lock); + while ( !__rtc_write_ready() ) ; + enabled = (REG_RTC_HWCR & 0x1); + pending = 0; + if ( enabled ) { + if ( (u32)REG_RTC_RSAR > (u32)REG_RTC_RSR ) /* 32bit val */ + pending = 1; + } + + wkalm->enabled = enabled; + wkalm->pending = pending; + spin_unlock_irq(&rtc_lock); +} + +static int set_rtc_wakeup_alarm(struct rtc_wkalrm *wkalm) +{ + int enabled; + //int pending; + + enabled = wkalm->enabled; + //pending = wkalm->pending; /* Fix me, what's pending mean??? */ + + while ( !__rtc_write_ready() ) ; /* set wakeup alarm enable */ + if ( enabled != (REG_RTC_HWCR & 0x1) ) { + while ( !__rtc_write_ready() ) ; + REG_RTC_HWCR = (REG_RTC_HWCR & ~0x1) | enabled; + } + while ( !__rtc_write_ready() ) ; /* set alarm function */ + if ( enabled != ((REG_RTC_RCR>>2) & 0x1) ) { + while ( !__rtc_write_ready() ) ; + REG_RTC_RCR = (REG_RTC_RCR & ~(1<<2)) | (enabled<<2); + } + + if ( !enabled ) /* if disabled wkalrm, rturn. */ + { + return 0; + } + + while ( !__rtc_write_ready() ) ; + if ( !(REG_RTC_RCR & RTC_RCR_AIE) ) { /* Enable alarm irq */ + __rtc_enable_alarm_irq(); + } + + set_rtc_alm_time(&wkalm->time); + + return 0; +} + + +static void set_rtc_irq_bit( int bit ) +{ + spin_lock_irq(&rtc_lock); + + while ( !__rtc_write_ready() ) ; + REG_RTC_RCR |= (1<= 0xc0 + * means "don't care" or "match all". Only the tm_hour, + * tm_min, and tm_sec values are filled in. + */ + + get_rtc_alm_time(&wtime); + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; + + case RTC_ALM_SET: /* Store a time into the alarm */ + { + struct rtc_time alm_tm; + + if (copy_from_user(&alm_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + if(rtc_valid_tm(&alm_tm) != 0) { + printk("invalid time set in Line:%d! \n",__LINE__); + return -EFAULT; + } + + return set_rtc_alm_time(&alm_tm); + } + case RTC_RD_TIME: /* Read the time/date from RTC */ + get_rtc_time(&wtime); + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + if(rtc_valid_tm(&rtc_tm) != 0) { + printk("invalid time set in Line:%d! \n",__LINE__); + return -EFAULT; + } + + return set_rtc_time(&rtc_tm); + } + case RTC_EPOCH_READ: /* Read the epoch. */ + return put_user (epoch, (unsigned long *)arg); + case RTC_EPOCH_SET: /* Set the epoch. */ + /* + * There were no RTC clocks before 1900. + */ + if (arg < 1900) + return -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + epoch = arg; + return 0; + case RTC_WKALM_SET: /* Wake alarm set. */ + { + struct rtc_wkalrm wkalrm; + + if (copy_from_user(&wkalrm, (struct rtc_wkalrm*)arg, + sizeof(struct rtc_wkalrm))) + return -EFAULT; + return set_rtc_wakeup_alarm(&wkalrm); + } + case RTC_WKALM_RD: /* Wake alarm read. */ + { + struct rtc_wkalrm wkalrm; + get_rtc_wakeup_alarm(&wkalrm); + return copy_to_user((void *)arg, &wkalrm, sizeof(struct rtc_wkalrm)) ? -EFAULT : 0; + } + /* set power down: shut down the machine. */ + case RTC_POWER_DOWN: /* enter HIBERNATE mode */ + dprintk("Power down. Bye....\n"); + while ( !__rtc_write_ready() ) ; + REG_RTC_HCR = 0x1; + return 0; +#ifdef DEBUG + case RTC_PRINT_REG: /* Print RTC registers */ + print_rtc_registers(); + return 0; +#endif + default: + return -EINVAL; + } + return 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +/* We use rtc_lock to protect against concurrent opens. So the BKL is not + * needed here. Or anywhere else in this driver. */ +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq (&rtc_lock); + + if(rtc_status) + goto out_busy; + + rtc_status = 1; + + spin_unlock_irq (&rtc_lock); + return 0; + +out_busy: + spin_unlock_irq (&rtc_lock); + return -EBUSY; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + + rtc_status = 0; + /* No need for locking -- nobody else can do anything until this rmw is + * committed, and no timer is running. */ + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + llseek: no_llseek, + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, +}; + + +static void run_sbin_rtc_alarm( void ) +{ + int i; + char *argv[2], *envp[3]; + + if (!sbin_rtc_alarm_handler_path[0]) + return; + + print_dbg(": sbin_rtc_alarm_handler_path=%s\n", sbin_rtc_alarm_handler_path); + + i = 0; + argv[i++] = sbin_rtc_alarm_handler_path; + argv[i] = 0; + + /* minimal command environment */ + i = 0; + envp[i++] = "HOME=/"; + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + + /* other stuff we want to pass to /sbin/hotplug */ + + envp[i] = 0; + + call_usermodehelper (argv [0], argv, envp, 0); +} + +static void rtc_alarm_task_handler(struct work_struct *work) +{ + run_sbin_rtc_alarm(); +} + +static struct work_struct rtc_alarm_task; + +static irqreturn_t jz_rtc_interrupt(int irq, void *dev_id) +{ + REG_RTC_HCR = 0x0; + printk("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); + spin_lock_irq(&rtc_lock); + + if ( __rtc_get_1Hz_flag() ) { + while ( !__rtc_write_ready() ) ; + __rtc_clear_1Hz_flag(); + dprintk("RTC 1Hz interrupt occur.\n"); + } + + if ( __rtc_get_alarm_flag() ) { /* rtc alarm interrupt */ + while ( !__rtc_write_ready() ) ; + __rtc_clear_alarm_flag(); + dprintk("RTC alarm interrupt occur.\n"); + //schedule_task( &rtc_alarm_task ); + schedule_work( &rtc_alarm_task ); + } + spin_unlock_irq(&rtc_lock); + + return IRQ_HANDLED; +} + + +#define RTC_MINOR 135 + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +int __init Jz_rtc_init(void) +{ + + INIT_WORK(&rtc_alarm_task, rtc_alarm_task_handler); + + /* Enabled rtc function, enable rtc alarm function */ + while ( !__rtc_write_ready() ) ; /* need we wait for WRDY??? */ + if ( !(REG_RTC_RCR & RTC_RCR_RTCE) || !(REG_RTC_RCR &RTC_RCR_AE) ) { + REG_RTC_RCR |= RTC_RCR_AE | RTC_RCR_RTCE; + } + /* clear irq flags */ + __rtc_clear_1Hz_flag(); + /* In a alarm reset, we expect a alarm interrupt. + * We can do something in the interrupt handler. + * So, do not clear alarm flag. + */ +/* __rtc_clear_alarm_flag(); */ + + if (request_irq(IRQ_RTC, jz_rtc_interrupt, 0, "rtc", NULL) < 0) + return -EBUSY; + + misc_register(&rtc_dev); + + printk("JzSOC onchip RTC installed !!!\n"); + return 0; + +} + +void __exit Jz_rtc_exit (void) +{ + misc_deregister(&rtc_dev); + free_irq (IRQ_RTC, NULL); +} + +module_init(Jz_rtc_init); +module_exit(Jz_rtc_exit); + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_jz.h linux-2.6.24.3-20100304/drivers/char/rtc_jz.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_jz.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/rtc_jz.h 2010-03-03 19:03:56.000000000 -0800 @@ -0,0 +1,74 @@ +#ifndef __RTC_JZ_H__ +#define __RTC_JZ_H__ + +//#define DEBUG 1 +#undef DEBUG + +#ifdef DEBUG +#define dprintk(x...) printk(x) +#define print_dbg(f, arg...) \ + printk("%s, %s[%d]:" f , __FUNCTION__, __FILE__, __LINE__ , ##arg ) +#else +#define dprintk(x...) +#define print_dbg(n, arg...) +#endif + + +#ifdef DEBUG + +static void print_rtc_time( struct rtc_time * tm ) +{ + printk("%02d%02d-%02d:%02d:%02d-%d\n", tm->tm_mon, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year); + printk("sec:\t%d\n", tm->tm_sec); + printk("min:\t%d\n", tm->tm_min); + printk("hour:\t%d\n", tm->tm_hour); + printk("mday:\t%d\n", tm->tm_mday); + printk("mon:\t%d\n", tm->tm_mon); + printk("year:\t%d\n", tm->tm_year); + printk("wday:\t%d\n", tm->tm_wday); + printk("yday:\t%d\n", tm->tm_yday); + printk("isdst:\t%d\n", tm->tm_isdst); + +} + +static void print_rtc_registers( void ) +{ + while ( !__rtc_write_ready() ) ; + printk("REG_RTC_RCR:\t 0x%8.8x\n", REG_RTC_RCR ); + printk("REG_RTC_RSR:\t 0x%8.8x\n", REG_RTC_RSR ); + printk("REG_RTC_RSAR:\t 0x%8.8x\n", REG_RTC_RSAR ); + printk("REG_RTC_RGR:\t 0x%8.8x\n", REG_RTC_RGR ); + printk("REG_RTC_HCR:\t 0x%8.8x\n", REG_RTC_HCR ); + printk("REG_RTC_HWFCR:\t 0x%8.8x\n", REG_RTC_HWFCR ); + printk("REG_RTC_HRCR:\t 0x%8.8x\n", REG_RTC_HRCR ); + printk("REG_RTC_HWCR:\t 0x%8.8x\n", REG_RTC_HWCR ); + printk("REG_RTC_HWRSR:\t 0x%8.8x\n", REG_RTC_HWRSR ); + printk("REG_RTC_HSPR:\t 0x%8.8x\n", REG_RTC_HSPR ); +} + +#define RTC_PRINT_REG _IOR('p', 0x12, unsigned long)/* Set power down */ +#endif /* #ifdef DEBUG */ + + +/* + * JZSOC ioctl calls that are permitted to the /dev/rtc interface + */ + +#define RTC_ENABLED _IO('p', 0x11) /* enable rtc */ +#define RTC_DISABLED _IO('p', 0x12) /* disable rtc */ +#define RTC_ALM_ON _IO('p', 0x13) /* enable rtc */ +#define RTC_ALM_OFF _IO('p', 0x14) /* disable rtc */ +#define RTC_1HZIE_ON _IO('p', 0x15) /* 1Hz int. enable on */ +#define RTC_1HZIE_OFF _IO('p', 0x16) /* ... off */ + +#define RTC_POWER_DOWN _IOR('p', 0x11, unsigned long)/* Set power down */ + +/* Registers define */ +/* RTC Control register */ +#define RTC_AIE 3 /* jz4740_06_rtc_spec.pdf, RTC Control Register */ +#define RTC_1HZIE 5 /* ... */ +#define RTC_ALM_EN 2 /* ... */ +#define RTC_EN 0 /* ... */ + +#endif /* #define __RTC_JZ_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_pcf8563.c linux-2.6.24.3-20100304/drivers/char/rtc_pcf8563.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/char/rtc_pcf8563.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/char/rtc_pcf8563.c 2010-03-03 19:03:57.000000000 -0800 @@ -0,0 +1,448 @@ +/* + * PCF8563 Real Time Clock interface for Linux + * + * It only support 24Hour Mode, And the stored values are in BCD format. + * The alarm register is start at minute reg, no second alarm register. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* get the user-level API */ +#include +#include + +/********************************************************************** + * register summary + **********************************************************************/ +#define RTC_SECONDS 2 +#define RTC_MINUTES 3 +#define RTC_HOURS 4 +#define RTC_DAY_OF_MONTH 5 +#define RTC_DAY_OF_WEEK 6 +#define RTC_MONTH 7 +#define RTC_YEAR 8 + +#define RTC_MINUTES_ALARM 9 +#define RTC_HOURS_ALARM 0x0a +#define RTC_DAY_ALARM 0x0b +#define RTC_WEEKDAY_ALARM 0x0c + +/* control registers - Moto names + */ +#define RTC_CONTROL 0x00 +#define RTC_STATUS 0x01 +#define RTC_CLKOUT 0x0d +#define RTC_TIMERCTL 0x0e +#define RTC_TIMERCOUNTDOWN 0x0f + + +/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) + * determines if the following two #defines are needed + */ +#ifndef BCD2BIN +#define BCD2BIN(val) (((val) & 0x0f) + ((val) >> 4) * 10) +#endif + +#ifndef BIN2BCD +#define BIN2BCD(val) ((((val) / 10) << 4) + (val) % 10) +#endif + +extern spinlock_t rtc_lock; +extern void i2c_open(void); +extern void i2c_close(void); +extern int i2c_read(unsigned char device, unsigned char *buf, + unsigned char address, int count); +extern int i2c_write(unsigned char device, unsigned char *buf, + unsigned char address, int count); +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + + +static void get_rtc_time (struct rtc_time *rtc_tm); +static void get_rtc_alm_time (struct rtc_time *alm_tm); + +/* + * rtc_status is never changed by rtc_interrupt, and ioctl/open/close is + * protected by the big kernel lock. However, ioctl can still disable the timer + * in rtc_status and then with del_timer after the interrupt has read + * rtc_status but before mod_timer is called, which would then reenable the + * timer (but you would need to have an awful timing before you'd trip on it) + */ +static unsigned long rtc_status = 0; /* bitmapped status byte. */ + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ +static unsigned int epoch = 1900; +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static unsigned char rtcframe[16]; + +static void read_rtcframe(void) +{ + i2c_open(); + i2c_read(0x51, rtcframe, 0, 16); + i2c_close(); +} + +static void write_rtcframe(void) +{ + i2c_open(); + i2c_write(0x51, rtcframe, 0, 16); + i2c_close(); +} + +static void write_rtc(unsigned char addr, unsigned char val) +{ + volatile unsigned char v = val; + i2c_open(); + i2c_write(0x51, (unsigned char *)&v, addr, 1); + i2c_close(); +} + +static unsigned char read_rtc(unsigned char addr) +{ + volatile unsigned char v; + i2c_open(); + i2c_read(0x51, (unsigned char *)&v, addr, 1); + i2c_close(); + return v; +} + +static void CMOS_WRITE(unsigned char addr, unsigned char val) +{ + rtcframe[addr] = val; +} + +static unsigned char CMOS_READ(unsigned char addr) +{ + return rtcframe[addr]; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + unsigned char sec,mon,mday,wday,year,hour,min; + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + + spin_lock_irq(&rtc_lock); + read_rtcframe(); + sec = CMOS_READ(RTC_SECONDS) & ~0x80; + min = CMOS_READ(RTC_MINUTES) & ~0x80; + hour = CMOS_READ(RTC_HOURS) & ~0xc0; + mday = CMOS_READ(RTC_DAY_OF_MONTH) & ~0xc0; + wday = CMOS_READ(RTC_DAY_OF_WEEK) & ~0xf8; + mon = CMOS_READ(RTC_MONTH) & ~0xe0; + year = CMOS_READ(RTC_YEAR) ; + + rtc_tm->tm_sec = BCD2BIN(sec); + rtc_tm->tm_min = BCD2BIN(min); + rtc_tm->tm_hour = BCD2BIN(hour); + rtc_tm->tm_mday = BCD2BIN(mday); + rtc_tm->tm_wday = wday; + /* Don't use centry, but start from year 1970 */ + rtc_tm->tm_mon = BCD2BIN(mon); + year = BCD2BIN(year); + if ((year += (epoch - 1900)) <= 69) + year += 100; + rtc_tm->tm_year = year; + + spin_unlock_irq(&rtc_lock); + + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + rtc_tm->tm_mon--; +} + +static void get_rtc_alm_time(struct rtc_time *alm_tm) +{ + unsigned char sec, min, hour; + + /* + * Only the values that we read from the RTC are set. That + * means only tm_hour, tm_min, and tm_sec. + */ + spin_lock_irq(&rtc_lock); + read_rtcframe(); + sec = 0; + min = CMOS_READ(RTC_MINUTES_ALARM); + hour = CMOS_READ(RTC_HOURS_ALARM); + + alm_tm->tm_sec = sec;//not set sec + alm_tm->tm_min = BCD2BIN(min); + alm_tm->tm_hour = BCD2BIN(hour); + + spin_unlock_irq(&rtc_lock); +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time wtime; + switch (cmd) { + case RTC_ALM_READ: /* Read the present alarm time */ + { + /* + * This returns a struct rtc_time. Reading >= 0xc0 + * means "don't care" or "match all". Only the tm_hour, + * tm_min, and tm_sec values are filled in. + */ + + get_rtc_alm_time(&wtime); + break; + } + case RTC_ALM_SET: /* Store a time into the alarm */ + { + unsigned char hrs, min, sec; + struct rtc_time alm_tm; + + if (copy_from_user(&alm_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + hrs = alm_tm.tm_hour; + min = alm_tm.tm_min; + sec = alm_tm.tm_sec; + + + + if (hrs >= 24) + return -EINVAL; + + hrs = BIN2BCD(hrs); + + if (min >= 60) + return -EINVAL; + + min = BIN2BCD(min); + + if (sec >= 60) + return -EINVAL; + + spin_lock_irq(&rtc_lock); + read_rtcframe(); + CMOS_WRITE(RTC_HOURS_ALARM, hrs | 0x80); + CMOS_WRITE(RTC_MINUTES_ALARM, min | 0x80); + + CMOS_WRITE(RTC_DAY_ALARM, CMOS_READ(RTC_DAY_ALARM) | 0x80); + CMOS_WRITE(RTC_WEEKDAY_ALARM, CMOS_READ(RTC_WEEKDAY_ALARM) | 0x80); + CMOS_WRITE(RTC_STATUS, CMOS_READ(RTC_STATUS) | 0x02);/*open alarm int*/ + write_rtcframe(); + spin_unlock_irq(&rtc_lock); + break; + } + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr, date; + unsigned int yrs; +// unsigned char ctr; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + + yrs = rtc_tm.tm_year + 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_wday; + date = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (date == 0)) + return -EINVAL; + + if (date > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= epoch) > 255) /* They are unsigned */ + return -EINVAL; + + spin_lock_irq(&rtc_lock); + /* These limits and adjustments are independant of + * whether the chip is in binary mode or not. + */ + if (yrs > 169) { + spin_unlock_irq(&rtc_lock); + return -EINVAL; + } + + if (yrs >= 100) + yrs -= 100; + + min = BIN2BCD(min); + sec = BIN2BCD(sec); + hrs = BIN2BCD(hrs); + mon = BIN2BCD(mon); + yrs = BIN2BCD(yrs); + date = BIN2BCD(date); + + read_rtcframe(); + CMOS_WRITE(RTC_SECONDS, sec ); + CMOS_WRITE(RTC_MINUTES, min); + CMOS_WRITE(RTC_HOURS, hrs); + CMOS_WRITE(RTC_DAY_OF_MONTH, date); + CMOS_WRITE(RTC_DAY_OF_WEEK, day); + CMOS_WRITE(RTC_MONTH, mon); + CMOS_WRITE(RTC_YEAR, yrs); + write_rtcframe(); + + spin_unlock_irq(&rtc_lock); + return 0; + } + case RTC_EPOCH_READ: /* Read the epoch. */ + { + return put_user (epoch, (unsigned long *)arg); + } + case RTC_EPOCH_SET: /* Set the epoch. */ + { + /* + * There were no RTC clocks before 1900. + */ + if (arg < 1900) + return -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + epoch = arg; + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +/* We use rtc_lock to protect against concurrent opens. So the BKL is not + * needed here. Or anywhere else in this driver. */ +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq (&rtc_lock); + + if(rtc_status) + goto out_busy; + + rtc_status = 1; + + spin_unlock_irq (&rtc_lock); + return 0; + +out_busy: + spin_unlock_irq (&rtc_lock); + return -EBUSY; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + + + /* No need for locking -- nobody else can do anything until this rmw is + * committed, and no timer is running. */ + rtc_status = 0; + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + llseek: no_llseek, + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, +}; + +#define RTC_MINOR 135 + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +int __init pcf_rtc_init(void) +{ + int r; + unsigned char ctr; + r = misc_register(&rtc_dev); + + ctr = read_rtc(RTC_CONTROL); + write_rtc(RTC_CONTROL,0x00 ); + + read_rtcframe(); + CMOS_WRITE(RTC_STATUS, 0x00); + CMOS_WRITE(RTC_CLKOUT, 0x80); + /* RTC clock out, 32.768k */ + + CMOS_WRITE(RTC_TIMERCTL, 0x00); + CMOS_WRITE(RTC_TIMERCOUNTDOWN, 0x00); + write_rtcframe(); + + printk("PCF8563 RTC installed !!!\n"); + return 0; + +} + +void __exit pcf_rtc_exit (void) +{ + misc_deregister(&rtc_dev); +} + +module_init(pcf_rtc_init); +module_exit(pcf_rtc_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/i2c-jz47xx.c linux-2.6.24.3-20100304/drivers/i2c/busses/i2c-jz47xx.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/i2c-jz47xx.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/i2c/busses/i2c-jz47xx.c 2010-03-03 19:04:40.000000000 -0800 @@ -0,0 +1,359 @@ +/* + * i2c_jz47xx.c for the INGENIC I2C bus access. + * + * Copyright (C) 2006 - 2009 Ingenic Semiconductor Inc. + * Author: + * The first Modified : + * Date:20091027 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "i2c-jz47xx.h" + +/* I2C protocol */ +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define TIMEOUT 1000 +unsigned long sub_addr = 0; + +struct jz_i2c { + spinlock_t lock; + wait_queue_head_t wait; + struct i2c_msg *msg; + unsigned int msg_num; + unsigned int slave_addr; + struct i2c_adapter adap; + struct clk *clk; +}; + +/* + * I2C bus protocol basic routines + */ +static int i2c_put_data(unsigned char data) +{ + unsigned int timeout = TIMEOUT*10; + __i2c_write(data); + __i2c_set_drf(); + while (__i2c_check_drf() != 0 && timeout) + timeout--; + while (!__i2c_transmit_ended()); + + timeout = TIMEOUT*10; + while (!__i2c_received_ack() && timeout) + timeout--; + if (timeout){ + return 0; + } + else{ + return -ETIMEDOUT; + } +} + + +static int i2c_get_data(unsigned char *data, int ack) +{ + int timeout = TIMEOUT*10; + if (!ack) + __i2c_send_nack(); + else + __i2c_send_ack(); + + while (__i2c_check_drf() == 0 && timeout) + timeout--; + if (timeout) { + if (!ack) + __i2c_send_stop(); + *data = __i2c_read(); + __i2c_clear_drf(); + return 0; + } else{ + + return -ETIMEDOUT; + } +} + +/* + * I2C interface + */ +void i2c_jz_setclk(unsigned int i2cclk) +{ + __i2c_set_clk(jz_clocks.extalclk, i2cclk); +} + + +static int xfer_read(unsigned char device, unsigned char *buf, int length) +{ + int cnt = length; + int timeout = 5; + + /*eeprom device address transfer*/ +#if defined(CONFIG_SENSORS_EEPROM) + device = 0xa << 3 | ((sub_addr & 0x0700) >> 8); + sub_addr = sub_addr & 0xff; +#endif + + + +L_try_again: + + if (timeout < 0) + goto L_timeout; + + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + __i2c_send_start(); + + + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_werr; + + if (i2c_put_data(sub_addr) < 0) + goto address_err; + + __i2c_send_start(); + + if (i2c_put_data((device << 1) | I2C_READ ) < 0) + goto device_rerr; + + + __i2c_send_ack(); /* Master sends ACK for continue reading */ + + + while (cnt) { + + if (cnt == 1) { + + if (i2c_get_data(buf, 0) < 0) + break; + } else { + + if (i2c_get_data(buf, 1) < 0){ + break; + } + } + cnt--; + buf++; + } + __i2c_send_stop(); + + return length - cnt; + device_rerr: + device_werr: + address_err: + + timeout --; + __i2c_send_stop(); + goto L_try_again; + +L_timeout: + __i2c_send_stop(); + printk("Read I2C device 0x%2x failed.\n", device); + return -ENODEV; +} + + +static int xfer_write(unsigned char device, unsigned char *buf, int length) +{ + int cnt = length; + int cnt_in_pg; + int timeout = 5; + unsigned char *tmpbuf; + + /*eeprom device address transfer*/ +#if defined(CONFIG_SENSORS_EEPROM) + device = 0xa << 3 | ((sub_addr & 0x0700) >> 8); + sub_addr = sub_addr & 0xff; +#endif + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ + + W_try_again: + if (timeout < 0) + goto W_timeout; + + cnt = length; + tmpbuf = (unsigned char *)buf; + + start_write_page: + cnt_in_pg = 0; + __i2c_send_start(); + if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) + goto device_err; + + if (i2c_put_data(sub_addr) < 0) + goto address_err; + + + + while (cnt) { + if (++cnt_in_pg > 8) { + __i2c_send_stop(); + mdelay(1); + sub_addr += 8; + mdelay(2);// add 20091027 + goto start_write_page; + + } + + + if (i2c_put_data(*tmpbuf) < 0) + break; + cnt--; + tmpbuf++; + } + __i2c_send_stop(); + return length - cnt; + device_err: + address_err: + timeout--; + __i2c_send_stop(); + goto W_try_again; + +W_timeout: + printk( "Write I2C device 0x%2x failed.\n", device); + __i2c_send_stop(); + return -ENODEV; +} + +static int i2c_jz_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num) +{ + int ret, i; + + dev_dbg(&adap->dev, "jz47xx_xfer: processing %d messages:\n", num); + for (i = 0; i < num; i++) { + dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i, + pmsg->flags & I2C_M_RD ? "read" : "writ", + pmsg->len, pmsg->len > 1 ? "s" : "", + pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr); + if (pmsg->len && pmsg->buf) { /* sanity check */ + if (pmsg->flags & I2C_M_RD){ + + ret = xfer_read(pmsg->addr, pmsg->buf, pmsg->len); + }else{ + + ret = xfer_write(pmsg->addr, pmsg->buf, pmsg->len); + } + if (ret) + return ret; + /* Wait until transfer is finished */ + } + dev_dbg(&adap->dev, "transfer complete\n"); + pmsg++; /* next message */ + } + return i; +} + +static u32 i2c_jz_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm i2c_jz_algorithm = { + .master_xfer = i2c_jz_xfer, + .functionality = i2c_jz_functionality, +}; + +static int i2c_jz_probe(struct platform_device *dev) +{ + + struct jz_i2c *i2c; + struct i2c_jz_platform_data *plat = dev->dev.platform_data; + int ret; + __gpio_as_i2c(); // open i2c 20091027 + __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */ + __i2c_enable(); + + i2c = kzalloc(sizeof(struct jz_i2c), GFP_KERNEL); + if (!i2c) { + printk("There is no enough memory\n"); + ret = -ENOMEM; + goto emalloc; + } + + i2c->adap.owner = THIS_MODULE; + i2c->adap.algo = &i2c_jz_algorithm; + i2c->adap.retries = 5; + spin_lock_init(&i2c->lock); + init_waitqueue_head(&i2c->wait); + sprintf(i2c->adap.name, "jz_i2c-i2c.%u", dev->id); + i2c->adap.algo_data = i2c; + i2c->adap.dev.parent = &dev->dev; + + if (plat) { + i2c->adap.class = plat->class; + } + + /* + * If "dev->id" is negative we consider it as zero. + * The reason to do so is to avoid sysfs names that only make + * sense when there are multiple adapters. + */ + i2c->adap.nr = dev->id != -1 ? dev->id : 0; + /* ret = i2c_add_adapter(&i2c->adap); */ + ret = i2c_add_numbered_adapter(&i2c->adap); + if (ret < 0) { + printk(KERN_INFO "I2C: Failed to add bus\n"); + goto eadapt; + } + + platform_set_drvdata(dev, i2c); + dev_info(&dev->dev, "JZ47xx i2c bus driver.\n"); + return 0; +eadapt: + __i2c_disable(); +emalloc: + return ret; +} + +static int i2c_jz_remove(struct platform_device *dev) +{ + struct i2c_adapter *adapter = platform_get_drvdata(dev); + int rc; + + rc = i2c_del_adapter(adapter); + platform_set_drvdata(dev, NULL); + return rc; +} + +static struct platform_driver i2c_jz_driver = { + .probe = i2c_jz_probe, + .remove = i2c_jz_remove, + .driver = { + .name = "jz_i2c", + }, +}; + +static int __init i2c_adap_jz_init(void) +{ + return platform_driver_register(&i2c_jz_driver); +} + +static void __exit i2c_adap_jz_exit(void) +{ + return platform_driver_unregister(&i2c_jz_driver); +} + +MODULE_LICENSE("GPL"); + +module_init(i2c_adap_jz_init); +module_exit(i2c_adap_jz_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/i2c-jz47xx.h linux-2.6.24.3-20100304/drivers/i2c/busses/i2c-jz47xx.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/i2c-jz47xx.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/i2c/busses/i2c-jz47xx.h 2010-03-03 19:04:40.000000000 -0800 @@ -0,0 +1,20 @@ +/* + * i2c_jz47xx.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 _I2C_JZ_H_ +#define _I2C_JZ_H_ + +struct i2c_slave_client; + +struct i2c_jz_platform_data { + unsigned int slave_addr; + struct i2c_slave_client *slave; + unsigned int class; +}; + +extern void jz_set_i2c_info(struct i2c_jz_platform_data *info); +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/Kconfig linux-2.6.24.3-20100304/drivers/i2c/busses/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/i2c/busses/Kconfig 2010-03-03 19:04:40.000000000 -0800 @@ -4,6 +4,14 @@ menu "I2C Hardware Bus support" +config I2C_JZ47XX + tristate "JZ47XX I2C Interface support" + depends on SOC_JZ4730 || SOC_JZ4740 + help + If you have devices in the Ingenic JZ4730/JZ4740 I2C bus, say yes to + this option. This driver can also be built as a module. If so, the + module will be called i2c-jz47xx. + config I2C_ALI1535 tristate "ALI 1535" depends on PCI diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/Makefile linux-2.6.24.3-20100304/drivers/i2c/busses/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/busses/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/i2c/busses/Makefile 2010-03-03 19:04:40.000000000 -0800 @@ -2,6 +2,7 @@ # Makefile for the i2c bus drivers. # +obj-$(CONFIG_I2C_JZ47XX) += i2c-jz47xx.o obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/i2c-dev.c linux-2.6.24.3-20100304/drivers/i2c/i2c-dev.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/i2c/i2c-dev.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/i2c/i2c-dev.c 2010-03-03 19:04:40.000000000 -0800 @@ -36,8 +36,9 @@ #include #include +extern unsigned short sub_addr; +extern int addr_val; static struct i2c_driver i2cdev_driver; - /* * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a * slave (i2c_client) with which messages will be exchanged. It's coupled @@ -422,6 +423,14 @@ case I2C_TIMEOUT: client->adapter->timeout = arg; break; + case I2C_SET_SUB_ADDRESS: + addr_val = 1; + sub_addr = arg; + break; + case I2C_SET_CLOCK: + i2c_jz_setclk(arg); + break; + default: /* NOTE: returning a fault code here could cause trouble * in buggy userspace code. Some old kernel bugs returned diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/gpio_keys.c linux-2.6.24.3-20100304/drivers/input/keyboard/gpio_keys.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/gpio_keys.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/keyboard/gpio_keys.c 2010-03-03 19:03:53.000000000 -0800 @@ -1,7 +1,13 @@ /* - * Driver for keys on GPIO lines capable of generating interrupts. + * linux/drivers/input/keyboard/gpio_keys.c * - * Copyright 2005 Phil Blundell + * JZ GPIO Buttons driver for JZ4740 PAVO + * + * User applications can access to this device via /dev/input/eventX. + * + * Copyright (c) 2005 - 2008 Ingenic Semiconductor Inc. + * + * Author: Richard * * 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 @@ -23,26 +29,131 @@ #include #include #include - #include +#include + + +#define SCAN_INTERVAL (10) + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button pavo_buttons[] = { + { + .gpio = 96, + .code = KEY_1, + .desc = "Button 0", + .active_low = 1, + }, + { + .gpio = 97, + .code = KEY_2, + .desc = "Button 1", + .active_low = 1, + }, + { + .gpio = 98, + .code = KEY_3, + .desc = "Button 2", + .active_low = 1, + }, + { + .gpio = 99, + .code = KEY_4, + .desc = "Button 3", + .active_low = 1, + } +}; + +static struct timer_list button_timer; +static spinlock_t gpio_lock; +static int button_no; + +static struct gpio_keys_platform_data pavo_button_data = { + .buttons = pavo_buttons, + .nbuttons = ARRAY_SIZE(pavo_buttons), +}; + +static struct platform_device pavo_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &pavo_button_data, + } +}; + +static void __init pavo_add_device_buttons(void) +{ + __gpio_as_input(96); + __gpio_as_irq_fall_edge(96); + + __gpio_as_input(97); + __gpio_as_irq_fall_edge(97); + + __gpio_as_input(98); + __gpio_as_irq_fall_edge(98); + + __gpio_as_input(99); + __gpio_as_irq_fall_edge(99); + + platform_device_register(&pavo_button_device); +} +#else +static void __init pavo_add_device_buttons(void) {} +#endif + +static void __init pavo_board_init(void) +{ + /* Push Buttons */ + pavo_add_device_buttons(); +} + +static void button_timer_callback(unsigned long data) +{ + unsigned long flags; + int gpio = pavo_buttons[button_no].gpio; + int code = pavo_buttons[button_no].code; + struct platform_device *pdev = (struct platform_device *)data; + struct input_dev *input = platform_get_drvdata(pdev); + int state; + + spin_lock_irqsave(&gpio_lock, flags); + state = __gpio_get_pin(gpio); + + if (state == 0) { + /* press down */ + input_report_key(input, code, 1); + input_sync(input); + mod_timer(&button_timer, jiffies + SCAN_INTERVAL); + } else { + /* up */ + input_report_key(input, code, 0); + input_sync(input); + udelay(1000); + __gpio_as_irq_fall_edge(gpio); + } + spin_unlock_irqrestore(&gpio_lock, flags); +} static irqreturn_t gpio_keys_isr(int irq, void *dev_id) { int i; struct platform_device *pdev = dev_id; struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; - struct input_dev *input = platform_get_drvdata(pdev); + __gpio_ack_irq(irq - IRQ_GPIO_0); for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; int gpio = button->gpio; - if (irq == gpio_to_irq(gpio)) { - unsigned int type = button->type ?: EV_KEY; - int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; - - input_event(input, type, button->code, !!state); - input_sync(input); + if (irq == (gpio + IRQ_GPIO_0) ) { + /* start timer */ + __gpio_as_input(gpio); + button_no = i; + mod_timer(&button_timer, jiffies + 2 * SCAN_INTERVAL); + break; } } @@ -62,7 +173,7 @@ platform_set_drvdata(pdev, input); - input->evbit[0] = BIT_MASK(EV_KEY); + spin_lock_init(&gpio_lock); input->name = pdev->name; input->phys = "gpio-keys/input0"; @@ -72,56 +183,42 @@ input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0100; + input->evbit[0] = BIT(EV_KEY) | BIT(EV_SYN) | BIT(EV_REP); for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; int irq; unsigned int type = button->type ?: EV_KEY; - error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); - if (error < 0) { - pr_err("gpio-keys: failed to request GPIO %d," - " error %d\n", button->gpio, error); - goto fail; - } - - error = gpio_direction_input(button->gpio); - if (error < 0) { - pr_err("gpio-keys: failed to configure input" - " direction for GPIO %d, error %d\n", - button->gpio, error); - gpio_free(button->gpio); - goto fail; - } - - irq = gpio_to_irq(button->gpio); + irq = IRQ_GPIO_0 + button->gpio; if (irq < 0) { error = irq; pr_err("gpio-keys: Unable to get irq number" " for GPIO %d, error %d\n", button->gpio, error); - gpio_free(button->gpio); goto fail; } error = request_irq(irq, gpio_keys_isr, - IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, button->desc ? button->desc : "gpio_keys", pdev); if (error) { pr_err("gpio-keys: Unable to claim irq %d; error %d\n", irq, error); - gpio_free(button->gpio); goto fail; } if (button->wakeup) wakeup = 1; - input_set_capability(input, type, button->code); } + /* Init timer */ + init_timer(&button_timer); + button_timer.data = (unsigned long)&pavo_button_device; + button_timer.function = button_timer_callback; + error = input_register_device(input); if (error) { pr_err("gpio-keys: Unable to register input device, " @@ -135,8 +232,7 @@ fail: while (--i >= 0) { - free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); - gpio_free(pdata->buttons[i].gpio); + free_irq(pdata->buttons[i].gpio + IRQ_GPIO_0 , pdev); } platform_set_drvdata(pdev, NULL); @@ -154,9 +250,8 @@ device_init_wakeup(&pdev->dev, 0); for (i = 0; i < pdata->nbuttons; i++) { - int irq = gpio_to_irq(pdata->buttons[i].gpio); + int irq = pdata->buttons[i].gpio + IRQ_GPIO_0; free_irq(irq, pdev); - gpio_free(pdata->buttons[i].gpio); } input_unregister_device(input); @@ -175,7 +270,7 @@ for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; if (button->wakeup) { - int irq = gpio_to_irq(button->gpio); + int irq = button->gpio + IRQ_GPIO_0; enable_irq_wake(irq); } } @@ -193,7 +288,7 @@ for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; if (button->wakeup) { - int irq = gpio_to_irq(button->gpio); + int irq = button->gpio + IRQ_GPIO_0; disable_irq_wake(irq); } } @@ -218,11 +313,13 @@ static int __init gpio_keys_init(void) { + pavo_board_init(); return platform_driver_register(&gpio_keys_device_driver); } static void __exit gpio_keys_exit(void) { + platform_device_unregister(&pavo_button_device); platform_driver_unregister(&gpio_keys_device_driver); } diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/jz_keypad_5x5.c linux-2.6.24.3-20100304/drivers/input/keyboard/jz_keypad_5x5.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/jz_keypad_5x5.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/keyboard/jz_keypad_5x5.c 2010-03-03 19:03:53.000000000 -0800 @@ -0,0 +1,329 @@ +/* + * JZ Keypad ( 5 x 5 ) Driver + * + * Copyright (c) 2005 - 2008 Ingenic Semiconductor Inc. + * + * Author: Jason 20090210 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define KB_ROWS 5 +#define KB_COLS 5 + +#define SCAN_INTERVAL (10) + +#define ROW_KEYBIT_MASK 0xFFE0 + +#define SET_GPIOS_AS_INPUT() \ +do { \ + unsigned short i; \ + \ + for (i = 0; i < KB_ROWS; i++) { \ + __gpio_as_input(jz_row_gpios[i]); \ + __gpio_as_input(jz_col_gpios[i]); \ + } \ +} while (0) + + +#define GET_ROW_GPIO_PINS() \ +({ \ + unsigned short _pins = 0, i; \ + for (i = 0; \ + i < KB_ROWS; \ + _pins |= __gpio_get_pin(jz_row_gpios[i]) << i, i++) \ + ; \ + _pins; \ +}) + +#define CHECK_IF_KEY_PRESSED(s) \ +({ \ + unsigned short i; \ + for (i = 0; i < KB_COLS && s[i] == 0x1F ; i++) \ + ; \ + i != KB_ROWS; \ +}) + +#define CLEAN_SCAN_RESULT(s) \ +do { \ + unsigned short i; \ + for (i = 0; i < KB_COLS; s[i++] = 0x1F) \ + ; \ +} while (0) + + +static const unsigned short jz_col_gpios[KB_ROWS] = {76, 75, 74, 73, 72}; +static const unsigned short jz_row_gpios[KB_COLS] = {181, 182, 79, 78, 77}; + +static const unsigned int jz_kbd_keycode[KB_ROWS * KB_COLS] = { + KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, + KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, + KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, + KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, + KEY_LEFTSHIFT, KEY_CAPSLOCK, KEY_SPACE, KEY_BACKSPACE, KEY_Y +}; + +struct jz_kbd { + unsigned int keycode[ARRAY_SIZE(jz_kbd_keycode)]; + struct input_dev *input; + char phys[32]; + + spinlock_t lock; + struct timer_list timer; + + unsigned int suspended; + unsigned long suspend_jiffies; +}; +static struct jz_kbd g_jz_kbd; + +static unsigned short scan_result[KB_COLS]; +static unsigned short pre_scan_result[KB_COLS] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F}; +static unsigned short pre_col, pre_row; + +/** + * Scan keypad by reading GPIO pins. + */ +static inline void jz_do_scan(unsigned short *s) +{ + unsigned short i; + + if (!s) + return ; + + for (i = 0; i < KB_COLS; i++) { + + SET_GPIOS_AS_INPUT(); + __gpio_clear_pin(jz_col_gpios[i]); + __gpio_as_output(jz_col_gpios[i]); + + udelay(1000); + + s[i] = GET_ROW_GPIO_PINS(); + } +} + +/** + * Call scan function and handle 'GPIO event'(like key down, key up), + * and report it to upper layer of input subsystem ... if necessary + */ +static void jz_kbd_scan(struct jz_kbd *kbd_data) +{ + unsigned short row, col, i; + unsigned long flags; + + if (kbd_data->suspended) + return; + + spin_lock_irqsave(&kbd_data->lock, flags); + + jz_do_scan(scan_result); + + /* check if any key was pressed or not */ + if (!CHECK_IF_KEY_PRESSED(scan_result)) { + + /* key up */ + if (CHECK_IF_KEY_PRESSED(pre_scan_result)) { + input_report_key(kbd_data->input, kbd_data->keycode[pre_row * KB_COLS + pre_col], 0); + input_sync(kbd_data->input); + } + pre_col = pre_row = 0xFFFF; + CLEAN_SCAN_RESULT(pre_scan_result); + + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; + } + + /* find the key */ + for (row = 0; row < KB_ROWS; row++) { + for (i = scan_result[row], col = 0; col < KB_COLS; col++) { + if ( !(i & 0x01) ) + break; + i >>= 1; + } + if (col != KB_COLS) + break; + } + + //printk("[DRIVER] row = %d, col = %d, key code: 0x%02X\n", row, col, kbd_data->keycode[row * KB_COLS + col]); + + /* the same as the preview one || new key */ + if ( (col == pre_col && row == pre_row) + || (pre_col == 0xFFFF && pre_row == 0xFFFF) ) { + + input_report_key(kbd_data->input, kbd_data->keycode[row * KB_COLS + col], 1); + input_sync(kbd_data->input); + + } else { + /* the preview key is up and other key is down */ + input_report_key(kbd_data->input, kbd_data->keycode[pre_row * KB_COLS + col], 0); + input_sync(kbd_data->input); + input_report_key(kbd_data->input, kbd_data->keycode[row * KB_COLS + col], 1); + input_sync(kbd_data->input); + } + + for (i = 0; i < KB_ROWS; i++) { + pre_scan_result[i] = scan_result[i]; + } + + pre_col = col; + pre_row = row; + + spin_unlock_irqrestore(&kbd_data->lock, flags); + + return; +} + +static void jz_kbd_timer_callback(unsigned long data) +{ + jz_kbd_scan(&g_jz_kbd); + mod_timer(&g_jz_kbd.timer, jiffies + SCAN_INTERVAL); +} + +#ifdef CONFIG_PM +static int jz_kbd_suspend(struct platform_device *dev, pm_message_t state) +{ + struct jz_kbd *jz_kbd = platform_get_drvdata(dev); + jz_kbd->suspended = 1; + + return 0; +} + +static int jz_kbd_resume(struct platform_device *dev) +{ + struct jz_kbd *jz_kbd = platform_get_drvdata(dev); + + jz_kbd->suspend_jiffies = jiffies; + jz_kbd->suspended = 0; + + return 0; +} + +#else +#define jz_kbd_suspend NULL +#define jz_kbd_resume NULL +#endif + +/** + * Driver init + */ +static int __init jz_kbd_probe(struct platform_device *dev) +{ + struct input_dev *input_dev; + int i, error; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + platform_set_drvdata(dev, &g_jz_kbd); + + strcpy(g_jz_kbd.phys, "input/kbd0"); + + spin_lock_init(&g_jz_kbd.lock); + + g_jz_kbd.suspend_jiffies = jiffies; + g_jz_kbd.input = input_dev; + + input_dev->private = &g_jz_kbd; + input_dev->name = "JZ 5x5 Keypad"; + input_dev->phys = g_jz_kbd.phys; + input_dev->cdev.dev = &dev->dev; + + input_dev->id.bustype = BUS_PARPORT; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_SYN); + input_dev->keycode = g_jz_kbd.keycode; + input_dev->keycodesize = sizeof(unsigned int); + input_dev->keycodemax = ARRAY_SIZE(jz_kbd_keycode); + + memcpy(g_jz_kbd.keycode, jz_kbd_keycode, sizeof(g_jz_kbd.keycode)); + + for ( i = 0; i < ARRAY_SIZE(jz_kbd_keycode); i++) + set_bit(g_jz_kbd.keycode[i], input_dev->keybit); + + init_timer(&g_jz_kbd.timer); + g_jz_kbd.timer.function = jz_kbd_timer_callback; + g_jz_kbd.timer.data = (unsigned long)&g_jz_kbd; + mod_timer(&g_jz_kbd.timer, jiffies + SCAN_INTERVAL); + + error = input_register_device(input_dev); + if (error) { + pr_err("gpio-keys: Unable to register input device, " + "error: %d\n", error); + } + printk("input: JZ 5x5 Keypad Registered.\n"); + + return 0; +} + +static int jz_kbd_remove(struct platform_device *dev) +{ + struct jz_kbd *kbd = platform_get_drvdata(dev); + + del_timer_sync(&kbd->timer); + + SET_GPIOS_AS_INPUT(); + + input_unregister_device(kbd->input); + + return 0; +} + +static struct platform_driver jz_kbd_driver = { + .probe = jz_kbd_probe, + .remove = jz_kbd_remove, + .suspend= jz_kbd_suspend, + .resume = jz_kbd_resume, + .driver = { + .name = "jz-5x5-keypad", + }, +}; + +static struct platform_device jzkbd_device = { + .name = "jz-5x5-keypad", + .id = -1, +}; + +static int __init jz_kbd_init(void) +{ + platform_device_register(&jzkbd_device); + return platform_driver_register(&jz_kbd_driver); +} + +static void __exit jz_kbd_exit(void) +{ + platform_device_unregister(&jzkbd_device); + platform_driver_unregister(&jz_kbd_driver); +} + +module_init(jz_kbd_init); +module_exit(jz_kbd_exit); + +MODULE_AUTHOR("Jason "); +MODULE_DESCRIPTION("JZ 5x5 keypad driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/jz_keypad.c linux-2.6.24.3-20100304/drivers/input/keyboard/jz_keypad.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/jz_keypad.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/keyboard/jz_keypad.c 2010-03-03 19:03:53.000000000 -0800 @@ -0,0 +1,357 @@ +/* + * linux/drivers/input/keyboard/jz_keypad.c + * + * JZ Keypad Driver + * + * Copyright (c) 2005 - 2008 Ingenic Semiconductor Inc. + * + * Author: Richard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define KB_ROWS 3 +#define KB_COLS 3 + +#define SCAN_INTERVAL (10) + +static unsigned short col[KB_COLS] = {85,87,91}; +static unsigned short row[KB_ROWS] = {60,61,62}; +static unsigned short s0[KB_COLS]; +static unsigned short s1[KB_COLS]={7,7,7}; +static unsigned short precol,prerow; + +static const unsigned int jz_kbd_keycode[KB_COLS * KB_ROWS] = { + KEY_1, KEY_4, KEY_7, + KEY_2, KEY_5, 0, + KEY_3, KEY_6, 0, +}; + +struct jz_kbd { + unsigned int keycode[ARRAY_SIZE(jz_kbd_keycode)]; + struct input_dev *input; + char phys[32]; + + spinlock_t lock; + struct timer_list timer; + + unsigned int suspended; + unsigned long suspend_jiffies; +}; + +static struct jz_kbd g_jz_kbd; + +static inline void jz_scan_kbd(unsigned short *s) +{ + int i; + + if (!s) + return; + + for (i = 0; i < KB_COLS; i++) { + + __gpio_as_input(85); /* row */ + __gpio_as_input(87); /* row */ + __gpio_as_input(91); /* row */ + + __gpio_as_input(60); /* col */ + __gpio_as_input(61); /* col */ + __gpio_as_input(62); /* col */ + + __gpio_clear_pin(col[i]); + __gpio_as_output(col[i]); + + udelay(1000); + s[i]=(__gpio_get_pin(60) << 0) | (__gpio_get_pin(61) << 1) | + (__gpio_get_pin(62) << 2); + } +} + +static void jz_kbd_scankeyboard(struct jz_kbd *kbd_data) +{ + unsigned int row,col; + unsigned long flags; + unsigned int num_pressed; + + if (kbd_data->suspended) + return; + + spin_lock_irqsave(&kbd_data->lock, flags); + + num_pressed = 0; + jz_scan_kbd(s0); + + /* look for key if pressed down on not, col & row */ + if (s0[0] == 7 && s0[1] == 7 && s0[2] == 7) { + if (s1[0] != 7 || s1[1] != 7 || s1[2] != 7) { + /* up */ + input_report_key(kbd_data->input, kbd_data->keycode[prerow * KB_COLS + precol], 0); + input_sync(kbd_data->input); + } + precol = prerow = -1; + s1[0] = s1[1] = s1[2] = 7; + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; + } + + if (s0[0] == 6 && s0[1] == 7 && s0[2] == 7) { + row = 0;//K7 + col = 2; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 3 && s0[2] == 7) { + row = 2;//k6 + col = 1; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 5 && s0[2] == 7) { + row = 1;//k5 + col = 1; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 6 && s0[2] == 7) { + row = 0;//k4 + col = 1; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 7 && s0[2] == 3) { + row = 2;//k3 + col = 0; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 7 && s0[2] == 5) { + row = 1;//k2 + col = 0; + goto find_row_col; + } + if (s0[0] == 7 && s0[1] == 7 && s0[2] == 6) { + row = 0;//k1 + col = 0; + goto find_row_col; + } + /* 2 or 3 buttons are pressed */ + s0[0] = s0[1] = s0[2] = 7; + s1[0] = s1[1] = s1[2] = 7; + prerow = precol = -1; + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; +find_row_col: + if (s1[0] == 7 && s1[1] == 7 && s1[2] == 7) { + /* down */ + input_report_key(kbd_data->input, kbd_data->keycode[row * KB_COLS + col], 1); + input_sync(kbd_data->input); + s1[0] = s0[0]; + s1[1] = s0[1]; + s1[2] = s0[2]; + + precol = col; + prerow = row; + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; + } + if (s1[0] != 7 || s1[1] != 7 || s1[2] != 7) { + /* is the same as the preview key */ + if (s0[0] == s1[0] && s0[1] == s1[1] && s0[2] == s1[2]) { + input_report_key(kbd_data->input, kbd_data->keycode[row * KB_COLS + col], 1); + input_sync(kbd_data->input); + s1[0] = s0[0]; + s1[1] = s0[1]; + s1[2] = s0[2]; + + precol = col; + prerow = row; + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; + } else { + /* the preview key is up and other key is down */ + if (s0[0] != s1[0] || s0[1] != s1[1] || s0[2] != s1[2]) { + input_report_key(kbd_data->input, kbd_data->keycode[prerow * KB_COLS + precol], 0); + input_sync(kbd_data->input); + input_report_key(kbd_data->input, kbd_data->keycode[row * KB_COLS + col], 1); + input_sync(kbd_data->input); + s1[0] = s0[0]; + s1[1] = s0[1]; + s1[2] = s0[2]; + precol = col; + prerow = row; + spin_unlock_irqrestore(&kbd_data->lock, flags); + return; + } + } + } +} + +static void jz_kbd_timer_callback(unsigned long data) +{ + jz_kbd_scankeyboard(&g_jz_kbd); + mod_timer(&g_jz_kbd.timer, jiffies + SCAN_INTERVAL); +} + +#ifdef CONFIG_PM +static int jz_kbd_suspend(struct platform_device *dev, pm_message_t state) +{ + struct jz_kbd *jz_kbd = platform_get_drvdata(dev); + jz_kbd->suspended = 1; + + return 0; +} + +static int jz_kbd_resume(struct platform_device *dev) +{ + struct jz_kbd *jz_kbd = platform_get_drvdata(dev); + + jz_kbd->suspend_jiffies = jiffies; + jz_kbd->suspended = 0; + + return 0; +} +#else +#define jz_kbd_suspend NULL +#define jz_kbd_resume NULL +#endif + +static int __init jz_kbd_probe(struct platform_device *dev) +{ + struct input_dev *input_dev; + int i, error; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + platform_set_drvdata(dev, &g_jz_kbd); + + strcpy(g_jz_kbd.phys, "input/kbd0"); + + spin_lock_init(&g_jz_kbd.lock); + + g_jz_kbd.suspend_jiffies = jiffies; + g_jz_kbd.input = input_dev; + + input_dev->private = &g_jz_kbd; + input_dev->name = "JZ Keypad"; + input_dev->phys = g_jz_kbd.phys; + input_dev->cdev.dev = &dev->dev; + + input_dev->id.bustype = BUS_PARPORT; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_SYN); + input_dev->keycode = g_jz_kbd.keycode; /* keycode array address */ + input_dev->keycodesize = sizeof(unsigned int); + input_dev->keycodemax = ARRAY_SIZE(jz_kbd_keycode); + + memcpy(g_jz_kbd.keycode, jz_kbd_keycode, sizeof(g_jz_kbd.keycode)); + + for (i = 0; i < ARRAY_SIZE(jz_kbd_keycode); i++) + set_bit(g_jz_kbd.keycode[i], input_dev->keybit); + + //clear_bit(0, input_dev->keybit); + + __gpio_as_input(85); + __gpio_as_input(87); + __gpio_as_input(91); + +#if 0 + __gpio_as_input(60); + __gpio_as_input(61); + __gpio_as_input(62); +#endif + + /* Init Keyboard rescan timer */ + init_timer(&g_jz_kbd.timer); + g_jz_kbd.timer.function = jz_kbd_timer_callback; + g_jz_kbd.timer.data = (unsigned long)&g_jz_kbd; + mod_timer(&g_jz_kbd.timer, jiffies + SCAN_INTERVAL); + + error = input_register_device(input_dev); + if (error) { + pr_err("gpio-keys: Unable to register input device, " + "error: %d\n", error); + } + printk("input: JZ Keypad Registered\n"); + + return 0; +} + +static int jz_kbd_remove(struct platform_device *dev) +{ + struct jz_kbd *jz_kbd = platform_get_drvdata(dev); + + del_timer_sync(&jz_kbd->timer); + + __gpio_as_input(85); + __gpio_as_input(87); + __gpio_as_input(91); + + /* These pins is conficting with cs8900a's CS RD WE pins on JZ4740-PAVO board */ + __gpio_as_input(60); + __gpio_as_input(61); + __gpio_as_input(62); + + input_unregister_device(jz_kbd->input); + + return 0; +} + +static struct platform_driver jz_kbd_driver = { + .probe = jz_kbd_probe, + .remove = jz_kbd_remove, + .suspend = jz_kbd_suspend, + .resume = jz_kbd_resume, + .driver = { + .name = "jz-keypad", + }, +}; + +/* + * Jz Keyboard Device + */ +static struct platform_device jzkbd_device = { + .name = "jz-keypad", + .id = -1, +}; + +static int __init jz_kbd_init(void) +{ + platform_device_register(&jzkbd_device); + return platform_driver_register(&jz_kbd_driver); +} + +static void __exit jz_kbd_exit(void) +{ + platform_device_unregister(&jzkbd_device); + platform_driver_unregister(&jz_kbd_driver); +} + +module_init(jz_kbd_init); +module_exit(jz_kbd_exit); + +MODULE_AUTHOR("Richard"); +MODULE_DESCRIPTION("JZ keypad driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/Kconfig linux-2.6.24.3-20100304/drivers/input/keyboard/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/keyboard/Kconfig 2010-03-03 19:03:53.000000000 -0800 @@ -259,9 +259,27 @@ To compile this driver as a module, choose M here: the module will be called aaed2000_kbd. +config KEYBOARD_JZ + tristate "JZ keypad support" + depends on JZSOC + help + Enable Y here to support JZ keypad. + + To compile this driver as a module, choose M here: the + module will be called jz-keypad. + +config 5x5_KEYBOARD_JZ + tristate "JZ 5x5 keypad support" + depends on JZSOC + help + Enable Y here to support JZ keypad. + + To compile this driver as a module, choose M here: the + module will be called jz-keypad. + config KEYBOARD_GPIO - tristate "GPIO Buttons" - depends on GENERIC_GPIO + tristate "JZ GPIO Buttons support" +# depends on GENERIC_GPIO help This driver implements support for buttons connected to GPIO pins of various CPUs (and some other chips). @@ -272,7 +290,7 @@ with configuration data saying which GPIOs are used. To compile this driver as a module, choose M here: the - module will be called gpio-keys. + module will be called gpio_keys. config KEYBOARD_MAPLE tristate "Maple bus keyboard" diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/Makefile linux-2.6.24.3-20100304/drivers/input/keyboard/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/keyboard/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/keyboard/Makefile 2010-03-03 19:03:53.000000000 -0800 @@ -19,6 +19,8 @@ obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o +obj-$(CONFIG_KEYBOARD_JZ) += jz_keypad.o +obj-$(CONFIG_5x5_KEYBOARD_JZ) += jz_keypad_5x5.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/ak4183.c linux-2.6.24.3-20100304/drivers/input/touchscreen/ak4183.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/ak4183.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/touchscreen/ak4183.c 2010-03-03 19:03:54.000000000 -0800 @@ -0,0 +1,316 @@ +/* + * drivers/input/touchscreen/ak4183.c + * + * ak4183.c i2c driver for volans board + * + * Touch screen driver for AK4183. + * + * Routine transform_to_screen_x() and transform_to_screen_y() come from + * drivers/input/touchscreen/jz_ts.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ak4183.h" + +#define DEBUG 0 + +#if DEBUG +# define warn(fmt, args...) printk(KERN_WARNING fmt, ##args) +# define info(fmt, args...) printk(KERN_INFO fmt, ##args) +# define dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) +#else +# define warn(fmt, args...) +# define info(fmt, args...) +# define dbg(fmt, args...) +#endif +#define err(fmt, args...) printk(KERN_ERR fmt, ##args) + +struct ak4183 *ts; +static unsigned int slave_addr = 0x48; + +/* + * ak4183 control command + * BIT Name Function + * 7 S Start Bit 0: Sleep mode, 1: Accelerate and Axis + * 6-4 A2-A0 Channel Selection Bits + * 3 X1 Don't care + * 2 PD0 Power down + * 1 Mode Resolution of A/D converter. 0: 12bit, 1: 8bit + * 0 X2 Don't care + */ +static inline void ak4183_write(u8 val) +{ + i2c_write(slave_addr, &val, 0, 1); +} + +static inline unsigned int ak4183_read(void) +{ + unsigned char val = 0; + + i2c_read(slave_addr, &val, 0, 1); + return val; +} + +static unsigned int ak4183_adc_read(u8 cmd) +{ + unsigned char val = 0; + + i2c_write(slave_addr, &cmd, 0, 1); + i2c_read(slave_addr, &val, 0, 1); + + return val; +} + +static inline unsigned int ak4183_read_xpos(void) +{ + return ak4183_adc_read(0xC2);//X-axis,0xC0 for 12bit,0xC2 for 8bit +} + +static inline unsigned int ak4183_read_pressure(void) +{ + unsigned int z1, z2, xpos, pressure=0;//300 Om + //Z1 pressure + z1 = ak4183_adc_read(0xE2);//0xE0 for 12bit,0xE2 for 8bit + if(z1>0) + { + //Z2 pressure + z2 = ak4183_adc_read(0xF2);//0xF0 for 12bit,0xF2 for 8bit + if(z2>z1) + { + xpos = ak4183_read_xpos(); + //pressure = (300*xpos*(z2-z1))/(4096*z1); + pressure = (300*xpos*(z2-z1))/(256*z1); + } + } + + return pressure; +} + +static inline unsigned int ak4183_read_ypos(void) +{ + return ak4183_adc_read(0xD2);//Y-axis,0xD0 for 12bit,0xD2 for 8bit +} + +static int is_pen_down(void) +{ + unsigned int p; + p = ak4183_read_pressure(); + return (p > 100) ? 1 : 0; +} + +static unsigned long transform_to_screen_x(unsigned long x) +{ + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return SCREEN_X - (x - TSMINX) * SCREEN_X / (TSMAXX - TSMINX); +} + +static unsigned long transform_to_screen_y(unsigned long y) +{ + if (y < TSMINY) y = TSMINY; + if (y > TSMAXY) y = TSMAXY; + + return (y - TSMINY) * SCREEN_Y / (TSMAXY - TSMINY); +} + +static irqreturn_t ak4183_irq(int irq, void *dev_id) +{ + schedule_delayed_work(&ts->work, 1); + + return IRQ_HANDLED; +} + +static unsigned int get_xaxis(void) +{ + int i, j; + unsigned int x_raw[SAMPLES]; + unsigned int tmp, x = 0; + + memset(x_raw, 0, sizeof(unsigned int)*SAMPLES); + + ak4183_write(0x82); + for (i = 0,j = 0; i < SAMPLES; i++) { + tmp = ak4183_read(); + if((tmp < TSMINX) || (tmp > TSMAXX)) + continue; + x_raw[j++] = tmp; + } + if (j > 4) { + for (i = 0; i < j; i++) { + x += x_raw[i]; + } + x /= j; + + return x; + } + + return 0xbadbabe; +} + +static unsigned int get_yaxis(void) +{ + int i, j; + unsigned int y_raw[SAMPLES]; + unsigned int tmp, y = 0; + + memset(y_raw, 0, sizeof(unsigned int)*SAMPLES); + + ak4183_write(0x92); + for (i = 0,j = 0; i < SAMPLES; i++) { + tmp = ak4183_read(); + if((tmp < TSMINY) || (tmp > TSMAXY)) + continue; + y_raw[j++] = tmp; + } + if (j > 4) { + for (i = 0; i < j; i++) { + y += y_raw[i]; + } + y /= j; + + return y; + } + + return 0xbadbabe; +} + +static void report_event(struct work_struct *work) +{ + int x = 0, y = 0, z1 = 0, z2 = 0; + +sample_again: + if (__gpio_get_pin(TS_PIN)) { + goto fake_touch; + } else { + x = get_xaxis(); + y = get_yaxis(); + z1 = ak4183_adc_read(0xE2); + z2 = ak4183_adc_read(0xF2); + if ((x == 0xbadbabe) || (y == 0xbadbabe)) { + mdelay(10); + goto sample_again; + } + x = transform_to_screen_x(x); + y = transform_to_screen_y(y); + input_report_abs(ts->input, ABS_X, x); + input_report_abs(ts->input, ABS_Y, y); + input_report_abs(ts->input, ABS_PRESSURE, z1); + input_report_key(ts->input, BTN_TOUCH, 1); + input_sync(ts->input); + } + + while(!__gpio_get_pin(TS_PIN)); + input_report_abs(ts->input, ABS_PRESSURE, 0); + input_report_key(ts->input, BTN_TOUCH, 0); + input_sync(ts->input); + +fake_touch: + return; +} + +/* + * Module init and exit + */ +static int __init ak4183_init(void) +{ + struct input_dev *input_dev; + int err = -1; + + __gpio_as_i2c(); + __gpio_as_irq_fall_edge(TS_PIN); + + i2c_open(); + + i2c_setclk(100000); /* 100KHz */ + + ts = kmalloc(sizeof(struct ak4183), GFP_KERNEL); + memset(ts, 0, sizeof(struct ak4183)); + + input_dev = input_allocate_device(); + if (!ts || !input_dev) { + err = -ENOMEM; + goto err_free_mem; + } + + strcpy(ts->phys, "input/ts0"); + + input_dev->name = "ak4183ts"; + input_dev->phys = ts->phys; + + set_bit(EV_ABS, input_dev->evbit); + set_bit(ABS_X, input_dev->absbit); + set_bit(ABS_Y, input_dev->absbit); + set_bit(ABS_PRESSURE, input_dev->absbit); + set_bit(EV_KEY, input_dev->evbit); + set_bit(BTN_TOUCH, input_dev->keybit); + + input_set_abs_params(input_dev, ABS_X, 0, SCREEN_X + 1, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_Y + 1, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_Z + 1, 0, 0); + + input_set_drvdata(input_dev, ts); + + err = input_register_device(input_dev); + if (err < 0) { + printk("Register ak4183 touch screen driver failed"); + return err; + } + + ts->input = input_dev; + spin_lock_init(&ts->lock); + INIT_DELAYED_WORK(&ts->work, report_event); + + err = request_irq(TS_IRQ, ak4183_irq, IRQF_DISABLED, AK4183_NAME, ts); + if (err) { + printk("unable to get touch screen IRQ %d", TS_IRQ); + goto err_free_irq; + } + + return 0; + +err_free_irq: + free_irq(TS_IRQ, ts); + +err_free_mem: + input_free_device(input_dev); + kfree(ts); + return err; +} + +static void __exit ak4183_exit(void) +{ + i2c_close(); + free_irq(TS_IRQ, ts); + input_unregister_device(ts->input); + cancel_delayed_work_sync(&ts->work); +} + +MODULE_AUTHOR("Ross"); +MODULE_DESCRIPTION("AK4183 touch screen driver"); +MODULE_LICENSE("GPL"); + +module_init(ak4183_init); +module_exit(ak4183_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/ak4183.h linux-2.6.24.3-20100304/drivers/input/touchscreen/ak4183.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/ak4183.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/touchscreen/ak4183.h 2010-03-03 19:03:54.000000000 -0800 @@ -0,0 +1,41 @@ +#ifndef __AK4183_H__ +#define __AK4183_H__ + +#define AK4183_NAME "ak4183" + +#define TS_PIN GPIO_PEN_IRQ +#define TS_IRQ (IRQ_GPIO_0 + TS_PIN) + +#define TSMINX 6 +#define TSMAXX 249 +#define TSMINY 9 +#define TSMAXY 240 + +#define SCREEN_X 480 +#define SCREEN_Y 272 +#define PRESS_Z 256 + +#define SAMPLES 5 + +struct ts_event { + u16 x; + u16 y; + u16 z1, z2; + u16 pressure; + int ignore; +}; + +struct ak4183 { + struct input_dev *input; + char phys[32]; + + struct ts_event event; + spinlock_t lock; + struct delayed_work work; + struct timer_list timer; + struct pm_dev *pmdev; + u16 x_plate_ohms; + int irq_enabled; +}; + +#endif /* __AK4183_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/jz_ts.c linux-2.6.24.3-20100304/drivers/input/touchscreen/jz_ts.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/jz_ts.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/touchscreen/jz_ts.c 2010-03-03 19:03:54.000000000 -0800 @@ -0,0 +1,892 @@ +/* + * JZ Touch Screen Driver + * + * Copyright (c) 2005 - 2009 Ingenic Semiconductor Inc. + * + * Author: Jason 20090219 + * Regen 20090324 add adkey + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 1 +#define DBG printk("%s(%d) \n",__FUNCTION__,__LINE__); +#else +#define DBG +#endif + +#define TS_NAME "jz-ts" + +#define KEY_SCAN_INTERVAL 5 +#define TS_SCAN_INTERVAL 0 + +/* from qwerty.kl of android */ +#define DPAD_CENTER 232 +#define DPAD_DOWN 108 +#define DPAD_UP 103 +#define DPAD_LEFT 105 +#define DPAD_RIGHT 106 + +/* TS event status */ +#define PENUP 0x00 +#define PENDOWN 0x01 + +/* Sample times in one sample process */ +//#define SAMPLE_TIMES 3 + +#define SAMPLE_TIMES 5 +#define DROP_SAMPLE_TIMES 1 /* min drop 1 sample */ +#define CAL_SAMPLE_TIMES (SAMPLE_TIMES - DROP_SAMPLE_TIMES) +#define VIRTUAL_SAMPLE 3 /* min >= 2 */ +/* Min pressure value. If less than it, filt the point. + * Mask it if it is not useful for you + */ +//#define MIN_PRESSURE 0x100 + +/* Max delta x distance between current point and last point. */ +#define MAX_DELTA_X_OF_2_POINTS 200 +/* Max delta x distance between current point and last point. */ +#define MAX_DELTA_Y_OF_2_POINTS 120 + +/* Max delta between points in one sample process + * Verify method : + * (diff value / min value) * 100 <= MAX_DELTA_OF_SAMPLING + */ +#define MAX_DELTA_OF_SAMPLING 20 + + +#define TS_ABS(x) ((x) > 0 ? (x): -(x)) +#define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a))) +#define MIN(a,b) (((a)<(b))?(a):(b)) + + +/************************************************************************/ +/* SAR ADC OPS */ +/************************************************************************/ + +typedef struct datasource { + u16 xbuf; + u16 ybuf; + u16 zbuf; + u16 reserve; +}datasource_t; +struct ts_event { + u16 status; + u16 x; + u16 y; + u16 pressure; + u16 pad; +}; +#define TOUCH_TYPE 1 +#define BAT_TYPE 2 +#define SADC_TYPE 4 + + +//sadc touch fifo size 2 * 32bit +#define FIFO_MAX_SIZE 2 + +/* + * TS deriver + */ +struct jz_ts_t { + int touch_cal_count; + + unsigned int ts_fifo[FIFO_MAX_SIZE][CAL_SAMPLE_TIMES]; + datasource_t data_s; + struct ts_event event; + int event_valid; + + + int cal_type; /* current calibrate type */ + int oldbat_value; + //struct timer_list acq_timer; // Timer for triggering acquisitions +#ifdef CONFIG_JZ_ADKEY + struct timer_list key_timer; // for adkey + int active_low; // for adkey's interrupt pin +#endif + wait_queue_head_t wait; // read wait queue + spinlock_t lock; + + /* Following 4 members use to pass arguments from u-boot to tell us the ts data. + * But in Android we do not use them. + */ +/* + int minx, miny, maxx, maxy; +*/ + int first_read; + + char phys[32]; + struct input_dev *input_dev; +}; + +static struct jz_ts_t *jz_ts; + +/* + * TS Event type + */ + +#ifdef CONFIG_JZ_ADKEY +struct ad_keys_button { + int code; /* input event code */ + int val; /* the ad value of the key */ + int fuzz; /* the error(+-fuzz) allowed of the ad value of the key */ +}; +static struct ad_keys_button ad_buttons[] = { + { + .code = DPAD_LEFT, + .val = DPAD_LEFT_LEVEL, + .fuzz = 40, + }, + { + .code = DPAD_DOWN, + .val = DPAD_DOWN_LEVEL, + .fuzz = 40, + }, + { + .code = DPAD_UP, + .val = DPAD_UP_LEVEL, + .fuzz = 40, + }, + { + .code = DPAD_CENTER, + .val = DPAD_CENTER_LEVEL, + .fuzz = 40, + }, + { + .code = DPAD_RIGHT, + .val = DPAD_RIGHT_LEVEL, + .fuzz = 40, + }, +}; +#define KEY_NUM (sizeof(ad_buttons) / sizeof(struct ad_keys_button)) +#endif + + +//static unsigned int p; + +static DECLARE_WAIT_QUEUE_HEAD (sadc_wait_queue); + +extern unsigned int (*codec_read_battery)(void); +#if 0 +static void reg_debug(void) +{ + printk("\t####CTRL####################################################\n"); + printk("\tPEND %s, ", REG_SADC_CTRL & SADC_CTRL_PENDM ? "masked" : "enabled"); + printk("PENU %s, ", REG_SADC_CTRL & SADC_CTRL_PENUM ? "masked" : "enabled"); + printk("TSRDY %s\n", REG_SADC_CTRL & SADC_CTRL_TSRDYM ? "masked" : "enabled"); + printk("\t----STATE---------------------------------------------------\n"); + printk("\tIRQ actived: %s, %s, %s\n", + REG_SADC_STATE & SADC_STATE_PEND ? "pen down" : " ", + REG_SADC_STATE & SADC_STATE_PENU ? "pen up " : " ", + REG_SADC_STATE & SADC_STATE_TSRDY ? "sample " : " "); + printk("\t############################################################\n"); +} +#endif +/* + * set adc clock to 24MHz/div. A/D works at freq between 500KHz to 8MHz. + */ +static void sadc_init_clock(int div) +{ + + REG_CPM_CLKGR &= ~CPM_CLKGR_SADC; + + if (div < 2) div = 2; + if (div > 23) div = 23; +#if defined(CONFIG_SOC_JZ4740) + REG_SADC_CFG &= ~SADC_CFG_CLKDIV_MASK; + REG_SADC_CFG |= (div - 1) << SADC_CFG_CLKDIV_BIT; +#endif +#if defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + div = 48; + + REG_SADC_ADCLK &= ~SADC_ADCLK_CLKDIV_MASK; + REG_SADC_ADCLK |= (div - 1) << SADC_ADCLK_CLKDIV_BIT; + REG_SADC_ADCLK &= ~SADC_ADCLK_CLKDIV_BIT; +// REG_SADC_ADCLK |= 39 << SADC_ADCLK_CLKDIV_10_BIT; /* if div ==3,here is 39 */ + + REG_SADC_ADCLK |= 4 << SADC_ADCLK_CLKDIV_10_BIT; /* if div ==48,here is 4 */ + + // if(SADC_STATE_SLEEPND & REG_SADC_STATE) + if( REG_SADC_STATE) + { + REG_SADC_ENA |= SADC_ENA_EXIT_SLP; + while(REG_SADC_ENA & SADC_ENA_EXIT_SLP); + // REG_SADC_STATE = SADC_STATE_SLEEPND; + } + + #endif +} + +static inline void sadc_start_sadcin(void) +{ + REG_SADC_ENA |= SADC_ENA_SADCINEN; +} + +static inline void sadc_start_pbat(void) +{ + REG_SADC_ENA |= SADC_ENA_PBATEN; /* Enable pbat adc */ +} + +static inline void ts_enable_pendown_irq(void) +{ + REG_SADC_CTRL &= ~SADC_CTRL_PENDM; +} + +static inline void ts_enable_penup_irq(void) +{ + REG_SADC_CTRL &= ~SADC_CTRL_PENUM; +} + +static inline void ts_disable_pendown_irq(void) +{ + REG_SADC_CTRL |= SADC_CTRL_PENDM; +} + +static inline void ts_disable_penup_irq(void) +{ + REG_SADC_CTRL |= SADC_CTRL_PENUM; +} + +static inline void sadc_enable_ts(void) +{ + REG_SADC_ENA |= SADC_ENA_TSEN; +} + +static inline void sadc_disable_ts(void) +{ + REG_SADC_ENA &= ~SADC_ENA_TSEN; +} + +static inline void sadc_start_ts(void) +{ + REG_SADC_SAMETIME = 10; /* about 0.02 ms,you can change it */ + REG_SADC_WAITTIME = 2; /* about 3.33 ms,you can change it */ + + REG_SADC_CFG &= ~(SADC_CFG_TS_DMA | SADC_CFG_XYZ_MASK | SADC_CFG_SNUM_MASK |SADC_CFG_EXIN | SADC_CFG_CLKOUT_NUM_MASK); + REG_SADC_CFG |= (SADC_CFG_XYZ1Z2 | SADC_CFG_SNUM(SAMPLE_TIMES) | SADC_CFG_SPZZ | SADC_CFG_DNUM(VIRTUAL_SAMPLE)); + + if (CFG_PBAT_DIV == 1) + REG_SADC_CFG |= SADC_CFG_PBAT_HIGH; /* full baterry voltage >= 2.5V */ + else + REG_SADC_CFG |= SADC_CFG_PBAT_LOW; /* full baterry voltage < 2.5V */ + +// REG_SADC_CTRL = (SADC_STATE_SLEEPND | SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM | SADC_CTRL_PENUM |SADC_CTRL_SRDYM); + REG_SADC_CTRL = ( SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM | SADC_CTRL_PENUM |SADC_CTRL_SRDYM); + REG_SADC_STATE = REG_SADC_STATE; + + REG_SADC_ENA |= SADC_ENA_TSEN; +} + +/** + * Read the battery voltage + */ +unsigned int jz_read_battery(void) +{ + unsigned int v; + unsigned int timeout = 0x3fff; + u16 pbat; + spin_lock_irq(&jz_ts->lock); + if(jz_ts->oldbat_value == 0xffffffff) + { + //printk("==========================\n"); + sadc_start_pbat(); + while(!(REG_SADC_STATE & SADC_STATE_PBATRDY) && --timeout) ; + pbat = REG_SADC_BATDAT; + v = pbat & 0x0fff; + jz_ts->oldbat_value = v; + REG_SADC_STATE = SADC_STATE_PBATRDY; // + REG_SADC_CTRL &= ~SADC_CTRL_PBATRDYM; + + //printk("==========================\n"); + } + if(!(jz_ts->cal_type & BAT_TYPE)) + { + jz_ts->cal_type |= BAT_TYPE; + sadc_start_pbat(); + //printk("start next pbat\n"); + } + + v = jz_ts->oldbat_value; + //printk("pbat = %d\n",v); + spin_unlock_irq(&jz_ts->lock); + return v; +} + +static inline void ts_data_ready(void) +{ + REG_SADC_CTRL |= SADC_CTRL_TSRDYM; +} + +#ifdef CONFIG_JZ_ADKEY +/** + * Read the battery voltage + */ +static unsigned int read_sadcin(void) +{ + unsigned int v; + unsigned int timeout = 0x3ff; + u16 val; + jz_ts->cal_type |= SADC_TYPE; + if(!(REG_SADC_STATE & SADC_STATE_SRDY)) + sadc_start_sadcin(); + + while(!(REG_SADC_STATE & SADC_STATE_SRDY) && --timeout) + ; + + val = REG_SADC_SADDAT; + v = val & 0x0fff; + REG_SADC_STATE = SADC_STATE_SRDY; + jz_ts->cal_type &= ~SADC_TYPE; + return v; +} + +static unsigned int key_scan(int ad_val) +{ + int i; + + for(i = 0; i= ad_val) && + (ad_val >=ad_buttons[i].val - ad_buttons[i].fuzz)) { + return ad_buttons[i].code; + } + } + return -1; +} + +static void key_timer_callback(unsigned long data) +{ + struct jz_ts_t *ts = (struct jz_ts_t *)data; + int state; + int active_low = ts->active_low; + int ad_val, code; + static int old_code; + + state = __gpio_get_pin(GPIO_ADKEY_INT); + ad_val = read_sadcin(); + + if (active_low) { + if (state == 0) { + /* press down */ + code = key_scan(ad_val); + old_code = code; + input_report_key(ts->input_dev, code, 1); + //emily input_sync(ts->input_dev); + mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL); + } else { + /* up */ + input_report_key(ts->input_dev, old_code, 0); + //emily input_sync(ts->input_dev); + udelay(1000); + __gpio_as_irq_fall_edge(GPIO_ADKEY_INT); + } + } else { + if (state == 1) { + /* press down */ + code = key_scan(ad_val); + old_code = code; + input_report_key(ts->input_dev, code, 1); + //emily input_sync(ts->input_dev); + mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL); + } else { + /* up */ + input_report_key(ts->input_dev, old_code, 0); + //emily input_sync(ts->input_dev); + udelay(1000); + __gpio_as_irq_rise_edge(GPIO_ADKEY_INT); + } + } +} + +static irqreturn_t key_interrupt(int irq, void * dev_id) +{ + struct jz_ts_t *ts = dev_id; + DBG; + __gpio_ack_irq(GPIO_ADKEY_INT); + __gpio_as_input(GPIO_ADKEY_INT); + sadc_start_sadcin(); + mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL); + return IRQ_HANDLED; +} +#endif + +/************************************************************************/ +/* Touch Screen module */ +/************************************************************************/ + +#define TSMAXX 3920 +#define TSMAXY 3700 +#define TSMAXZ (1024) /* measure data */ + +#define TSMINX 150 +#define TSMINY 270 +#define TSMINZ 0 + + +#define SCREEN_MAXX 1023 +#define SCREEN_MAXY 1023 +#define PRESS_MAXZ 256 + +static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x ) +{ +/* Now we don't need u-boot to tell us the ts data. */ +/* + if (ts->minx) + { + if (x < ts->minx) x = ts->minx; + if (x > ts->maxx) x = ts->maxx; + + return (x - ts->minx) * SCREEN_MAXX / (ts->maxx - ts->minx); + } + else + { +*/ + if (x < TSMINX) x = TSMINX; + if (x > TSMAXX) x = TSMAXX; + + return (x - TSMINX) * SCREEN_MAXX / (TSMAXX - TSMINX); +/* + } +*/ +} + +static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y) +{ +/* Now we don't need u-boot to tell us the ts data. */ +/* + if (ts->miny) + { + if (y < ts->miny) y = ts->miny; + if (y > ts->maxy) y = ts->maxy; + + return (ts->maxy - y) * SCREEN_MAXY / (ts->maxy - ts->miny); + } + else + { +*/ + if (y < TSMINY) y = TSMINY; + if (y > TSMAXY) y = TSMAXY; + + return (TSMAXY - y) * SCREEN_MAXY / (TSMAXY - TSMINY); +/* + } +*/ +} +static unsigned long transform_to_screen_z(struct jz_ts_t *ts, unsigned long z){ + if(z < TSMINZ) z = TSMINZ; + if (z > TSMAXY) z = TSMAXY; + return (TSMAXZ - z) * PRESS_MAXZ / (TSMAXZ - TSMINZ); +} + /* R plane calibrate,please look up spec 11th page*/ + +#define Yr_PLANE 272 +#define Xr_PLANE 480 + +#define Touch_Formula_One(z1,z2,ref,r) ({ \ + int z; \ + if((z1) > 0){ \ + z = ((ref) * (z2)) / (z1); \ + if((z2) > (z1)) z = (z * r - (ref) * r) / (4096); \ + else z = 0; \ + }else \ + z = 4095; \ + z; \ + }) + + +static int ts_data_filter(struct jz_ts_t *ts){ + int i,xt = 0,yt = 0,zt1 = 0,zt2 = 0,zt3 = 0,zt4 = 0,t1_count = 0,t2_count = 0,z; + + datasource_t *ds = &ts->data_s; + int t,xmin = 0x0fff,ymin = 0x0fff,xmax = 0,ymax = 0;//,z1min = 0xfff,z1max = 0,z2min = 0xfff,z2max = 0; + + /* fifo high 16 bit = y,fifo low 16 bit = x */ + + for(i = 0;i < CAL_SAMPLE_TIMES;i++){ + + t = (ts->ts_fifo[0][i] & 0x0fff); +#if (CAL_SAMPLE_TIMES >= 3) + if(t > xmax) xmax = t; + if(t < xmin) xmin = t; +#endif + xt += t; + t = (ts->ts_fifo[0][i] >> 16) & 0x0fff; +#if (CAL_SAMPLE_TIMES >= 3) + if(t > ymax) ymax = t; + if(t < ymin) ymin = t; +#endif + + yt += t; + if(ts->ts_fifo[1][i] & 0x8000) + { + t = (ts->ts_fifo[1][i] & 0x0fff); + zt1 += t; + + t = (ts->ts_fifo[1][i] >> 16) & 0x0fff; + zt2 += t; + + t1_count++; + }else + { + t = (ts->ts_fifo[1][i] & 0x0fff); + zt3 += t; + + t = (ts->ts_fifo[1][i] >> 16) & 0x0fff; + zt4 += t; + + t2_count++; + } + } +#if (CAL_SAMPLE_TIMES >= 3) + xt = xt - xmin - xmax; + yt = yt - ymin - ymax; +#endif + + xt /= (CAL_SAMPLE_TIMES - 2); + yt /= (CAL_SAMPLE_TIMES - 2); + if(t1_count > 0) + { + zt1 /= t1_count; + zt2 /= t1_count; + zt1 = Touch_Formula_One(zt1,zt2,xt,Xr_PLANE); + } + if(t2_count) + { + zt3 /= t2_count; + zt4 /= t2_count; + zt3 = Touch_Formula_One(zt3,zt4,yt,Yr_PLANE); + } + if((t1_count) && (t2_count)) + z = (zt1 + zt3) / 2; + else if(t1_count) + z = zt1; + else if(t2_count) + z = zt3; + else + z = 0; + + ds->xbuf = xt; + ds->ybuf = yt; + ds->zbuf = z; + return 1; + +} +static void ts_transform_data(struct jz_ts_t *ts){ + + struct ts_event *event = &ts->event; + // event->x = transform_to_screen_x(ts,ts->data_s.xbuf); + // event->y = transform_to_screen_y(ts,ts->data_s.ybuf); + // event->pressure = transform_to_screen_z(ts,ts->data_s.zbuf); + event->x =ts->data_s.xbuf; + event->y =ts->data_s.ybuf; + event->pressure =ts->data_s.zbuf; + + if(event->pressure == 0) event->pressure = 1; +} +static void handle_ts_event(struct jz_ts_t *ts){ + struct ts_event *event = &ts->event; + + input_report_abs(ts->input_dev, ABS_X, event->x); + input_report_abs(ts->input_dev, ABS_Y, event->y); + input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure); + +// printk("event->x = %d,event->y = %d event->pressure = %d\n",event->x,event->y,event->pressure); + + /* Android need it ... */ + input_report_key(ts->input_dev, BTN_TOUCH, 1); + + input_sync(ts->input_dev); + +} + +static void handle_touch(struct jz_ts_t *ts,unsigned int *data,int size){ + /* drop no touch calibrate points */ + if(ts->cal_type & (~TOUCH_TYPE)) + ts->cal_type |= ~TOUCH_TYPE; + if(ts->event_valid){ + handle_ts_event(ts); + ts->event_valid = 0; + } + + if(ts->touch_cal_count >= DROP_SAMPLE_TIMES) + { + if(ts->touch_cal_count < SAMPLE_TIMES){ + ts->ts_fifo[0][ts->touch_cal_count - DROP_SAMPLE_TIMES] = data[0]; + ts->ts_fifo[1][ts->touch_cal_count - DROP_SAMPLE_TIMES] = data[1]; + }else + { + /* drop sample*/ + if(ts->cal_type & TOUCH_TYPE){ + if(ts_data_filter(ts)){ + ts->event_valid = 1; + ts_transform_data(ts); + } + + } + ts->touch_cal_count = 0; + } + } + ts->touch_cal_count++; +} + +static void handle_pbat(struct jz_ts_t *ts,unsigned int *fifo,int size){ + ts->oldbat_value = (*fifo) & 0xfff; // max data = 4096 + jz_ts->cal_type &= ~BAT_TYPE; + //printk("interrupt pbat v = %d\n",ts->oldbat_value); + REG_SADC_ENA &= ~SADC_ENA_PBATEN; +} +static void handle_sadc(struct jz_ts_t *ts,unsigned int *fifo,int size){ + +} + +static irqreturn_t sadc_interrupt(int irq, void * dev_id) +{ + struct jz_ts_t *ts = dev_id; + unsigned int state; + unsigned int fifo[FIFO_MAX_SIZE]; + static int pen_is_down = 0; + + spin_lock_irq(&ts->lock); + + state = REG_SADC_STATE & (~REG_SADC_CTRL); + /* first handle pen up interrupt */ + if(state & SADC_STATE_PENU){ + /* REG_SADC_CTRL used in pendown & penup mutex */ + + REG_SADC_CTRL |= SADC_CTRL_PENUM; + REG_SADC_CTRL &= ~SADC_CTRL_PENDM; + + if(pen_is_down == 1) + { + /* mask pen up and wait pen down */ + REG_SADC_CTRL |= SADC_CTRL_TSRDYM; + { + input_report_abs(ts->input_dev, ABS_PRESSURE, 0); + /* Android need it ... */ + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_sync(ts->input_dev); + ts->cal_type &= ~TOUCH_TYPE; + ts->event_valid = 0; + } + + } + pen_is_down = 0; + }else if(state & SADC_CTRL_PENDM){ + /* REG_SADC_CTRL used in pendown & penup mutex */ + REG_SADC_CTRL |= SADC_CTRL_PENDM; + REG_SADC_CTRL &= ~SADC_CTRL_PENUM; + REG_SADC_CTRL &= ~SADC_CTRL_TSRDYM; + + if(pen_is_down == 0){ + /* mask pen down and wait pen up */ + pen_is_down = 1; + ts->event_valid = 0; + ts->cal_type |= TOUCH_TYPE; + ts->touch_cal_count = 0; + } + state |= SADC_STATE_PENU; + // state |= SADC_STATE_SLEEPND; + }else if(state & SADC_STATE_TSRDY){ + + fifo[0] = REG_SADC_TSDAT; + fifo[1] = REG_SADC_TSDAT; + + /* alone here clear state */ + REG_SADC_STATE = SADC_STATE_TSRDY; + + if(pen_is_down) + handle_touch(ts,fifo,2); + + }else if(state & SADC_STATE_PBATRDY){ + + + fifo[0] = REG_SADC_BATDAT; + handle_pbat(ts,fifo,1); + + }else if(state & SADC_STATE_SRDY){ + /* no use */ + fifo[0] = REG_SADC_SADDAT; + handle_sadc(ts,fifo,1); + + }//else if(state & SADC_STATE_SLEEPND){ + else if(state){ + //after power will use + //REG_SADC_CTRL |= SADC_STATE_SLEEPND; + + } + //when data count not is set_count penup is not clear; + if(!(state & SADC_STATE_TSRDY)) + REG_SADC_STATE = state; + spin_unlock_irq(&ts->lock); + + return IRQ_HANDLED; +} + +#if 0 +static void jz_acq_timer(unsigned long data) +{ + struct jz_ts_t *ts = (struct jz_ts_t *)data; + spin_lock_irq(&ts->lock); + //printk("REG_SADC_CTRL = %x REG_SADC_ENA = %x REG_SADC_CFG = %x\n",REG_SADC_CTRL,REG_SADC_ENA,REG_SADC_CFG); + //printk("REG_SADC_STATE = %x REG_CPM_CLKGR = %x\n",REG_SADC_STATE,REG_CPM_CLKGR); + // schedule next acquire + ts->acq_timer.expires = jiffies + 100;//TS_SCAN_INTERVAL; + del_timer(&ts->acq_timer); + add_timer(&ts->acq_timer); + REG_CPM_CLKGR &= ~CPM_CLKGR_SADC; + spin_unlock_irq(&ts->lock); + +} +#endif + +static int __init jz_ts_init(void) +{ + struct input_dev *input_dev; + struct jz_ts_t *ts; + int error; + + DBG; + ts = jz_ts = kzalloc(sizeof(struct jz_ts_t), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ts || !input_dev) + return -ENOMEM; + + input_dev->name = "qwerty"; /* Set to 'qwerty' to load /system/usr/keychars/qwerty.kcm.bin by Android */ + input_dev->phys = ts->phys; + + + +/* + old: + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); +*/ + + /* For Android */ + set_bit(EV_ABS, input_dev->evbit); + set_bit(ABS_X, input_dev->absbit); + set_bit(ABS_Y, input_dev->absbit); + set_bit(ABS_PRESSURE, input_dev->absbit); + set_bit(EV_KEY, input_dev->evbit); + set_bit(BTN_TOUCH, input_dev->keybit); + +#ifdef CONFIG_JZ_ADKEY + set_bit(DPAD_CENTER, input_dev->keybit); + set_bit(DPAD_DOWN, input_dev->keybit); + set_bit(DPAD_UP, input_dev->keybit); + set_bit(DPAD_LEFT, input_dev->keybit); + set_bit(DPAD_RIGHT, input_dev->keybit); +#endif + input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAXX + 1, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAXY + 1, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAXZ + 1, 0, 0); + input_set_drvdata(input_dev, ts); + error = input_register_device(input_dev); + + strcpy(ts->phys, "input/ts0"); + spin_lock_init(&ts->lock); + + ts->input_dev = input_dev; +#if 0 + // Init ts acquisition timer function + + init_timer(&ts->acq_timer); + ts->acq_timer.function = jz_acq_timer; + ts->acq_timer.data = (unsigned long)ts; + ts->irq_enabled = 1; + ts->acq_timer.expires = jiffies + 100; + add_timer(&ts->acq_timer); +#endif + if (error) { + printk("Input device register failed !\n"); + goto err_free_dev; + } + + sadc_init_clock(6); + //ts_disable_pendown_irq(); + //ts_disable_penup_irq(); + REG_SADC_CTRL = 0x3f; + + error = request_irq(IRQ_SADC, sadc_interrupt, IRQF_DISABLED, TS_NAME, ts); + if (error) { + pr_err("unable to get PenDown IRQ %d", IRQ_SADC); + goto err_free_irq; + } + ts->cal_type = 0; + + ts->oldbat_value = 0xffffffff; //battery cal data first is invalid + + DBG; +#ifdef CONFIG_JZ_ADKEY + // Init key acquisition timer function + init_timer(&ts->key_timer); + ts->key_timer.function = key_timer_callback; + ts->key_timer.data = (unsigned long)ts; + ts->active_low = ACTIVE_LOW_ADKEY; + + error = request_irq(IRQ_GPIO_0 + GPIO_ADKEY_INT, key_interrupt, IRQF_DISABLED, TS_NAME, ts); + if (error) { + pr_err("unable to get AD KEY IRQ %d", IRQ_GPIO_0 + GPIO_ADKEY_INT); + goto err_free_irq; + } + + __gpio_disable_pull(GPIO_ADKEY_INT); + if(ts->active_low) + __gpio_as_irq_fall_edge(GPIO_ADKEY_INT); + else + __gpio_as_irq_rise_edge(GPIO_ADKEY_INT); + +#endif + sadc_start_ts(); + + printk("input: JZ Touch Screen registered.\n"); + + return 0; + +err_free_irq: + free_irq(IRQ_SADC, ts); +#ifdef CONFIG_JZ_ADKEY + free_irq(IRQ_GPIO_0 + GPIO_ADKEY_INT, ts); +#endif +err_free_dev: + input_free_device(ts->input_dev); + kfree(ts); + return 0; +} + +static void __exit jz_ts_exit(void) +{ + + ts_disable_pendown_irq(); + ts_disable_penup_irq(); + sadc_disable_ts(); + free_irq(IRQ_SADC, jz_ts); + input_unregister_device(jz_ts->input_dev); + +} + +module_init(jz_ts_init); +module_exit(jz_ts_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("JZ TouchScreen Driver"); +MODULE_AUTHOR("Jason "); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/Kconfig linux-2.6.24.3-20100304/drivers/input/touchscreen/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/touchscreen/Kconfig 2010-03-03 19:03:54.000000000 -0800 @@ -11,6 +11,25 @@ if INPUT_TOUCHSCREEN + + +config TOUCHSCREEN_JZ + tristate "JZ touchscreen" + default y + help + Say Y here to enable JZ SAR A/D controller if you use touchscreen + on JZ platform. + + To compile this driver as a module, choose M here, and the + module jz_ts should be called. + +config JZ_ADKEY + bool "JZ ADKEY" + depends on TOUCHSCREEN_JZ + help + The AD value of the key is get by JZ SAR A/D controller when any ad key + is pressed down. + config TOUCHSCREEN_ADS7846 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER @@ -29,6 +48,15 @@ To compile this driver as a module, choose M here: the module will be called ads7846. +config TOUCHSCREEN_AK4183 + tristate "AK4183 based touchscreen for volans board" + depends on SOC_JZ4750L + help + Say Y here if you have a touchscreen interface using the + Ak4183 touch screen controller. + + If unsure, say N (but it's safe to say "Y"). + config TOUCHSCREEN_BITSY tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" depends on SA1100_BITSY diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/Makefile linux-2.6.24.3-20100304/drivers/input/touchscreen/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/input/touchscreen/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/input/touchscreen/Makefile 2010-03-03 19:03:54.000000000 -0800 @@ -5,7 +5,9 @@ # Each configuration option enables a list of files. obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o +obj-$(CONFIG_TOUCHSCREEN_AK4183) += ak4183.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o +obj-$(CONFIG_TOUCHSCREEN_JZ) += jz_ts.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4730_cim.c linux-2.6.24.3-20100304/drivers/media/video/jz4730_cim.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4730_cim.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz4730_cim.c 2010-03-03 19:04:44.000000000 -0800 @@ -0,0 +1,622 @@ +/* + * linux/drivers/char/jzchar/cim.c + * + * Camera Interface Module (CIM) driver for JzSOC + * This driver is independent of the camera sensor + * + * Copyright (C) 2005 JunZheng semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CIM_NAME "cim" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("JzSOC Camera Interface Module driver"); +MODULE_LICENSE("GPL"); + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif +/* + * Define the Max Image Size + */ +#define MAX_IMAGE_WIDTH 2048 +#define MAX_IMAGE_HEIGHT 2048 +#define MAX_IMAGE_BPP 16 +#define MAX_FRAME_SIZE (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * MAX_IMAGE_BPP / 8) +#define CIM_RAM_ADDR (CIM_BASE + 0x1000) + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} img_param_t; + +typedef struct +{ + u32 cfg; + u32 ctrl; + u32 mclk; +} cim_config_t; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: img_param_t * +#define IOCTL_CIM_CONFIG 1 // arg type: cim_config_t * +#define IOCTL_STOP_CIM 2 // arg type: void +#define IOCTL_GET_IMG_PARAM 3 // arg type: img_param_t * +#define IOCTL_GET_CIM_CONFIG 4 // arg type: cim_config_t * +#define IOCTL_TEST_CIM_RAM 5 // no arg type * + +/* + * CIM DMA descriptor + */ +struct cim_desc { + u32 nextdesc; /* Physical address of next desc */ + u32 framebuf; /* Physical address of frame buffer */ + u32 frameid; /* Frame ID */ + u32 dmacmd; /* DMA command */ + u32 pagenum; +}; + +/* + * CIM device structure + */ +struct cim_device { + struct video_device *jz_cim; + unsigned char *framebuf; + unsigned int frame_size; + unsigned int page_order; + wait_queue_head_t wait_queue; + struct cim_desc *frame_desc __attribute__ ((aligned (16))); +}; + +/* global*/ +static struct cim_device *cim_dev; + +/*========================================================================== + * CIM init routines + *========================================================================*/ +#if defined(CONFIG_SOC_JZ4750) +static void cim_image_area(img_param_t *c) { + /*set the image data area start 0, 0, lines_per_frame and pixels_per_line*/ + REG_CIM_SIZE = 0; + REG_CIM_OFFSET = 0; + if (REG_CIM_CTRL & CIM_CTRL_SIZEEN_MASK) { + REG_CIM_SIZE = (c->height << CIM_SIZE_LPF_BIT) | (c->width << CIM_SIZE_PPL_BIT); + REG_CIM_OFFSET = (0 << CIM_OFFSET_V_BIT) | (0 << CIM_OFFSET_H_BIT); +// REG_CIM_OFFSET = (100 << CIM_OFFSET_V_BIT) | (50 << CIM_OFFSET_H_BIT); + } +} +#endif + +static void cim_config(cim_config_t *c) +{ + REG_CIM_CFG = c->cfg; + REG_CIM_CTRL = c->ctrl; + + /*Set the master clock output*/ +#if defined(CONFIG_SOC_JZ4730) + __cim_set_master_clk(__cpm_get_sclk(), c->mclk); +#elif defined(CONFIG_SOC_JZ4740) + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#elif defined(CONFIG_SOC_JZ4750) + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#else + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#endif + /* Enable sof, eof and stop interrupts*/ + __cim_enable_sof_intr(); + __cim_enable_eof_intr(); + __cim_enable_stop_intr(); +} + +/*========================================================================== + * CIM start/stop operations + *========================================================================*/ +static int cim_start_dma(char *ubuf) +{ + struct cim_desc *jz_frame_desc; + int cim_frame_size = 0; + jz_frame_desc = cim_dev->frame_desc; + dprintk("framedesc = %x\n", (u32) jz_frame_desc); + __cim_disable(); + dprintk("__cim_disable\n"); + __cim_set_da(virt_to_phys(cim_dev->frame_desc)); + __cim_clear_state(); // clear state register + __cim_reset_rxfifo(); // resetting rxfifo + __cim_unreset_rxfifo(); + __cim_enable_dma(); // enable dma + __cim_enable(); + + dprintk("__cim_enable\n"); +// while(1) { +// mdelay(10); +// dprintk("REG_CIM_DA = 0x%08x\n", REG_CIM_DA); +// dprintk("REG_CIM_FA = 0x%08x\n", REG_CIM_FA); +// dprintk("REG_CIM_FID = 0x%08x\n", REG_CIM_FID); +// dprintk("REG_CIM_CMD = 0x%08x\n", REG_CIM_CMD); +// dprintk("REG_CIM_CFG = 0x%08x\n", REG_CIM_CFG); +// dprintk("REG_CIM_STATE = 0x%08x\n", REG_CIM_STATE); +// dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); +// dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); +// dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); +// mdelay(100); +// } + // wait for interrupts + interruptible_sleep_on(&cim_dev->wait_queue); + dprintk("interruptible_sleep_on\n"); + dprintk("REG_CIM_DA = 0x%08x\n", REG_CIM_DA); + dprintk("REG_CIM_FA = 0x%08x\n", REG_CIM_FA); + dprintk("REG_CIM_FID = 0x%08x\n", REG_CIM_FID); + dprintk("REG_CIM_CMD = 0x%08x\n", REG_CIM_CMD); + dprintk("REG_CIM_CFG = 0x%08x\n", REG_CIM_CFG); + dprintk("REG_CIM_STATE = 0x%08x\n", REG_CIM_STATE); + dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); + dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); + dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); + dprintk("REG_CIM_CMD_3 = %x\n", REG_CIM_CMD); + dprintk("REG_CIM_FA = %x\n", REG_CIM_FA); + /* copy frame data to user buffer */ + jz_frame_desc = cim_dev->frame_desc; + + while(jz_frame_desc != NULL) + { + dprintk("ubuf = %x, framebuf = %x,frame_size= %d\n", (u32)ubuf,(u32) jz_frame_desc->framebuf, jz_frame_desc->dmacmd & 0xffffff); + memcpy(ubuf, phys_to_virt(jz_frame_desc->framebuf), ((jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4)); + ubuf += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + cim_frame_size += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + jz_frame_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + } + return cim_dev->frame_size; +} +static void cim_stop(void) +{ + __cim_disable(); + __cim_clear_state(); +} + +/*========================================================================== + * Framebuffer allocation and destroy + *========================================================================*/ +static void cim_fb_destroy(void) +{ + int pages; + struct cim_desc *jz_frame_desc, *p_desc; + if (cim_dev->frame_desc == NULL) { + printk("Original memory is NULL\n"); + return; + } + jz_frame_desc = cim_dev->frame_desc; + while (jz_frame_desc != NULL) { + dprintk("framebuf = %x,thisdesc = %x,frame_size= %d\n", (u32) jz_frame_desc->framebuf, (unsigned int)jz_frame_desc, (jz_frame_desc->dmacmd & 0xffffff) * 4); + p_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + pages = jz_frame_desc->pagenum; + dprintk("page_order = %d\n", pages); + free_pages((unsigned long)phys_to_virt(jz_frame_desc->framebuf), pages); + kfree(jz_frame_desc); + jz_frame_desc = p_desc; + } + cim_dev->frame_desc = NULL; +} + +static struct cim_desc *get_desc_list(int page_order) +{ + int num, page_nums = 0; + unsigned char *p_buf; + struct cim_desc *desc_list_head __attribute__ ((aligned (16))); + struct cim_desc *desc_list_tail __attribute__ ((aligned (16))); + struct cim_desc *p_desc; +// num = page_order - 1; + num = page_order; + desc_list_head = desc_list_tail = NULL; + + while(page_nums < (1 << page_order)) { + p_desc = (struct cim_desc *)kmalloc(sizeof(struct cim_desc), GFP_KERNEL); + if (NULL == p_desc) + return NULL; + //return -ENOMEM; + cim_realloc_pages: + p_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, num); + if ( !(p_buf) && num != 0) { + num --; + goto cim_realloc_pages; + } + else if ( !(p_buf) && num == 0) { + printk("No memory can be alloc!\n"); + //return -ENOMEM; + return NULL; + } + else { + if (desc_list_head == NULL) { + dprintk("Page_list_head\n"); + desc_list_head = p_desc; + } + + else + desc_list_tail->nextdesc = virt_to_phys(p_desc); + + desc_list_tail = p_desc; + desc_list_tail->framebuf = virt_to_phys(p_buf); + dprintk("framebuf addr is 0x%08x\n", (u32)desc_list_tail->framebuf); + dprintk("frame_desc addr is 0x%08x\n",(u32)virt_to_phys(desc_list_tail)); + + desc_list_tail->frameid = 0x52052018; + desc_list_tail->pagenum = num; + if ((page_nums + (1<< num)) < (1 << page_order)) { + desc_list_tail->dmacmd = ((1 << num) * 4096) >> 2 ; + } + else + desc_list_tail->dmacmd = + (cim_dev->frame_size - page_nums * 4096) >> 2 ; + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + page_nums += (1 << num); + dprintk("the pages_num is %d\n", page_nums); + } + } + + desc_list_tail->nextdesc = virt_to_phys(NULL); + /* stop after capturing a frame */ + desc_list_tail->dmacmd |= (CIM_CMD_STOP | CIM_CMD_EOFINT); + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + + return desc_list_head; +} + +static int cim_fb_alloc(int img_width, int img_height, int img_bpp) +{ +#if defined(CONFIG_SOC_JZ4750) + if ((REG_CIM_CFG & (CIM_CFG_DF_MASK | CIM_CFG_BYPASS_MASK)) == 0) + cim_dev->frame_size = img_width * (img_height-1) * (img_bpp/8); + else + cim_dev->frame_size = img_width * img_height * (img_bpp/8); +#else + cim_dev->frame_size = img_width * img_height * (img_bpp/8); +#endif + cim_dev->page_order = get_order(cim_dev->frame_size); + dprintk("cim_dev->page_order=%d\n", cim_dev->page_order); + /* frame buffer ?? need large mem ??*/ + cim_dev->frame_desc = get_desc_list(cim_dev->page_order); + if (cim_dev->frame_desc == NULL) + return -ENOMEM; + dma_cache_wback((unsigned long)(cim_dev->frame_desc), 16); + return 0; +} + +/*========================================================================== + * File operations + *========================================================================*/ + +static int cim_open(struct inode *inode, struct file *filp); +static int cim_release(struct inode *inode, struct file *filp); +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int cim_mmap(struct file *file, struct vm_area_struct *vma); + +static struct file_operations cim_fops = +{ + open: cim_open, + release: cim_release, + read: cim_read, + write: cim_write, + ioctl: cim_ioctl, + compat_ioctl: v4l_compat_ioctl32, + mmap: cim_mmap +}; + +static struct video_device jz_v4l_device = { + .name = "jz cim", + //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | + // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + .fops = &cim_fops, + .minor = -1, + .owner = THIS_MODULE, + .release = video_device_release, +}; + +static int cim_open(struct inode *inode, struct file *filp) +{ + + try_module_get(THIS_MODULE); + return 0; +} + +static int cim_release(struct inode *inode, struct file *filp) +{ + cim_fb_destroy(); + cim_stop(); + + module_put(THIS_MODULE); + return 0; +} + +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + if (size < cim_dev->frame_size) + return -EINVAL; + dprintk("read cim\n"); + return cim_start_dma(buf); +} + +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("cim error: write is not implemented\n"); + return -1; +} + +static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + switch (cmd) { + case IOCTL_GET_IMG_PARAM: + { + img_param_t i; + return copy_to_user(argp, &i, sizeof(img_param_t)) ? -EFAULT : 0; + } + case IOCTL_SET_IMG_PARAM: + { + img_param_t i; + int img_width, img_height, img_bpp; + if (copy_from_user((void *)&i, (void *)arg, sizeof(img_param_t))) + return -EFAULT; +#if defined(CONFIG_SOC_JZ4750) + cim_image_area(&i); +#endif + img_width = i.width; + img_height = i.height; + img_bpp = i.bpp; + dprintk("ioctl_set_cim_param\n"); + if ((img_width * img_height * img_bpp/8) > MAX_FRAME_SIZE){ + printk("ERROR! Image is too large!\n"); + return -EINVAL; + } + /* allocate frame buffers */ + if (cim_dev->frame_desc == NULL){ + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + else + if ((img_width * img_height * img_bpp/8) > cim_dev->frame_size){ + /* realloc the buffer */ + cim_fb_destroy(); + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERRROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + break; + } + case IOCTL_CIM_CONFIG: + { + cim_config_t c; + + if (copy_from_user((void *)&c, (void *)arg, sizeof(cim_config_t))) + return -EFAULT; + + cim_config(&c); + + break; + } + case IOCTL_TEST_CIM_RAM: + { + + int i; + volatile unsigned int *ptr; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + printk("RAM test!\n"); + printk("CIM_RAM_ADDR = 0x%08x\n", CIM_RAM_ADDR); + for (i = 0; i < 1024; ptr++, i++) + *ptr = i; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + dma_cache_wback((unsigned long)CIM_RAM_ADDR,0xffc); + + for (i = 0; i < 1024; i++) { + if (i != *ptr) + printk("*ptr!=i, *ptr=%d, i=%d\n", *ptr, i); + if (i%32 == 0) { + if (i%128 == 0) + printk("\n"); + printk("*ptr=%04d, i=%04d | ", *ptr, i); + } + ptr++; + } + printk("\n"); + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return 0; +} + +/* Use mmap /dev/fb can only get a non-cacheable Virtual Address. */ +static int cim_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned long start; + unsigned long off; + u32 len; + + off = vma->vm_pgoff << PAGE_SHIFT; + //fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); + + /* frame buffer memory */ + start = cim_dev->frame_desc->framebuf; + len = PAGE_ALIGN((start & ~PAGE_MASK) + (cim_dev->frame_desc->dmacmd & CIM_CMD_LEN_MASK)); + start &= PAGE_MASK; + + if ((vma->vm_end - vma->vm_start + off) > len) + return -EINVAL; + off += start; + + vma->vm_pgoff = off >> PAGE_SHIFT; + vma->vm_flags |= VM_IO; + +#if defined(CONFIG_MIPS32) + pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; +// pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NO_WA; /* WT cachable */ + pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; +#endif + + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + vma->vm_flags |= VM_IO; + return -EAGAIN; + + return 0; +} +/*========================================================================== + * Interrupt handler + *========================================================================*/ + +static irqreturn_t cim_irq_handler(int irq, void *dev_id) +{ + u32 state = REG_CIM_STATE; + dprintk("REG_CIM_STATE = %x\n", REG_CIM_STATE); + dprintk("REG_CIM_CTRL = %x\n", REG_CIM_CTRL); +#if 1 + if (state & CIM_STATE_RXF_OF) { + dprintk("OverFlow interrupt!\n"); + } +#endif + if (state & CIM_STATE_DMA_EOF) { + dprintk("EOF interrupt!\n"); + __cim_disable_dma(); + __cim_disable(); + wake_up_interruptible(&cim_dev->wait_queue); + dprintk("EOF interrupt wake up!\n"); + } + + if (state & CIM_STATE_DMA_STOP) { + // Got a frame, wake up wait routine + __cim_disable_dma(); + __cim_disable(); + dprintk("Stop interrupt!\n"); + wake_up_interruptible(&cim_dev->wait_queue); + } +#if 1 + if (state & CIM_STATE_RXF_TRIG) { + dprintk("Trig!\n"); + } +#endif + + /* clear status flags*/ + REG_CIM_STATE = 0; + return IRQ_HANDLED; +} + +static int v4l_device_init(void) +{ + cim_dev = kzalloc(sizeof(struct cim_device), GFP_KERNEL); + if (!cim_dev) return -ENOMEM; + cim_dev->jz_cim = video_device_alloc(); + if (!cim_dev->jz_cim) { + return -ENOMEM; + } + memcpy(cim_dev->jz_cim, &jz_v4l_device, sizeof(struct video_device)); + cim_dev->frame_desc = NULL; + cim_dev->frame_size = 0; + cim_dev->page_order = 0; + return 0; +} +/*========================================================================== + * Module init and exit + *========================================================================*/ + +static int __init jz_cim_init(void) +{ + struct cim_device *dev; + int ret; + /* allocate device */ + ret = v4l_device_init(); + if (ret) + return ret; + /* record device */ + dev = cim_dev; + init_waitqueue_head(&dev->wait_queue); + + ret = video_register_device(dev->jz_cim, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + printk(KERN_ERR "CIM Video4Linux-device " + "registration failed\n"); + return -EINVAL; + } + + if (ret < 0) { + cim_fb_destroy(); + kfree(dev); + return ret; + } + + if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED, + CIM_NAME, dev))) { + printk(KERN_ERR "request_irq return error, ret=%d\n", ret); + cim_fb_destroy(); + kfree(dev); + printk(KERN_ERR "CIM could not get IRQ\n"); + return ret; + } + + printk("JzSOC Camera Interface Module (CIM) driver registered\n"); + + return 0; +} + +static void __exit jz_cim_exit(void) +{ + free_irq(IRQ_CIM, cim_dev); + kfree(cim_dev); + video_unregister_device(cim_dev->jz_cim); +} + +module_init(jz_cim_init); +module_exit(jz_cim_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4740_cim.c linux-2.6.24.3-20100304/drivers/media/video/jz4740_cim.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4740_cim.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz4740_cim.c 2010-03-03 19:04:45.000000000 -0800 @@ -0,0 +1,622 @@ +/* + * linux/drivers/char/jzchar/cim.c + * + * Camera Interface Module (CIM) driver for JzSOC + * This driver is independent of the camera sensor + * + * Copyright (C) 2005 JunZheng semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CIM_NAME "cim" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("JzSOC Camera Interface Module driver"); +MODULE_LICENSE("GPL"); + +#undef DEBUG +//#define DEBUG +#ifdef DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif +/* + * Define the Max Image Size + */ +#define MAX_IMAGE_WIDTH 2048 +#define MAX_IMAGE_HEIGHT 2048 +#define MAX_IMAGE_BPP 16 +#define MAX_FRAME_SIZE (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * MAX_IMAGE_BPP / 8) +#define CIM_RAM_ADDR (CIM_BASE + 0x1000) + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} img_param_t; + +typedef struct +{ + u32 cfg; + u32 ctrl; + u32 mclk; +} cim_config_t; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: img_param_t * +#define IOCTL_CIM_CONFIG 1 // arg type: cim_config_t * +#define IOCTL_STOP_CIM 2 // arg type: void +#define IOCTL_GET_IMG_PARAM 3 // arg type: img_param_t * +#define IOCTL_GET_CIM_CONFIG 4 // arg type: cim_config_t * +#define IOCTL_TEST_CIM_RAM 5 // no arg type * + +/* + * CIM DMA descriptor + */ +struct cim_desc { + u32 nextdesc; /* Physical address of next desc */ + u32 framebuf; /* Physical address of frame buffer */ + u32 frameid; /* Frame ID */ + u32 dmacmd; /* DMA command */ + u32 pagenum; +}; + +/* + * CIM device structure + */ +struct cim_device { + struct video_device *jz_cim; + unsigned char *framebuf; + unsigned int frame_size; + unsigned int page_order; + wait_queue_head_t wait_queue; + struct cim_desc *frame_desc __attribute__ ((aligned (16))); +}; + +/* global*/ +static struct cim_device *cim_dev; + +/*========================================================================== + * CIM init routines + *========================================================================*/ +#if defined(CONFIG_SOC_JZ4750) +static void cim_image_area(img_param_t *c) { + /*set the image data area start 0, 0, lines_per_frame and pixels_per_line*/ + REG_CIM_SIZE = 0; + REG_CIM_OFFSET = 0; + if (REG_CIM_CTRL & CIM_CTRL_SIZEEN_MASK) { + REG_CIM_SIZE = (c->height << CIM_SIZE_LPF_BIT) | (c->width << CIM_SIZE_PPL_BIT); + REG_CIM_OFFSET = (0 << CIM_OFFSET_V_BIT) | (0 << CIM_OFFSET_H_BIT); +// REG_CIM_OFFSET = (100 << CIM_OFFSET_V_BIT) | (50 << CIM_OFFSET_H_BIT); + } +} +#endif + +static void cim_config(cim_config_t *c) +{ + REG_CIM_CFG = c->cfg; + REG_CIM_CTRL = c->ctrl; + + /*Set the master clock output*/ +#if defined(CONFIG_SOC_JZ4730) + __cim_set_master_clk(__cpm_get_sclk(), c->mclk); +#elif defined(CONFIG_SOC_JZ4740) + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#elif defined(CONFIG_SOC_JZ4750) + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#else + __cim_set_master_clk(__cpm_get_hclk(), c->mclk); +#endif + /* Enable sof, eof and stop interrupts*/ + __cim_enable_sof_intr(); + __cim_enable_eof_intr(); + __cim_enable_stop_intr(); +} + +/*========================================================================== + * CIM start/stop operations + *========================================================================*/ +static int cim_start_dma(char *ubuf) +{ + struct cim_desc *jz_frame_desc; + int cim_frame_size = 0; + jz_frame_desc = cim_dev->frame_desc; + dprintk("framedesc = %x\n", (u32) jz_frame_desc); + __cim_disable(); + dprintk("__cim_disable\n"); + __cim_set_da(virt_to_phys(cim_dev->frame_desc)); + __cim_clear_state(); // clear state register + __cim_reset_rxfifo(); // resetting rxfifo + __cim_unreset_rxfifo(); + __cim_enable_dma(); // enable dma + __cim_enable(); + + dprintk("__cim_enable\n"); +// while(1) { +// mdelay(10); +// dprintk("REG_CIM_DA = 0x%08x\n", REG_CIM_DA); +// dprintk("REG_CIM_FA = 0x%08x\n", REG_CIM_FA); +// dprintk("REG_CIM_FID = 0x%08x\n", REG_CIM_FID); +// dprintk("REG_CIM_CMD = 0x%08x\n", REG_CIM_CMD); +// dprintk("REG_CIM_CFG = 0x%08x\n", REG_CIM_CFG); +// dprintk("REG_CIM_STATE = 0x%08x\n", REG_CIM_STATE); +// dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); +// dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); +// dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); +// mdelay(100); +// } + // wait for interrupts + interruptible_sleep_on(&cim_dev->wait_queue); + dprintk("interruptible_sleep_on\n"); + dprintk("REG_CIM_DA = 0x%08x\n", REG_CIM_DA); + dprintk("REG_CIM_FA = 0x%08x\n", REG_CIM_FA); + dprintk("REG_CIM_FID = 0x%08x\n", REG_CIM_FID); + dprintk("REG_CIM_CMD = 0x%08x\n", REG_CIM_CMD); + dprintk("REG_CIM_CFG = 0x%08x\n", REG_CIM_CFG); + dprintk("REG_CIM_STATE = 0x%08x\n", REG_CIM_STATE); + dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); + dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); + dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); + dprintk("REG_CIM_CMD_3 = %x\n", REG_CIM_CMD); + dprintk("REG_CIM_FA = %x\n", REG_CIM_FA); + /* copy frame data to user buffer */ + jz_frame_desc = cim_dev->frame_desc; + + while(jz_frame_desc != NULL) + { + dprintk("ubuf = %x, framebuf = %x,frame_size= %d\n", (u32)ubuf,(u32) jz_frame_desc->framebuf, jz_frame_desc->dmacmd & 0xffffff); + memcpy(ubuf, phys_to_virt(jz_frame_desc->framebuf), ((jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4)); + ubuf += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + cim_frame_size += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + jz_frame_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + } + return cim_dev->frame_size; +} +static void cim_stop(void) +{ + __cim_disable(); + __cim_clear_state(); +} + +/*========================================================================== + * Framebuffer allocation and destroy + *========================================================================*/ +static void cim_fb_destroy(void) +{ + int pages; + struct cim_desc *jz_frame_desc, *p_desc; + if (cim_dev->frame_desc == NULL) { + printk("Original memory is NULL\n"); + return; + } + jz_frame_desc = cim_dev->frame_desc; + while (jz_frame_desc != NULL) { + dprintk("framebuf = %x,thisdesc = %x,frame_size= %d\n", (u32) jz_frame_desc->framebuf, (unsigned int)jz_frame_desc, (jz_frame_desc->dmacmd & 0xffffff) * 4); + p_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + pages = jz_frame_desc->pagenum; + dprintk("page_order = %d\n", pages); + free_pages((unsigned long)phys_to_virt(jz_frame_desc->framebuf), pages); + kfree(jz_frame_desc); + jz_frame_desc = p_desc; + } + cim_dev->frame_desc = NULL; +} + +static struct cim_desc *get_desc_list(int page_order) +{ + int num, page_nums = 0; + unsigned char *p_buf; + struct cim_desc *desc_list_head __attribute__ ((aligned (16))); + struct cim_desc *desc_list_tail __attribute__ ((aligned (16))); + struct cim_desc *p_desc; +// num = page_order - 1; + num = page_order; + desc_list_head = desc_list_tail = NULL; + + while(page_nums < (1 << page_order)) { + p_desc = (struct cim_desc *)kmalloc(sizeof(struct cim_desc), GFP_KERNEL); + if (NULL == p_desc) + return NULL; + //return -ENOMEM; + cim_realloc_pages: + p_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, num); + if ( !(p_buf) && num != 0) { + num --; + goto cim_realloc_pages; + } + else if ( !(p_buf) && num == 0) { + printk("No memory can be alloc!\n"); + //return -ENOMEM; + return NULL; + } + else { + if (desc_list_head == NULL) { + dprintk("Page_list_head\n"); + desc_list_head = p_desc; + } + + else + desc_list_tail->nextdesc = virt_to_phys(p_desc); + + desc_list_tail = p_desc; + desc_list_tail->framebuf = virt_to_phys(p_buf); + dprintk("framebuf addr is 0x%08x\n", (u32)desc_list_tail->framebuf); + dprintk("frame_desc addr is 0x%08x\n",(u32)virt_to_phys(desc_list_tail)); + + desc_list_tail->frameid = 0x52052018; + desc_list_tail->pagenum = num; + if ((page_nums + (1<< num)) < (1 << page_order)) { + desc_list_tail->dmacmd = ((1 << num) * 4096) >> 2 ; + } + else + desc_list_tail->dmacmd = + (cim_dev->frame_size - page_nums * 4096) >> 2 ; + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + page_nums += (1 << num); + dprintk("the pages_num is %d\n", page_nums); + } + } + + desc_list_tail->nextdesc = virt_to_phys(NULL); + /* stop after capturing a frame */ + desc_list_tail->dmacmd |= (CIM_CMD_STOP | CIM_CMD_EOFINT); + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + + return desc_list_head; +} + +static int cim_fb_alloc(int img_width, int img_height, int img_bpp) +{ +#if defined(CONFIG_SOC_JZ4750) + if ((REG_CIM_CFG & (CIM_CFG_DF_MASK | CIM_CFG_BYPASS_MASK)) == 0) + cim_dev->frame_size = img_width * (img_height-1) * (img_bpp/8); + else + cim_dev->frame_size = img_width * img_height * (img_bpp/8); +#else + cim_dev->frame_size = img_width * img_height * (img_bpp/8); +#endif + cim_dev->page_order = get_order(cim_dev->frame_size); + dprintk("cim_dev->page_order=%d\n", cim_dev->page_order); + /* frame buffer ?? need large mem ??*/ + cim_dev->frame_desc = get_desc_list(cim_dev->page_order); + if (cim_dev->frame_desc == NULL) + return -ENOMEM; + dma_cache_wback((unsigned long)(cim_dev->frame_desc), 16); + return 0; +} + +/*========================================================================== + * File operations + *========================================================================*/ + +static int cim_open(struct inode *inode, struct file *filp); +static int cim_release(struct inode *inode, struct file *filp); +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int cim_mmap(struct file *file, struct vm_area_struct *vma); + +static struct file_operations cim_fops = +{ + open: cim_open, + release: cim_release, + read: cim_read, + write: cim_write, + ioctl: cim_ioctl, + compat_ioctl: v4l_compat_ioctl32, + mmap: cim_mmap +}; + +static struct video_device jz_v4l_device = { + .name = "jz cim", + //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | + // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + .fops = &cim_fops, + .minor = -1, + .owner = THIS_MODULE, + .release = video_device_release, +}; + +static int cim_open(struct inode *inode, struct file *filp) +{ + + try_module_get(THIS_MODULE); + return 0; +} + +static int cim_release(struct inode *inode, struct file *filp) +{ + cim_fb_destroy(); + cim_stop(); + + module_put(THIS_MODULE); + return 0; +} + +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + if (size < cim_dev->frame_size) + return -EINVAL; + dprintk("read cim\n"); + return cim_start_dma(buf); +} + +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("cim error: write is not implemented\n"); + return -1; +} + +static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + switch (cmd) { + case IOCTL_GET_IMG_PARAM: + { + img_param_t i; + return copy_to_user(argp, &i, sizeof(img_param_t)) ? -EFAULT : 0; + } + case IOCTL_SET_IMG_PARAM: + { + img_param_t i; + int img_width, img_height, img_bpp; + if (copy_from_user((void *)&i, (void *)arg, sizeof(img_param_t))) + return -EFAULT; +#if defined(CONFIG_SOC_JZ4750) + cim_image_area(&i); +#endif + img_width = i.width; + img_height = i.height; + img_bpp = i.bpp; + dprintk("ioctl_set_cim_param\n"); + if ((img_width * img_height * img_bpp/8) > MAX_FRAME_SIZE){ + printk("ERROR! Image is too large!\n"); + return -EINVAL; + } + /* allocate frame buffers */ + if (cim_dev->frame_desc == NULL){ + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + else + if ((img_width * img_height * img_bpp/8) > cim_dev->frame_size){ + /* realloc the buffer */ + cim_fb_destroy(); + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERRROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + break; + } + case IOCTL_CIM_CONFIG: + { + cim_config_t c; + + if (copy_from_user((void *)&c, (void *)arg, sizeof(cim_config_t))) + return -EFAULT; + + cim_config(&c); + + break; + } + case IOCTL_TEST_CIM_RAM: + { + + int i; + volatile unsigned int *ptr; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + printk("RAM test!\n"); + printk("CIM_RAM_ADDR = 0x%08x\n", CIM_RAM_ADDR); + for (i = 0; i < 1024; ptr++, i++) + *ptr = i; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + dma_cache_wback((unsigned long)CIM_RAM_ADDR,0xffc); + + for (i = 0; i < 1024; i++) { + if (i != *ptr) + printk("*ptr!=i, *ptr=%d, i=%d\n", *ptr, i); + if (i%32 == 0) { + if (i%128 == 0) + printk("\n"); + printk("*ptr=%04d, i=%04d | ", *ptr, i); + } + ptr++; + } + printk("\n"); + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return 0; +} + +/* Use mmap /dev/fb can only get a non-cacheable Virtual Address. */ +static int cim_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned long start; + unsigned long off; + u32 len; + + off = vma->vm_pgoff << PAGE_SHIFT; + //fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); + + /* frame buffer memory */ + start = cim_dev->frame_desc->framebuf; + len = PAGE_ALIGN((start & ~PAGE_MASK) + (cim_dev->frame_desc->dmacmd & CIM_CMD_LEN_MASK)); + start &= PAGE_MASK; + + if ((vma->vm_end - vma->vm_start + off) > len) + return -EINVAL; + off += start; + + vma->vm_pgoff = off >> PAGE_SHIFT; + vma->vm_flags |= VM_IO; + +#if defined(CONFIG_MIPS32) + pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; +// pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NO_WA; /* WT cachable */ + pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; +#endif + + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + vma->vm_flags |= VM_IO; + return -EAGAIN; + + return 0; +} +/*========================================================================== + * Interrupt handler + *========================================================================*/ + +static irqreturn_t cim_irq_handler(int irq, void *dev_id) +{ + u32 state = REG_CIM_STATE; + dprintk("REG_CIM_STATE = %x\n", REG_CIM_STATE); + dprintk("REG_CIM_CTRL = %x\n", REG_CIM_CTRL); +#if 1 + if (state & CIM_STATE_RXF_OF) { + dprintk("OverFlow interrupt!\n"); + } +#endif + if (state & CIM_STATE_DMA_EOF) { + dprintk("EOF interrupt!\n"); + __cim_disable_dma(); + __cim_disable(); + wake_up_interruptible(&cim_dev->wait_queue); + dprintk("EOF interrupt wake up!\n"); + } + + if (state & CIM_STATE_DMA_STOP) { + // Got a frame, wake up wait routine + __cim_disable_dma(); + __cim_disable(); + dprintk("Stop interrupt!\n"); + wake_up_interruptible(&cim_dev->wait_queue); + } +#if 1 + if (state & CIM_STATE_RXF_TRIG) { + dprintk("Trig!\n"); + } +#endif + + /* clear status flags*/ + REG_CIM_STATE = 0; + return IRQ_HANDLED; +} + +static int v4l_device_init(void) +{ + cim_dev = kzalloc(sizeof(struct cim_device), GFP_KERNEL); + if (!cim_dev) return -ENOMEM; + cim_dev->jz_cim = video_device_alloc(); + if (!cim_dev->jz_cim) { + return -ENOMEM; + } + memcpy(cim_dev->jz_cim, &jz_v4l_device, sizeof(struct video_device)); + cim_dev->frame_desc = NULL; + cim_dev->frame_size = 0; + cim_dev->page_order = 0; + return 0; +} +/*========================================================================== + * Module init and exit + *========================================================================*/ + +static int __init jz_cim_init(void) +{ + struct cim_device *dev; + int ret; + /* allocate device */ + ret = v4l_device_init(); + if (ret) + return ret; + /* record device */ + dev = cim_dev; + init_waitqueue_head(&dev->wait_queue); + + ret = video_register_device(dev->jz_cim, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + printk(KERN_ERR "CIM Video4Linux-device " + "registration failed\n"); + return -EINVAL; + } + + if (ret < 0) { + cim_fb_destroy(); + kfree(dev); + return ret; + } + + if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED, + CIM_NAME, dev))) { + printk(KERN_ERR "request_irq return error, ret=%d\n", ret); + cim_fb_destroy(); + kfree(dev); + printk(KERN_ERR "CIM could not get IRQ\n"); + return ret; + } + + printk("JzSOC Camera Interface Module (CIM) driver registered\n"); + + return 0; +} + +static void __exit jz_cim_exit(void) +{ + free_irq(IRQ_CIM, cim_dev); + kfree(cim_dev); + video_unregister_device(cim_dev->jz_cim); +} + +module_init(jz_cim_init); +module_exit(jz_cim_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4750_cim.c linux-2.6.24.3-20100304/drivers/media/video/jz4750_cim.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4750_cim.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz4750_cim.c 2010-03-03 19:04:44.000000000 -0800 @@ -0,0 +1,734 @@ +/* + * linux/drivers/char/jzchar/cim.c + * + * Camera Interface Module (CIM) driver for JzSOC + * This driver is independent of the camera sensor + * + * Copyright (C) 2005 JunZheng semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jz4750_cim.h" + +#define CIM_NAME "cim" + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("JzSOC Camera Interface Module driver"); +MODULE_LICENSE("GPL"); + +#if defined(CONFIG_SOC_JZ4750D) +//#define USE_CIM_OFRCV 1 /* Test overflow recovery */ +#define USE_CIM_DMA_SYNC 1 //set da every time +#endif + +//#define CIM_DEBUG +#undef CIM_DEBUG +#ifdef CIM_DEBUG +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif +/* + * Define the Max Image Size + */ +#define MAX_IMAGE_WIDTH 2048 +#define MAX_IMAGE_HEIGHT 2048 +#define MAX_IMAGE_BPP 16 +#define MAX_FRAME_SIZE (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * MAX_IMAGE_BPP / 8) +#define CIM_RAM_ADDR (CIM_BASE + 0x1000) + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} img_param_t; + +typedef struct +{ + u32 cfg; + u32 ctrl; + u32 mclk; + u32 size; + u32 offs; +} cim_config_t; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: img_param_t * +#define IOCTL_CIM_CONFIG 1 // arg type: cim_config_t * +#define IOCTL_STOP_CIM 2 // arg type: void +#define IOCTL_GET_IMG_PARAM 3 // arg type: img_param_t * +#define IOCTL_GET_CIM_CONFIG 4 // arg type: cim_config_t * +#define IOCTL_TEST_CIM_RAM 5 // no arg type * +#define IOCTL_START_CIM 6 // arg type: void + +/* + * CIM DMA descriptor + */ +struct cim_desc { + u32 nextdesc; /* Physical address of next desc */ + u32 framebuf; /* Physical address of frame buffer */ + u32 frameid; /* Frame ID */ + u32 dmacmd; /* DMA command */ + u32 pagenum; +}; + +/* + * CIM device structure + */ +struct cim_device { + struct video_device *jz_cim; + unsigned char *framebuf; + unsigned int frame_size; + unsigned int page_order; + wait_queue_head_t wait_queue; + struct cim_desc *frame_desc __attribute__ ((aligned (16))); +}; + +/* global*/ +static struct cim_device *cim_dev; +static int start_init = 1; +static int irq_sleep; +/*========================================================================== + * CIM init routines + *========================================================================*/ + +static void cim_image_area(img_param_t *c) { + /*set the image data area start 0, 0, lines_per_frame and pixels_per_line*/ + REG_CIM_SIZE = 0; + REG_CIM_OFFSET = 0; +#if defined(CONFIG_SOC_JZ4750D) + if (REG_CIM_CTRL & CIM_CTRL_WIN_EN) { + REG_CIM_SIZE = (c->height << CIM_SIZE_LPF_BIT) | (c->width << CIM_SIZE_PPL_BIT); +// REG_CIM_OFFSET = (0 << CIM_OFFSET_V_BIT) | (0 << CIM_OFFSET_H_BIT); +// REG_CIM_OFFSET = (100 << CIM_OFFSET_V_BIT) | (50 << CIM_OFFSET_H_BIT); + REG_CIM_OFFSET = (200 << CIM_OFFSET_V_BIT) | (300 << CIM_OFFSET_H_BIT); + } +#endif +} + + +static void cim_config(cim_config_t *c) +{ + REG_CIM_CFG = c->cfg; + REG_CIM_CTRL = c->ctrl; + REG_CIM_SIZE = c->size; + REG_CIM_OFFSET = c->offs; + + dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); + dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); + /* Set the master clock output */ + /* If use pll clock, enable it */ +// __cim_set_master_clk(__cpm_get_hclk(), c->mclk); + + /* Enable sof, eof and stop interrupts*/ + +// __cim_enable_sof_intr(); + __cim_enable_eof_intr(); +#if defined(USE_CIM_EEOFINT) + __cim_enable_eeof_intr(); +#endif +// __cim_enable_stop_intr(); +// __cim_enable_trig_intr(); +// __cim_enable_rxfifo_overflow_intr(); +// __cim_enable_vdd_intr(); +// printk("hclk=%d, mclk = %d\n", __cpm_get_hclk(),c->mclk); + dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); +} + +/*========================================================================== + * CIM start/stop operations + *========================================================================*/ +static int cim_start_dma(char *ubuf) +{ + + struct cim_desc *jz_frame_desc; + int cim_frame_size = 0; + dprintk("==========start_init = %d\n", start_init); + __cim_disable(); + __cim_set_da(virt_to_phys(cim_dev->frame_desc)); + __cim_clear_state(); // clear state register + __cim_reset_rxfifo(); // resetting rxfifo + __cim_unreset_rxfifo(); + __cim_enable_dma(); // enable dma + __cim_enable(); + interruptible_sleep_on(&cim_dev->wait_queue); + +#if 1 + dprintk("interruptible_sleep_on\n"); + dprintk("REG_CIM_DA = 0x%08x\n", REG_CIM_DA); + dprintk("REG_CIM_FA = 0x%08x\n", REG_CIM_FA); + dprintk("REG_CIM_FID = 0x%08x\n", REG_CIM_FID); + dprintk("REG_CIM_CMD = 0x%08x\n", REG_CIM_CMD); + dprintk("REG_CIM_CFG = 0x%08x\n", REG_CIM_CFG); + dprintk("REG_CIM_STATE = 0x%08x\n", REG_CIM_STATE); + dprintk("REG_CIM_CTRL = 0x%08x\n", REG_CIM_CTRL); + dprintk("REG_CIM_SIZE = 0x%08x\n", REG_CIM_SIZE); + dprintk("REG_CIM_OFFSET = 0x%08x\n", REG_CIM_OFFSET); + dprintk("REG_CIM_CMD_3 = %x\n", REG_CIM_CMD); + dprintk("REG_CIM_FA = %x\n", REG_CIM_FA); +#endif + /* copy frame data to user buffer */ +#if 0 + jz_frame_desc = cim_dev->frame_desc; + + while (jz_frame_desc != NULL) + { + dprintk("ubuf = %x, framebuf = %x,frame_size= %d\n", (u32)ubuf,(u32) jz_frame_desc->framebuf, jz_frame_desc->dmacmd & 0xffffff); + memcpy(ubuf, phys_to_virt(jz_frame_desc->framebuf), ((jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4)); + ubuf += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + cim_frame_size += (jz_frame_desc->dmacmd & CIM_CMD_LEN_MASK) * 4; + jz_frame_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + } +#endif + dprintk("---------**********-----\n"); + return cim_dev->frame_size; +} +static void cim_stop(void) +{ + __cim_disable(); + __cim_clear_state(); +} + +/*========================================================================== + * Framebuffer allocation and destroy + *========================================================================*/ +static void cim_fb_destroy(void) +{ + int pages; + struct cim_desc *jz_frame_desc, *p_desc; + __cim_disable_dma(); + __cim_disable(); + + dprintk("cim_dev->frame_desc = %x\n", (u32)cim_dev->frame_desc); + if (cim_dev->frame_desc == NULL) { + printk("Original memory is NULL\n"); + return; + } + jz_frame_desc = cim_dev->frame_desc; +// while (jz_frame_desc != NULL) { +// while (jz_frame_desc != cim_dev->frame_desc) { + dprintk("framebuf = %x,thisdesc = %x,frame_size= %d\n", (u32) jz_frame_desc->framebuf, (unsigned int)jz_frame_desc, (jz_frame_desc->dmacmd & 0xffffff) * 4); + p_desc = (struct cim_desc *)phys_to_virt(jz_frame_desc->nextdesc); + pages = jz_frame_desc->pagenum; + dprintk("page_order = %d\n", pages); + free_pages((unsigned long)phys_to_virt(jz_frame_desc->framebuf), pages); + kfree(jz_frame_desc); + jz_frame_desc = p_desc; +// } + cim_dev->frame_desc = NULL; + start_init = 1; +} + +static struct cim_desc *get_desc_list(int page_order) +{ + int num, page_nums = 0; + unsigned char *p_buf; + struct cim_desc *desc_list_head __attribute__ ((aligned (16))); + struct cim_desc *desc_list_tail __attribute__ ((aligned (16))); + struct cim_desc *p_desc; +// num = page_order - 1; + num = page_order; + desc_list_head = desc_list_tail = NULL; + + while(page_nums < (1 << page_order)) { + p_desc = (struct cim_desc *)kmalloc(sizeof(struct cim_desc), GFP_KERNEL); + if (NULL == p_desc) + return NULL; + //return -ENOMEM; + cim_realloc_pages: + p_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, num); + if ( !(p_buf) && num != 0) { + num --; + goto cim_realloc_pages; + } + else if ( !(p_buf) && num == 0) { + printk("No memory can be alloc!\n"); + //return -ENOMEM; + return NULL; + } + else { + if (desc_list_head == NULL) { + dprintk("Page_list_head\n"); + desc_list_head = p_desc; + } + + else + desc_list_tail->nextdesc = virt_to_phys(p_desc); + + desc_list_tail = p_desc; + desc_list_tail->framebuf = virt_to_phys(p_buf); + dprintk("framebuf addr is 0x%08x\n", (u32)desc_list_tail->framebuf); + dprintk("frame_desc addr is 0x%08x\n",(u32)virt_to_phys(desc_list_tail)); + + desc_list_tail->frameid = 0x52052018; + desc_list_tail->pagenum = num; + if ((page_nums + (1<< num)) < (1 << page_order)) { + desc_list_tail->dmacmd = ((1 << num) * 4096) >> 2 ; + } + else + desc_list_tail->dmacmd = + (cim_dev->frame_size - page_nums * 4096) >> 2 ; + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + page_nums += (1 << num); + dprintk("the pages_num is %d\n", page_nums); + dma_cache_wback((unsigned long)(desc_list_tail), 16); + } + } + +// desc_list_tail->nextdesc = virt_to_phys(NULL); + desc_list_tail->nextdesc = virt_to_phys(desc_list_head); + desc_list_tail->dmacmd |= CIM_CMD_EOFINT; +#if defined(CONFIG_SOC_JZ4750D) +#if defined(USE_CIM_OFRCV) + desc_list_tail->dmacmd |= (CIM_CMD_EOFINT | CIM_CMD_OFRCV); +#endif +#if defined(USE_CIM_DMA_SYNC) /* wake ervry time */ + desc_list_tail->nextdesc = virt_to_phys(NULL); + desc_list_tail->dmacmd |= (CIM_CMD_STOP | CIM_CMD_EOFINT | CIM_CMD_OFRCV); +#endif +#if defined(USE_CIM_EEOFINT) +// desc_list_tail->dmacmd |= CIM_CMD_EEOFINT; + desc_list_tail->dmacmd |= (CIM_CMD_STOP | CIM_CMD_EOFINT | CIM_CMD_EEOFINT); +#endif +#endif + /* stop after capturing a frame */ +// desc_list_tail->dmacmd |= (CIM_CMD_STOP | CIM_CMD_EOFINT | CIM_CMD_SOFINT); + + + + + dma_cache_wback((unsigned long)(desc_list_tail), 16); + dprintk("the desc_list_tail->dmacmd is 0x%08x\n", desc_list_tail->dmacmd); + + return desc_list_head; +} + +static int cim_fb_alloc(int img_width, int img_height, int img_bpp) +{ + if ((REG_CIM_CFG & (CIM_CFG_DF_MASK | CIM_CFG_BYPASS_MASK)) == 0) + cim_dev->frame_size = img_width * (img_height-1) * (img_bpp/8); + else + cim_dev->frame_size = img_width * img_height * (img_bpp/8); + + cim_dev->page_order = get_order(cim_dev->frame_size); + dprintk("cim_dev->page_order=%d\n", cim_dev->page_order); + /* frame buffer ?? need large mem ??*/ + cim_dev->frame_desc = get_desc_list(cim_dev->page_order); + if (cim_dev->frame_desc == NULL) + return -ENOMEM; + dma_cache_wback((unsigned long)(cim_dev->frame_desc), 16); + return 0; +} + +/*========================================================================== + * File operations + *========================================================================*/ + +static int cim_open(struct inode *inode, struct file *filp); +static int cim_release(struct inode *inode, struct file *filp); +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int cim_mmap(struct file *file, struct vm_area_struct *vma); + +static struct file_operations cim_fops = +{ + open: cim_open, + release: cim_release, + read: cim_read, + write: cim_write, + ioctl: cim_ioctl, + compat_ioctl: v4l_compat_ioctl32, + mmap: cim_mmap +}; + +static struct video_device jz_v4l_device = { + .name = "jz cim", + //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | + // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + .fops = &cim_fops, + .minor = -1, + .owner = THIS_MODULE, + .release = video_device_release, +}; + +static int cim_open(struct inode *inode, struct file *filp) +{ + + try_module_get(THIS_MODULE); + return 0; +} + +static int cim_release(struct inode *inode, struct file *filp) +{ + dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); + cim_fb_destroy(); + cim_stop(); + + module_put(THIS_MODULE); + return 0; +} + +static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + printk("============cim error: write is not implemented\n"); + if (size < cim_dev->frame_size) + return -EINVAL; + return cim_start_dma(buf); +} + +static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("cim error: write is not implemented\n"); + return -1; +} + +static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + switch (cmd) { + case IOCTL_GET_IMG_PARAM: + { + unsigned int i; + i = cim_dev->frame_desc->framebuf; +// printk("cim_dev->frame_desc->framebuf = 0x%08x\n", cim_dev->frame_desc->framebuf); + dprintk("&&cim_dev->frame_desc->framebuf = 0x%08x\n", i); + + return copy_to_user(argp, &i, sizeof(unsigned int)) ? -EFAULT : 0; + } + case IOCTL_STOP_CIM: + { + __cim_disable_dma(); // enable dma + __cim_disable(); + +// cim_fb_destroy(); + return 0; + } + case IOCTL_START_CIM: + { + __cim_set_da(virt_to_phys(cim_dev->frame_desc)); + __cim_clear_state(); // clear state register + __cim_reset_rxfifo(); // resetting rxfifo + __cim_unreset_rxfifo(); + __cim_enable_dma(); // enable dma + __cim_enable(); + return 0; + } + case IOCTL_SET_IMG_PARAM: + { + img_param_t i; + int img_width, img_height, img_bpp; + if (copy_from_user((void *)&i, (void *)arg, sizeof(img_param_t))) + return -EFAULT; + img_width = i.width; + img_height = i.height; + img_bpp = i.bpp; + printk("ALLOC =========\n"); + if ((img_width * img_height * img_bpp/8) > MAX_FRAME_SIZE){ + printk("ERROR! Image is too large!\n"); + return -EINVAL; + } + /* allocate frame buffers */ + if (cim_dev->frame_desc == NULL){ + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + else + if ((img_width * img_height * img_bpp/8) > cim_dev->frame_size){ + /* realloc the buffer */ + dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); + cim_fb_destroy(); + if (cim_fb_alloc(img_width, img_height, img_bpp) < 0){ + printk("ERRROR! Init & alloc cim fail!\n"); + return -ENOMEM; + } + } + break; + } + case IOCTL_CIM_CONFIG: + { + cim_config_t c; + + if (copy_from_user((void *)&c, (void *)arg, sizeof(cim_config_t))) + return -EFAULT; + cim_config(&c); + + break; + } + case IOCTL_TEST_CIM_RAM: + { + + int i; + volatile unsigned int *ptr; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + dprintk("RAM test!\n"); + dprintk("CIM_RAM_ADDR = 0x%08x\n", CIM_RAM_ADDR); + for (i = 0; i < 1024; ptr++, i++) + *ptr = i; + ptr = (volatile unsigned int *)(CIM_RAM_ADDR); + dma_cache_wback((unsigned long)CIM_RAM_ADDR,0xffc); + + for (i = 0; i < 1024; i++) { + if (i != *ptr) + dprintk("*ptr!=i, *ptr=%d, i=%d\n", *ptr, i); + if (i%32 == 0) { + if (i%128 == 0) + dprintk("\n"); + dprintk("*ptr=%04d, i=%04d | ", *ptr, i); + } + ptr++; + } + dprintk("\n"); + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return 0; +} + +/* Use mmap /dev/fb can only get a non-cacheable Virtual Address. */ +static int cim_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned long start; + unsigned long off; + u32 len; + + dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); + off = vma->vm_pgoff << PAGE_SHIFT; + + /* frame buffer memory */ + start = cim_dev->frame_desc->framebuf; + len = PAGE_ALIGN((start & ~PAGE_MASK) + (cim_dev->frame_desc->dmacmd & CIM_CMD_LEN_MASK)*4); + start &= PAGE_MASK; + printk("vma->vm_end = 0x%08lx,\nvma->vm_start = 0x%08lx,\noff = 0x%08lx,\n len = 0x%08x\n\n", vma->vm_end, vma->vm_start, off, len); + if ((vma->vm_end - vma->vm_start + off) > len) { + printk("Error: vma is larger than memory length\n"); + return -EINVAL; + } + off += start; + + vma->vm_pgoff = off >> PAGE_SHIFT; + vma->vm_flags |= VM_IO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Uncacheable */ + +#if defined(CONFIG_MIPS32) + pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; + pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */ +#endif + + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} +/*========================================================================== + * Interrupt handler + *========================================================================*/ + +static irqreturn_t cim_irq_handler(int irq, void *dev_id) +{ + u32 state = REG_CIM_STATE; + dprintk("REG_CIM_STATE = %x\n", REG_CIM_STATE); + dprintk("IRQ:REG_CIM_CTRL = %x\n", REG_CIM_CTRL); + +#if 0 //sof + /* recommed don't open it */ + if ((REG_CIM_CTRL & CIM_CTRL_DMA_SOFM) && (state & CIM_STATE_DMA_SOF)) { + dprintk("SOF interrupt!\n"); + REG_CIM_STATE &= ~CIM_STATE_DMA_SOF; + } +#endif +#if 0 //eeof + if ((REG_CIM_CTRL & CIM_CTRL_DMA_EEOFM) && (state & CIM_STATE_DMA_EEOF)) { + dprintk("EEOF interrupt!\n"); + __cim_disable_dma(); + __cim_disable(); + wake_up_interruptible(&cim_dev->wait_queue); + REG_CIM_STATE &= ~CIM_STATE_DMA_EEOF; + } +#endif + +#if 1 //eof + if ((REG_CIM_CTRL & CIM_CTRL_DMA_EOFM) && (state & CIM_STATE_DMA_EOF)) { +// if (state & CIM_STATE_DMA_EOF) { + dprintk("EOF interrupt!\n"); + +#if defined(USE_CIM_DMA_SYNC) /* wake ervry time */ +// __cim_disable_dma(); +// __cim_disable(); + wake_up_interruptible(&cim_dev->wait_queue); +#else +// if(irq_sleep == 1) + wake_up_interruptible(&cim_dev->wait_queue); +#endif + REG_CIM_STATE &= ~CIM_STATE_DMA_EOF; + return IRQ_HANDLED; + } +#endif +#if 0 //overflow + if (state & CIM_STATE_RXF_OF) { + printk("OverFlow interrupt!\n"); + REG_CIM_STATE &= ~CIM_STATE_RXF_OF; +// dprintk("REG_CIM_STATE = %x\n", REG_CIM_STATE); + return IRQ_HANDLED; + } +#endif +#if 1 // stop + if ((REG_CIM_CTRL & CIM_CTRL_DMA_STOPM) && (state & CIM_STATE_DMA_STOP)) { + // Got a frame, wake up wait routine +//#if defined(USE_CIM_DMA_SYNC) /* wake ervry time */ + __cim_disable_dma(); +// __cim_disable(); + + dprintk("Stop interrupt!\n"); +// wake_up_interruptible(&cim_dev->wait_queue); + REG_CIM_STATE &= ~CIM_STATE_DMA_STOP; + } +#endif + +#if 0 //trig + if ((REG_CIM_CTRL & CIM_CTRL_RXF_TRIGM) && (state & CIM_STATE_RXF_TRIG)) { + REG_CIM_STATE &= ~CIM_STATE_RXF_TRIG; + dprintk("Trig interrupt!\n"); + } +#endif + +#if 0 //vdd + /* only happen disable cim during DMA transfer*/ + if ((REG_CIM_CTRL & CIM_CTRL_VDDM) && (state & CIM_STATE_VDD)) { + dprintk(">>CIM Disable Done Interrupt!\n"); + REG_CIM_STATE &= ~CIM_STATE_VDD; + } +#endif + /* clear status flags*/ + dprintk("before clear REG_CIM_STATE = %x\n", REG_CIM_STATE); +// REG_CIM_STATE = 0; + + return IRQ_HANDLED; +} + +/*Camera gpio init, different operationg according sensor*/ +static void camera_gpio_init(void) { + + __gpio_as_cim(); + __gpio_as_i2c(); + __sensor_gpio_init(); +} + +static int v4l_device_init(void) +{ + camera_gpio_init(); + cim_dev = kzalloc(sizeof(struct cim_device), GFP_KERNEL); + if (!cim_dev) return -ENOMEM; + cim_dev->jz_cim = video_device_alloc(); + if (!cim_dev->jz_cim) { + return -ENOMEM; + } + memcpy(cim_dev->jz_cim, &jz_v4l_device, sizeof(struct video_device)); + cim_dev->frame_desc = NULL; + cim_dev->frame_size = 0; + cim_dev->page_order = 0; + return 0; +} +/*========================================================================== + * Module init and exit + *========================================================================*/ + +static int __init jz4750_cim_init(void) +{ + struct cim_device *dev; + int ret; + /* allocate device */ + ret = v4l_device_init(); + if (ret) + return ret; + /* record device */ + dev = cim_dev; + init_waitqueue_head(&dev->wait_queue); + + ret = video_register_device(dev->jz_cim, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + printk(KERN_ERR "CIM Video4Linux-device " + "registration failed\n"); + return -EINVAL; + } + + if (ret < 0) { + dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); + cim_fb_destroy(); + kfree(dev); + return ret; + } + + if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED, + CIM_NAME, dev))) { + printk(KERN_ERR "request_irq return error, ret=%d\n", ret); + dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); + cim_fb_destroy(); + kfree(dev); + printk(KERN_ERR "CIM could not get IRQ\n"); + return ret; + } + + printk("JzSOC Camera Interface Module (CIM) driver registered\n"); + + return 0; +} + +static void __exit jz4750_cim_exit(void) +{ + free_irq(IRQ_CIM, cim_dev); + kfree(cim_dev); + video_unregister_device(cim_dev->jz_cim); +} + +module_init(jz4750_cim_init); +module_exit(jz4750_cim_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4750_cim.h linux-2.6.24.3-20100304/drivers/media/video/jz4750_cim.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz4750_cim.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz4750_cim.h 2010-03-03 19:04:45.000000000 -0800 @@ -0,0 +1,49 @@ +/* + * linux/drivers/media/video/jz4750_cim.h -- Ingenic Jz4750 On-Chip CIM driver + * + * Copyright (C) 2005-2008, Ingenic Semiconductor Inc. + * + * 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 __JZ4750_CIM_H__ +#define __JZ4750_CIM_H__ + +/* gpio init */ +#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) /* board pavo */ +#define GPIO_CAMERA_RST (32*4+8) /* CIM_MCLK as reset */ +#else +#error "driver/video/Jzlcd.h, please define SPI pins on your board." +#endif + +#define CONFIG_OV9650 1 + +#if defined(CONFIG_OV9650) || defined(CONFIG_OV2640) +#if defined(CONFIG_JZ4750_APUS) /* board pavo */ +#define __sensor_gpio_init() \ +do {\ + __gpio_as_output(GPIO_CAMERA_RST); \ + __gpio_set_pin(GPIO_CAMERA_RST); \ + mdelay(50); \ + __gpio_clear_pin(GPIO_CAMERA_RST);\ +} while(0) + +#elif defined(CONFIG_JZ4750D_FUWA1) /* board pavo */ +#define __sensor_gpio_init() \ +do {\ + __gpio_as_output(GPIO_CAMERA_RST); \ + __gpio_set_pin(GPIO_CAMERA_RST); \ + mdelay(50); \ + __gpio_clear_pin(GPIO_CAMERA_RST);\ +} while(0) +#endif +#endif + +#ifndef __sensor_gpio_init +#define __sensor_gpio_init() +#endif +#endif /* __JZ4750_CIM_H__ */ + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz_cim.h linux-2.6.24.3-20100304/drivers/media/video/jz_cim.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz_cim.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz_cim.h 2010-03-03 19:04:44.000000000 -0800 @@ -0,0 +1,36 @@ +/* + * JzSOC CIM driver + * + * Copyright (C) 2005 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __JZ_CIM_H__ +#define __JZ_CIM_H__ + +typedef struct +{ + u32 width; + u32 height; + u32 bpp; +} IMG_PARAM; + +/* + * IOCTL_XXX commands + */ +#define IOCTL_SET_IMG_PARAM 0 // arg type: IMG_PARAM * + +#endif /* __JZ__CIM_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz_sensor.c linux-2.6.24.3-20100304/drivers/media/video/jz_sensor.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/jz_sensor.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/jz_sensor.c 2010-03-03 19:04:44.000000000 -0800 @@ -0,0 +1,202 @@ +/* + * linux/drivers/char/jzchar/sensor.c + * + * Common CMOS Camera Sensor Driver + * + * Copyright (C) 2006 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include "jz-chars.h" + +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Jianli Wei"); +MODULE_DESCRIPTION("Common CMOS Camera Sensor Driver"); +MODULE_LICENSE("GPL"); + +/* + * ioctl commands + */ +#define IOCTL_SET_ADDR 0 /* set i2c address */ +#define IOCTL_SET_CLK 1 /* set i2c clock */ +#define IOCTL_WRITE_REG 2 /* write sensor register */ +#define IOCTL_READ_REG 3 /* read sensor register */ + +/* + * i2c related + */ +static unsigned int i2c_addr = 0x42; +static unsigned int i2c_clk = 100000; + +struct video_device *jz_sensor; + +static void write_reg(u8 reg, u8 val) +{ + i2c_open(); + i2c_setclk(i2c_clk); + i2c_write((i2c_addr >> 1), &val, reg, 1); + i2c_close(); +} + +static u8 read_reg(u8 reg) +{ + u8 val; + + i2c_open(); + i2c_setclk(i2c_clk); + i2c_read((i2c_addr >> 1), &val, reg, 1); + i2c_close(); + return val; +} + +/* + * fops routines + */ + +static int sensor_open(struct inode *inode, struct file *filp); +static int sensor_release(struct inode *inode, struct file *filp); +static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l); +static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l); +static int sensor_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +static struct file_operations sensor_fops = +{ + open: sensor_open, + release: sensor_release, + read: sensor_read, + write: sensor_write, + ioctl: sensor_ioctl, +}; + +static int sensor_open(struct inode *inode, struct file *filp) +{ + try_module_get(THIS_MODULE); + return 0; +} + +static int sensor_release(struct inode *inode, struct file *filp) +{ + module_put(THIS_MODULE); + return 0; +} + +static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l) +{ + printk("sensor: read is not implemented\n"); + return -1; +} + +static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l) +{ + printk("sensor: write is not implemented\n"); + return -1; +} + +static int sensor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case IOCTL_SET_ADDR: + if (copy_from_user(&i2c_addr, (void *)arg, 4)) + return -EFAULT; + break; + case IOCTL_SET_CLK: + if (copy_from_user(&i2c_clk, (void *)arg, 4)) + return -EFAULT; + break; + case IOCTL_WRITE_REG: + { + u8 regval[2]; + + if (copy_from_user(regval, (void *)arg, 2)) + return -EFAULT; + + write_reg(regval[0], regval[1]); + break; + } + case IOCTL_READ_REG: + { + u8 reg, val; + + if (copy_from_user(®, (void *)arg, 1)) + return -EFAULT; + + val = read_reg(reg); + + if (copy_to_user((void *)(arg + 1), &val, 1)) + return -EFAULT; + break; + } + default: + printk("Not supported command: 0x%x\n", cmd); + return -EINVAL; + break; + } + return ret; +} + +static struct video_device jz_v4l_device = { + .name = "jz sensor", + //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | + // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + .fops = &sensor_fops, + .minor = -1, +}; + +/* + * Module init and exit + */ + +static int __init jz_sensor_init(void) +{ + int ret; +// cim_dev = kzalloc(sizeof(struct cim_device), GFP_KERNEL); + jz_sensor = video_device_alloc(); + memcpy(jz_sensor, &jz_v4l_device, sizeof(struct video_device)); + jz_sensor->release = video_device_release; +// ret = jz_register_chrdev(SENSOR_MINOR, "sensor", &sensor_fops, NULL); + ret = video_register_device(jz_sensor, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + return ret; + } + + printk("Ingenic CMOS camera sensor driver registered\n"); + + return 0; +} + +static void __exit jz_sensor_exit(void) +{ +// jz_unregister_chrdev(SENSOR_MINOR, "sensor"); + video_unregister_device(jz_sensor); +} + +module_init(jz_sensor_init); +module_exit(jz_sensor_exit); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/Kconfig linux-2.6.24.3-20100304/drivers/media/video/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/Kconfig 2010-03-03 19:04:44.000000000 -0800 @@ -514,6 +514,24 @@ Say Y here to build in support for the Vino video input system found on SGI Indy machines. +config VIDEO_JZ4730_CIM + tristate 'JzSOC Camera Interface Module (CIM) support' + depends on VIDEO_V4L2 && FB_JZSOC && SOC_JZ4730 + select VIDEO_JZ_SENSOR + +config VIDEO_JZ4740_CIM + tristate 'JzSOC Camera Interface Module (CIM) support' + depends on VIDEO_V4L2 && FB_JZSOC && SOC_JZ4740 + select VIDEO_JZ_SENSOR + +config VIDEO_JZ4750_CIM + tristate 'JzSOC Camera Interface Module (CIM) support' + depends on VIDEO_V4L2 && FB_JZSOC && (SOC_JZ4750 || SOC_JZ4750D) + select VIDEO_JZ_SENSOR + +config VIDEO_JZ_SENSOR + tristate "Jz generic camera sensor driver" + config VIDEO_STRADIS tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)" depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/Makefile linux-2.6.24.3-20100304/drivers/media/video/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/media/video/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/media/video/Makefile 2010-03-03 19:04:45.000000000 -0800 @@ -15,6 +15,11 @@ obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o endif +obj-$(CONFIG_VIDEO_JZ4730_CIM) += jz4730_cim.o +obj-$(CONFIG_VIDEO_JZ4740_CIM) += jz4740_cim.o +obj-$(CONFIG_VIDEO_JZ4750_CIM) += jz4750_cim.o +obj-$(CONFIG_VIDEO_JZ_SENSOR) += jz_sensor.o + obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/card/block.c linux-2.6.24.3-20100304/drivers/mmc/card/block.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/card/block.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/card/block.c 2010-03-03 19:04:52.000000000 -0800 @@ -225,7 +225,11 @@ brq.mrq.cmd = &brq.cmd; brq.mrq.data = &brq.data; +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + brq.cmd.arg = req->sector + 16384; +#else brq.cmd.arg = req->sector; +#endif if (!mmc_card_blockaddr(card)) brq.cmd.arg <<= 9; brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/core/mmc.c linux-2.6.24.3-20100304/drivers/mmc/core/mmc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/core/mmc.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/core/mmc.c 2010-03-03 19:04:51.000000000 -0800 @@ -141,8 +141,13 @@ e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); - csd->capacity = (1 + m) << (e + 2); +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + csd->capacity = (1 + m) << (e + 2); + csd->capacity -= 16384; +#else + csd->capacity = (1 + m) << (e + 2); +#endif csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); @@ -402,8 +407,9 @@ EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); if (err) goto free_card; - - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + + /* all mmc v4 support 8 bit mmc card */ + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_8); } if (!oldcard) diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/core/sd.c linux-2.6.24.3-20100304/drivers/mmc/core/sd.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/core/sd.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/core/sd.c 2010-03-03 19:04:51.000000000 -0800 @@ -110,8 +110,13 @@ e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); - csd->capacity = (1 + m) << (e + 2); +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + csd->capacity = (1 + m) << (e + 2); + csd->capacity -= 16384; +#else + csd->capacity = (1 + m) << (e + 2); +#endif csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); @@ -138,8 +143,13 @@ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); m = UNSTUFF_BITS(resp, 48, 22); - csd->capacity = (1 + m) << 10; +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + csd->capacity = (1 + m) << 10; + csd->capacity -= 16384; +#else + csd->capacity = (1 + m) << 10; +#endif csd->read_blkbits = 9; csd->read_partial = 0; csd->write_misalign = 0; @@ -269,9 +279,11 @@ goto out; if ((status[16] & 0xF) != 1) { +#if 0 printk(KERN_WARNING "%s: Problem switching card " "into high-speed mode!\n", mmc_hostname(card->host)); +#endif } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_SD_HS); @@ -386,6 +398,9 @@ goto free_card; mmc_decode_cid(card); + + /* set 24MHz clock again, why?? */ + mmc_set_clock(host, 24000000); } /* diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz4750_mmc.c linux-2.6.24.3-20100304/drivers/mmc/host/jz4750_mmc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz4750_mmc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/jz4750_mmc.c 2010-03-03 19:04:51.000000000 -0800 @@ -0,0 +1,1062 @@ +/* + * linux/drivers/mmc/jz_mmc.c - JZ SD/MMC driver + * + * Copyright (C) 2005 - 2008 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "jz4750_mmc.h" + +#define DRIVER_NAME "jz-mmc" + +#define USE_DMA + +static int r_type = 0; +static int rxdmachan = 0; +static int txdmachan = 0; +static int mmc_slot_enable = 0; +static int auto_select_bus = MSC_4BIT_BUS; /* default 4 bit bus*/ + +/* Start the MMC clock and operation */ +static inline int jz_mmc_start_op(void) +{ + REG_MSC_STRPCL(MSC_ID) = MSC_STRPCL_START_OP; + + return MMC_NO_ERROR; +} + +static inline u32 jz_mmc_calc_clkrt(int is_low, u32 rate) +{ + u32 clkrt; + u32 clk_src = is_low ? 24000000 : 48000000; + + clkrt = 0; + while (rate < clk_src) { + clkrt++; + clk_src >>= 1; + } + return clkrt; +} + +/* Select the MMC clock frequency */ +static int jz_mmc_set_clock(u32 rate) +{ + int clkrt; + + /* __cpm_select_msc_clk_high will select 48M clock for MMC/SD card + * perhaps this will made some card with bad quality init fail,or + * bad stabilization. + */ + if (rate > SD_CLOCK_FAST) { + __cpm_select_msc_clk_high(MSC_ID,1); /* select clock source from CPM */ + clkrt = jz_mmc_calc_clkrt(0, rate); + } else { + __cpm_select_msc_clk(MSC_ID,1); /* select clock source from CPM */ + clkrt = jz_mmc_calc_clkrt(1, rate); + } + +#ifndef CONFIG_FPGA + REG_MSC_CLKRT(MSC_ID) = clkrt; +#else + REG_MSC_CLKRT(MSC_ID) = 7; +#endif + return MMC_NO_ERROR; +} + +static void jz_mmc_enable_irq(struct jz_mmc_host *host, unsigned int mask) +{ + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->imask &= ~mask; + REG_MSC_IMASK(MSC_ID) = host->imask; + spin_unlock_irqrestore(&host->lock, flags); +} + +static void jz_mmc_disable_irq(struct jz_mmc_host *host, unsigned int mask) +{ + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->imask |= mask; + REG_MSC_IMASK(MSC_ID) = host->imask; + spin_unlock_irqrestore(&host->lock, flags); +} + +void jz_set_dma_block_size(int dmanr, int nbyte); + +#ifdef USE_DMA +static inline void +jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode) +{ + unsigned long flags; + + flags = claim_dma_lock(); + disable_dma(chan); + clear_dma_ff(chan); + jz_set_dma_block_size(chan, 32); + set_dma_mode(chan, mode); + set_dma_addr(chan, phyaddr); + set_dma_count(chan, count + 31); + enable_dma(chan); + release_dma_lock(flags); +} + +static irqreturn_t jz_mmc_dma_rx_callback(int irq, void *devid) +{ + int chan = rxdmachan; + + disable_dma(chan); + if (__dmac_channel_address_error_detected(chan)) { + printk(KERN_DEBUG "%s: DMAC address error.\n", + __FUNCTION__); + __dmac_channel_clear_address_error(chan); + } + if (__dmac_channel_transmit_end_detected(chan)) { + __dmac_channel_clear_transmit_end(chan); + } + return IRQ_HANDLED; +} +static irqreturn_t jz_mmc_dma_tx_callback(int irq, void *devid) +{ + int chan = txdmachan; + + disable_dma(chan); + if (__dmac_channel_address_error_detected(chan)) { + printk(KERN_DEBUG "%s: DMAC address error.\n", + __FUNCTION__); + __dmac_channel_clear_address_error(chan); + } + if (__dmac_channel_transmit_end_detected(chan)) { + __dmac_channel_clear_transmit_end(chan); + } + return IRQ_HANDLED; +} + +/* Prepare DMA to start data transfer from the MMC card */ +static void jz_mmc_rx_setup_data(struct jz_mmc_host *host, + struct mmc_data *data) +{ + unsigned int nob = data->blocks; + int channelrx = rxdmachan; + int i; + u32 size; + + if (data->flags & MMC_DATA_STREAM) + nob = 0xffff; + + REG_MSC_NOB(MSC_ID) = nob; + REG_MSC_BLKLEN(MSC_ID) = data->blksz; + size = nob * data->blksz; + + if (data->flags & MMC_DATA_READ) { + host->dma.dir = DMA_FROM_DEVICE; + } else { + host->dma.dir = DMA_TO_DEVICE; + } + + host->dma.len = + dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma.dir); + + for (i = 0; i < host->dma.len; i++) { + host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); + host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); + dma_cache_wback_inv((unsigned long) + CKSEG0ADDR(sg_dma_address(data->sg)) + + data->sg->offset, + host->sg_cpu[i].dcmd); + jz_mmc_start_dma(channelrx, host->sg_cpu[i].dtadr, + host->sg_cpu[i].dcmd, DMA_MODE_READ); + } +} + +/* Prepare DMA to start data transfer from the MMC card */ +static void jz_mmc_tx_setup_data(struct jz_mmc_host *host, + struct mmc_data *data) +{ + unsigned int nob = data->blocks; + int channeltx = txdmachan; + int i; + u32 size; + + if (data->flags & MMC_DATA_STREAM) + nob = 0xffff; + + REG_MSC_NOB(MSC_ID) = nob; + REG_MSC_BLKLEN(MSC_ID) = data->blksz; + size = nob * data->blksz; + + if (data->flags & MMC_DATA_READ) { + host->dma.dir = DMA_FROM_DEVICE; + } else { + host->dma.dir = DMA_TO_DEVICE; + } + + host->dma.len = + dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma.dir); + + for (i = 0; i < host->dma.len; i++) { + host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); + host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); + dma_cache_wback_inv((unsigned long) + CKSEG0ADDR(sg_dma_address(data->sg)) + + data->sg->offset, + host->sg_cpu[i].dcmd); + jz_mmc_start_dma(channeltx, host->sg_cpu[i].dtadr, + host->sg_cpu[i].dcmd, DMA_MODE_WRITE); + } +} +#else +static void jz_mmc_receive_pio(struct jz_mmc_host *host) +{ + + struct mmc_data *data = 0; + int sg_len = 0, max = 0, count = 0; + u32 *buf = 0; + struct scatterlist *sg; + unsigned int nob; + + data = host->mrq->data; + nob = data->blocks; + REG_MSC_NOB(MSC_ID) = nob; + REG_MSC_BLKLEN(MSC_ID) = data->blksz; + + max = host->pio.len; + if (host->pio.index < host->dma.len) { + sg = &data->sg[host->pio.index]; + buf = sg_virt(sg) + host->pio.offset; + + /* This is the space left inside the buffer */ + sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; + /* Check to if we need less then the size of the sg_buffer */ + if (sg_len < max) max = sg_len; + } + max = max / 4; + for(count = 0; count < max; count++) { + while (REG_MSC_STAT(MSC_ID) & MSC_STAT_DATA_FIFO_EMPTY) + ; + *buf++ = REG_MSC_RXFIFO(MSC_ID); + } + host->pio.len -= count; + host->pio.offset += count; + + if (sg_len && count == sg_len) { + host->pio.index++; + host->pio.offset = 0; + } +} + +static void jz_mmc_send_pio(struct jz_mmc_host *host) +{ + + struct mmc_data *data = 0; + int sg_len, max, count = 0; + u32 *wbuf = 0; + struct scatterlist *sg; + unsigned int nob; + + data = host->mrq->data; + nob = data->blocks; + + REG_MSC_NOB(MSC_ID) = nob; + REG_MSC_BLKLEN(MSC_ID) = data->blksz; + + /* This is the pointer to the data buffer */ + sg = &data->sg[host->pio.index]; + wbuf = sg_virt(sg) + host->pio.offset; + + /* This is the space left inside the buffer */ + sg_len = data->sg[host->pio.index].length - host->pio.offset; + + /* Check to if we need less then the size of the sg_buffer */ + max = (sg_len > host->pio.len) ? host->pio.len : sg_len; + max = max / 4; + for(count = 0; count < max; count++ ) { + while (REG_MSC_STAT(MSC_ID) & MSC_STAT_DATA_FIFO_FULL) + ; + REG_MSC_TXFIFO(MSC_ID) = *wbuf++; + } + + host->pio.len -= count; + host->pio.offset += count; + + if (count == sg_len) { + host->pio.index++; + host->pio.offset = 0; + } +} + +static int +jz_mmc_prepare_data(struct jz_mmc_host *host, struct mmc_data *data) +{ + int datalen = data->blocks * data->blksz; + + host->dma.dir = DMA_BIDIRECTIONAL; + host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, host->dma.dir); + if (host->dma.len == 0) + return -ETIMEDOUT; + + host->pio.index = 0; + host->pio.offset = 0; + host->pio.len = datalen; + return 0; +} +#endif + +static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat); + +static void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq) +{ + host->mrq = NULL; + host->cmd = NULL; + host->data = NULL; + mmc_request_done(host->mmc, mrq); +} + +static void jz_mmc_start_cmd(struct jz_mmc_host *host, + struct mmc_command *cmd, unsigned int cmdat) +{ + u32 timeout = 0x3fffff; + unsigned int stat; + struct jz_mmc_host *hst = host; + WARN_ON(host->cmd != NULL); + host->cmd = cmd; + + /* mask interrupts */ + REG_MSC_IMASK(MSC_ID) = 0xffff; + + /* clear status */ + REG_MSC_IREG(MSC_ID) = 0xffff; + + if (cmd->flags & MMC_RSP_BUSY) + cmdat |= MSC_CMDAT_BUSY; + +#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) + switch (RSP_TYPE(mmc_resp_type(cmd))) { + case RSP_TYPE(MMC_RSP_R1): /* r1,r1b, r6, r7 */ + cmdat |= MSC_CMDAT_RESPONSE_R1; + r_type = 1; + break; + case RSP_TYPE(MMC_RSP_R3): + cmdat |= MSC_CMDAT_RESPONSE_R3; + r_type = 1; + break; + case RSP_TYPE(MMC_RSP_R2): + cmdat |= MSC_CMDAT_RESPONSE_R2; + r_type = 2; + break; + default: + break; + } + + REG_MSC_CMD(MSC_ID) = cmd->opcode; + + /* Set argument */ +#ifdef CONFIG_MSC0_JZ4750 +#ifdef CONFIG_JZ4750_MSC0_BUS_1 + if (cmd->opcode == 6) { + /* set 1 bit sd card bus*/ + if (cmd->arg ==2) + REG_MSC_ARG(MSC_ID) = 0; + + /* set 1 bit mmc card bus*/ + if (cmd->arg == 0x3b70101) { + REG_MSC_ARG(MSC_ID) = 0x3b70001; + } + } else + REG_MSC_ARG(MSC_ID) = cmd->arg; + +#elif defined CONFIG_JZ4750_MSC0_BUS_8 + if (cmd->opcode == 6) { + /* set 8 bit mmc card bus*/ + if (cmd->arg == 0x3b70101) + REG_MSC_ARG(MSC_ID) = 0x3b70201; + else + REG_MSC_ARG(MSC_ID) = cmd->arg; + + } else + REG_MSC_ARG(MSC_ID) = cmd->arg; +#else + REG_MSC_ARG(MSC_ID) = cmd->arg; +#endif /* CONFIG_JZ4750_MSC0_BUS_1 */ +#else +#ifdef CONFIG_JZ4750_MSC1_BUS_1 + if (cmd->opcode == 6) { + /* set 1 bit sd card bus*/ + if (cmd->arg ==2) + REG_MSC_ARG(MSC_ID) = 0; + + /* set 1 bit mmc card bus*/ + if (cmd->arg == 0x3b70101) { + REG_MSC_ARG(MSC_ID) = 0x3b70001; + } + } else + REG_MSC_ARG(MSC_ID) = cmd->arg; + +#else + REG_MSC_ARG(MSC_ID) = cmd->arg; +#endif /* CONFIG_JZ4750_MSC1_BUS_1 */ +#endif /* CONFIG_MSC0_JZ4750*/ + + /* Set command */ + REG_MSC_CMDAT(MSC_ID) = cmdat; + + /* Send command */ + jz_mmc_start_op(); + + while (timeout-- && !(REG_MSC_STAT(MSC_ID) & MSC_STAT_END_CMD_RES)) + ; + + REG_MSC_IREG(MSC_ID) = MSC_IREG_END_CMD_RES; /* clear irq flag */ + if (cmd->opcode == 12) { + while (timeout-- && !(REG_MSC_IREG(MSC_ID) & MSC_IREG_PRG_DONE)) + ; + REG_MSC_IREG(MSC_ID) = MSC_IREG_PRG_DONE; /* clear status */ + } + if (!mmc_slot_enable) { + /* It seems that MSC can't report the MSC_STAT_TIME_OUT_RES when + * card was removed. We force to return here. + */ + cmd->error = -ETIMEDOUT; + jz_mmc_finish_request(hst, hst->mrq); + return; + } + + if (SD_IO_SEND_OP_COND == cmd->opcode) { + /* + * Don't support SDIO card currently. + */ + cmd->error = -ETIMEDOUT; + jz_mmc_finish_request(hst, hst->mrq); + return; + } + + /* Check for status */ + stat = REG_MSC_STAT(MSC_ID); + jz_mmc_cmd_done(hst, stat); + if (host->data) { + if (cmd->opcode == MMC_WRITE_BLOCK || cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) +#ifdef USE_DMA + jz_mmc_tx_setup_data(host, host->data); +#else + jz_mmc_send_pio(host); + else + jz_mmc_receive_pio(host); +#endif + } +} + +static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat) +{ + struct mmc_command *cmd = host->cmd; + int i, temp[16]; + u8 *buf; + u32 data, v, w1, w2; + + if (!cmd) + return 0; + + host->cmd = NULL; + buf = (u8 *) temp; + switch (r_type) { + case 1: + { + data = REG_MSC_RES(MSC_ID); + buf[0] = (data >> 8) & 0xff; + buf[1] = data & 0xff; + data = REG_MSC_RES(MSC_ID); + buf[2] = (data >> 8) & 0xff; + buf[3] = data & 0xff; + data = REG_MSC_RES(MSC_ID); + buf[4] = data & 0xff; + cmd->resp[0] = + buf[1] << 24 | buf[2] << 16 | buf[3] << 8 | + buf[4]; + break; + } + case 2: + { + data = REG_MSC_RES(MSC_ID); + v = data & 0xffff; + for (i = 0; i < 4; i++) { + data = REG_MSC_RES(MSC_ID); + w1 = data & 0xffff; + data = REG_MSC_RES(MSC_ID); + w2 = data & 0xffff; + cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8; + v = w2; + } + break; + } + case 0: + break; + } + if (stat & MSC_STAT_TIME_OUT_RES) { + printk("MSC_STAT_TIME_OUT_RES\n"); + cmd->error = -ETIMEDOUT; + } else if (stat & MSC_STAT_CRC_RES_ERR && cmd->flags & MMC_RSP_CRC) { + printk("MSC_STAT_CRC\n"); + if (cmd->opcode == MMC_ALL_SEND_CID || + cmd->opcode == MMC_SEND_CSD || + cmd->opcode == MMC_SEND_CID) { + /* a bogus CRC error can appear if the msb of + the 15 byte response is a one */ + if ((cmd->resp[0] & 0x80000000) == 0) + cmd->error = -EILSEQ; + } + } + /* + * Did I mention this is Sick. We always need to + * discard the upper 8 bits of the first 16-bit word. + */ + if (host->data && cmd->error == 0) + jz_mmc_enable_irq(host, MSC_IMASK_DATA_TRAN_DONE); + else + jz_mmc_finish_request(host, host->mrq); + + return 1; +} + +static int jz_mmc_data_done(struct jz_mmc_host *host, unsigned int stat) +{ + struct mmc_data *data = host->data; + + if (!data) + return 0; + REG_MSC_IREG(MSC_ID) = MSC_IREG_DATA_TRAN_DONE; /* clear status */ + dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + host->dma_dir); + if (stat & MSC_STAT_TIME_OUT_READ) { + printk("MMC/SD timeout, MMC_STAT 0x%x\n", stat); + data->error = -ETIMEDOUT; + } else if (REG_MSC_STAT(MSC_ID) & + (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR)) { + printk("MMC/SD CRC error, MMC_STAT 0x%x\n", stat); + data->error = -EILSEQ; + } + /* + * There appears to be a hardware design bug here. There seems to + * be no way to find out how much data was transferred to the card. + * This means that if there was an error on any block, we mark all + * data blocks as being in error. + */ + if (data->error == 0) + data->bytes_xfered = data->blocks * data->blksz; + else + data->bytes_xfered = 0; + + jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE); + host->data = NULL; + if (host->mrq->stop) { + jz_mmc_start_cmd(host, host->mrq->stop, 0); + } else { + jz_mmc_finish_request(host, host->mrq); + } + return 1; +} + +static void jz_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + unsigned int cmdat; + + /* Save current request for the future processing */ + host->mrq = mrq; + host->data = mrq->data; + cmdat = host->cmdat; + host->cmdat &= ~MSC_CMDAT_INIT; + + if (mrq->data) { + cmdat &= ~MSC_CMDAT_BUSY; +#ifdef USE_DMA + if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) + + cmdat |= + MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; + else { +#ifdef CONFIG_MSC0_JZ4750 +#ifdef CONFIG_JZ4750_MSC0_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; +#elif defined CONFIG_JZ4750_MSC0_BUS_4 + if(auto_select_bus == MSC_1BIT_BUS) { + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; + } else { + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; + } +#else + cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN; +#endif /* CONFIG_JZ4750_MSC0_BUS_1 */ +#else +#ifdef CONFIG_JZ4750_MSC1_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; +#else + cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN; +#endif /* CONFIG_JZ4750_MSC1_BUS_1 */ +#endif /* CONFIG_MSC0_JZ4750 */ + } + if (mrq->data->flags & MMC_DATA_WRITE) + cmdat |= MSC_CMDAT_WRITE; + + if (mrq->data->flags & MMC_DATA_STREAM) + cmdat |= MSC_CMDAT_STREAM_BLOCK; + if (mrq->cmd->opcode != MMC_WRITE_BLOCK + && mrq->cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK) + jz_mmc_rx_setup_data(host, mrq->data); +#else /*USE_DMA*/ + + if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; + else { +#ifdef CONFIG_MSC0_JZ4750 +#ifdef CONFIG_JZ4750_MSC0_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; +#elif defined CONFIG_JZ4750_MSC0_BUS_4 + if(auto_select_bus == MSC_1BIT_BUS) { + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; + } else { + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT | MSC_CMDAT_DATA_EN; + } +#else + cmdat |= MSC_CMDAT_DATA_EN; +#endif +#else +#ifdef CONFIG_JZ4750_MSC1_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; +#else + cmdat |= MSC_CMDAT_DATA_EN; +#endif /* CONFIG_JZ4750_MSC1_BUS_1 */ +#endif /* CONFIG_MSC0_JZ4750 */ + } + if (mrq->data->flags & MMC_DATA_WRITE) + cmdat |= MSC_CMDAT_WRITE; + + if (mrq->data->flags & MMC_DATA_STREAM) + cmdat |= MSC_CMDAT_STREAM_BLOCK; + jz_mmc_prepare_data(host, host->data); +#endif /*USE_DMA*/ + } + jz_mmc_start_cmd(host, mrq->cmd, cmdat); +} + +static irqreturn_t jz_mmc_irq(int irq, void *devid) +{ + struct jz_mmc_host *host = devid; + unsigned int ireg; + int handled = 0; + + ireg = REG_MSC_IREG(MSC_ID); + + if (ireg) { + unsigned stat = REG_MSC_STAT(MSC_ID); + if (ireg & MSC_IREG_DATA_TRAN_DONE) + handled |= jz_mmc_data_done(host, stat); + } + return IRQ_RETVAL(handled); +} + +/* Returns true if MMC slot is empty */ +static int jz_mmc_slot_is_empty(int slot) +{ + int empty; + +#ifdef CONFIG_FPGA + return 0; +#endif + +#ifdef CONFIG_MSC1_JZ4750 + empty = (__msc1_card_detected(slot) == 0) ? 1 : 0; +#else + empty = (__msc0_card_detected(slot) == 0) ? 1 : 0; +#endif + + if (empty) { + + /* wait for card insertion */ +#ifdef CONFIG_SOC_JZ4750 +#ifdef CONFIG_MSC1_JZ4750 + __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); +#else + __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); +#endif +#else + __gpio_as_irq_fall_edge(MSC1_HOTPLUG_PIN); +#endif + + } else { + /* wait for card removal */ +#ifdef CONFIG_SOC_JZ4750 +#ifdef CONFIG_MSC1_JZ4750 + __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); +#else + __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); +#endif +#else + __gpio_as_irq_rise_edge(MSC1_HOTPLUG_PIN); +#endif + } + + return empty; +} + +static irqreturn_t jz_mmc_detect_irq(int irq, void *devid) +{ + struct jz_mmc_host *host = (struct jz_mmc_host *) devid; + + auto_select_bus = MSC_4BIT_BUS; + if (jz_mmc_slot_is_empty(0)) { + mmc_slot_enable = 0; + mmc_detect_change(host->mmc, 50); + } else { + mmc_slot_enable = 1; + mmc_detect_change(host->mmc, 50); + } + return IRQ_HANDLED; +} + +static int jz_mmc_get_ro(struct mmc_host *mmc) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + + if (host->pdata && host->pdata->get_ro) + return host->pdata->get_ro(mmc_dev(mmc)); + /* Host doesn't support read only detection so assume writeable */ + return 0; +} + +/* set clock and power */ +static void jz_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + + if (ios->clock) + jz_mmc_set_clock(ios->clock); + + if (host->power_mode != ios->power_mode) { + host->power_mode = ios->power_mode; + + if (ios->power_mode == MMC_POWER_ON) + host->cmdat |= CMDAT_INIT; + } + + if (ios->bus_width == MMC_BUS_WIDTH_4) { + auto_select_bus = MSC_4BIT_BUS; + host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT; + } + else if (ios->bus_width == MMC_BUS_WIDTH_8) { + host->cmdat |= MSC_CMDAT_BUS_WIDTH_8BIT; + auto_select_bus = MSC_8BIT_BUS; + } else { + /* 1 bit bus*/ + host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_8BIT; + auto_select_bus = MSC_1BIT_BUS; + } +} + +static const struct mmc_host_ops jz_mmc_ops = { + .request = jz_mmc_request, + .get_ro = jz_mmc_get_ro, + .set_ios = jz_mmc_set_ios, +}; +static int jz_mmc_pm_callback(struct pm_dev *pm_dev, + pm_request_t req, void *data); + +static int jz_mmc_probe(struct platform_device *pdev) +{ + int retval; + struct mmc_host *mmc; + struct jz_mmc_host *host = NULL; + int irq; + struct resource *r; + +#if defined CONFIG_MSC0_JZ4750 || defined CONFIG_MSC0_JZ4750_MODULE +#ifdef CONFIG_SOC_JZ4750 + __gpio_as_msc0_8bit(); // for jz4750 +#else + __gpio_as_msc0_4bit(); // for jz4750d +#endif + __msc0_init_io(); + __msc0_enable_power(); +#endif + +#if defined CONFIG_MSC1_JZ4750 || defined CONFIG_MSC1_JZ4750_MODULE + __gpio_as_msc1_4bit(); + __msc1_init_io(); + __msc1_enable_power(); +#endif + __msc_reset(MSC_ID); + REG_MSC_LPM(MSC_ID) = 0x1; + + MMC_IRQ_MASK(); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!r || irq < 0) + return -ENXIO; + + mmc = mmc_alloc_host(sizeof(struct jz_mmc_host), &pdev->dev); + if (!mmc) { + retval = -ENOMEM; + goto out; + } + mmc->ops = &jz_mmc_ops; + mmc->f_min = MMC_CLOCK_SLOW; + mmc->f_max = SD_CLOCK_HIGH; + /* + * We can do SG-DMA, but we don't because we never know how much + * data we successfully wrote to the card. + */ + mmc->max_phys_segs = NR_SG; + + mmc->max_seg_size = PAGE_SIZE * 16; + mmc->max_req_size = mmc->max_seg_size; + mmc->max_blk_size = 4095; + /* + * Block count register is 16 bits. + */ + mmc->max_blk_count = 65535; + host = mmc_priv(mmc); + host->mmc = mmc; + host->pdata = pdev->dev.platform_data; + mmc->ocr_avail = host->pdata ? + host->pdata->ocr_mask : MMC_VDD_32_33 | MMC_VDD_33_34; + host->mmc->caps = + MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SD_HIGHSPEED + | MMC_CAP_MMC_HIGHSPEED; + /* + *MMC_CAP_4_BIT_DATA (1 << 0) The host can do 4 bit transfers + * + */ + host->sg_cpu = + dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, + GFP_KERNEL); + if (!host->sg_cpu) { + retval = -ENOMEM; + goto out; + } + spin_lock_init(&host->lock); + host->irq = IRQ_MSC; /* is it useful ?*/ + host->imask = 0xffff; + /* + * Ensure that the host controller is shut down, and setup + * with our defaults. + */ + retval = request_irq(IRQ_MSC, jz_mmc_irq, 0, "MMC/SD", host); + if (retval) { + printk(KERN_ERR "MMC/SD: can't request MMC/SD IRQ\n"); + return retval; + } + + jz_mmc_slot_is_empty(0); + /* Request card detect interrupt */ + + retval = request_irq(MSC_HOTPLUG_IRQ, jz_mmc_detect_irq, 0, //SA_INTERRUPT, + "MMC card detect", host); + if (retval) { + printk(KERN_ERR "MMC/SD: can't request card detect IRQ\n"); + goto err1; + } +#ifdef USE_DMA + /* Request MMC Rx DMA channel */ + rxdmachan = + jz_request_dma(DMA_ID_MSC_RX, "MMC Rx", jz_mmc_dma_rx_callback, + 0, host); + if (rxdmachan < 0) { + printk(KERN_ERR "jz_request_dma failed for MMC Rx\n"); + goto err2; + } + + if (rxdmachan < HALF_DMA_NUM) + REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC; + else + REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC; + + /* Request MMC Tx DMA channel */ + txdmachan = + jz_request_dma(DMA_ID_MSC_TX, "MMC Tx", jz_mmc_dma_tx_callback, + 0, host); + if (txdmachan < 0) { + printk(KERN_ERR "jz_request_dma failed for MMC Tx\n"); + goto err3; + } + + if (txdmachan < HALF_DMA_NUM) + REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC; + else + REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC; + +#endif + platform_set_drvdata(pdev, mmc); + mmc_add_host(mmc); +#ifdef CONFIG_PM + /* Register MMC slot as as power-managed device */ + pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, jz_mmc_pm_callback); +#endif + printk("JZ SD/MMC card driver registered\n"); + + /* Detect card during initialization */ +#if defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + if (!jz_mmc_slot_is_empty(0)) { + mmc_slot_enable = 1; + mmc_detect_change(host->mmc, 0); + } +#endif + return 0; + +err1:free_irq(IRQ_MSC, &host); +#ifdef USE_DMA + err2:jz_free_dma(rxdmachan); + err3:jz_free_dma(txdmachan); +#endif +out: + if (host) { + if (host->sg_cpu) + dma_free_coherent(&pdev->dev, PAGE_SIZE, + host->sg_cpu, host->sg_dma); + } + if (mmc) + mmc_free_host(mmc); + return -1; +} + +static int jz_mmc_remove(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + long flags; + + platform_set_drvdata(pdev, NULL); + + if (mmc) { + struct jz_mmc_host *host = mmc_priv(mmc); + + if (host->pdata && host->pdata->exit) + host->pdata->exit(&pdev->dev, mmc); + + mmc_remove_host(mmc); + + local_irq_save(flags); + __msc0_disable_power(); + jz_free_dma(rxdmachan); + jz_free_dma(txdmachan); + free_irq(IRQ_MSC, host); + free_irq(MSC_HOTPLUG_IRQ, host); + local_irq_restore(flags); + dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); + + mmc_free_host(mmc); + } + return 0; +} + +#ifdef CONFIG_PM +pm_message_t state; +static int jz_mmc_suspend(struct platform_device *dev, pm_message_t state) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + int ret = 0; + + if (mmc) + ret = mmc_suspend_host(mmc, state); + + return ret; +} + +static int jz_mmc_resume(struct platform_device *dev) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + int ret = 0; + + if (mmc) + ret = mmc_resume_host(mmc); + + return ret; +} +static int jz_mmc_pm_callback(struct pm_dev *pm_dev, + pm_request_t req, void *data) +{ + struct platform_device *pdev = (struct platform_device *)pm_dev; + + switch(req) { + case PM_RESUME: + jz_mmc_resume(pdev); + break; + case PM_SUSPEND: + /* state has no use */ + jz_mmc_suspend(pdev,state); + break; + default: + printk("MMC/SD: invalid PM request %d\n", req); + break; + } + return 0; +} +#else +#define jz_mmc_suspend NULL +#define jz_mmc_resume NULL +#endif + +static struct platform_driver jz_mmc_driver = { + .probe = jz_mmc_probe, + .remove = jz_mmc_remove, + .suspend = jz_mmc_suspend, + .resume = jz_mmc_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init jz_mmc_init(void) +{ + return platform_driver_register(&jz_mmc_driver); +} + +static void __exit jz_mmc_exit(void) +{ + platform_driver_unregister(&jz_mmc_driver); +} + +module_init(jz_mmc_init); +module_exit(jz_mmc_exit); + +MODULE_DESCRIPTION("JZ47XX SD/Multimedia Card Interface Driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz4750_mmc.h linux-2.6.24.3-20100304/drivers/mmc/host/jz4750_mmc.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz4750_mmc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/jz4750_mmc.h 2010-03-03 19:04:51.000000000 -0800 @@ -0,0 +1,92 @@ +#ifndef __JZ4750_MMC_H__ +#define __JZ4750_MMC_H__ + +#include + +#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ +#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ +#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ +#define SD_CLOCK_HIGH 24000000 /* 24 MHz for SD Cards */ +#define MMC_NO_ERROR 0 + +#define NR_SG 1 + +#if defined CONFIG_MSC0_JZ4750 || defined CONFIG_MSC0_JZ4750_MODULE +#define MSC_ID 0 +#define MSC_HOTPLUG_IRQ MSC0_HOTPLUG_IRQ +#define IRQ_MSC IRQ_MSC0 +#define DMA_ID_MSC_RX DMA_ID_MSC0_RX +#define DMA_ID_MSC_TX DMA_ID_MSC0_TX +#define MSC_HOTPLUG_PIN MSC0_HOTPLUG_PIN +#endif + +#if defined CONFIG_MSC1_JZ4750 || defined CONFIG_MSC1_JZ4750_MODULE +#define MSC_ID 1 +#define MSC_HOTPLUG_IRQ MSC1_HOTPLUG_IRQ +#define IRQ_MSC IRQ_MSC1 +#define DMA_ID_MSC_RX DMA_ID_MSC1_RX +#define DMA_ID_MSC_TX DMA_ID_MSC1_TX +#define MSC_HOTPLUG_PIN MSC1_HOTPLUG_PIN +#endif + +#define MSC_1BIT_BUS 0 +#define MSC_4BIT_BUS 1 +#define MSC_8BIT_BUS 2 + +#define SZ_4K 0x00001000 + +struct jz_mmc_host { + struct mmc_host *mmc; + spinlock_t lock; + struct { + int len; + int dir; + } dma; + struct { + int index; + int offset; + int len; + } pio; + int irq; + unsigned int clkrt; + unsigned int cmdat; + unsigned int imask; + unsigned int power_mode; + struct jz_mmc_platform_data *pdata; + struct mmc_request *mrq; + struct mmc_command *cmd; + struct mmc_data *data; + dma_addr_t sg_dma; + struct jzsoc_dma_desc *sg_cpu; + unsigned int dma_len; + unsigned int dma_dir; +}; + +#define MMC_IRQ_MASK() \ +do { \ + REG_MSC_IMASK(MSC_ID) = 0xffff; \ + REG_MSC_IREG(MSC_ID) = 0xffff; \ +} while (0) + +typedef struct jzsoc_dma_desc { + volatile u32 ddadr; /* Points to the next descriptor + flags */ + volatile u32 dsadr; /* DSADR value for the current transfer */ + volatile u32 dtadr; /* DTADR value for the current transfer */ + volatile u32 dcmd; /* DCMD value for the current transfer */ +} jzsoc_dma_desc; + +#include + +struct device; +struct mmc_host; + +struct jz_mmc_platform_data { + unsigned int ocr_mask; /* available voltages */ + unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ + int (*init)(struct device *, irq_handler_t , void *); + int (*get_ro)(struct device *); + void (*setpower)(struct device *, unsigned int); + void (*exit)(struct device *, void *); +}; + +#endif /* __JZ4750_MMC_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz_mmc.c linux-2.6.24.3-20100304/drivers/mmc/host/jz_mmc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz_mmc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/jz_mmc.c 2010-03-03 19:04:51.000000000 -0800 @@ -0,0 +1,1026 @@ +/* + * linux/drivers/mmc/jz_mmc.c - JZ SD/MMC driver + * + * Copyright (C) 2005 - 2008 Ingenic Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "jz_mmc.h" + +#define DRIVER_NAME "jz-mmc" + +#define NR_SG 1 + +#if defined(CONFIG_SOC_JZ4725) || defined(CONFIG_SOC_JZ4720) +#undef USE_DMA +#else +#define USE_DMA +#endif + +struct jz_mmc_host { + struct mmc_host *mmc; + spinlock_t lock; + struct { + int len; + int dir; + } dma; + struct { + int index; + int offset; + int len; + } pio; + int irq; + unsigned int clkrt; + unsigned int cmdat; + unsigned int imask; + unsigned int power_mode; + struct jz_mmc_platform_data *pdata; + struct mmc_request *mrq; + struct mmc_command *cmd; + struct mmc_data *data; + dma_addr_t sg_dma; + struct jzsoc_dma_desc *sg_cpu; + unsigned int dma_len; + unsigned int dma_dir; + struct pm_dev *pmdev; +}; + +static int r_type = 0; + +#define MMC_IRQ_MASK() \ +do { \ + REG_MSC_IMASK = 0xff; \ + REG_MSC_IREG = 0xff; \ +} while (0) + +static int rxdmachan = 0; +static int txdmachan = 0; +static int mmc_slot_enable = 0; + +/* Stop the MMC clock and wait while it happens */ +static inline int jz_mmc_stop_clock(void) +{ + int timeout = 1000; + + REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; + while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) { + timeout--; + if (timeout == 0) + return 0; + udelay(1); + } + return MMC_NO_ERROR; +} + +/* Start the MMC clock and operation */ +static inline int jz_mmc_start_clock(void) +{ + REG_MSC_STRPCL = + MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; + return MMC_NO_ERROR; +} + +static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate) +{ + u32 clkrt; + u32 clk_src = is_sd ? 24000000 : 20000000; + + clkrt = 0; + while (rate < clk_src) { + clkrt++; + clk_src >>= 1; + } + return clkrt; +} + +/* Select the MMC clock frequency */ +static int jz_mmc_set_clock(u32 rate) +{ + int clkrt; + + jz_mmc_stop_clock(); + __cpm_select_msc_clk(1); /* select clock source from CPM */ + clkrt = jz_mmc_calc_clkrt(1, rate); + REG_MSC_CLKRT = clkrt; + return MMC_NO_ERROR; +} + +static void jz_mmc_enable_irq(struct jz_mmc_host *host, unsigned int mask) +{ + unsigned long flags; + spin_lock_irqsave(&host->lock, flags); + host->imask &= ~mask; + REG_MSC_IMASK = host->imask; + spin_unlock_irqrestore(&host->lock, flags); +} + +static void jz_mmc_disable_irq(struct jz_mmc_host *host, unsigned int mask) +{ + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->imask |= mask; + REG_MSC_IMASK = host->imask; + spin_unlock_irqrestore(&host->lock, flags); +} + +void jz_set_dma_block_size(int dmanr, int nbyte); + +#ifdef USE_DMA +static inline void +jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode) +{ + unsigned long flags; + + flags = claim_dma_lock(); + disable_dma(chan); + clear_dma_ff(chan); + jz_set_dma_block_size(chan, 32); + set_dma_mode(chan, mode); + set_dma_addr(chan, phyaddr); + set_dma_count(chan, count + 31); + enable_dma(chan); + release_dma_lock(flags); +} + +static irqreturn_t jz_mmc_dma_rx_callback(int irq, void *devid) +{ + int chan = rxdmachan; + + disable_dma(chan); + if (__dmac_channel_address_error_detected(chan)) { + printk(KERN_DEBUG "%s: DMAC address error.\n", + __FUNCTION__); + __dmac_channel_clear_address_error(chan); + } + if (__dmac_channel_transmit_end_detected(chan)) { + __dmac_channel_clear_transmit_end(chan); + } + return IRQ_HANDLED; +} +static irqreturn_t jz_mmc_dma_tx_callback(int irq, void *devid) +{ + int chan = txdmachan; + + disable_dma(chan); + if (__dmac_channel_address_error_detected(chan)) { + printk(KERN_DEBUG "%s: DMAC address error.\n", + __FUNCTION__); + __dmac_channel_clear_address_error(chan); + } + if (__dmac_channel_transmit_end_detected(chan)) { + __dmac_channel_clear_transmit_end(chan); + } + return IRQ_HANDLED; +} + +/* Prepare DMA to start data transfer from the MMC card */ +static void jz_mmc_rx_setup_data(struct jz_mmc_host *host, + struct mmc_data *data) +{ + unsigned int nob = data->blocks; + int channelrx = rxdmachan; + int i; + u32 size; + + if (data->flags & MMC_DATA_STREAM) + nob = 0xffff; + + REG_MSC_NOB = nob; + REG_MSC_BLKLEN = data->blksz; + size = nob * data->blksz; + + if (data->flags & MMC_DATA_READ) { + host->dma.dir = DMA_FROM_DEVICE; + } else { + host->dma.dir = DMA_TO_DEVICE; + } + + host->dma.len = + dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma.dir); + + for (i = 0; i < host->dma.len; i++) { + host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); + host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); + dma_cache_wback_inv((unsigned long) + CKSEG0ADDR(sg_dma_address(data->sg)) + + data->sg->offset, + host->sg_cpu[i].dcmd); + jz_mmc_start_dma(channelrx, host->sg_cpu[i].dtadr, + host->sg_cpu[i].dcmd, DMA_MODE_READ); + } +} + +/* Prepare DMA to start data transfer from the MMC card */ +static void jz_mmc_tx_setup_data(struct jz_mmc_host *host, + struct mmc_data *data) +{ + unsigned int nob = data->blocks; + int channeltx = txdmachan; + int i; + u32 size; + + if (data->flags & MMC_DATA_STREAM) + nob = 0xffff; + + REG_MSC_NOB = nob; + REG_MSC_BLKLEN = data->blksz; + size = nob * data->blksz; + + if (data->flags & MMC_DATA_READ) { + host->dma.dir = DMA_FROM_DEVICE; + } else { + host->dma.dir = DMA_TO_DEVICE; + } + + host->dma.len = + dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma.dir); + + for (i = 0; i < host->dma.len; i++) { + host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); + host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]); + dma_cache_wback_inv((unsigned long) + CKSEG0ADDR(sg_dma_address(data->sg)) + + data->sg->offset, + host->sg_cpu[i].dcmd); + jz_mmc_start_dma(channeltx, host->sg_cpu[i].dtadr, + host->sg_cpu[i].dcmd, DMA_MODE_WRITE); + } +} +#else +static void jz_mmc_receive_pio(struct jz_mmc_host *host) +{ + + struct mmc_data *data = 0; + int sg_len = 0, max = 0, count = 0; + u32 *buf = 0; + struct scatterlist *sg; + unsigned int nob; + + data = host->mrq->data; + nob = data->blocks; + REG_MSC_NOB = nob; + REG_MSC_BLKLEN = data->blksz; + + max = host->pio.len; + if (host->pio.index < host->dma.len) { + sg = &data->sg[host->pio.index]; + buf = sg_virt(sg) + host->pio.offset; + + /* This is the space left inside the buffer */ + sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; + /* Check to if we need less then the size of the sg_buffer */ + if (sg_len < max) max = sg_len; + } + max = max / 4; + for(count = 0; count < max; count++) { + while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY) + ; + *buf++ = REG_MSC_RXFIFO; + } + host->pio.len -= count; + host->pio.offset += count; + + if (sg_len && count == sg_len) { + host->pio.index++; + host->pio.offset = 0; + } +} + +static void jz_mmc_send_pio(struct jz_mmc_host *host) +{ + + struct mmc_data *data = 0; + int sg_len, max, count = 0; + u32 *wbuf = 0; + struct scatterlist *sg; + unsigned int nob; + + data = host->mrq->data; + nob = data->blocks; + + REG_MSC_NOB = nob; + REG_MSC_BLKLEN = data->blksz; + + /* This is the pointer to the data buffer */ + sg = &data->sg[host->pio.index]; + wbuf = sg_virt(sg) + host->pio.offset; + + /* This is the space left inside the buffer */ + sg_len = data->sg[host->pio.index].length - host->pio.offset; + + /* Check to if we need less then the size of the sg_buffer */ + max = (sg_len > host->pio.len) ? host->pio.len : sg_len; + max = max / 4; + for(count = 0; count < max; count++ ) { + while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL) + ; + REG_MSC_TXFIFO = *wbuf++; + } + + host->pio.len -= count; + host->pio.offset += count; + + if (count == sg_len) { + host->pio.index++; + host->pio.offset = 0; + } +} + +static int +jz_mmc_prepare_data(struct jz_mmc_host *host, struct mmc_data *data) +{ + int datalen = data->blocks * data->blksz; + + host->dma.dir = DMA_BIDIRECTIONAL; + host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, host->dma.dir); + if (host->dma.len == 0) + return -ETIMEDOUT; + + host->pio.index = 0; + host->pio.offset = 0; + host->pio.len = datalen; + return 0; +} +#endif + +static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat); + +static void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq) +{ + jz_mmc_stop_clock(); + host->mrq = NULL; + host->cmd = NULL; + host->data = NULL; + mmc_request_done(host->mmc, mrq); +} + +static void jz_mmc_start_cmd(struct jz_mmc_host *host, + struct mmc_command *cmd, unsigned int cmdat) +{ + u32 timeout = 0x3fffff; + unsigned int stat; + struct jz_mmc_host *hst = host; + WARN_ON(host->cmd != NULL); + host->cmd = cmd; + + /* stop MMC clock */ + jz_mmc_stop_clock(); + + /* mask interrupts */ + REG_MSC_IMASK = 0xff; + + /* clear status */ + REG_MSC_IREG = 0xff; + + if (cmd->flags & MMC_RSP_BUSY) + cmdat |= MSC_CMDAT_BUSY; + +#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) + switch (RSP_TYPE(mmc_resp_type(cmd))) { + case RSP_TYPE(MMC_RSP_R1): /* r1,r1b, r6, r7 */ + cmdat |= MSC_CMDAT_RESPONSE_R1; + r_type = 1; + break; + case RSP_TYPE(MMC_RSP_R3): + cmdat |= MSC_CMDAT_RESPONSE_R3; + r_type = 1; + break; + case RSP_TYPE(MMC_RSP_R2): + cmdat |= MSC_CMDAT_RESPONSE_R2; + r_type = 2; + break; + default: + break; + } + REG_MSC_CMD = cmd->opcode; + + /* Set argument */ +#ifdef CONFIG_JZ_MMC_BUS_1 + if (cmd->opcode == 6) { + /* set 1 bit sd card bus*/ + if (cmd->arg ==2) + REG_MSC_ARG = 0; + + /* set 1 bit mmc card bus*/ + if (cmd->arg == 0x3b70101) + REG_MSC_ARG = 0x3b70001; + } else + REG_MSC_ARG = cmd->arg; +#else + REG_MSC_ARG = cmd->arg; +#endif + + /* Set command */ + REG_MSC_CMDAT = cmdat; + + /* Send command */ + jz_mmc_start_clock(); + + while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES)) + ; + + REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear irq flag */ + if (cmd->opcode == 12) { + while (timeout-- && !(REG_MSC_IREG & MSC_IREG_PRG_DONE)) + ; + REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */ + } + if (!mmc_slot_enable) { + /* It seems that MSC can't report the MSC_STAT_TIME_OUT_RES when + * card was removed. We force to return here. + */ + cmd->error = -ETIMEDOUT; + jz_mmc_finish_request(hst, hst->mrq); + return; + } + + if (SD_IO_SEND_OP_COND == cmd->opcode) { + /* + * Don't support SDIO card currently. + */ + cmd->error = -ETIMEDOUT; + jz_mmc_finish_request(hst, hst->mrq); + return; + } + + /* Check for status */ + stat = REG_MSC_STAT; + jz_mmc_cmd_done(hst, stat); + if (host->data) { + if (cmd->opcode == MMC_WRITE_BLOCK || cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) +#ifdef USE_DMA + jz_mmc_tx_setup_data(host, host->data); +#else + jz_mmc_send_pio(host); + else + jz_mmc_receive_pio(host); +#endif + } +} + +static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat) +{ + struct mmc_command *cmd = host->cmd; + int i, temp[16]; + u8 *buf; + u32 data, v, w1, w2; + + if (!cmd) + return 0; + + host->cmd = NULL; + buf = (u8 *) temp; + switch (r_type) { + case 1: + { + data = REG_MSC_RES; + buf[0] = (data >> 8) & 0xff; + buf[1] = data & 0xff; + data = REG_MSC_RES; + buf[2] = (data >> 8) & 0xff; + buf[3] = data & 0xff; + data = REG_MSC_RES; + buf[4] = data & 0xff; + cmd->resp[0] = + buf[1] << 24 | buf[2] << 16 | buf[3] << 8 | + buf[4]; + break; + } + case 2: + { + data = REG_MSC_RES; + v = data & 0xffff; + for (i = 0; i < 4; i++) { + data = REG_MSC_RES; + w1 = data & 0xffff; + data = REG_MSC_RES; + w2 = data & 0xffff; + cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8; + v = w2; + } + break; + } + case 0: + break; + } + if (stat & MSC_STAT_TIME_OUT_RES) { + printk("MSC_STAT_TIME_OUT_RES\n"); + cmd->error = -ETIMEDOUT; + } else if (stat & MSC_STAT_CRC_RES_ERR && cmd->flags & MMC_RSP_CRC) { + printk("MSC_STAT_CRC\n"); + if (cmd->opcode == MMC_ALL_SEND_CID || + cmd->opcode == MMC_SEND_CSD || + cmd->opcode == MMC_SEND_CID) { + /* a bogus CRC error can appear if the msb of + the 15 byte response is a one */ + if ((cmd->resp[0] & 0x80000000) == 0) + cmd->error = -EILSEQ; + } + } + /* + * Did I mention this is Sick. We always need to + * discard the upper 8 bits of the first 16-bit word. + */ + if (host->data && cmd->error == 0) + jz_mmc_enable_irq(host, MSC_IMASK_DATA_TRAN_DONE); + else + jz_mmc_finish_request(host, host->mrq); + + return 1; +} + +static int jz_mmc_data_done(struct jz_mmc_host *host, unsigned int stat) +{ + struct mmc_data *data = host->data; + + if (!data) + return 0; + REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ + jz_mmc_stop_clock(); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + host->dma_dir); + if (stat & MSC_STAT_TIME_OUT_READ) { + printk("MMC/SD timeout, MMC_STAT 0x%x\n", stat); + data->error = -ETIMEDOUT; + } else if (REG_MSC_STAT & + (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR)) { + printk("MMC/SD CRC error, MMC_STAT 0x%x\n", stat); + data->error = -EILSEQ; + } + /* + * There appears to be a hardware design bug here. There seems to + * be no way to find out how much data was transferred to the card. + * This means that if there was an error on any block, we mark all + * data blocks as being in error. + */ + if (data->error == 0) + data->bytes_xfered = data->blocks * data->blksz; + else + data->bytes_xfered = 0; + + jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE); + host->data = NULL; + if (host->mrq->stop) { + jz_mmc_stop_clock(); + jz_mmc_start_cmd(host, host->mrq->stop, 0); + } else { + jz_mmc_finish_request(host, host->mrq); + } + return 1; +} + +static void jz_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + unsigned int cmdat; + + /* stop MMC clock */ + jz_mmc_stop_clock(); + + /* Save current request for the future processing */ + host->mrq = mrq; + host->data = mrq->data; + cmdat = host->cmdat; + host->cmdat &= ~MSC_CMDAT_INIT; + + if (mrq->data) { + cmdat &= ~MSC_CMDAT_BUSY; +#ifdef USE_DMA + if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) + + cmdat |= + MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; + else { +#ifdef CONFIG_JZ_MMC_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN | + MSC_CMDAT_DMA_EN; +#else + cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN; +#endif + } + if (mrq->data->flags & MMC_DATA_WRITE) + cmdat |= MSC_CMDAT_WRITE; + + if (mrq->data->flags & MMC_DATA_STREAM) + cmdat |= MSC_CMDAT_STREAM_BLOCK; + if (mrq->cmd->opcode != MMC_WRITE_BLOCK + && mrq->cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK) + jz_mmc_rx_setup_data(host, mrq->data); +#else /*USE_DMA*/ + + if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; + else { +#ifdef CONFIG_JZ_MMC_BUS_1 + cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; + cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN; +#else + cmdat |= MSC_CMDAT_DATA_EN; +#endif + } + if (mrq->data->flags & MMC_DATA_WRITE) + cmdat |= MSC_CMDAT_WRITE; + + if (mrq->data->flags & MMC_DATA_STREAM) + cmdat |= MSC_CMDAT_STREAM_BLOCK; + jz_mmc_prepare_data(host, host->data); +#endif /*USE_DMA*/ + } + jz_mmc_start_cmd(host, mrq->cmd, cmdat); +} + +static irqreturn_t jz_mmc_irq(int irq, void *devid) +{ + struct jz_mmc_host *host = devid; + unsigned int ireg; + int handled = 0; + + ireg = REG_MSC_IREG; + + if (ireg) { + unsigned stat = REG_MSC_STAT; + if (ireg & MSC_IREG_DATA_TRAN_DONE) + handled |= jz_mmc_data_done(host, stat); + } + return IRQ_RETVAL(handled); +} + +/* Returns true if MMC slot is empty */ +static int jz_mmc_slot_is_empty(int slot) +{ + int empty; + + empty = (__msc_card_detected(slot) == 0) ? 1 : 0; + + if (empty) { + /* wait for card insertion */ +#ifdef CONFIG_MIPS_JZ4740_LYRA + __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); +#else + __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); +#endif + } else { + /* wait for card removal */ +#ifdef CONFIG_MIPS_JZ4740_LYRA + __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN); +#else + __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN); +#endif + } + + return empty; +} + +static irqreturn_t jz_mmc_detect_irq(int irq, void *devid) +{ + struct jz_mmc_host *host = (struct jz_mmc_host *) devid; + + if (jz_mmc_slot_is_empty(0)) { + mmc_slot_enable = 0; + mmc_detect_change(host->mmc, 50); + } else { + mmc_slot_enable = 1; + mmc_detect_change(host->mmc, 50); + } + return IRQ_HANDLED; +} + +static int jz_mmc_get_ro(struct mmc_host *mmc) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + + if (host->pdata && host->pdata->get_ro) + return host->pdata->get_ro(mmc_dev(mmc)); + /* Host doesn't support read only detection so assume writeable */ + return 0; +} + +/* set clock and power */ +static void jz_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct jz_mmc_host *host = mmc_priv(mmc); + + if (ios->clock) + jz_mmc_set_clock(ios->clock); + else + jz_mmc_stop_clock(); + + if (host->power_mode != ios->power_mode) { + host->power_mode = ios->power_mode; + + if (ios->power_mode == MMC_POWER_ON) + host->cmdat |= CMDAT_INIT; + } + + if ((ios->bus_width == MMC_BUS_WIDTH_4) || (ios->bus_width == MMC_BUS_WIDTH_8)) + host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT; + else + host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_4BIT; +} + +static const struct mmc_host_ops jz_mmc_ops = { + .request = jz_mmc_request, + .get_ro = jz_mmc_get_ro, + .set_ios = jz_mmc_set_ios, +}; +static int jz_mmc_pm_callback(struct pm_dev *pm_dev, + pm_request_t req, void *data); + +static int jz_mmc_probe(struct platform_device *pdev) +{ + int retval; + struct mmc_host *mmc; + struct jz_mmc_host *host = NULL; + int irq; + struct resource *r; + + __gpio_as_msc(); + __msc_init_io(); + __msc_enable_power(); + + __msc_reset(); + + /* On reset, stop MMC clock */ + jz_mmc_stop_clock(); + + MMC_IRQ_MASK(); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!r || irq < 0) + return -ENXIO; + + r = request_mem_region(r->start, SZ_4K, DRIVER_NAME); + if (!r) + return -EBUSY; + + mmc = mmc_alloc_host(sizeof(struct jz_mmc_host), &pdev->dev); + if (!mmc) { + retval = -ENOMEM; + goto out; + } + mmc->ops = &jz_mmc_ops; + mmc->f_min = MMC_CLOCK_SLOW; + mmc->f_max = SD_CLOCK_FAST; + /* + * We can do SG-DMA, but we don't because we never know how much + * data we successfully wrote to the card. + */ + mmc->max_phys_segs = NR_SG; + /* + * Our hardware DMA can handle a maximum of one page per SG entry. + */ + mmc->max_seg_size = PAGE_SIZE; + /* + * Block length register is 10 bits. + */ + mmc->max_blk_size = 1023; + /* + * Block count register is 16 bits. + */ + mmc->max_blk_count = 65535; + host = mmc_priv(mmc); + host->mmc = mmc; + host->pdata = pdev->dev.platform_data; + mmc->ocr_avail = host->pdata ? + host->pdata->ocr_mask : MMC_VDD_32_33 | MMC_VDD_33_34; + host->mmc->caps = + MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SD_HIGHSPEED + | MMC_CAP_MMC_HIGHSPEED; + /* + *MMC_CAP_4_BIT_DATA (1 << 0) The host can do 4 bit transfers + * + */ + host->sg_cpu = + dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, + GFP_KERNEL); + if (!host->sg_cpu) { + retval = -ENOMEM; + goto out; + } + spin_lock_init(&host->lock); + host->irq = IRQ_MSC; + host->imask = 0xff; + /* + * Ensure that the host controller is shut down, and setup + * with our defaults. + */ + retval = request_irq(IRQ_MSC, jz_mmc_irq, 0, "MMC/SD", host); + if (retval) { + printk(KERN_ERR "MMC/SD: can't request MMC/SD IRQ\n"); + return retval; + } + jz_mmc_slot_is_empty(0); + /* Request card detect interrupt */ + + retval = request_irq(MSC_HOTPLUG_IRQ, jz_mmc_detect_irq, 0, //SA_INTERRUPT, + "MMC card detect", host); + if (retval) { + printk(KERN_ERR "MMC/SD: can't request card detect IRQ\n"); + goto err1; + } +#ifdef USE_DMA + /* Request MMC Rx DMA channel */ + rxdmachan = + jz_request_dma(DMA_ID_MSC_RX, "MMC Rx", jz_mmc_dma_rx_callback, + 0, host); + if (rxdmachan < 0) { + printk(KERN_ERR "jz_request_dma failed for MMC Rx\n"); + goto err2; + } + + /* Request MMC Tx DMA channel */ + txdmachan = + jz_request_dma(DMA_ID_MSC_TX, "MMC Tx", jz_mmc_dma_tx_callback, + 0, host); + if (txdmachan < 0) { + printk(KERN_ERR "jz_request_dma failed for MMC Tx\n"); + goto err3; + } +#endif + platform_set_drvdata(pdev, mmc); + mmc_add_host(mmc); +#ifdef CONFIG_PM + /* Register MMC slot as as power-managed device */ + host->pmdev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, jz_mmc_pm_callback); + if (host->pmdev) + host->pmdev->data = pdev; +#endif + printk("JZ SD/MMC card driver registered\n"); + + /* Detect card during initialization */ +#ifdef CONFIG_SOC_JZ4740 + if (!jz_mmc_slot_is_empty(0)) { + mmc_slot_enable = 1; + mmc_detect_change(host->mmc, 0); + } +#endif + return 0; + +err1:free_irq(IRQ_MSC, &host); +#ifdef USE_DMA + err2:jz_free_dma(rxdmachan); + err3:jz_free_dma(txdmachan); +#endif +out: + if (host) { + if (host->sg_cpu) + dma_free_coherent(&pdev->dev, PAGE_SIZE, + host->sg_cpu, host->sg_dma); + } + if (mmc) + mmc_free_host(mmc); + return -1; +} + +static int jz_mmc_remove(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + long flags; + + platform_set_drvdata(pdev, NULL); + + if (mmc) { + struct jz_mmc_host *host = mmc_priv(mmc); + + if (host->pdata && host->pdata->exit) + host->pdata->exit(&pdev->dev, mmc); + + mmc_remove_host(mmc); + + local_irq_save(flags); + jz_mmc_stop_clock(); + __msc_disable_power(); + jz_free_dma(rxdmachan); + jz_free_dma(txdmachan); + free_irq(IRQ_MSC, host); + local_irq_restore(flags); + mmc_free_host(mmc); + } + return 0; +} + +#ifdef CONFIG_PM +pm_message_t state; +static int jz_mmc_suspend(struct platform_device *dev, pm_message_t state) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + int ret = 0; + + __msc_disable_power(); + if (mmc) + ret = mmc_suspend_host(mmc, state); + + return ret; +} + +static int jz_mmc_resume(struct platform_device *dev) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + int ret = 0; +#if 0 + /*for sandisk BB0807011816D and other strange cards*/ + int i; + + for(i = 104; i < 110; i++) + __gpio_as_input(i); + + /* perhaps you should mdelay more */ + mdelay(1000); + __gpio_as_msc(); +#endif + __msc_init_io(); + __msc_enable_power(); + __msc_reset(); + + if (!jz_mmc_slot_is_empty(0)) { + mmc_slot_enable = 1; + mmc_detect_change(mmc, 10); + } + + if (mmc) + ret = mmc_resume_host(mmc); + + return ret; +} +static int jz_mmc_pm_callback(struct pm_dev *pm_dev, + pm_request_t req, void *data) +{ + struct platform_device *pdev = (struct platform_device *)pm_dev->data; + + switch(req) { + case PM_RESUME: + jz_mmc_resume(pdev); + break; + case PM_SUSPEND: + /* state has no use */ + jz_mmc_suspend(pdev, state); + break; + default: + printk("MMC/SD: invalid PM request %d\n", req); + break; + } + return 0; +} +#else +#define jz_mmc_suspend NULL +#define jz_mmc_resume NULL +#endif + +static struct platform_driver jz_mmc_driver = { + .probe = jz_mmc_probe, + .remove = jz_mmc_remove, + .suspend = jz_mmc_suspend, + .resume = jz_mmc_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init jz_mmc_init(void) +{ + return platform_driver_register(&jz_mmc_driver); +} + +static void __exit jz_mmc_exit(void) +{ + platform_driver_unregister(&jz_mmc_driver); +} + +module_init(jz_mmc_init); +module_exit(jz_mmc_exit); + +MODULE_DESCRIPTION("JZ47XX SD/Multimedia Card Interface Driver"); +MODULE_LICENSE("GPL"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz_mmc.h linux-2.6.24.3-20100304/drivers/mmc/host/jz_mmc.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/jz_mmc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/jz_mmc.h 2010-03-03 19:04:51.000000000 -0800 @@ -0,0 +1,65 @@ +#ifndef __JZ_MMC_H__ +#define __JZ_MMC_H__ + +#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ +#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ +#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ +#define MMC_NO_ERROR 0 +/* Extra MMC commands for state control */ +/* Use negative numbers to disambiguate */ +#define MMC_CIM_RESET -1 +#define MMC_SET_CLOCK 100 + +typedef struct jzsoc_dma_desc { + volatile u32 ddadr; /* Points to the next descriptor + flags */ + volatile u32 dsadr; /* DSADR value for the current transfer */ + volatile u32 dtadr; /* DTADR value for the current transfer */ + volatile u32 dcmd; /* DCMD value for the current transfer */ +} jzsoc_dma_desc; + + + + +#include + +struct device; +struct mmc_host; + +struct jz_mmc_platform_data { + unsigned int ocr_mask; /* available voltages */ + unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ + int (*init)(struct device *, irq_handler_t , void *); + int (*get_ro)(struct device *); + void (*setpower)(struct device *, unsigned int); + void (*exit)(struct device *, void *); +}; + +//extern void pxa_set_mci_info(struct pxamci_platform_data *info); + + + +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + + +#endif /* __JZ_MMC_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/Kconfig linux-2.6.24.3-20100304/drivers/mmc/host/Kconfig --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/Kconfig 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/Kconfig 2010-03-03 19:04:51.000000000 -0800 @@ -4,6 +4,104 @@ comment "MMC/SD Host Controller Drivers" +config MMC_JZ + tristate "JZ SD/Multimedia Card Interface support" + depends on SOC_JZ4730 || SOC_JZ4740 + help + This selects the Ingenic JZ4730/JZ4740 SD/Multimedia card Interface. + If you have abIngenic platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. +choice + depends on MMC_JZ + prompt "MMC BUS Width" + default JZ_MMC_BUS_4 + help + This defines the BUS Width of the Ingenic JZ4730/JZ4740 SD/Multimedia card Interface. + +config JZ_MMC_BUS_1 + bool "1 Bit Bus" + help + 1 Bit SD/Multimedia Card Bus + +config JZ_MMC_BUS_4 + bool "4 Bit Bus" + help + 4 Bit SD/Multimedia Card Bus + +endchoice + +config MSC0_JZ4750 + tristate "JZ4750 SD/Multimedia Card 0 Interface support" + depends on SOC_JZ4750 || SOC_JZ4750D + help + This selects the Ingenic JZ4750 SD/Multimedia card 0 Interface. + If you have a Ingenic platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +choice + depends on MSC0_JZ4750 + prompt "MSC0 BUS Width" + default JZ4750_MSC0_BUS_4 + help + This defines the BUS Width of the Ingenic JZ4750 SD/Multimedia card Interface. + +config JZ4750_MSC0_BUS_1 + bool "1 Bit Bus" + help + 1 Bit SD/Multimedia Card Bus + +config JZ4750_MSC0_BUS_4 + bool "4 Bit Bus" + help + 4 Bit SD/Multimedia Card Bus + +config JZ4750_MSC0_BUS_8 + bool "8 Bit Bus" + help + 8 Bit Multimedia Card Bus + +endchoice + +config MSC1_JZ4750 + tristate "JZ4750 SD/Multimedia Card 1 Interface support" + depends on SOC_JZ4750 || SOC_JZ4750D + help + This selects the Ingenic JZ4750 SD/Multimedia card 1 Interface. + If you have a Ingenic platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +choice + depends on MSC1_JZ4750 + prompt "MSC1 BUS Width" + default JZ4750_MSC1_BUS_4 + help + This defines the BUS Width of the Ingenic JZ4750 SD/Multimedia card Interface. + +config JZ4750_MSC1_BUS_1 + bool "1 Bit Bus" + help + 1 Bit SD/Multimedia Card Bus + +config JZ4750_MSC1_BUS_4 + bool "4 Bit Bus" + help + 4 Bit SD/Multimedia Card Bus +endchoice + +config JZ4750_BOOT_FROM_MSC0 + tristate "JZ4750 Boot from SD/Multimedia Card Interface support" + depends on SOC_JZ4750 || SOC_JZ4750D + help + This selects boot from the Sd/Multimedia Card. + + If unsure,say N. + config MMC_ARMMMCI tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/Makefile linux-2.6.24.3-20100304/drivers/mmc/host/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mmc/host/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mmc/host/Makefile 2010-03-03 19:04:51.000000000 -0800 @@ -6,6 +6,9 @@ EXTRA_CFLAGS += -DDEBUG endif +obj-$(CONFIG_MMC_JZ) += jz_mmc.o +obj-$(CONFIG_MSC0_JZ4750) += jz4750_mmc.o +obj-$(CONFIG_MSC1_JZ4750) += jz4750_mmc.o obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_IMX) += imxmmc.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/Makefile linux-2.6.24.3-20100304/drivers/mtd/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/Makefile 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/Makefile 2010-03-03 19:04:36.000000000 -0800 @@ -3,9 +3,9 @@ # # Core functionality. -obj-$(CONFIG_MTD) += mtd.o mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o +obj-$(CONFIG_MTD) += $(mtd-y) obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o @@ -15,14 +15,15 @@ # 'Users' - code which presents functionality to userspace. obj-$(CONFIG_MTD_CHAR) += mtdchar.o obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o -obj-$(CONFIG_MTD_BLOCK) += mtdblock.o +#obj-$(CONFIG_MTD_BLOCK) += mtdblock.o +obj-$(CONFIG_MTD_BLOCK) += mtdblock-jz.o +obj-$(CONFIG_UDC_USE_LB_CACHE) += udc_cache.o obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o obj-$(CONFIG_FTL) += ftl.o obj-$(CONFIG_NFTL) += nftl.o obj-$(CONFIG_INFTL) += inftl.o obj-$(CONFIG_RFD_FTL) += rfd_ftl.o obj-$(CONFIG_SSFDC) += ssfdc.o -obj-$(CONFIG_MTD_OOPS) += mtdoops.o nftl-objs := nftlcore.o nftlmount.o inftl-objs := inftlcore.o inftlmount.o @@ -30,3 +31,6 @@ obj-y += chips/ maps/ devices/ nand/ onenand/ obj-$(CONFIG_MTD_UBI) += ubi/ + +$(obj)/mtdblock-jz.o: $(obj)/mtdblock-jz.o.original + @cp $(obj)/mtdblock-jz.o.original $(obj)/mtdblock-jz.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd_blkdevs.c linux-2.6.24.3-20100304/drivers/mtd/mtd_blkdevs.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd_blkdevs.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd_blkdevs.c 2010-03-03 19:04:36.000000000 -0800 @@ -41,8 +41,8 @@ unsigned long block, nsect; char *buf; - block = req->sector << 9 >> tr->blkshift; - nsect = req->current_nr_sectors << 9 >> tr->blkshift; + block = ((unsigned long long)req->sector) << 9 >> tr->blkshift; + nsect = ((unsigned long long)req->current_nr_sectors) << 9 >> tr->blkshift; buf = req->buffer; @@ -278,7 +278,7 @@ /* 2.5 has capacity in units of 512 bytes while still having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ - set_capacity(gd, (new->size * tr->blksize) >> 9); + set_capacity(gd, ((u_int64_t)new->size * tr->blksize) >> 9); gd->private_data = new; new->blkcore_priv = gd; diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdblock.c linux-2.6.24.3-20100304/drivers/mtd/mtdblock.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdblock.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtdblock.c 2010-03-03 19:04:35.000000000 -0800 @@ -1,7 +1,7 @@ /* * Direct MTD block device access * - * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $ + * $Id: mtdblock.c,v 1.1.1.1 2008-03-28 04:29:21 jlwei Exp $ * * (C) 2000-2003 Nicolas Pitre * (C) 1999-2003 David Woodhouse @@ -15,7 +15,7 @@ #include #include #include - +#include #include #include #include @@ -361,12 +361,27 @@ kfree(dev); } + +static int mtdblock_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) +{ + struct gendisk *gd = dev->blkcore_priv; + memset(geo, 0, sizeof(*geo)); + geo->heads = 4; + geo->sectors = 16; + geo->cylinders = dev->size/(4*16); + + printk("cylinders: %x \n", geo->cylinders); + printk("sects: %x\n", dev->size); + return 0; +} + static struct mtd_blktrans_ops mtdblock_tr = { .name = "mtdblock", .major = 31, .part_bits = 0, .blksize = 512, .open = mtdblock_open, + .getgeo = mtdblock_getgeo, .flush = mtdblock_flush, .release = mtdblock_release, .readsect = mtdblock_readsect, diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdblock-jz.o.original linux-2.6.24.3-20100304/drivers/mtd/mtdblock-jz.o.original --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdblock-jz.o.original 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtdblock-jz.o.original 2010-03-03 19:04:36.000000000 -0800 @@ -0,0 +1,55 @@ +ELFÔ3P4(!<‚Œ€(CŒ!(£¥Œ àêÿ$ÿ<ÿÿB4$¢Â¬à!<àØbŒ<àÜbŒèÿ½'°¯¿¯ !€€! ¿°½'àÿ½'°¯!€ ±¯!(!ˆ€$¿¯ ! $$¢¢ #Ž!‚¦¿±°à ½'àÿ½'¿¯±¯²¯°¯‚Œ!ˆ€¨CŒRŒPdŒTpŒ$#€€ÿÿ2$$Žÿÿ$B’ '®&®%®,(®!04"®ÿÿR2 !(0r($Ž !(#Ž $ŽfŒ¿²±°ÿ$ ½'ˆÿ½'t¿¯p¾¯l·¯h¶¯dµ¯`´¯\³¯X²¯T±¯P°¯<‚Œ–ŒHŒ¨ÓŽ TŒT~ŽPwŽ‚’$B0‡C! €}!0 ƒc0b„$Æ$úÿÈ$ôÿ$t¿p¾l·h¶dµ`´\³X²T±P°!€àx½'Ç$*èi@À!À!TF$šÀ¨ç$èÆ$Â$B0ùÿC!´DŒüÿÃŒ+dôÿ`!àÀ¨ç$òÿèÆ$°'²¬! !(8$ <$Ì'& $!$0¢¯4£¯@¦¯H§¯¤¯ThŽ#×'0 DÃB8PiŽ8Çÿÿ„0 1%ãÿÿ„$ F $ !0DÃ/°¯+@Â!8eHÂŽ!8 ø@! ÀÌ#Žÿÿ$b!´b! ûB0b t¿p¾l·h¶dµ`´\³X²T±P°!€àx½'b! B4b t¿p¾l·h¶dµ`´\³X²T±P°!€àx½'!À©À¨!0$Øÿ½'³¯²¯±¯°¯ ¿¯‚ Â!bD¬P£\¥TdŒ€ÂŽ'e8• …00”%8g 8Å< 0! À ø@ÌpŒ@T¦T¥¡ ! à†&Ä+(Ô!µ* Ä! À-€!¨`P¥ÚT¤Œôÿ$!(f ! à'†&BŽ€B0@ „Œ â®<EŽ„$ !0  âŽÿ@< „$Z!  Â!b@¬„Œ Ð$ â®EŽ<„$ !0 E âŽX¢⎌¥P‡Œ!e!B(' (…ˆã æ0€â%ˆ± ˆ“ €”¨P âŽó!C|¢¯P¢'¢¯H‚Ž!0!8  ø@! €<<d$%!0À@!8`H ¢¯HÃc$b(åÿ@Hï<<D$e$ !0ÀVHÀ¯”¤Œ¥P†Œ!e!B(' (…ˆÃ Ç0€Â%ˆ± ˆ €˜¨P¢'|¨¯¢¯H‚Ž!0!8  ø@! €<<d$%!0À@!8` NULL +drivers/mtd/mtdblock-jz.c%s: zone_ptr is null +zone_ptr is null +zone_ptr->block_info is null +%s Warning: too many bad blocks: %d, nand flash is un-useable +%s: total bad block num=%d, current bad phys_block=%d +%s: increase use count +this is part mtd info +&mtdblk->cache_mutex vmalloc 0x%x bytes for jz_mtdblock%d. + kmalloc 0x%x bytes for jz_mtdblock%d. + Allocating block cache in mtdblock-jz.c failed. + Use the block cache allocated early in nand_base.c. +ERROR 1: bad block allowed set error!!! +current partiton totoal_phys_block: %d, bad block allowed set is %d +NOTICE: If you are using Yaffs2 or Jffs2, you can ignore ERROR 1 + +%s: erase %d block failed +%s erase block %d for marking bad failed +%s ERROR: can't find_free_block!! +%s WARNING: uncorretable ecc or too many bit error cause bad block +%s: uncorretable ecc ---> correctable ecc due to %d times read retry +%s: erase failed , mark to bad block: 0x%x +%s: write failed , mark to bad block: 0x%x +%s: fill_block1 phys_block:%d,page:%d,retry:%d +%s: reading error when modifying phys_block %d +!%s: fill_block2 phys_block:%d,page:%d,retry:%d +%s: phys_block 0x%x erasing failed, marked bad, and find new block 0x%x +%s: phys_block 0x%x programing failed, marked bad, and find new block 0x%x +%s:erase old_phys_block %d faild,mark it bad + vfree 0x%x bytes for jz_mtdblock%d. + kfree 0x%x bytes for jz_mtdblock%d. +%s: decrease use count +%s %s WARNING: page %d uncorretable ecc or too many bit error cause bad block,move this block +%s: page %d uncorretable ecc ---> correctable ecc due to %d times read retry,but still move this block +%s ERROR: can't find_free_block!!mtdblock,Dmtdblock_releasemtdblock_openmtdblock_block_lookup_map_entrydo_cached_readmtdblock_flush_cacheudc_flush_cacheudc_get_mtdudc_get_mtdblkudc_mtdblock_writesectudc_mtdblock_readsectØ”"%|t„T„ +$Tmtdblklogmtdblkn=mtdblk=$€øÿÿÿT€øÿÿÿ„T€üÿÿÿ|€øÿÿÿ Ø€üÿÿÿ |ÿÀüÿÿÿx€øÿÿÿ(è€øÿÿÿ˜€üÿÿÿ „€øÿÿÿ tÿÀüÿÿÿˆè €øÿÿÿˆL€üÿÿÿ DÿÀüÿÿÿ€XÿÀüÿÿÿà€øÿÿÿ „€üÿÿÿ0€øÿÿÿ ÿÀüÿÿÿ€€üÿÿÿ”"Ô"ÿÀüÿÿÿ@€øÿÿÿ%GCC: (GNU) 4.2.1.symtab.strtab.shstrtab.rel.text.rel.init.text.rel.exit.text.reginfo.rodata.str1.4.rel__ksymtab_gpl.rel__kcrctab_gpl.rodata__ksymtab_strings.rel.data.rel.exitcall.exit.rel.initcall6.init.rel.init.setup.init.data.bss.sbss.rel.pdr.mdebug.abi32.comment@@% ü8è )€%% äEX8& 4 #include -#include #include #include #include @@ -82,8 +81,6 @@ return -EINVAL; } - - static int mtd_open(struct inode *inode, struct file *file) { int minor = iminor(inode); @@ -136,8 +133,7 @@ DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); - /* Only sync if opened RW */ - if ((file->f_mode & 2) && mtd->sync) + if (mtd->sync) mtd->sync(mtd); put_mtd_device(mtd); @@ -156,7 +152,7 @@ { struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; - size_t retlen=0; + size_mtd_t retlen=0; size_t total_retlen=0; int ret=0; int len; @@ -250,7 +246,7 @@ struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; char *kbuf; - size_t retlen; + size_mtd_t retlen; size_t total_retlen=0; int ret=0; int len; @@ -535,7 +531,7 @@ { struct mtd_oob_buf buf; struct mtd_oob_ops ops; - + if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) return -EFAULT; @@ -575,6 +571,73 @@ break; } + case MEMWRITEPAGE: + { + struct mtd_page_buf buf; + struct mtd_oob_ops ops; + + memset(&ops, 0, sizeof(ops)); +#if 1 + if(!(file->f_mode & 2)) + return -EPERM; +#endif + + if (copy_from_user(&buf, argp, sizeof(struct mtd_page_buf))) + return -EFAULT; + + if (buf.ooblength > mtd->oobsize) + return -EINVAL; + + if (!mtd->write_oob) + ret = -EOPNOTSUPP; + else + ret = access_ok(VERIFY_READ, buf.oobptr, + buf.ooblength) ? 0 : EFAULT; + + if (ret) + return ret; + + ops.len = mtd->writesize; + ops.ooblen = buf.ooblength; + ops.ooboffs = buf.start & (mtd->oobsize - 1); + ops.mode = MTD_OOB_PLACE; + + if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) + return -EINVAL; + + /* alloc memory and copy oob data from user mode to kernel mode */ + ops.oobbuf = kmalloc(buf.ooblength, GFP_KERNEL); + if (!ops.oobbuf) + return -ENOMEM; + + if (copy_from_user(ops.oobbuf, buf.oobptr, buf.ooblength)) { + kfree(ops.oobbuf); + return -EFAULT; + } + + /* alloc memory and copy page data from user mode to kernel mode */ + ops.datbuf = kmalloc(mtd->writesize, GFP_KERNEL); + if (!ops.datbuf) + return -ENOMEM; + + if (copy_from_user(ops.datbuf, buf.datptr, mtd->writesize)) { + kfree(ops.datbuf); + return -EFAULT; + } + + buf.start &= ~(mtd->oobsize - 1); + ret = mtd->write_oob(mtd, buf.start, &ops); + + if (copy_to_user(argp + 2*sizeof(uint32_t), &ops.retlen, + sizeof(uint32_t))) + ret = -EFAULT; + + kfree(ops.oobbuf); + kfree(ops.datbuf); + break; + } + + case MEMLOCK: { struct erase_info_user info; @@ -626,9 +689,9 @@ case MEMGETBADBLOCK: { - loff_t offs; + loff_mtd_t offs; - if (copy_from_user(&offs, argp, sizeof(loff_t))) + if (copy_from_user(&offs, argp, sizeof(loff_mtd_t))) return -EFAULT; if (!mtd->block_isbad) ret = -EOPNOTSUPP; @@ -639,9 +702,9 @@ case MEMSETBADBLOCK: { - loff_t offs; + loff_mtd_t offs; - if (copy_from_user(&offs, argp, sizeof(loff_t))) + if (copy_from_user(&offs, argp, sizeof(loff_mtd_t))) return -EFAULT; if (!mtd->block_markbad) ret = -EOPNOTSUPP; @@ -756,9 +819,9 @@ } default: + printk("line : %d\n", __LINE__); ret = -ENOTTY; } - return ret; } /* memory_ioctl */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdcore.c linux-2.6.24.3-20100304/drivers/mtd/mtdcore.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdcore.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtdcore.c 2010-03-03 19:04:35.000000000 -0800 @@ -303,10 +303,10 @@ */ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t *retlen) + unsigned long count, loff_mtd_t to, size_mtd_t *retlen) { unsigned long i; - size_t totlen = 0, thislen; + size_mtd_t totlen = 0, thislen; int ret = 0; if(!mtd->write) { @@ -350,8 +350,9 @@ if (!this) return 0; - return sprintf(buf, "mtd%d: %8.8x %8.8x \"%s\"\n", i, this->size, - this->erasesize, this->name); + return sprintf(buf, "mtd%d: %09llx %8.8x %d %d \"%s\"\n", + i, this->size, this->erasesize, !!((this->flags)&MTD_NAND_CPU_MODE), + !!((this->flags)&MTD_MTDBLOCK_JZ_INVALID), this->name); } static int mtd_read_proc (char *page, char **start, off_t off, int count, @@ -362,7 +363,7 @@ mutex_lock(&mtd_table_mutex); - len = sprintf(page, "dev: size erasesize name\n"); + len = sprintf(page, "dev: size erasesize cpu_mode jz_mtdblock_invalid name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { l = mtd_proc_info(page + len, i); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdpart.c linux-2.6.24.3-20100304/drivers/mtd/mtdpart.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtdpart.c 2008-02-25 16:20:20.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtdpart.c 2010-03-03 19:04:35.000000000 -0800 @@ -5,7 +5,7 @@ * * This code is GPL * - * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $ + * $Id: mtdpart.c,v 1.1.1.1 2008-03-28 04:29:21 jlwei Exp $ * * 02-21-2002 Thomas Gleixner * added support for read_oob, write_oob @@ -28,7 +28,7 @@ struct mtd_part { struct mtd_info mtd; struct mtd_info *master; - u_int32_t offset; + u_int64_t offset; int index; struct list_head list; int registered; @@ -46,8 +46,8 @@ * to the _real_ device. */ -static int part_read (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_read (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); int res; @@ -67,8 +67,8 @@ return res; } -static int part_point (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char **buf) +static int part_point (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, u_char **buf) { struct mtd_part *part = PART(mtd); if (from >= mtd->size) @@ -79,14 +79,14 @@ len, retlen, buf); } -static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) +static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_mtd_t from, size_mtd_t len) { struct mtd_part *part = PART(mtd); part->master->unpoint (part->master, addr, from + part->offset, len); } -static int part_read_oob(struct mtd_info *mtd, loff_t from, +static int part_read_oob(struct mtd_info *mtd, loff_mtd_t from, struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); @@ -107,8 +107,8 @@ return res; } -static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_read_user_prot_reg (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); return part->master->read_user_prot_reg (part->master, from, @@ -116,14 +116,14 @@ } static int part_get_user_prot_info (struct mtd_info *mtd, - struct otp_info *buf, size_t len) + struct otp_info *buf, size_mtd_t len) { struct mtd_part *part = PART(mtd); return part->master->get_user_prot_info (part->master, buf, len); } -static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); return part->master->read_fact_prot_reg (part->master, from, @@ -131,14 +131,14 @@ } static int part_get_fact_prot_info (struct mtd_info *mtd, - struct otp_info *buf, size_t len) + struct otp_info *buf, size_mtd_t len) { struct mtd_part *part = PART(mtd); return part->master->get_fact_prot_info (part->master, buf, len); } -static int part_write (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int part_write (struct mtd_info *mtd, loff_mtd_t to, size_mtd_t len, + size_mtd_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) @@ -151,7 +151,7 @@ len, retlen, buf); } -static int part_write_oob(struct mtd_info *mtd, loff_t to, +static int part_write_oob(struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); @@ -166,22 +166,22 @@ return part->master->write_oob(part->master, to + part->offset, ops); } -static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_write_user_prot_reg (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); return part->master->write_user_prot_reg (part->master, from, len, retlen, buf); } -static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) +static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len) { struct mtd_part *part = PART(mtd); return part->master->lock_user_prot_reg (part->master, from, len); } static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t *retlen) + unsigned long count, loff_mtd_t to, size_mtd_t *retlen) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) @@ -222,7 +222,7 @@ } EXPORT_SYMBOL_GPL(mtd_erase_callback); -static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) +static int part_lock (struct mtd_info *mtd, loff_mtd_t ofs, size_mtd_t len) { struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) @@ -230,7 +230,7 @@ return part->master->lock(part->master, ofs + part->offset, len); } -static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) +static int part_unlock (struct mtd_info *mtd, loff_mtd_t ofs, size_mtd_t len) { struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) @@ -256,7 +256,7 @@ part->master->resume(part->master); } -static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) +static int part_block_isbad (struct mtd_info *mtd, loff_mtd_t ofs) { struct mtd_part *part = PART(mtd); if (ofs >= mtd->size) @@ -265,7 +265,7 @@ return part->master->block_isbad(part->master, ofs); } -static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) +static int part_block_markbad (struct mtd_info *mtd, loff_mtd_t ofs) { struct mtd_part *part = PART(mtd); int res; @@ -320,10 +320,10 @@ int nbparts) { struct mtd_part *slave; - u_int32_t cur_offset = 0; + u_int64_t cur_offset = 0; int i; - printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); + //printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); for (i = 0; i < nbparts; i++) { @@ -340,6 +340,11 @@ /* set up the MTD object for this partition */ slave->mtd.type = master->type; slave->mtd.flags = master->flags & ~parts[i].mask_flags; + if (parts[i].mtdblock_jz_invalid) + slave->mtd.flags |= MTD_MTDBLOCK_JZ_INVALID; + if (parts[i].cpu_mode) + slave->mtd.flags |= MTD_NAND_CPU_MODE; + slave->mtd.size = parts[i].size; slave->mtd.writesize = master->writesize; slave->mtd.oobsize = master->oobsize; @@ -351,6 +356,7 @@ slave->mtd.read = part_read; slave->mtd.write = part_write; + slave->mtd.priv = master->priv; //add by Nancy if(master->point && master->unpoint){ slave->mtd.point = part_point; @@ -398,11 +404,12 @@ slave->offset = cur_offset; if (slave->offset == MTDPART_OFS_NXTBLK) { slave->offset = cur_offset; - if ((cur_offset % master->erasesize) != 0) { + if (((u32)cur_offset % master->erasesize) != 0) { /* Round up to next erasesize */ - slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; + //slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; + slave->offset = ((cur_offset >> (ffs(master->erasesize)-1)) + 1) * master->erasesize; printk(KERN_NOTICE "Moving partition %d: " - "0x%08x -> 0x%08x\n", i, + "0x%09llx -> 0x%09llx\n", i, cur_offset, slave->offset); } } @@ -410,8 +417,10 @@ slave->mtd.size = master->size - slave->offset; cur_offset = slave->offset + slave->mtd.size; - printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, - slave->offset + slave->mtd.size, slave->mtd.name); + printk (KERN_NOTICE "0x%09llx-0x%09llx : \"%s\" \"%s\" \"%s\"\n", slave->offset, + slave->offset + slave->mtd.size, slave->mtd.name, + ((slave->mtd.flags)&MTD_NAND_CPU_MODE)?"cpu_mode":"dma_mode", + ((slave->mtd.flags)&MTD_MTDBLOCK_JZ_INVALID)?"jz_mtdblock_invalid":"jz_mtdblock_valid"); /* let's do some sanity checks */ if (slave->offset >= master->size) { @@ -423,7 +432,7 @@ } if (slave->offset + slave->mtd.size > master->size) { slave->mtd.size = master->size - slave->offset; - printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", + printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n", parts[i].name, master->name, slave->mtd.size); } if (master->numeraseregions>1) { @@ -446,7 +455,7 @@ } if ((slave->mtd.flags & MTD_WRITEABLE) && - (slave->offset % slave->mtd.erasesize)) { + ((u32)slave->offset % slave->mtd.erasesize)) { /* Doesn't start on a boundary of major erase size */ /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ slave->mtd.flags &= ~MTD_WRITEABLE; @@ -454,7 +463,7 @@ parts[i].name); } if ((slave->mtd.flags & MTD_WRITEABLE) && - (slave->mtd.size % slave->mtd.erasesize)) { + ((u32)slave->mtd.size % slave->mtd.erasesize)) { slave->mtd.flags &= ~MTD_WRITEABLE; printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", parts[i].name); @@ -462,7 +471,7 @@ slave->mtd.ecclayout = master->ecclayout; if (master->block_isbad) { - uint32_t offs = 0; + uint64_t offs = 0; while(offs < slave->mtd.size) { if (master->block_isbad(master, @@ -560,3 +569,7 @@ EXPORT_SYMBOL_GPL(parse_mtd_partitions); EXPORT_SYMBOL_GPL(register_mtd_parser); EXPORT_SYMBOL_GPL(deregister_mtd_parser); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nicolas Pitre "); +MODULE_DESCRIPTION("Generic support for partitioning of MTD devices"); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,538 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2004 Ferenc Havasi , + * University of Szeged, Hungary + * + * For licensing information, see the file 'LICENCE' in this directory + * in the jffs2 directory. + */ + +#include "compr.h" +#include +#include +#include + +#define FAVOUR_LZO_PERCENT 80 + +extern int page_size; + +/* LIST IMPLEMENTATION (from linux/list.h) */ + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = (void *) 0; + entry->prev = (void *) 0; +} + +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + + +/* Available compressors are on this list */ +static LIST_HEAD(jffs2_compressor_list); + +/* Actual compression mode */ +static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; + +void jffs2_set_compression_mode(int mode) +{ + jffs2_compression_mode = mode; +} + +int jffs2_get_compression_mode(void) +{ + return jffs2_compression_mode; +} + +/* Statistics for blocks stored without compression */ +static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; + +/* Compression test stuffs */ + +static int jffs2_compression_check = 0; + +static unsigned char *jffs2_compression_check_buf = NULL; + +void jffs2_compression_check_set(int yesno) +{ + jffs2_compression_check = yesno; +} + +int jffs2_compression_check_get(void) +{ + return jffs2_compression_check; +} + +static int jffs2_error_cnt = 0; + +int jffs2_compression_check_errorcnt_get(void) +{ + return jffs2_error_cnt; +} + +#define JFFS2_BUFFER_FILL 0x55 + +/* Called before compression (if compression_check is setted) to prepare + the buffer for buffer overflow test */ +static void jffs2_decompression_test_prepare(unsigned char *buf, int size) +{ + memset(buf,JFFS2_BUFFER_FILL,size+1); +} + +/* Called after compression (if compression_check is setted) to test the result */ +static void jffs2_decompression_test(struct jffs2_compressor *compr, + unsigned char *data_in, unsigned char *output_buf, + uint32_t cdatalen, uint32_t datalen, uint32_t buf_size) +{ + uint32_t i; + + /* buffer overflow test */ + for (i=buf_size;i>cdatalen;i--) { + if (output_buf[i]!=JFFS2_BUFFER_FILL) { + fprintf(stderr,"COMPR_ERROR: buffer overflow at %s. " + "(bs=%d csize=%d b[%d]=%d)\n", compr->name, + buf_size, cdatalen, i, (int)(output_buf[i])); + jffs2_error_cnt++; + return; + } + } + /* allocing temporary buffer for decompression */ + if (!jffs2_compression_check_buf) { + jffs2_compression_check_buf = malloc(page_size); + if (!jffs2_compression_check_buf) { + fprintf(stderr,"No memory for buffer allocation. Compression check disabled.\n"); + jffs2_compression_check = 0; + return; + } + } + /* decompressing */ + if (!compr->decompress) { + fprintf(stderr,"JFFS2 compression check: there is no decompress function at %s.\n", compr->name); + jffs2_error_cnt++; + return; + } + if (compr->decompress(output_buf,jffs2_compression_check_buf,cdatalen,datalen,NULL)) { + fprintf(stderr,"JFFS2 compression check: decompression failed at %s.\n", compr->name); + jffs2_error_cnt++; + } + /* validate decompression */ + else { + for (i=0;iname, i); + jffs2_error_cnt++; + break; + } + } + } +} + +/* + * Return 1 to use this compression + */ +static int jffs2_is_best_compression(struct jffs2_compressor *this, + struct jffs2_compressor *best, uint32_t size, uint32_t bestsize) +{ + switch (jffs2_compression_mode) { + case JFFS2_COMPR_MODE_SIZE: + if (bestsize > size) + return 1; + return 0; + case JFFS2_COMPR_MODE_FAVOURLZO: + if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > size)) + return 1; + if ((best->compr != JFFS2_COMPR_LZO) && (bestsize > size)) + return 1; + if ((this->compr == JFFS2_COMPR_LZO) && (bestsize > (size * FAVOUR_LZO_PERCENT / 100))) + return 1; + if ((bestsize * FAVOUR_LZO_PERCENT / 100) > size) + return 1; + + return 0; + } + /* Shouldn't happen */ + return 0; +} + +/* jffs2_compress: + * @data: Pointer to uncompressed data + * @cdata: Pointer to returned pointer to buffer for compressed data + * @datalen: On entry, holds the amount of data available for compression. + * On exit, expected to hold the amount of data actually compressed. + * @cdatalen: On entry, holds the amount of space available for compressed + * data. On exit, expected to hold the actual size of the compressed + * data. + * + * Returns: Lower byte to be stored with data indicating compression type used. + * Zero is used to show that the data could not be compressed - the + * compressed version was actually larger than the original. + * Upper byte will be used later. (soon) + * + * If the cdata buffer isn't large enough to hold all the uncompressed data, + * jffs2_compress should compress as much as will fit, and should set + * *datalen accordingly to show the amount of data which were compressed. + */ +uint16_t jffs2_compress( unsigned char *data_in, unsigned char **cpage_out, + uint32_t *datalen, uint32_t *cdatalen) +{ + int ret = JFFS2_COMPR_NONE; + int compr_ret; + struct jffs2_compressor *this, *best=NULL; + unsigned char *output_buf = NULL, *tmp_buf; + uint32_t orig_slen, orig_dlen; + uint32_t best_slen=0, best_dlen=0; + + switch (jffs2_compression_mode) { + case JFFS2_COMPR_MODE_NONE: + break; + case JFFS2_COMPR_MODE_PRIORITY: + orig_slen = *datalen; + orig_dlen = *cdatalen; + output_buf = malloc(orig_dlen+jffs2_compression_check); + if (!output_buf) { + fprintf(stderr,"mkfs.jffs2: No memory for compressor allocation. Compression failed.\n"); + goto out; + } + list_for_each_entry(this, &jffs2_compressor_list, list) { + /* Skip decompress-only backwards-compatibility and disabled modules */ + if ((!this->compress)||(this->disabled)) + continue; + + this->usecount++; + + if (jffs2_compression_check) /*preparing output buffer for testing buffer overflow */ + jffs2_decompression_test_prepare(output_buf, orig_dlen); + + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); + this->usecount--; + if (!compr_ret) { + ret = this->compr; + this->stat_compr_blocks++; + this->stat_compr_orig_size += *datalen; + this->stat_compr_new_size += *cdatalen; + if (jffs2_compression_check) + jffs2_decompression_test(this, data_in, output_buf, *cdatalen, *datalen, orig_dlen); + break; + } + } + if (ret == JFFS2_COMPR_NONE) free(output_buf); + break; + case JFFS2_COMPR_MODE_FAVOURLZO: + case JFFS2_COMPR_MODE_SIZE: + orig_slen = *datalen; + orig_dlen = *cdatalen; + list_for_each_entry(this, &jffs2_compressor_list, list) { + uint32_t needed_buf_size; + + if (jffs2_compression_mode == JFFS2_COMPR_MODE_FAVOURLZO) + needed_buf_size = orig_slen + jffs2_compression_check; + else + needed_buf_size = orig_dlen + jffs2_compression_check; + + /* Skip decompress-only backwards-compatibility and disabled modules */ + if ((!this->compress)||(this->disabled)) + continue; + /* Allocating memory for output buffer if necessary */ + if ((this->compr_buf_size < needed_buf_size) && (this->compr_buf)) { + free(this->compr_buf); + this->compr_buf_size=0; + this->compr_buf=NULL; + } + if (!this->compr_buf) { + tmp_buf = malloc(needed_buf_size); + if (!tmp_buf) { + fprintf(stderr,"mkfs.jffs2: No memory for compressor allocation. (%d bytes)\n",orig_dlen); + continue; + } + else { + this->compr_buf = tmp_buf; + this->compr_buf_size = orig_dlen; + } + } + this->usecount++; + if (jffs2_compression_check) /*preparing output buffer for testing buffer overflow */ + jffs2_decompression_test_prepare(this->compr_buf,this->compr_buf_size); + *datalen = orig_slen; + *cdatalen = orig_dlen; + compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); + this->usecount--; + if (!compr_ret) { + if (jffs2_compression_check) + jffs2_decompression_test(this, data_in, this->compr_buf, *cdatalen, *datalen, this->compr_buf_size); + if (((!best_dlen) || jffs2_is_best_compression(this, best, *cdatalen, best_dlen)) + && (*cdatalen < *datalen)) { + best_dlen = *cdatalen; + best_slen = *datalen; + best = this; + } + } + } + if (best_dlen) { + *cdatalen = best_dlen; + *datalen = best_slen; + output_buf = best->compr_buf; + best->compr_buf = NULL; + best->compr_buf_size = 0; + best->stat_compr_blocks++; + best->stat_compr_orig_size += best_slen; + best->stat_compr_new_size += best_dlen; + ret = best->compr; + } + break; + default: + fprintf(stderr,"mkfs.jffs2: unknow compression mode.\n"); + } +out: + if (ret == JFFS2_COMPR_NONE) { + *cpage_out = data_in; + *datalen = *cdatalen; + none_stat_compr_blocks++; + none_stat_compr_size += *datalen; + } + else { + *cpage_out = output_buf; + } + return ret; +} + + +int jffs2_register_compressor(struct jffs2_compressor *comp) +{ + struct jffs2_compressor *this; + + if (!comp->name) { + fprintf(stderr,"NULL compressor name at registering JFFS2 compressor. Failed.\n"); + return -1; + } + comp->compr_buf_size=0; + comp->compr_buf=NULL; + comp->usecount=0; + comp->stat_compr_orig_size=0; + comp->stat_compr_new_size=0; + comp->stat_compr_blocks=0; + comp->stat_decompr_blocks=0; + + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (this->priority < comp->priority) { + list_add(&comp->list, this->list.prev); + goto out; + } + } + list_add_tail(&comp->list, &jffs2_compressor_list); +out: + return 0; +} + +int jffs2_unregister_compressor(struct jffs2_compressor *comp) +{ + + if (comp->usecount) { + fprintf(stderr,"mkfs.jffs2: Compressor modul is in use. Unregister failed.\n"); + return -1; + } + list_del(&comp->list); + + return 0; +} + +#define JFFS2_STAT_BUF_SIZE 16000 + +char *jffs2_list_compressors(void) +{ + struct jffs2_compressor *this; + char *buf, *act_buf; + + act_buf = buf = malloc(JFFS2_STAT_BUF_SIZE); + list_for_each_entry(this, &jffs2_compressor_list, list) { + act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority); + if ((this->disabled)||(!this->compress)) + act_buf += sprintf(act_buf,"disabled"); + else + act_buf += sprintf(act_buf,"enabled"); + act_buf += sprintf(act_buf,"\n"); + } + return buf; +} + +char *jffs2_stats(void) +{ + struct jffs2_compressor *this; + char *buf, *act_buf; + + act_buf = buf = malloc(JFFS2_STAT_BUF_SIZE); + + act_buf += sprintf(act_buf,"Compression mode: "); + switch (jffs2_compression_mode) { + case JFFS2_COMPR_MODE_NONE: + act_buf += sprintf(act_buf,"none"); + break; + case JFFS2_COMPR_MODE_PRIORITY: + act_buf += sprintf(act_buf,"priority"); + break; + case JFFS2_COMPR_MODE_SIZE: + act_buf += sprintf(act_buf,"size"); + break; + case JFFS2_COMPR_MODE_FAVOURLZO: + act_buf += sprintf(act_buf, "favourlzo"); + break; + default: + act_buf += sprintf(act_buf,"unkown"); + break; + } + act_buf += sprintf(act_buf,"\nCompressors:\n"); + act_buf += sprintf(act_buf,"%10s ","none"); + act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks, + none_stat_compr_size, none_stat_decompr_blocks); + list_for_each_entry(this, &jffs2_compressor_list, list) { + act_buf += sprintf(act_buf,"%10s (prio:%d) ",this->name,this->priority); + if ((this->disabled)||(!this->compress)) + act_buf += sprintf(act_buf,"- "); + else + act_buf += sprintf(act_buf,"+ "); + act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks, + this->stat_compr_new_size, this->stat_compr_orig_size, + this->stat_decompr_blocks); + act_buf += sprintf(act_buf,"\n"); + } + return buf; +} + +int jffs2_set_compression_mode_name(const char *name) +{ + if (!strcmp("none",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; + return 0; + } + if (!strcmp("priority",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; + return 0; + } + if (!strcmp("size",name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; + return 0; + } + if (!strcmp("favourlzo", name)) { + jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; + return 0; + } + + return 1; +} + +static int jffs2_compressor_Xable(const char *name, int disabled) +{ + struct jffs2_compressor *this; + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (!strcmp(this->name, name)) { + this->disabled = disabled; + return 0; + } + } + return 1; +} + +int jffs2_enable_compressor_name(const char *name) +{ + return jffs2_compressor_Xable(name, 0); +} + +int jffs2_disable_compressor_name(const char *name) +{ + return jffs2_compressor_Xable(name, 1); +} + +int jffs2_set_compressor_priority(const char *name, int priority) +{ + struct jffs2_compressor *this,*comp; + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (!strcmp(this->name, name)) { + this->priority = priority; + comp = this; + goto reinsert; + } + } + fprintf(stderr,"mkfs.jffs2: compressor %s not found.\n",name); + return 1; +reinsert: + /* list is sorted in the order of priority, so if + we change it we have to reinsert it into the + good place */ + list_del(&comp->list); + list_for_each_entry(this, &jffs2_compressor_list, list) { + if (this->priority < comp->priority) { + list_add(&comp->list, this->list.prev); + return 0; + } + } + list_add_tail(&comp->list, &jffs2_compressor_list); + return 0; +} + + +int jffs2_compressors_init(void) +{ +#ifdef CONFIG_JFFS2_ZLIB + jffs2_zlib_init(); +#endif +#ifdef CONFIG_JFFS2_RTIME + jffs2_rtime_init(); +#endif +#ifdef CONFIG_JFFS2_LZO + jffs2_lzo_init(); +#endif + return 0; +} + +int jffs2_compressors_exit(void) +{ +#ifdef CONFIG_JFFS2_RTIME + jffs2_rtime_exit(); +#endif +#ifdef CONFIG_JFFS2_ZLIB + jffs2_zlib_exit(); +#endif +#ifdef CONFIG_JFFS2_LZO + jffs2_lzo_exit(); +#endif + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr.h 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,119 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2004 Ferenc Havasi , + * University of Szeged, Hungary + * + * For licensing information, see the file 'LICENCE' in the + * jffs2 directory. + */ + +#ifndef __JFFS2_COMPR_H__ +#define __JFFS2_COMPR_H__ + +#include +#include +#include +#include "linux/jffs2.h" + +#define CONFIG_JFFS2_ZLIB +#define CONFIG_JFFS2_RTIME +#define CONFIG_JFFS2_LZO + +#define JFFS2_RUBINMIPS_PRIORITY 10 +#define JFFS2_DYNRUBIN_PRIORITY 20 +#define JFFS2_RTIME_PRIORITY 50 +#define JFFS2_ZLIB_PRIORITY 60 +#define JFFS2_LZO_PRIORITY 80 + +#define JFFS2_COMPR_MODE_NONE 0 +#define JFFS2_COMPR_MODE_PRIORITY 1 +#define JFFS2_COMPR_MODE_SIZE 2 +#define JFFS2_COMPR_MODE_FAVOURLZO 3 + +#define kmalloc(a,b) malloc(a) +#define kfree(a) free(a) +#ifndef GFP_KERNEL +#define GFP_KERNEL 0 +#endif + +#define vmalloc(a) malloc(a) +#define vfree(a) free(a) + +#define printk(...) fprintf(stderr,__VA_ARGS__) + +#define KERN_EMERG +#define KERN_ALERT +#define KERN_CRIT +#define KERN_ERR +#define KERN_WARNING +#define KERN_NOTICE +#define KERN_INFO +#define KERN_DEBUG + +struct list_head { + struct list_head *next, *prev; +}; + +void jffs2_set_compression_mode(int mode); +int jffs2_get_compression_mode(void); +int jffs2_set_compression_mode_name(const char *mode_name); + +int jffs2_enable_compressor_name(const char *name); +int jffs2_disable_compressor_name(const char *name); + +int jffs2_set_compressor_priority(const char *name, int priority); + +struct jffs2_compressor { + struct list_head list; + int priority; /* used by prirority comr. mode */ + char *name; + char compr; /* JFFS2_COMPR_XXX */ + int (*compress)(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *srclen, uint32_t *destlen, void *model); + int (*decompress)(unsigned char *cdata_in, unsigned char *data_out, + uint32_t cdatalen, uint32_t datalen, void *model); + int usecount; + int disabled; /* if seted the compressor won't compress */ + unsigned char *compr_buf; /* used by size compr. mode */ + uint32_t compr_buf_size; /* used by size compr. mode */ + uint32_t stat_compr_orig_size; + uint32_t stat_compr_new_size; + uint32_t stat_compr_blocks; + uint32_t stat_decompr_blocks; +}; + +int jffs2_register_compressor(struct jffs2_compressor *comp); +int jffs2_unregister_compressor(struct jffs2_compressor *comp); + +int jffs2_compressors_init(void); +int jffs2_compressors_exit(void); + +uint16_t jffs2_compress(unsigned char *data_in, unsigned char **cpage_out, + uint32_t *datalen, uint32_t *cdatalen); + +/* If it is setted, a decompress will be called after every compress */ +void jffs2_compression_check_set(int yesno); +int jffs2_compression_check_get(void); +int jffs2_compression_check_errorcnt_get(void); + +char *jffs2_list_compressors(void); +char *jffs2_stats(void); + +/* Compressor modules */ + +/* These functions will be called by jffs2_compressors_init/exit */ +#ifdef CONFIG_JFFS2_ZLIB +int jffs2_zlib_init(void); +void jffs2_zlib_exit(void); +#endif +#ifdef CONFIG_JFFS2_RTIME +int jffs2_rtime_init(void); +void jffs2_rtime_exit(void); +#endif +#ifdef CONFIG_JFFS2_LZO +int jffs2_lzo_init(void); +void jffs2_lzo_exit(void); +#endif + +#endif /* __JFFS2_COMPR_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_lzo.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_lzo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_lzo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_lzo.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,120 @@ +/* + * JFFS2 LZO Compression Interface. + * + * Copyright (C) 2007 Nokia Corporation. All rights reserved. + * + * Author: Richard Purdie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include "compr.h" + +extern int page_size; + +static void *lzo_mem; +static void *lzo_compress_buf; + +/* + * Note about LZO compression. + * + * We want to use the _999_ compression routine which gives better compression + * rates at the expense of time. Decompression time is unaffected. We might as + * well use the standard lzo library routines for this but they will overflow + * the destination buffer since they don't check the destination size. + * + * We therefore compress to a temporary buffer and copy if it will fit. + * + */ +static int jffs2_lzo_cmpr(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, void *model) +{ + uint32_t compress_size; + int ret; + + ret = lzo1x_999_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); + + if (ret != LZO_E_OK) + return -1; + + if (compress_size > *dstlen) + return -1; + + memcpy(cpage_out, lzo_compress_buf, compress_size); + *dstlen = compress_size; + + return 0; +} + +static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) +{ + int ret; + uint32_t dl; + + ret = lzo1x_decompress_safe(data_in,srclen,cpage_out,&dl,NULL); + + if (ret != LZO_E_OK || dl != destlen) + return -1; + + return 0; +} + +static struct jffs2_compressor jffs2_lzo_comp = { + .priority = JFFS2_LZO_PRIORITY, + .name = "lzo", + .compr = JFFS2_COMPR_LZO, + .compress = &jffs2_lzo_cmpr, + .decompress = &jffs2_lzo_decompress, + .disabled = 1, +}; + +int jffs2_lzo_init(void) +{ + int ret; + + lzo_mem = malloc(LZO1X_999_MEM_COMPRESS); + if (!lzo_mem) + return -1; + + /* Worse case LZO compression size from their FAQ */ + lzo_compress_buf = malloc(page_size + (page_size / 16) + 64 + 3); + if (!lzo_compress_buf) { + free(lzo_mem); + return -1; + } + + ret = jffs2_register_compressor(&jffs2_lzo_comp); + if (ret < 0) { + free(lzo_compress_buf); + free(lzo_mem); + } + + return ret; +} + +void jffs2_lzo_exit(void) +{ + jffs2_unregister_compressor(&jffs2_lzo_comp); + free(lzo_compress_buf); + free(lzo_mem); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_rtime.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_rtime.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_rtime.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_rtime.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,119 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001-2003 Red Hat, Inc. + * + * Created by Arjan van de Ven + * + * For licensing information, see the file 'LICENCE' in this directory. + * + * Very simple lz77-ish encoder. + * + * Theory of operation: Both encoder and decoder have a list of "last + * occurrences" for every possible source-value; after sending the + * first source-byte, the second byte indicated the "run" length of + * matches + * + * The algorithm is intended to only send "whole bytes", no bit-messing. + * + */ + +#include +#include +#include "compr.h" + +/* _compress returns the compressed size, -1 if bigger */ +static int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, void *model) +{ + short positions[256]; + int outpos = 0; + int pos=0; + + memset(positions,0,sizeof(positions)); + + while (pos < (*sourcelen) && outpos <= (*dstlen)-2) { + int backpos, runlen=0; + unsigned char value; + + value = data_in[pos]; + + cpage_out[outpos++] = data_in[pos++]; + + backpos = positions[value]; + positions[value]=pos; + + while ((backpos < pos) && (pos < (*sourcelen)) && + (data_in[pos]==data_in[backpos++]) && (runlen<255)) { + pos++; + runlen++; + } + cpage_out[outpos++] = runlen; + } + + if (outpos >= pos) { + /* We failed */ + return -1; + } + + /* Tell the caller how much we managed to compress, and how much space it took */ + *sourcelen = pos; + *dstlen = outpos; + return 0; +} + + +static int jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) +{ + short positions[256]; + int outpos = 0; + int pos=0; + + memset(positions,0,sizeof(positions)); + + while (outpos= outpos) { + while(repeat) { + cpage_out[outpos++] = cpage_out[backoffs++]; + repeat--; + } + } else { + memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat); + outpos+=repeat; + } + } + } + return 0; +} + + +static struct jffs2_compressor jffs2_rtime_comp = { + .priority = JFFS2_RTIME_PRIORITY, + .name = "rtime", + .disabled = 0, + .compr = JFFS2_COMPR_RTIME, + .compress = &jffs2_rtime_compress, + .decompress = &jffs2_rtime_decompress, +}; + +int jffs2_rtime_init(void) +{ + return jffs2_register_compressor(&jffs2_rtime_comp); +} + +void jffs2_rtime_exit(void) +{ + jffs2_unregister_compressor(&jffs2_rtime_comp); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_zlib.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_zlib.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/compr_zlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/compr_zlib.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,145 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by David Woodhouse + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + */ + +#include +#include +#include +#include +#include +#include "compr.h" + +#define min(x,y) ((x)<(y)?(x):(y)) + +/* Plan: call deflate() with avail_in == *sourcelen, + avail_out = *dstlen - 12 and flush == Z_FINISH. + If it doesn't manage to finish, call it again with + avail_in == 0 and avail_out set to the remaining 12 + bytes for it to clean up. +Q: Is 12 bytes sufficient? + */ +#define STREAM_END_SPACE 12 + +int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, void *model) +{ + z_stream strm; + int ret; + + if (*dstlen <= STREAM_END_SPACE) + return -1; + + strm.zalloc = (void *)0; + strm.zfree = (void *)0; + + if (Z_OK != deflateInit(&strm, 3)) { + return -1; + } + strm.next_in = data_in; + strm.total_in = 0; + + strm.next_out = cpage_out; + strm.total_out = 0; + + while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) { + strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE); + strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out); + ret = deflate(&strm, Z_PARTIAL_FLUSH); + if (ret != Z_OK) { + deflateEnd(&strm); + return -1; + } + } + strm.avail_out += STREAM_END_SPACE; + strm.avail_in = 0; + ret = deflate(&strm, Z_FINISH); + if (ret != Z_STREAM_END) { + deflateEnd(&strm); + return -1; + } + deflateEnd(&strm); + + if (strm.total_out >= strm.total_in) + return -1; + + + *dstlen = strm.total_out; + *sourcelen = strm.total_in; + return 0; +} + +int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) +{ + z_stream strm; + int ret; + + strm.zalloc = (void *)0; + strm.zfree = (void *)0; + + if (Z_OK != inflateInit(&strm)) { + return 1; + } + strm.next_in = data_in; + strm.avail_in = srclen; + strm.total_in = 0; + + strm.next_out = cpage_out; + strm.avail_out = destlen; + strm.total_out = 0; + + while((ret = inflate(&strm, Z_FINISH)) == Z_OK) + ; + + inflateEnd(&strm); + return 0; +} + +static struct jffs2_compressor jffs2_zlib_comp = { + .priority = JFFS2_ZLIB_PRIORITY, + .name = "zlib", + .disabled = 0, + .compr = JFFS2_COMPR_ZLIB, + .compress = &jffs2_zlib_compress, + .decompress = &jffs2_zlib_decompress, +}; + +int jffs2_zlib_init(void) +{ + return jffs2_register_compressor(&jffs2_zlib_comp); +} + +void jffs2_zlib_exit(void) +{ + jffs2_unregister_compressor(&jffs2_zlib_comp); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/COPYING linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/COPYING --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/COPYING 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/COPYING 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/crc32.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/crc32.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/crc32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/crc32.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,95 @@ +/* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + */ + +#include + +const uint32_t crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/crc32.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/crc32.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/crc32.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/crc32.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,19 @@ +#ifndef CRC32_H +#define CRC32_H + +#include + +extern const uint32_t crc32_table[256]; + +/* Return a 32-bit CRC of the contents of the buffer. */ + + static inline uint32_t +crc32(uint32_t val, const void *ss, int len) +{ + const unsigned char *s = ss; + while (--len >= 0) + val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8); + return val; +} + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/device_table.txt linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/device_table.txt --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/device_table.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/device_table.txt 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,129 @@ +# This is a sample device table file for use with mkfs.jffs2. You can +# do all sorts of interesting things with a device table file. For +# example, if you want to adjust the permissions on a particular file +# you can just add an entry like: +# /sbin/foobar f 2755 0 0 - - - - - +# and (assuming the file /sbin/foobar exists) it will be made setuid +# root (regardless of what its permissions are on the host filesystem. +# +# Device table entries take the form of: +# +# where name is the file name, type can be one of: +# f A regular file +# d Directory +# c Character special device file +# b Block special device file +# p Fifo (named pipe) +# uid is the user id for the target file, gid is the group id for the +# target file. The rest of the entried apply only to device special +# file. + +# When building a target filesystem, it is desirable to not have to +# become root and then run 'mknod' a thousand times. Using a device +# table you can create device nodes and directories "on the fly". +# Furthermore, you can use a single table entry to create a many device +# minors. For example, if I wanted to create /dev/hda and /dev/hda[0-15] +# I could just use the following two table entries: +# /dev/hda b 640 0 0 3 0 0 0 - +# /dev/hda b 640 0 0 3 1 1 1 15 +# +# Have fun +# -Erik Andersen +# + +# +/dev d 755 0 0 - - - - - +/dev/mem c 640 0 0 1 1 0 0 - +/dev/kmem c 640 0 0 1 2 0 0 - +/dev/null c 640 0 0 1 3 0 0 - +/dev/zero c 640 0 0 1 5 0 0 - +/dev/random c 640 0 0 1 8 0 0 - +/dev/urandom c 640 0 0 1 9 0 0 - +/dev/tty c 666 0 0 5 0 0 0 - +/dev/tty c 666 0 0 4 0 0 1 6 +/dev/console c 640 0 0 5 1 0 0 - +/dev/ram b 640 0 0 1 1 0 0 - +/dev/ram b 640 0 0 1 0 0 1 4 +/dev/loop b 640 0 0 7 0 0 1 2 +/dev/ptmx c 666 0 0 5 2 0 0 - +#/dev/ttyS c 640 0 0 4 64 0 1 4 +#/dev/psaux c 640 0 0 10 1 0 0 - +#/dev/rtc c 640 0 0 10 135 0 0 - + +# Adjust permissions on some normal files +#/etc/shadow f 600 0 0 - - - - - +#/bin/tinylogin f 4755 0 0 - - - - - + +# User-mode Linux stuff +/dev/ubda b 640 0 0 98 0 0 0 - +/dev/ubda b 640 0 0 98 1 1 1 15 + +# IDE Devices +/dev/hda b 640 0 0 3 0 0 0 - +/dev/hda b 640 0 0 3 1 1 1 15 +/dev/hdb b 640 0 0 3 64 0 0 - +/dev/hdb b 640 0 0 3 65 1 1 15 +#/dev/hdc b 640 0 0 22 0 0 0 - +#/dev/hdc b 640 0 0 22 1 1 1 15 +#/dev/hdd b 640 0 0 22 64 0 0 - +#/dev/hdd b 640 0 0 22 65 1 1 15 +#/dev/hde b 640 0 0 33 0 0 0 - +#/dev/hde b 640 0 0 33 1 1 1 15 +#/dev/hdf b 640 0 0 33 64 0 0 - +#/dev/hdf b 640 0 0 33 65 1 1 15 +#/dev/hdg b 640 0 0 34 0 0 0 - +#/dev/hdg b 640 0 0 34 1 1 1 15 +#/dev/hdh b 640 0 0 34 64 0 0 - +#/dev/hdh b 640 0 0 34 65 1 1 15 + +# SCSI Devices +#/dev/sda b 640 0 0 8 0 0 0 - +#/dev/sda b 640 0 0 8 1 1 1 15 +#/dev/sdb b 640 0 0 8 16 0 0 - +#/dev/sdb b 640 0 0 8 17 1 1 15 +#/dev/sdc b 640 0 0 8 32 0 0 - +#/dev/sdc b 640 0 0 8 33 1 1 15 +#/dev/sdd b 640 0 0 8 48 0 0 - +#/dev/sdd b 640 0 0 8 49 1 1 15 +#/dev/sde b 640 0 0 8 64 0 0 - +#/dev/sde b 640 0 0 8 65 1 1 15 +#/dev/sdf b 640 0 0 8 80 0 0 - +#/dev/sdf b 640 0 0 8 81 1 1 15 +#/dev/sdg b 640 0 0 8 96 0 0 - +#/dev/sdg b 640 0 0 8 97 1 1 15 +#/dev/sdh b 640 0 0 8 112 0 0 - +#/dev/sdh b 640 0 0 8 113 1 1 15 +#/dev/sg c 640 0 0 21 0 0 1 15 +#/dev/scd b 640 0 0 11 0 0 1 15 +#/dev/st c 640 0 0 9 0 0 1 8 +#/dev/nst c 640 0 0 9 128 0 1 8 +#/dev/st c 640 0 0 9 32 1 1 4 +#/dev/st c 640 0 0 9 64 1 1 4 +#/dev/st c 640 0 0 9 96 1 1 4 + +# Floppy disk devices +#/dev/fd b 640 0 0 2 0 0 1 2 +#/dev/fd0d360 b 640 0 0 2 4 0 0 - +#/dev/fd1d360 b 640 0 0 2 5 0 0 - +#/dev/fd0h1200 b 640 0 0 2 8 0 0 - +#/dev/fd1h1200 b 640 0 0 2 9 0 0 - +#/dev/fd0u1440 b 640 0 0 2 28 0 0 - +#/dev/fd1u1440 b 640 0 0 2 29 0 0 - +#/dev/fd0u2880 b 640 0 0 2 32 0 0 - +#/dev/fd1u2880 b 640 0 0 2 33 0 0 - + +# All the proprietary cdrom devices in the world +#/dev/aztcd b 640 0 0 29 0 0 0 - +#/dev/bpcd b 640 0 0 41 0 0 0 - +#/dev/capi20 c 640 0 0 68 0 0 1 2 +#/dev/cdu31a b 640 0 0 15 0 0 0 - +#/dev/cdu535 b 640 0 0 24 0 0 0 - +#/dev/cm206cd b 640 0 0 32 0 0 0 - +#/dev/sjcd b 640 0 0 18 0 0 0 - +#/dev/sonycd b 640 0 0 15 0 0 0 - +#/dev/gscd b 640 0 0 16 0 0 0 - +#/dev/sbpcd b 640 0 0 25 0 0 0 - +#/dev/sbpcd b 640 0 0 25 0 0 1 4 +#/dev/mcd b 640 0 0 23 0 0 0 - +#/dev/optcd b 640 0 0 17 0 0 0 - + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/docfdisk.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/docfdisk.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/docfdisk.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/docfdisk.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,317 @@ +/* + * docfdisk.c: Modify INFTL partition tables + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _XOPEN_SOURCE 500 /* for pread/pwrite */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +unsigned char *buf; + +mtd_info_t meminfo; +erase_info_t erase; +int fd; +struct INFTLMediaHeader *mh; + +#define MAXSCAN 10 + +void show_header(int mhoffs) { + int i, unitsize, numunits, bmbits, numpart; + int start, end, num, nextunit; + unsigned int flags; + struct INFTLPartition *ip; + + bmbits = le32_to_cpu(mh->BlockMultiplierBits); + printf(" bootRecordID = %s\n" + " NoOfBootImageBlocks = %d\n" + " NoOfBinaryPartitions = %d\n" + " NoOfBDTLPartitions = %d\n" + " BlockMultiplierBits = %d\n" + " FormatFlags = %d\n" + " OsakVersion = %d.%d.%d.%d\n" + " PercentUsed = %d\n", + mh->bootRecordID, le32_to_cpu(mh->NoOfBootImageBlocks), + le32_to_cpu(mh->NoOfBinaryPartitions), + le32_to_cpu(mh->NoOfBDTLPartitions), + bmbits, + le32_to_cpu(mh->FormatFlags), + ((unsigned char *) &mh->OsakVersion)[0] & 0xf, + ((unsigned char *) &mh->OsakVersion)[1] & 0xf, + ((unsigned char *) &mh->OsakVersion)[2] & 0xf, + ((unsigned char *) &mh->OsakVersion)[3] & 0xf, + le32_to_cpu(mh->PercentUsed)); + + numpart = le32_to_cpu(mh->NoOfBinaryPartitions) + + le32_to_cpu(mh->NoOfBDTLPartitions); + unitsize = meminfo.erasesize >> bmbits; + numunits = meminfo.size / unitsize; + nextunit = mhoffs / unitsize; + nextunit++; + printf("Unitsize is %d bytes. Device has %d units.\n", + unitsize, numunits); + if (numunits > 32768) { + printf("WARNING: More than 32768 units! Unexpectedly small BlockMultiplierBits.\n"); + } + if (bmbits && (numunits <= 16384)) { + printf("NOTICE: Unexpectedly large BlockMultiplierBits.\n"); + } + for (i = 0; i < 4; i++) { + ip = &(mh->Partitions[i]); + flags = le32_to_cpu(ip->flags); + start = le32_to_cpu(ip->firstUnit); + end = le32_to_cpu(ip->lastUnit); + num = le32_to_cpu(ip->virtualUnits); + if (start < nextunit) { + printf("ERROR: Overlapping or misordered partitions!\n"); + } + if (start > nextunit) { + printf(" Unpartitioned space: %d bytes\n" + " virtualUnits = %d\n" + " firstUnit = %d\n" + " lastUnit = %d\n", + (start - nextunit) * unitsize, start - nextunit, + nextunit, start - 1); + } + if (flags & INFTL_BINARY) + printf(" Partition %d (BDK):", i+1); + else + printf(" Partition %d (BDTL):", i+1); + printf(" %d bytes\n" + " virtualUnits = %d\n" + " firstUnit = %d\n" + " lastUnit = %d\n" + " flags = 0x%x\n" + " spareUnits = %d\n", + num * unitsize, num, start, end, + le32_to_cpu(ip->flags), le32_to_cpu(ip->spareUnits)); + if (num > (1 + end - start)) { + printf("ERROR: virtualUnits not consistent with first/lastUnit!\n"); + } + end++; + if (end > nextunit) + nextunit = end; + if (flags & INFTL_LAST) + break; + } + if (i >= 4) { + printf("Odd. Last partition was not marked with INFTL_LAST.\n"); + i--; + } + if ((i+1) != numpart) { + printf("ERROR: Number of partitions != (NoOfBinaryPartitions + NoOfBDTLPartitions)\n"); + } + if (nextunit > numunits) { + printf("ERROR: Partitions appear to extend beyond end of device!\n"); + } + if (nextunit < numunits) { + printf(" Unpartitioned space: %d bytes\n" + " virtualUnits = %d\n" + " firstUnit = %d\n" + " lastUnit = %d\n", + (numunits - nextunit) * unitsize, numunits - nextunit, + nextunit, numunits - 1); + } +} + + +int main(int argc, char **argv) +{ + int ret, i, mhblock, unitsize, block; + unsigned int nblocks[4], npart; + unsigned int totblocks; + struct INFTLPartition *ip; + unsigned char *oobbuf; + struct mtd_oob_buf oob; + char line[20]; + int mhoffs; + struct INFTLMediaHeader *mh2; + + if (argc < 2) { + printf( + "Usage: %s [ [ [ [ 4) { + printf("Max 4 partitions allowed.\n"); + return 1; + } + + for (i = 0; i < npart; i++) { + nblocks[i] = strtoul(argv[2+i], NULL, 0); + if (i && !nblocks[i-1]) { + printf("No sizes allowed after 0\n"); + return 1; + } + } + + // Open and size the device + if ((fd = open(argv[1], O_RDWR)) < 0) { + perror("Open flash device"); + return 1; + } + + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("ioctl(MEMGETINFO)"); + return 1; + } + + printf("Device size is %d bytes. Erasesize is %d bytes.\n", + meminfo.size, meminfo.erasesize); + + buf = malloc(meminfo.erasesize); + oobbuf = malloc((meminfo.erasesize / meminfo.writesize) * meminfo.oobsize); + if (!buf || !oobbuf) { + printf("Can't malloc block buffer\n"); + return 1; + } + oob.length = meminfo.oobsize; + + mh = (struct INFTLMediaHeader *) buf; + + for (mhblock = 0; mhblock < MAXSCAN; mhblock++) { + if ((ret = pread(fd, buf, meminfo.erasesize, mhblock * meminfo.erasesize)) < 0) { + if (errno == EBADMSG) { + printf("ECC error at eraseblock %d\n", mhblock); + continue; + } + perror("Read eraseblock"); + return 1; + } + if (ret != meminfo.erasesize) { + printf("Short read!\n"); + return 1; + } + if (!strcmp("BNAND", mh->bootRecordID)) break; + } + if (mhblock >= MAXSCAN) { + printf("Unable to find INFTL Media Header\n"); + return 1; + } + printf("Found INFTL Media Header at block %d:\n", mhblock); + mhoffs = mhblock * meminfo.erasesize; + + oob.ptr = oobbuf; + oob.start = mhoffs; + for (i = 0; i < meminfo.erasesize; i += meminfo.writesize) { + if (ioctl(fd, MEMREADOOB, &oob)) { + perror("ioctl(MEMREADOOB)"); + return 1; + } + oob.start += meminfo.writesize; + oob.ptr += meminfo.oobsize; + } + + show_header(mhoffs); + + if (!npart) + return 0; + + printf("\n" + "-------------------------------------------------------------------------\n"); + + unitsize = meminfo.erasesize >> le32_to_cpu(mh->BlockMultiplierBits); + totblocks = meminfo.size / unitsize; + block = mhoffs / unitsize; + block++; + + mh->NoOfBDTLPartitions = 0; + mh->NoOfBinaryPartitions = npart; + + for (i = 0; i < npart; i++) { + ip = &(mh->Partitions[i]); + ip->firstUnit = cpu_to_le32(block); + if (!nblocks[i]) + nblocks[i] = totblocks - block; + ip->virtualUnits = cpu_to_le32(nblocks[i]); + block += nblocks[i]; + ip->lastUnit = cpu_to_le32(block-1); + ip->spareUnits = 0; + ip->flags = cpu_to_le32(INFTL_BINARY); + } + if (block > totblocks) { + printf("Requested partitions extend beyond end of device.\n"); + return 1; + } + ip->flags = cpu_to_le32(INFTL_BINARY | INFTL_LAST); + + /* update the spare as well */ + mh2 = (struct INFTLMediaHeader *) (buf + 4096); + memcpy((void *) mh2, (void *) mh, sizeof(struct INFTLMediaHeader)); + + printf("\nProposed new Media Header:\n"); + show_header(mhoffs); + + printf("\nReady to update device. Type 'yes' to proceed, anything else to abort: "); + fgets(line, sizeof(line), stdin); + if (strcmp("yes\n", line)) + return 0; + printf("Updating MediaHeader...\n"); + + erase.start = mhoffs; + erase.length = meminfo.erasesize; + if (ioctl(fd, MEMERASE, &erase)) { + perror("ioctl(MEMERASE)"); + printf("Your MediaHeader may be hosed. UHOH!\n"); + return 1; + } + + oob.ptr = oobbuf; + oob.start = mhoffs; + for (i = 0; i < meminfo.erasesize; i += meminfo.writesize) { + memset(oob.ptr, 0xff, 6); // clear ECC. + if (ioctl(fd, MEMWRITEOOB, &oob)) { + perror("ioctl(MEMWRITEOOB)"); + printf("Your MediaHeader may be hosed. UHOH!\n"); + return 1; + } + if ((ret = pwrite(fd, buf, meminfo.writesize, oob.start)) < 0) { + perror("Write page"); + printf("Your MediaHeader may be hosed. UHOH!\n"); + return 1; + } + if (ret != meminfo.writesize) { + printf("Short write!\n"); + printf("Your MediaHeader may be hosed. UHOH!\n"); + return 1; + } + + oob.start += meminfo.writesize; + oob.ptr += meminfo.oobsize; + buf += meminfo.writesize; + } + + printf("Success. REBOOT or unload the diskonchip module to update partitions!\n"); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/doc_loadbios.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/doc_loadbios.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/doc_loadbios.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/doc_loadbios.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +unsigned char databuf[512]; + +int main(int argc,char **argv) +{ + mtd_info_t meminfo; + int ifd,ofd; + struct stat statbuf; + erase_info_t erase; + unsigned long retlen, ofs, iplsize, ipltailsize; + unsigned char *iplbuf; + iplbuf = NULL; + + if (argc < 3) { + fprintf(stderr,"You must specify a device," + " the source firmware file and the offset\n"); + return 1; + } + + // Open and size the device + if ((ofd = open(argv[1],O_RDWR)) < 0) { + perror("Open flash device"); + return 1; + } + + if ((ifd = open(argv[2], O_RDONLY)) < 0) { + perror("Open firmware file\n"); + close(ofd); + return 1; + } + + if (fstat(ifd, &statbuf) != 0) { + perror("Stat firmware file"); + goto error; + } + +#if 0 + if (statbuf.st_size > 65536) { + printf("Firmware too large (%ld bytes)\n",statbuf.st_size); + goto error; + } +#endif + + if (ioctl(ofd,MEMGETINFO,&meminfo) != 0) { + perror("ioctl(MEMGETINFO)"); + goto error; + } + + iplsize = (ipltailsize = 0); + if (argc >= 4) { + /* DoC Millennium has IPL in the first 1K of flash memory */ + /* You may want to specify the offset 1024 to store + the firmware next to IPL. */ + iplsize = strtoul(argv[3], NULL, 0); + ipltailsize = iplsize % meminfo.erasesize; + } + + if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) { + perror("lseek"); + goto error; + } + + if (ipltailsize) { + iplbuf = malloc(ipltailsize); + if (iplbuf == NULL) { + fprintf(stderr, "Not enough memory for IPL tail buffer of" + " %lu bytes\n", (unsigned long) ipltailsize); + goto error; + } + printf("Reading IPL%s area of length %lu at offset %lu\n", + (iplsize - ipltailsize) ? " tail" : "", + (long unsigned) ipltailsize, + (long unsigned) (iplsize - ipltailsize)); + if (read(ofd, iplbuf, ipltailsize) != ipltailsize) { + perror("read"); + goto error; + } + } + + erase.length = meminfo.erasesize; + + for (ofs = iplsize - ipltailsize ; + ofs < iplsize + statbuf.st_size ; + ofs += meminfo.erasesize) { + erase.start = ofs; + printf("Performing Flash Erase of length %lu at offset %lu\n", + (long unsigned) erase.length, (long unsigned) erase.start); + + if (ioctl(ofd,MEMERASE,&erase) != 0) { + perror("ioctl(MEMERASE)"); + goto error; + } + } + + if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) { + perror("lseek"); + goto error; + } + + if (ipltailsize) { + printf("Writing IPL%s area of length %lu at offset %lu\n", + (iplsize - ipltailsize) ? " tail" : "", + (long unsigned) ipltailsize, + (long unsigned) (iplsize - ipltailsize)); + if (write(ofd, iplbuf, ipltailsize) != ipltailsize) { + perror("write"); + goto error; + } + } + + printf("Writing the firmware of length %lu at %lu... ", + (unsigned long) statbuf.st_size, + (unsigned long) iplsize); + do { + retlen = read(ifd, databuf, 512); + if (retlen < 512) + memset(databuf+retlen, 0xff, 512-retlen); + if (write(ofd, databuf, 512) != 512) { + perror("write"); + goto error; + } + } while (retlen == 512); + printf("Done.\n"); + + if (iplbuf != NULL) + free(iplbuf); + close(ifd); + close(ofd); + return 0; + +error: + if (iplbuf != NULL) + free(iplbuf); + close(ifd); + close(ofd); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/feature-removal-schedule.txt linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/feature-removal-schedule.txt --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/feature-removal-schedule.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/feature-removal-schedule.txt 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,9 @@ +The following is a list of files and features that are going to be +removed in the mtd-utils source tree. Every entry should contain what +exactly is going away, why it is happening, and who is going to be doing +the work. When the feature is removed from the utils, it should also +be removed from this file. + +--------------------------- + +--------------------------- diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/fec.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/fec.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/fec.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/fec.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,917 @@ +/* + * fec.c -- forward error correction based on Vandermonde matrices + * 980624 + * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) + * + * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), + * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari + * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * The following parameter defines how many bits are used for + * field elements. The code supports any value from 2 to 16 + * but fastest operation is achieved with 8 bit elements + * This is the only parameter you may want to change. + */ +#ifndef GF_BITS +#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ +#endif + +#include +#include +#include + +/* + * compatibility stuff + */ +#ifdef MSDOS /* but also for others, e.g. sun... */ +#define NEED_BCOPY +#define bcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifdef NEED_BCOPY +#define bcopy(s, d, siz) memcpy((d), (s), (siz)) +#define bzero(d, siz) memset((d), '\0', (siz)) +#endif + +/* + * stuff used for testing purposes only + */ + +#ifdef TEST +#define DEB(x) +#define DDB(x) x +#define DEBUG 0 /* minimal debugging */ +#ifdef MSDOS +#include +struct timeval { + unsigned long ticks; +}; +#define gettimeofday(x, dummy) { (x)->ticks = clock() ; } +#define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC ) +typedef unsigned long u_long ; +typedef unsigned short u_short ; +#else /* typically, unix systems */ +#include +#define DIFF_T(a,b) \ + (1+ 1000000*(a.tv_sec - b.tv_sec) + (a.tv_usec - b.tv_usec) ) +#endif + +#define TICK(t) \ + {struct timeval x ; \ + gettimeofday(&x, NULL) ; \ + t = x.tv_usec + 1000000* (x.tv_sec & 0xff ) ; \ + } +#define TOCK(t) \ + { u_long t1 ; TICK(t1) ; \ + if (t1 < t) t = 256000000 + t1 - t ; \ + else t = t1 - t ; \ + if (t == 0) t = 1 ;} + +u_long ticks[10]; /* vars for timekeeping */ +#else +#define DEB(x) +#define DDB(x) +#define TICK(x) +#define TOCK(x) +#endif /* TEST */ + +/* + * You should not need to change anything beyond this point. + * The first part of the file implements linear algebra in GF. + * + * gf is the type used to store an element of the Galois Field. + * Must constain at least GF_BITS bits. + * + * Note: unsigned char will work up to GF(256) but int seems to run + * faster on the Pentium. We use int whenever have to deal with an + * index, since they are generally faster. + */ +#if (GF_BITS < 2 && GF_BITS >16) +#error "GF_BITS must be 2 .. 16" +#endif +#if (GF_BITS <= 8) +typedef unsigned char gf; +#else +typedef unsigned short gf; +#endif + +#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ + +/* + * Primitive polynomials - see Lin & Costello, Appendix A, + * and Lee & Messerschmitt, p. 453. + */ +static char *allPp[] = { /* GF_BITS polynomial */ + NULL, /* 0 no code */ + NULL, /* 1 no code */ + "111", /* 2 1+x+x^2 */ + "1101", /* 3 1+x+x^3 */ + "11001", /* 4 1+x+x^4 */ + "101001", /* 5 1+x^2+x^5 */ + "1100001", /* 6 1+x+x^6 */ + "10010001", /* 7 1 + x^3 + x^7 */ + "101110001", /* 8 1+x^2+x^3+x^4+x^8 */ + "1000100001", /* 9 1+x^4+x^9 */ + "10010000001", /* 10 1+x^3+x^10 */ + "101000000001", /* 11 1+x^2+x^11 */ + "1100101000001", /* 12 1+x+x^4+x^6+x^12 */ + "11011000000001", /* 13 1+x+x^3+x^4+x^13 */ + "110000100010001", /* 14 1+x+x^6+x^10+x^14 */ + "1100000000000001", /* 15 1+x+x^15 */ + "11010000000010001" /* 16 1+x+x^3+x^12+x^16 */ +}; + + +/* + * To speed up computations, we have tables for logarithm, exponent + * and inverse of a number. If GF_BITS <= 8, we use a table for + * multiplication as well (it takes 64K, no big deal even on a PDA, + * especially because it can be pre-initialized an put into a ROM!), + * otherwhise we use a table of logarithms. + * In any case the macro gf_mul(x,y) takes care of multiplications. + */ + +static gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */ +static int gf_log[GF_SIZE + 1]; /* Poly->index form conversion table */ +static gf inverse[GF_SIZE+1]; /* inverse of field elem. */ + /* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */ + +/* + * modnn(x) computes x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, + * without a slow divide. + */ +static inline gf +modnn(int x) +{ + while (x >= GF_SIZE) { + x -= GF_SIZE; + x = (x >> GF_BITS) + (x & GF_SIZE); + } + return x; +} + +#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;} + +/* + * gf_mul(x,y) multiplies two numbers. If GF_BITS<=8, it is much + * faster to use a multiplication table. + * + * USE_GF_MULC, GF_MULC0(c) and GF_ADDMULC(x) can be used when multiplying + * many numbers by the same constant. In this case the first + * call sets the constant, and others perform the multiplications. + * A value related to the multiplication is held in a local variable + * declared with USE_GF_MULC . See usage in addmul1(). + */ +#if (GF_BITS <= 8) +static gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1]; + +#define gf_mul(x,y) gf_mul_table[x][y] + +#define USE_GF_MULC register gf * __gf_mulc_ +#define GF_MULC0(c) __gf_mulc_ = gf_mul_table[c] +#define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x] + +static void +init_mul_table() +{ + int i, j; + for (i=0; i< GF_SIZE+1; i++) + for (j=0; j< GF_SIZE+1; j++) + gf_mul_table[i][j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ; + + for (j=0; j< GF_SIZE+1; j++) + gf_mul_table[0][j] = gf_mul_table[j][0] = 0; +} +#else /* GF_BITS > 8 */ +static inline gf +gf_mul(x,y) +{ + if ( (x) == 0 || (y)==0 ) return 0; + + return gf_exp[gf_log[x] + gf_log[y] ] ; +} +#define init_mul_table() + +#define USE_GF_MULC register gf * __gf_mulc_ +#define GF_MULC0(c) __gf_mulc_ = &gf_exp[ gf_log[c] ] +#define GF_ADDMULC(dst, x) { if (x) dst ^= __gf_mulc_[ gf_log[x] ] ; } +#endif + +/* + * Generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m] + * Lookup tables: + * index->polynomial form gf_exp[] contains j= \alpha^i; + * polynomial form -> index form gf_log[ j = \alpha^i ] = i + * \alpha=x is the primitive element of GF(2^m) + * + * For efficiency, gf_exp[] has size 2*GF_SIZE, so that a simple + * multiplication of two numbers can be resolved without calling modnn + */ + +/* + * i use malloc so many times, it is easier to put checks all in + * one place. + */ +static void * +my_malloc(int sz, char *err_string) +{ + void *p = malloc( sz ); + if (p == NULL) { + fprintf(stderr, "-- malloc failure allocating %s\n", err_string); + exit(1) ; + } + return p ; +} + +#define NEW_GF_MATRIX(rows, cols) \ + (gf *)my_malloc(rows * cols * sizeof(gf), " ## __LINE__ ## " ) + +/* + * initialize the data structures used for computations in GF. + */ +static void +generate_gf(void) +{ + int i; + gf mask; + char *Pp = allPp[GF_BITS] ; + + mask = 1; /* x ** 0 = 1 */ + gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */ + /* + * first, generate the (polynomial representation of) powers of \alpha, + * which are stored in gf_exp[i] = \alpha ** i . + * At the same time build gf_log[gf_exp[i]] = i . + * The first GF_BITS powers are simply bits shifted to the left. + */ + for (i = 0; i < GF_BITS; i++, mask <<= 1 ) { + gf_exp[i] = mask; + gf_log[gf_exp[i]] = i; + /* + * If Pp[i] == 1 then \alpha ** i occurs in poly-repr + * gf_exp[GF_BITS] = \alpha ** GF_BITS + */ + if ( Pp[i] == '1' ) + gf_exp[GF_BITS] ^= mask; + } + /* + * now gf_exp[GF_BITS] = \alpha ** GF_BITS is complete, so can als + * compute its inverse. + */ + gf_log[gf_exp[GF_BITS]] = GF_BITS; + /* + * Poly-repr of \alpha ** (i+1) is given by poly-repr of + * \alpha ** i shifted left one-bit and accounting for any + * \alpha ** GF_BITS term that may occur when poly-repr of + * \alpha ** i is shifted. + */ + mask = 1 << (GF_BITS - 1 ) ; + for (i = GF_BITS + 1; i < GF_SIZE; i++) { + if (gf_exp[i - 1] >= mask) + gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1); + else + gf_exp[i] = gf_exp[i - 1] << 1; + gf_log[gf_exp[i]] = i; + } + /* + * log(0) is not defined, so use a special value + */ + gf_log[0] = GF_SIZE ; + /* set the extended gf_exp values for fast multiply */ + for (i = 0 ; i < GF_SIZE ; i++) + gf_exp[i + GF_SIZE] = gf_exp[i] ; + + /* + * again special cases. 0 has no inverse. This used to + * be initialized to GF_SIZE, but it should make no difference + * since noone is supposed to read from here. + */ + inverse[0] = 0 ; + inverse[1] = 1; + for (i=2; i<=GF_SIZE; i++) + inverse[i] = gf_exp[GF_SIZE-gf_log[i]]; +} + +/* + * Various linear algebra operations that i use often. + */ + +/* + * addmul() computes dst[] = dst[] + c * src[] + * This is used often, so better optimize it! Currently the loop is + * unrolled 16 times, a good value for 486 and pentium-class machines. + * The case c=0 is also optimized, whereas c=1 is not. These + * calls are unfrequent in my typical apps so I did not bother. + * + * Note that gcc on + */ +#define addmul(dst, src, c, sz) \ + if (c != 0) addmul1(dst, src, c, sz) + +#define UNROLL 16 /* 1, 4, 8, 16 */ +static void +addmul1(gf *dst1, gf *src1, gf c, int sz) +{ + USE_GF_MULC ; + register gf *dst = dst1, *src = src1 ; + gf *lim = &dst[sz - UNROLL + 1] ; + + GF_MULC0(c) ; + +#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */ + for (; dst < lim ; dst += UNROLL, src += UNROLL ) { + GF_ADDMULC( dst[0] , src[0] ); + GF_ADDMULC( dst[1] , src[1] ); + GF_ADDMULC( dst[2] , src[2] ); + GF_ADDMULC( dst[3] , src[3] ); +#if (UNROLL > 4) + GF_ADDMULC( dst[4] , src[4] ); + GF_ADDMULC( dst[5] , src[5] ); + GF_ADDMULC( dst[6] , src[6] ); + GF_ADDMULC( dst[7] , src[7] ); +#endif +#if (UNROLL > 8) + GF_ADDMULC( dst[8] , src[8] ); + GF_ADDMULC( dst[9] , src[9] ); + GF_ADDMULC( dst[10] , src[10] ); + GF_ADDMULC( dst[11] , src[11] ); + GF_ADDMULC( dst[12] , src[12] ); + GF_ADDMULC( dst[13] , src[13] ); + GF_ADDMULC( dst[14] , src[14] ); + GF_ADDMULC( dst[15] , src[15] ); +#endif + } +#endif + lim += UNROLL - 1 ; + for (; dst < lim; dst++, src++ ) /* final components */ + GF_ADDMULC( *dst , *src ); +} + +/* + * computes C = AB where A is n*k, B is k*m, C is n*m + */ +static void +matmul(gf *a, gf *b, gf *c, int n, int k, int m) +{ + int row, col, i ; + + for (row = 0; row < n ; row++) { + for (col = 0; col < m ; col++) { + gf *pa = &a[ row * k ]; + gf *pb = &b[ col ]; + gf acc = 0 ; + for (i = 0; i < k ; i++, pa++, pb += m ) + acc ^= gf_mul( *pa, *pb ) ; + c[ row * m + col ] = acc ; + } + } +} + +#ifdef DEBUG +/* + * returns 1 if the square matrix is identiy + * (only for test) + */ +static int +is_identity(gf *m, int k) +{ + int row, col ; + for (row=0; row 1) { + fprintf(stderr, "singular matrix\n"); + goto fail ; + } + } + } + } + if (icol == -1) { + fprintf(stderr, "XXX pivot not found!\n"); + goto fail ; + } +found_piv: + ++(ipiv[icol]) ; + /* + * swap rows irow and icol, so afterwards the diagonal + * element will be correct. Rarely done, not worth + * optimizing. + */ + if (irow != icol) { + for (ix = 0 ; ix < k ; ix++ ) { + SWAP( src[irow*k + ix], src[icol*k + ix], gf) ; + } + } + indxr[col] = irow ; + indxc[col] = icol ; + pivot_row = &src[icol*k] ; + c = pivot_row[icol] ; + if (c == 0) { + fprintf(stderr, "singular matrix 2\n"); + goto fail ; + } + if (c != 1 ) { /* otherwhise this is a NOP */ + /* + * this is done often , but optimizing is not so + * fruitful, at least in the obvious ways (unrolling) + */ + DEB( pivswaps++ ; ) + c = inverse[ c ] ; + pivot_row[icol] = 1 ; + for (ix = 0 ; ix < k ; ix++ ) + pivot_row[ix] = gf_mul(c, pivot_row[ix] ); + } + /* + * from all rows, remove multiples of the selected row + * to zero the relevant entry (in fact, the entry is not zero + * because we know it must be zero). + * (Here, if we know that the pivot_row is the identity, + * we can optimize the addmul). + */ + id_row[icol] = 1; + if (bcmp(pivot_row, id_row, k*sizeof(gf)) != 0) { + for (p = src, ix = 0 ; ix < k ; ix++, p += k ) { + if (ix != icol) { + c = p[icol] ; + p[icol] = 0 ; + addmul(p, pivot_row, c, k ); + } + } + } + id_row[icol] = 0; + } /* done all columns */ + for (col = k-1 ; col >= 0 ; col-- ) { + if (indxr[col] <0 || indxr[col] >= k) + fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]); + else if (indxc[col] <0 || indxc[col] >= k) + fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]); + else + if (indxr[col] != indxc[col] ) { + for (row = 0 ; row < k ; row++ ) { + SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ; + } + } + } + error = 0 ; +fail: + free(indxc); + free(indxr); + free(ipiv); + free(id_row); + free(temp_row); + return error ; +} + +/* + * fast code for inverting a vandermonde matrix. + * XXX NOTE: It assumes that the matrix + * is not singular and _IS_ a vandermonde matrix. Only uses + * the second column of the matrix, containing the p_i's. + * + * Algorithm borrowed from "Numerical recipes in C" -- sec.2.8, but + * largely revised for my purposes. + * p = coefficients of the matrix (p_i) + * q = values of the polynomial (known) + */ + +int +invert_vdm(gf *src, int k) +{ + int i, j, row, col ; + gf *b, *c, *p; + gf t, xx ; + + if (k == 1) /* degenerate case, matrix must be p^0 = 1 */ + return 0 ; + /* + * c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1 + * b holds the coefficient for the matrix inversion + */ + c = NEW_GF_MATRIX(1, k); + b = NEW_GF_MATRIX(1, k); + + p = NEW_GF_MATRIX(1, k); + + for ( j=1, i = 0 ; i < k ; i++, j+=k ) { + c[i] = 0 ; + p[i] = src[j] ; /* p[i] */ + } + /* + * construct coeffs. recursively. We know c[k] = 1 (implicit) + * and start P_0 = x - p_0, then at each stage multiply by + * x - p_i generating P_i = x P_{i-1} - p_i P_{i-1} + * After k steps we are done. + */ + c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */ + for (i = 1 ; i < k ; i++ ) { + gf p_i = p[i] ; /* see above comment */ + for (j = k-1 - ( i - 1 ) ; j < k-1 ; j++ ) + c[j] ^= gf_mul( p_i, c[j+1] ) ; + c[k-1] ^= p_i ; + } + + for (row = 0 ; row < k ; row++ ) { + /* + * synthetic division etc. + */ + xx = p[row] ; + t = 1 ; + b[k-1] = 1 ; /* this is in fact c[k] */ + for (i = k-2 ; i >= 0 ; i-- ) { + b[i] = c[i+1] ^ gf_mul(xx, b[i+1]) ; + t = gf_mul(xx, t) ^ b[i] ; + } + for (col = 0 ; col < k ; col++ ) + src[col*k + row] = gf_mul(inverse[t], b[col] ); + } + free(c) ; + free(b) ; + free(p) ; + return 0 ; +} + +static int fec_initialized = 0 ; +static void +init_fec() +{ + TICK(ticks[0]); + generate_gf(); + TOCK(ticks[0]); + DDB(fprintf(stderr, "generate_gf took %ldus\n", ticks[0]);) + TICK(ticks[0]); + init_mul_table(); + TOCK(ticks[0]); + DDB(fprintf(stderr, "init_mul_table took %ldus\n", ticks[0]);) + fec_initialized = 1 ; +} + +/* + * This section contains the proper FEC encoding/decoding routines. + * The encoding matrix is computed starting with a Vandermonde matrix, + * and then transforming it into a systematic matrix. + */ + +#define FEC_MAGIC 0xFECC0DEC + +struct fec_parms { + u_long magic ; + int k, n ; /* parameters of the code */ + gf *enc_matrix ; +} ; + +void +fec_free(struct fec_parms *p) +{ + if (p==NULL || + p->magic != ( ( (FEC_MAGIC ^ p->k) ^ p->n) ^ (int)(p->enc_matrix)) ) { + fprintf(stderr, "bad parameters to fec_free\n"); + return ; + } + free(p->enc_matrix); + free(p); +} + +/* + * create a new encoder, returning a descriptor. This contains k,n and + * the encoding matrix. + */ +struct fec_parms * +fec_new(int k, int n) +{ + int row, col ; + gf *p, *tmp_m ; + + struct fec_parms *retval ; + + if (fec_initialized == 0) + init_fec(); + + if (k > GF_SIZE + 1 || n > GF_SIZE + 1 || k > n ) { + fprintf(stderr, "Invalid parameters k %d n %d GF_SIZE %d\n", + k, n, GF_SIZE ); + return NULL ; + } + retval = my_malloc(sizeof(struct fec_parms), "new_code"); + retval->k = k ; + retval->n = n ; + retval->enc_matrix = NEW_GF_MATRIX(n, k); + retval->magic = ( ( FEC_MAGIC ^ k) ^ n) ^ (int)(retval->enc_matrix) ; + tmp_m = NEW_GF_MATRIX(n, k); + /* + * fill the matrix with powers of field elements, starting from 0. + * The first row is special, cannot be computed with exp. table. + */ + tmp_m[0] = 1 ; + for (col = 1; col < k ; col++) + tmp_m[col] = 0 ; + for (p = tmp_m + k, row = 0; row < n-1 ; row++, p += k) { + for ( col = 0 ; col < k ; col ++ ) + p[col] = gf_exp[modnn(row*col)]; + } + + /* + * quick code to build systematic matrix: invert the top + * k*k vandermonde matrix, multiply right the bottom n-k rows + * by the inverse, and construct the identity matrix at the top. + */ + TICK(ticks[3]); + invert_vdm(tmp_m, k); /* much faster than invert_mat */ + matmul(tmp_m + k*k, tmp_m, retval->enc_matrix + k*k, n - k, k, k); + /* + * the upper matrix is I so do not bother with a slow multiply + */ + bzero(retval->enc_matrix, k*k*sizeof(gf) ); + for (p = retval->enc_matrix, col = 0 ; col < k ; col++, p += k+1 ) + *p = 1 ; + free(tmp_m); + TOCK(ticks[3]); + + DDB(fprintf(stderr, "--- %ld us to build encoding matrix\n", + ticks[3]);) + DEB(pr_matrix(retval->enc_matrix, n, k, "encoding_matrix");) + return retval ; +} + +/* + * fec_encode accepts as input pointers to n data packets of size sz, + * and produces as output a packet pointed to by fec, computed + * with index "index". + */ +void +fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz) +{ + int i, k = code->k ; + gf *p ; + + if (GF_BITS > 8) + sz /= 2 ; + + if (index < k) + bcopy(src[index], fec, sz*sizeof(gf) ) ; + else if (index < code->n) { + p = &(code->enc_matrix[index*k] ); + bzero(fec, sz*sizeof(gf)); + for (i = 0; i < k ; i++) + addmul(fec, src[i], p[i], sz ) ; + } else + fprintf(stderr, "Invalid index %d (max %d)\n", + index, code->n - 1 ); +} + +void fec_encode_linear(struct fec_parms *code, gf *src, gf *fec, int index, int sz) +{ + int i, k = code->k ; + gf *p ; + + if (GF_BITS > 8) + sz /= 2 ; + + if (index < k) + bcopy(src + (index * sz), fec, sz*sizeof(gf) ) ; + else if (index < code->n) { + p = &(code->enc_matrix[index*k] ); + bzero(fec, sz*sizeof(gf)); + for (i = 0; i < k ; i++) + addmul(fec, src + (i * sz), p[i], sz ) ; + } else + fprintf(stderr, "Invalid index %d (max %d)\n", + index, code->n - 1 ); +} +/* + * shuffle move src packets in their position + */ +static int +shuffle(gf *pkt[], int index[], int k) +{ + int i; + + for ( i = 0 ; i < k ; ) { + if (index[i] >= k || index[i] == i) + i++ ; + else { + /* + * put pkt in the right position (first check for conflicts). + */ + int c = index[i] ; + + if (index[c] == c) { + DEB(fprintf(stderr, "\nshuffle, error at %d\n", i);) + return 1 ; + } + SWAP(index[i], index[c], int) ; + SWAP(pkt[i], pkt[c], gf *) ; + } + } + DEB( /* just test that it works... */ + for ( i = 0 ; i < k ; i++ ) { + if (index[i] < k && index[i] != i) { + fprintf(stderr, "shuffle: after\n"); + for (i=0; ik ; + gf *p, *matrix = NEW_GF_MATRIX(k, k); + + TICK(ticks[9]); + for (i = 0, p = matrix ; i < k ; i++, p += k ) { +#if 1 /* this is simply an optimization, not very useful indeed */ + if (index[i] < k) { + bzero(p, k*sizeof(gf) ); + p[i] = 1 ; + } else +#endif + if (index[i] < code->n ) + bcopy( &(code->enc_matrix[index[i]*k]), p, k*sizeof(gf) ); + else { + fprintf(stderr, "decode: invalid index %d (max %d)\n", + index[i], code->n - 1 ); + free(matrix) ; + return NULL ; + } + } + TICK(ticks[9]); + if (invert_mat(matrix, k)) { + free(matrix); + matrix = NULL ; + } + TOCK(ticks[9]); + return matrix ; +} + +/* + * fec_decode receives as input a vector of packets, the indexes of + * packets, and produces the correct vector as output. + * + * Input: + * code: pointer to code descriptor + * pkt: pointers to received packets. They are modified + * to store the output packets (in place) + * index: pointer to packet indexes (modified) + * sz: size of each packet + */ +int +fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz) +{ + gf *m_dec ; + gf **new_pkt ; + int row, col , k = code->k ; + + if (GF_BITS > 8) + sz /= 2 ; + + if (shuffle(pkt, index, k)) /* error if true */ + return 1 ; + m_dec = build_decode_matrix(code, pkt, index); + + if (m_dec == NULL) + return 1 ; /* error */ + /* + * do the actual decoding + */ + new_pkt = my_malloc (k * sizeof (gf * ), "new pkt pointers" ); + for (row = 0 ; row < k ; row++ ) { + if (index[row] >= k) { + new_pkt[row] = my_malloc (sz * sizeof (gf), "new pkt buffer" ); + bzero(new_pkt[row], sz * sizeof(gf) ) ; + for (col = 0 ; col < k ; col++ ) + addmul(new_pkt[row], pkt[col], m_dec[row*k + col], sz) ; + } + } + /* + * move pkts to their final destination + */ + for (row = 0 ; row < k ; row++ ) { + if (index[row] >= k) { + bcopy(new_pkt[row], pkt[row], sz*sizeof(gf)); + free(new_pkt[row]); + } + } + free(new_pkt); + free(m_dec); + + return 0; +} + +/*********** end of FEC code -- beginning of test code ************/ + +#if (TEST || DEBUG) +void +test_gf() +{ + int i ; + /* + * test gf tables. Sufficiently tested... + */ + for (i=0; i<= GF_SIZE; i++) { + if (gf_exp[gf_log[i]] != i) + fprintf(stderr, "bad exp/log i %d log %d exp(log) %d\n", + i, gf_log[i], gf_exp[gf_log[i]]); + + if (i != 0 && gf_mul(i, inverse[i]) != 1) + fprintf(stderr, "bad mul/inv i %d inv %d i*inv(i) %d\n", + i, inverse[i], gf_mul(i, inverse[i]) ); + if (gf_mul(0,i) != 0) + fprintf(stderr, "bad mul table 0,%d\n",i); + if (gf_mul(i,0) != 0) + fprintf(stderr, "bad mul table %d,0\n",i); + } +} +#endif /* TEST */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/fectest.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/fectest.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/fectest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/fectest.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mcast_image.h" +#include "crc32.h" + +#define ERASE_SIZE 131072 +//#define PKT_SIZE 1400 +#define NR_PKTS ((ERASE_SIZE + PKT_SIZE - 1) / PKT_SIZE) +#define DROPS 8 + +int main(void) +{ + int i, j; + unsigned char buf[NR_PKTS * PKT_SIZE]; + unsigned char pktbuf[(NR_PKTS + DROPS) * PKT_SIZE]; + struct fec_parms *fec; + unsigned char *srcs[NR_PKTS]; + unsigned char *pkt[NR_PKTS + DROPS]; + int pktnr[NR_PKTS + DROPS]; + struct timeval then, now; + + srand(3453); + for (i=0; i < sizeof(buf); i++) + if (i < ERASE_SIZE) + buf[i] = rand(); + else + buf[i] = 0; + + for (i=0; i < NR_PKTS + DROPS; i++) + srcs[i] = buf + (i * PKT_SIZE); + + for (i=0; i < NR_PKTS + DROPS; i++) { + pkt[i] = malloc(PKT_SIZE); + pktnr[i] = -1; + } + fec = fec_new(NR_PKTS, NR_PKTS + DROPS); + if (!fec) { + printf("fec_init() failed\n"); + exit(1); + } + j = 0; + for (i=0; i < NR_PKTS + DROPS; i++) { +#if 1 + if (i == 27 || i == 40 || i == 44 || i == 45 || i == 56 ) + continue; +#endif + if (i == 69 || i == 93 || i == 103) + continue; + fec_encode(fec, srcs, pkt[j], i, PKT_SIZE); + pktnr[j] = i; + j++; + } + gettimeofday(&then, NULL); + if (fec_decode(fec, pkt, pktnr, PKT_SIZE)) { + printf("Decode failed\n"); + exit(1); + } + + for (i=0; i < NR_PKTS; i++) + memcpy(pktbuf + (i*PKT_SIZE), pkt[i], PKT_SIZE); + gettimeofday(&now, NULL); + now.tv_sec -= then.tv_sec; + now.tv_usec -= then.tv_usec; + if (now.tv_usec < 0) { + now.tv_usec += 1000000; + now.tv_sec--; + } + + if (memcmp(pktbuf, buf, ERASE_SIZE)) { + int fd; + printf("Compare failed\n"); + fd = open("before", O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd >= 0) + write(fd, buf, ERASE_SIZE); + close(fd); + fd = open("after", O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (fd >= 0) + write(fd, pktbuf, ERASE_SIZE); + + exit(1); + } + + printf("Decoded in %ld.%06lds\n", now.tv_sec, now.tv_usec); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flashcp.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flashcp.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flashcp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flashcp.c 2010-03-03 19:04:35.000000000 -0800 @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2d3D, Inc. + * Written by Abraham vd Merwe + * All rights reserved. + * + * Renamed to flashcp.c to avoid conflicts with fcp from fsh package + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int bool; +#define true 1 +#define false 0 + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +/* for debugging purposes only */ +#ifdef DEBUG +#undef DEBUG +#define DEBUG(fmt,args...) { log_printf (LOG_ERROR,"%d: ",__LINE__); log_printf (LOG_ERROR,fmt,## args); } +#else +#undef DEBUG +#define DEBUG(fmt,args...) +#endif + +#define KB(x) ((x) / 1024) +#define PERCENTAGE(x,total) (((x) * 100) / (total)) + +/* size of read/write buffer */ +#define BUFSIZE (10 * 1024) + +/* cmd-line flags */ +#define FLAG_NONE 0x00 +#define FLAG_VERBOSE 0x01 +#define FLAG_HELP 0x02 +#define FLAG_FILENAME 0x04 +#define FLAG_DEVICE 0x08 + +/* error levels */ +#define LOG_NORMAL 1 +#define LOG_ERROR 2 + +static void log_printf (int level,const char *fmt, ...) +{ + FILE *fp = level == LOG_NORMAL ? stdout : stderr; + va_list ap; + va_start (ap,fmt); + vfprintf (fp,fmt,ap); + va_end (ap); + fflush (fp); +} + +static void showusage (const char *progname,bool error) +{ + int level = error ? LOG_ERROR : LOG_NORMAL; + + log_printf (level, + "\n" + "Flash Copy - Written by Abraham van der Merwe \n" + "\n" + "usage: %s [ -v | --verbose ] \n" + " %s -h | --help\n" + "\n" + " -h | --help Show this help message\n" + " -v | --verbose Show progress reports\n" + " File which you want to copy to flash\n" + " Flash device to write to (e.g. /dev/mtd0, /dev/mtd1, etc.)\n" + "\n", + progname,progname); + + exit (error ? EXIT_FAILURE : EXIT_SUCCESS); +} + +static int safe_open (const char *pathname,int flags) +{ + int fd; + + fd = open (pathname,flags); + if (fd < 0) + { + log_printf (LOG_ERROR,"While trying to open %s",pathname); + if (flags & O_RDWR) + log_printf (LOG_ERROR," for read/write access"); + else if (flags & O_RDONLY) + log_printf (LOG_ERROR," for read access"); + else if (flags & O_WRONLY) + log_printf (LOG_ERROR," for write access"); + log_printf (LOG_ERROR,": %m\n"); + exit (EXIT_FAILURE); + } + + return (fd); +} + +static void safe_read (int fd,const char *filename,void *buf,size_t count,bool verbose) +{ + ssize_t result; + + result = read (fd,buf,count); + if (count != result) + { + if (verbose) log_printf (LOG_NORMAL,"\n"); + if (result < 0) + { + log_printf (LOG_ERROR,"While reading data from %s: %m\n",filename); + exit (EXIT_FAILURE); + } + log_printf (LOG_ERROR,"Short read count returned while reading from %s\n",filename); + exit (EXIT_FAILURE); + } +} + +static void safe_rewind (int fd,const char *filename) +{ + if (lseek (fd,0L,SEEK_SET) < 0) + { + log_printf (LOG_ERROR,"While seeking to start of %s: %m\n",filename); + exit (EXIT_FAILURE); + } +} + +/******************************************************************************/ + +static int dev_fd = -1,fil_fd = -1; + +static void cleanup (void) +{ + if (dev_fd > 0) close (dev_fd); + if (fil_fd > 0) close (fil_fd); +} + +int main (int argc,char *argv[]) +{ + const char *progname,*filename = NULL,*device = NULL; + int i,flags = FLAG_NONE; + ssize_t result; + size_t size,written; + struct mtd_info_user mtd; + struct erase_info_user erase; + struct stat filestat; + unsigned char src[BUFSIZE],dest[BUFSIZE]; + + (progname = strrchr (argv[0],'/')) ? progname++ : (progname = argv[0]); + + /********************* + * parse cmd-line + *****************/ + + for (;;) { + int option_index = 0; + static const char *short_options = "hv"; + static const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 'h': + flags |= FLAG_HELP; + DEBUG("Got FLAG_HELP\n"); + break; + case 'v': + flags |= FLAG_VERBOSE; + DEBUG("Got FLAG_VERBOSE\n"); + break; + default: + DEBUG("Unknown parameter: %s\n",argv[option_index]); + showusage (progname,true); + } + } + if (optind+2 == argc) { + flags |= FLAG_FILENAME; + filename = argv[optind]; + DEBUG("Got filename: %s\n",filename); + + flags |= FLAG_DEVICE; + device = argv[optind+1]; + DEBUG("Got device: %s\n",device); + } + + if (flags & FLAG_HELP || progname == NULL || device == NULL) + showusage (progname,flags != FLAG_HELP); + + atexit (cleanup); + + /* get some info about the flash device */ + dev_fd = safe_open (device,O_SYNC | O_RDWR); + if (ioctl (dev_fd,MEMGETINFO,&mtd) < 0) + { + DEBUG("ioctl(): %m\n"); + log_printf (LOG_ERROR,"This doesn't seem to be a valid MTD flash device!\n"); + exit (EXIT_FAILURE); + } + + /* get some info about the file we want to copy */ + fil_fd = safe_open (filename,O_RDONLY); + if (fstat (fil_fd,&filestat) < 0) + { + log_printf (LOG_ERROR,"While trying to get the file status of %s: %m\n",filename); + exit (EXIT_FAILURE); + } + + /* does it fit into the device/partition? */ + if (filestat.st_size > mtd.size) + { + log_printf (LOG_ERROR,"%s won't fit into %s!\n",filename,device); + exit (EXIT_FAILURE); + } + + /***************************************************** + * erase enough blocks so that we can write the file * + *****************************************************/ + +#warning "Check for smaller erase regions" + + erase.start = 0; + erase.length = filestat.st_size & ~(mtd.erasesize - 1); + if (filestat.st_size % mtd.erasesize) erase.length += mtd.erasesize; + if (flags & FLAG_VERBOSE) + { + /* if the user wants verbose output, erase 1 block at a time and show him/her what's going on */ + int blocks = erase.length / mtd.erasesize; + erase.length = mtd.erasesize; + log_printf (LOG_NORMAL,"Erasing blocks: 0/%d (0%%)",blocks); + for (i = 1; i <= blocks; i++) + { + log_printf (LOG_NORMAL,"\rErasing blocks: %d/%d (%d%%)",i,blocks,PERCENTAGE (i,blocks)); + if (ioctl (dev_fd,MEMERASE,&erase) < 0) + { + log_printf (LOG_NORMAL,"\n"); + log_printf (LOG_ERROR, + "While erasing blocks 0x%.8x-0x%.8x on %s: %m\n", + (unsigned int) erase.start,(unsigned int) (erase.start + erase.length),device); + exit (EXIT_FAILURE); + } + erase.start += mtd.erasesize; + } + log_printf (LOG_NORMAL,"\rErasing blocks: %d/%d (100%%)\n",blocks,blocks); + } + else + { + /* if not, erase the whole chunk in one shot */ + if (ioctl (dev_fd,MEMERASE,&erase) < 0) + { + log_printf (LOG_ERROR, + "While erasing blocks from 0x%.8x-0x%.8x on %s: %m\n", + (unsigned int) erase.start,(unsigned int) (erase.start + erase.length),device); + exit (EXIT_FAILURE); + } + } + DEBUG("Erased %u / %luk bytes\n",erase.length,filestat.st_size); + + /********************************** + * write the entire file to flash * + **********************************/ + + if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL,"Writing data: 0k/%luk (0%%)",KB (filestat.st_size)); + size = filestat.st_size; + i = BUFSIZE; + written = 0; + while (size) + { + if (size < BUFSIZE) i = size; + if (flags & FLAG_VERBOSE) + log_printf (LOG_NORMAL,"\rWriting data: %dk/%luk (%lu%%)", + KB (written + i), + KB (filestat.st_size), + PERCENTAGE (written + i,filestat.st_size)); + + /* read from filename */ + safe_read (fil_fd,filename,src,i,flags & FLAG_VERBOSE); + + /* write to device */ + result = write (dev_fd,src,i); + if (i != result) + { + if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL,"\n"); + if (result < 0) + { + log_printf (LOG_ERROR, + "While writing data to 0x%.8x-0x%.8x on %s: %m\n", + written,written + i,device); + exit (EXIT_FAILURE); + } + log_printf (LOG_ERROR, + "Short write count returned while writing to x%.8x-0x%.8x on %s: %d/%lu bytes written to flash\n", + written,written + i,device,written + result,filestat.st_size); + exit (EXIT_FAILURE); + } + + written += i; + size -= i; + } + if (flags & FLAG_VERBOSE) + log_printf (LOG_NORMAL, + "\rWriting data: %luk/%luk (100%%)\n", + KB (filestat.st_size), + KB (filestat.st_size)); + DEBUG("Wrote %d / %luk bytes\n",written,filestat.st_size); + + /********************************** + * verify that flash == file data * + **********************************/ + + safe_rewind (fil_fd,filename); + safe_rewind (dev_fd,device); + size = filestat.st_size; + i = BUFSIZE; + written = 0; + if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL,"Verifying data: 0k/%luk (0%%)",KB (filestat.st_size)); + while (size) + { + if (size < BUFSIZE) i = size; + if (flags & FLAG_VERBOSE) + log_printf (LOG_NORMAL, + "\rVerifying data: %dk/%luk (%lu%%)", + KB (written + i), + KB (filestat.st_size), + PERCENTAGE (written + i,filestat.st_size)); + + /* read from filename */ + safe_read (fil_fd,filename,src,i,flags & FLAG_VERBOSE); + + /* read from device */ + safe_read (dev_fd,device,dest,i,flags & FLAG_VERBOSE); + + /* compare buffers */ + if (memcmp (src,dest,i)) + { + log_printf (LOG_ERROR, + "File does not seem to match flash data. First mismatch at 0x%.8x-0x%.8x\n", + written,written + i); + exit (EXIT_FAILURE); + } + + written += i; + size -= i; + } + if (flags & FLAG_VERBOSE) + log_printf (LOG_NORMAL, + "\rVerifying data: %luk/%luk (100%%)\n", + KB (filestat.st_size), + KB (filestat.st_size)); + DEBUG("Verified %d / %luk bytes\n",written,filestat.st_size); + + exit (EXIT_SUCCESS); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_eraseall.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_eraseall.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_eraseall.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_eraseall.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,286 @@ +/* eraseall.c -- erase the whole of a MTD device + + Copyright (C) 2000 Arcom Control System Ltd + + Renamed to flash_eraseall.c + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crc32.h" + +#include +#include + +#define PROGRAM "flash_eraseall" +#define VERSION "$Revision: 1.1.1.1 $" + +static const char *exe_name; +static const char *mtd_device; +static int quiet; /* true -- don't output progress */ +static int jffs2; // format for jffs2 usage + +static void process_options (int argc, char *argv[]); +static void display_help (void); +static void display_version (void); +static struct jffs2_unknown_node cleanmarker; +int target_endian = __BYTE_ORDER; + +int main (int argc, char *argv[]) +{ + mtd_info_t meminfo; + int fd, clmpos = 0, clmlen = 8; + erase_info_t erase; + int isNAND, bbtest = 1; + + process_options(argc, argv); + + + if ((fd = open(mtd_device, O_RDWR)) < 0) { + fprintf(stderr, "%s: %s: %s\n", exe_name, mtd_device, strerror(errno)); + exit(1); + } + + + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + fprintf(stderr, "%s: %s: unable to get MTD device info\n", exe_name, mtd_device); + exit(1); + } + + erase.length = meminfo.erasesize; + isNAND = meminfo.type == MTD_NANDFLASH ? 1 : 0; + + if (jffs2) { + cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); + cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); + if (!isNAND) + cleanmarker.totlen = cpu_to_je32 (sizeof (struct jffs2_unknown_node)); + else { + struct nand_oobinfo oobinfo; + + if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) { + fprintf(stderr, "%s: %s: unable to get NAND oobinfo\n", exe_name, mtd_device); + exit(1); + } + + /* Check for autoplacement */ + if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { + /* Get the position of the free bytes */ + if (!oobinfo.oobfree[0][1]) { + fprintf (stderr, " Eeep. Autoplacement selected and no empty space in oob\n"); + exit(1); + } + clmpos = oobinfo.oobfree[0][0]; + clmlen = oobinfo.oobfree[0][1]; + if (clmlen > 8) + clmlen = 8; + } else { + /* Legacy mode */ + switch (meminfo.oobsize) { + case 8: + clmpos = 6; + clmlen = 2; + break; + case 16: + clmpos = 8; + clmlen = 8; + break; + case 64: + clmpos = 16; + clmlen = 8; + break; + } + } + cleanmarker.totlen = cpu_to_je32(8); + } + cleanmarker.hdr_crc = cpu_to_je32 (crc32 (0, &cleanmarker, sizeof (struct jffs2_unknown_node) - 4)); + } + + for (erase.start = 0; erase.start < meminfo.size; erase.start += meminfo.erasesize) { + if (bbtest) { + unsigned long long offset = erase.start; + int ret = ioctl(fd, MEMGETBADBLOCK, &offset); + if (ret > 0) { + if (!quiet) + printf ("\nSkipping bad block at 0x%09llx\n", erase.start); + continue; + } else if (ret < 0) { + if (errno == EOPNOTSUPP) { + bbtest = 0; + if (isNAND) { + fprintf(stderr, "%s: %s: Bad block check not available\n", exe_name, mtd_device); + exit(1); + } + } else { + fprintf(stderr, "\n%s: %s: MTD get bad block failed: %s\n", exe_name, mtd_device, strerror(errno)); + exit(1); + } + } + } + + if (!quiet) { + printf + ("\rErasing %d Kibyte @ %llx -- %2u %% complete.", + meminfo.erasesize / 1024, erase.start, + (unsigned long long) + (erase.start + meminfo.erasesize) * 100 / meminfo.size); + } + fflush(stdout); + + if (ioctl(fd, MEMERASE, &erase) != 0) { + fprintf(stderr, "\n%s: %s: MTD Erase failure: %s\n", exe_name, mtd_device, strerror(errno)); + continue; + } + + /* format for JFFS2 ? */ + if (!jffs2) + continue; + + /* write cleanmarker */ + if (isNAND) { + struct mtd_oob_buf oob; + oob.ptr = (unsigned char *) &cleanmarker; + oob.start = erase.start + clmpos; + oob.length = clmlen; + if (ioctl (fd, MEMWRITEOOB, &oob) != 0) { + fprintf(stderr, "\n%s: %s: MTD writeoob failure: %s\n", exe_name, mtd_device, strerror(errno)); + continue; + } + } else { + if (lseek (fd, erase.start, SEEK_SET) < 0) { + fprintf(stderr, "\n%s: %s: MTD lseek failure: %s\n", exe_name, mtd_device, strerror(errno)); + continue; + } + if (write (fd , &cleanmarker, sizeof (cleanmarker)) != sizeof (cleanmarker)) { + fprintf(stderr, "\n%s: %s: MTD write failure: %s\n", exe_name, mtd_device, strerror(errno)); + continue; + } + } + if (!quiet) + printf (" Cleanmarker written at %x.", erase.start); + } + if (!quiet) + printf("\n"); + + return 0; +} + + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + exe_name = argv[0]; + + for (;;) { + int option_index = 0; + static const char *short_options = "jq"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"jffs2", no_argument, 0, 'j'}, + {"quiet", no_argument, 0, 'q'}, + {"silent", no_argument, 0, 'q'}, + + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'q': + quiet = 1; + break; + case 'j': + jffs2 = 1; + break; + case '?': + error = 1; + break; + } + } + if (optind == argc) { + fprintf(stderr, "%s: no MTD device specified\n", exe_name); + error = 1; + } + if (error) { + fprintf(stderr, "Try `%s --help' for more information.\n", + exe_name); + exit(1); + } + + mtd_device = argv[optind]; +} + + +void display_help (void) +{ + printf("Usage: %s [OPTION] MTD_DEVICE\n" + "Erases all of the specified MTD device.\n" + "\n" + " -j, --jffs2 format the device for jffs2\n" + " -q, --quiet don't display progress messages\n" + " --silent same as --quiet\n" + " --help display this help and exit\n" + " --version output version information and exit\n", + exe_name); + exit(0); +} + + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "Copyright (C) 2000 Arcom Control Systems Ltd\n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_erase.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_erase.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_erase.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_erase.c 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,189 @@ +/* + * flash_erase.c -- erase parts of a MTD device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int region_erase(int Fd, int start, int count, int unlock, int regcount) +{ + int i, j; + region_info_t * reginfo; + + reginfo = calloc(regcount, sizeof(region_info_t)); + + for(i = 0; i < regcount; i++) + { + reginfo[i].regionindex = i; + if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0) + return 8; + else + printf("Region %d is at %d of %d sector and with sector " + "size %x\n", i, reginfo[i].offset, reginfo[i].numblocks, + reginfo[i].erasesize); + } + + // We have all the information about the chip we need. + + for(i = 0; i < regcount; i++) + { //Loop through the regions + region_info_t * r = &(reginfo[i]); + + if((start >= reginfo[i].offset) && + (start < (r->offset + r->numblocks*r->erasesize))) + break; + } + + if(i >= regcount) + { + printf("Starting offset %x not within chip.\n", start); + return 8; + } + + //We are now positioned within region i of the chip, so start erasing + //count sectors from there. + + for(j = 0; (j < count)&&(i < regcount); j++) + { + erase_info_t erase; + region_info_t * r = &(reginfo[i]); + + erase.start = start; + erase.length = r->erasesize; + + if(unlock != 0) + { //Unlock the sector first. + if(ioctl(Fd, MEMUNLOCK, &erase) != 0) + { + perror("\nMTD Unlock failure"); + close(Fd); + return 8; + } + } + printf("\rPerforming Flash Erase of length 0x%llx at offset 0x%llx", + erase.length, erase.start); + fflush(stdout); + if(ioctl(Fd, MEMERASE, &erase) != 0) + { + perror("\nMTD Erase failure"); + close(Fd); + return 8; + } + + + start += erase.length; + if(start >= (r->offset + r->numblocks*r->erasesize)) + { //We finished region i so move to region i+1 + printf("\nMoving to region %d\n", i+1); + i++; + } + } + + printf(" done\n"); + + return 0; +} + +int non_region_erase(int Fd, int start, int count, int unlock) +{ + mtd_info_t meminfo; + + if (ioctl(Fd,MEMGETINFO,&meminfo) == 0) + { + erase_info_t erase; + + erase.start = start; + + erase.length = meminfo.erasesize; + + for (; count > 0; count--) { + printf("\rPerforming Flash Erase of length 0x%llx at offset 0x%llx", + erase.length, erase.start); + fflush(stdout); + + if(unlock != 0) + { + //Unlock the sector first. + printf("\rPerforming Flash unlock at offset 0x%llx",erase.start); + if(ioctl(Fd, MEMUNLOCK, &erase) != 0) + { + perror("\nMTD Unlock failure"); + close(Fd); + return 8; + } + } + + if (ioctl(Fd,MEMERASE,&erase) != 0) + { + perror("\nMTD Erase failure"); + close(Fd); + return 8; + } + erase.start += meminfo.erasesize; + } + printf(" done\n"); + } + return 0; +} + +int main(int argc,char *argv[]) +{ + int regcount; + int Fd; + int start; + int count; + int unlock; + int res = 0; + + if (1 >= argc || !strcmp(argv[1], "-h") || !strcmp (argv[1], "--help") ) { + printf("Usage: flash_erase MTD-device [start] [cnt (# erase blocks)] [lock]\n" + " flash_erase -h | --help\n") ; + return 16 ; + } + + if (argc > 2) + start = strtol(argv[2], NULL, 0); + else + start = 0; + + if (argc > 3) + count = strtol(argv[3], NULL, 0); + else + count = 1; + + if(argc > 4) + unlock = strtol(argv[4], NULL, 0); + else + unlock = 0; + + + // Open and size the device + if ((Fd = open(argv[1],O_RDWR)) < 0) + { + fprintf(stderr,"File open error\n"); + return 8; + } + + printf("Erase Total %d Units\n", count); + + if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0) + { + if(regcount == 0) + { + res = non_region_erase(Fd, start, count, unlock); + } + else + { + res = region_erase(Fd, start, count, unlock, regcount); + } + } + + return res; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_info.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_info.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_info.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_info.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,55 @@ +/* + * flash_info.c -- print info about a MTD device + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc,char *argv[]) +{ + int regcount; + int Fd; + + if (1 >= argc) + { + fprintf(stderr,"Usage: flash_info device\n"); + return 16; + } + + // Open and size the device + if ((Fd = open(argv[1],O_RDONLY)) < 0) + { + fprintf(stderr,"File open error\n"); + return 8; + } + + if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0) + { + int i; + region_info_t reginfo; + printf("Device %s has %d erase regions\n", argv[1], regcount); + for (i = 0; i < regcount; i++) + { + reginfo.regionindex = i; + if(ioctl(Fd, MEMGETREGIONINFO, ®info) == 0) + { + printf("Region %d is at 0x%x with size 0x%x and " + "has 0x%x blocks\n", i, reginfo.offset, + reginfo.erasesize, reginfo.numblocks); + } + else + { + printf("Strange can not read region %d from a %d region device\n", + i, regcount); + } + } + } + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_lock.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_lock.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_lock.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_lock.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,84 @@ +/* + * FILE flash_lock.c + * + * This utility locks one or more sectors of flash device. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + int fd; + struct mtd_info_user mtdInfo; + struct erase_info_user mtdLockInfo; + int num_sectors; + int ofs; + + /* + * Parse command line options + */ + if(argc != 4) + { + fprintf(stderr, "USAGE: %s \n", argv[0]); + exit(1); + } + else if(strncmp(argv[1], "/dev/mtd", 8) != 0) + { + fprintf(stderr, "'%s' is not a MTD device. Must specify mtd device: /dev/mtd?\n", argv[1]); + exit(1); + } + + fd = open(argv[1], O_RDWR); + if(fd < 0) + { + fprintf(stderr, "Could not open mtd device: %s\n", argv[1]); + exit(1); + } + + if(ioctl(fd, MEMGETINFO, &mtdInfo)) + { + fprintf(stderr, "Could not get MTD device info from %s\n", argv[1]); + close(fd); + exit(1); + } + sscanf(argv[2], "%x",&ofs); + sscanf(argv[3], "%d",&num_sectors); + if(ofs > mtdInfo.size - mtdInfo.erasesize) + { + fprintf(stderr, "%x is beyond device size %x\n",ofs,(unsigned int)(mtdInfo.size - mtdInfo.erasesize)); + exit(1); + } + + if (num_sectors == -1) { + num_sectors = mtdInfo.size/mtdInfo.erasesize; + } + else { + if(num_sectors > mtdInfo.size/mtdInfo.erasesize) + { + fprintf(stderr, "%d are too many sectors, device only has %d\n",num_sectors,(int)(mtdInfo.size/mtdInfo.erasesize)); + exit(1); + } + } + + mtdLockInfo.start = ofs; + mtdLockInfo.length = num_sectors * mtdInfo.erasesize; + if(ioctl(fd, MEMLOCK, &mtdLockInfo)) + { + fprintf(stderr, "Could not lock MTD device: %s\n", argv[1]); + close(fd); + exit(1); + } + + return 0; +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_dump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_dump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_dump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_dump.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,54 @@ +/* + * flash_otp_dump.c -- display One-Time-Programm data + */ + +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc,char *argv[]) +{ + int fd, val, i, offset, ret; + unsigned char buf[16]; + + if (argc != 3 || (strcmp(argv[1], "-f") && strcmp(argv[1], "-u"))) { + fprintf(stderr,"Usage: %s [ -f | -u ] \n", argv[0]); + return EINVAL; + } + + fd = open(argv[2], O_RDONLY); + if (fd < 0) { + perror(argv[2]); + return errno; + } + + val = argv[1][1] == 'f' ? MTD_OTP_FACTORY : MTD_OTP_USER; + ret = ioctl(fd, OTPSELECT, &val); + if (ret < 0) { + perror("OTPSELECT"); + return errno; + } + + printf("OTP %s data for %s\n", + argv[1][1] == 'f' ? "factory" : "user", argv[2]); + offset = 0; + while ((ret = read(fd, buf, sizeof(buf)))) { + if (ret < 0) { + perror("read()"); + return errno; + } + printf("0x%04x:", offset); + for (i = 0; i < ret; i++) + printf(" %02x", buf[i]); + printf("\n"); + offset += ret; + } + + close(fd); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_info.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_info.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_info.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_info.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,63 @@ +/* + * flash_otp_info.c -- print info about One-Time-Programm data + */ + +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc,char *argv[]) +{ + int fd, val, i, ret; + + if (argc != 3 || (strcmp(argv[1], "-f") && strcmp(argv[1], "-u"))) { + fprintf(stderr,"Usage: %s [ -f | -u ] \n", argv[0]); + return EINVAL; + } + + fd = open(argv[2], O_RDONLY); + if (fd < 0) { + perror(argv[2]); + return errno; + } + + val = argv[1][1] == 'f' ? MTD_OTP_FACTORY : MTD_OTP_USER; + ret = ioctl(fd, OTPSELECT, &val); + if (ret < 0) { + perror("OTPSELECT"); + return errno; + } + + ret = ioctl(fd, OTPGETREGIONCOUNT, &val); + if (ret < 0) { + perror("OTPGETREGIONCOUNT"); + return errno; + } + + printf("Number of OTP %s blocks on %s: %d\n", + argv[1][1] == 'f' ? "factory" : "user", argv[2], val); + + if (val > 0) { + struct otp_info info[val]; + + ret = ioctl(fd, OTPGETREGIONINFO, &info); + if (ret < 0) { + perror("OTPGETREGIONCOUNT"); + return errno; + } + + for (i = 0; i < val; i++) + printf("block %2d: offset = 0x%04x " + "size = %2d bytes %s\n", + i, info[i].start, info[i].length, + info[i].locked ? "[locked]" : "[unlocked]"); + } + + close(fd); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_lock.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_lock.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_lock.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_lock.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,70 @@ +/* + * flash_otp_lock.c -- lock area of One-Time-Program data + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc,char *argv[]) +{ + int fd, val, ret, offset, size; + char *p, buf[8]; + + if (argc != 5 || strcmp(argv[1], "-u")) { + fprintf(stderr, "Usage: %s -u \n", argv[0]); + fprintf(stderr, "offset and size must match on OTP region boundaries\n"); + fprintf(stderr, "CAUTION! ONCE LOCKED, OTP REGIONS CAN'T BE UNLOCKED!\n"); + return EINVAL; + } + + fd = open(argv[2], O_WRONLY); + if (fd < 0) { + perror(argv[2]); + return errno; + } + + val = MTD_OTP_USER; + ret = ioctl(fd, OTPSELECT, &val); + if (ret < 0) { + perror("OTPSELECT"); + return errno; + } + + offset = strtoul(argv[3], &p, 0); + if (argv[3][0] == 0 || *p != 0) { + fprintf(stderr, "%s: bad offset value\n", argv[0]); + return ERANGE; + } + + size = strtoul(argv[4], &p, 0); + if (argv[4][0] == 0 || *p != 0) { + fprintf(stderr, "%s: bad size value\n", argv[0]); + return ERANGE; + } + + printf("About to lock OTP user data on %s from 0x%x to 0x%x\n", + argv[2], offset, offset + size); + printf("Are you sure (yes|no)? "); + if (fgets(buf, sizeof(buf), stdin) && strcmp(buf, "yes\n") == 0) { + struct otp_info info; + info.start = offset; + info.length = size; + ret = ioctl(fd, OTPLOCK, &info); + if (ret < 0) { + perror("OTPLOCK"); + return errno; + } + printf("Done.\n"); + } else { + printf("Aborted\n"); + } + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_write.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_write.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_otp_write.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_otp_write.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,96 @@ +/* + * flash_otp_write.c -- write One-Time-Program data + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc,char *argv[]) +{ + int fd, val, ret, size, wrote, len; + mtd_info_t mtdInfo; + off_t offset; + char *p, buf[2048]; + + if (argc != 4 || strcmp(argv[1], "-u")) { + fprintf(stderr, "Usage: %s -u \n", argv[0]); + fprintf(stderr, "the raw data to write should be provided on stdin\n"); + fprintf(stderr, "CAUTION! ONCE SET TO 0, OTP DATA BITS CAN'T BE ERASED!\n"); + return EINVAL; + } + + fd = open(argv[2], O_WRONLY); + if (fd < 0) { + perror(argv[2]); + return errno; + } + + val = MTD_OTP_USER; + ret = ioctl(fd, OTPSELECT, &val); + if (ret < 0) { + perror("OTPSELECT"); + return errno; + } + + if (ioctl(fd, MEMGETINFO, &mtdInfo)) { + perror("MEMGETINFO"); + return errno; + } + + offset = strtoul(argv[3], &p, 0); + if (argv[3][0] == 0 || *p != 0) { + fprintf(stderr, "%s: bad offset value\n", argv[0]); + return ERANGE; + } + + if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { + perror("lseek()"); + return errno; + } + + printf("Writing OTP user data on %s at offset 0x%lx\n", argv[2], offset); + + if (mtdInfo.type == MTD_NANDFLASH) + len = mtdInfo.writesize; + else + len = 256; + + wrote = 0; + while ((size = read(0, buf, len))) { + if (size < 0) { + perror("read()"); + return errno; + } + p = buf; + while (size > 0) { + if (mtdInfo.type == MTD_NANDFLASH) { + /* Fill remain buffers with 0xff */ + memset(buf + size, 0xff, mtdInfo.writesize - size); + size = mtdInfo.writesize; + } + ret = write(fd, p, size); + if (ret < 0) { + perror("write()"); + return errno; + } + if (ret == 0) { + printf("write() returned 0 after writing %d bytes\n", wrote); + return 0; + } + p += ret; + wrote += ret; + size -= ret; + } + } + + printf("Wrote %d bytes of OTP user data\n", wrote); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_unlock.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_unlock.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/flash_unlock.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/flash_unlock.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,64 @@ +/* + * FILE flash_unlock.c + * + * This utility unlock all sectors of flash device. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + int fd; + struct mtd_info_user mtdInfo; + struct erase_info_user mtdLockInfo; + + /* + * Parse command line options + */ + if(argc != 2) + { + fprintf(stderr, "USAGE: %s \n", argv[0]); + exit(1); + } + else if(strncmp(argv[1], "/dev/mtd", 8) != 0) + { + fprintf(stderr, "'%s' is not a MTD device. Must specify mtd device: /dev/mtd?\n", argv[1]); + exit(1); + } + + fd = open(argv[1], O_RDWR); + if(fd < 0) + { + fprintf(stderr, "Could not open mtd device: %s\n", argv[1]); + exit(1); + } + + if(ioctl(fd, MEMGETINFO, &mtdInfo)) + { + fprintf(stderr, "Could not get MTD device info from %s\n", argv[1]); + close(fd); + exit(1); + } + + mtdLockInfo.start = 0; + mtdLockInfo.length = mtdInfo.size; + if(ioctl(fd, MEMUNLOCK, &mtdLockInfo)) + { + fprintf(stderr, "Could not unlock MTD device: %s\n", argv[1]); + close(fd); + exit(1); + } + + return 0; +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ftl_check.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ftl_check.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ftl_check.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ftl_check.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,232 @@ +/* Ported to MTD system. + * Based on: + */ +/*====================================================================== + + Utility to create an FTL partition in a memory region + + ftl_check.c 1.10 1999/10/25 20:01:35 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL"), in which + case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + + ======================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define TO_LE32(x) (x) +# define TO_LE16(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +# define TO_LE32(x) (bswap_32(x)) +# define TO_LE16(x) (bswap_16(x)) +#else +# error cannot detect endianess +#endif + +#define FROM_LE32(x) TO_LE32(x) +#define FROM_LE16(x) TO_LE16(x) + +/*====================================================================*/ + +static void print_size(u_int s) +{ + if ((s > 0x100000) && ((s % 0x100000) == 0)) + printf("%d mb", s / 0x100000); + else if ((s > 0x400) && ((s % 0x400) == 0)) + printf("%d kb", s / 0x400); + else + printf("%d bytes", s); +} + +/*====================================================================*/ + +static void check_partition(int fd, int verbose) +{ + mtd_info_t mtd; + erase_unit_header_t hdr, hdr2; + u_int i, j, nbam, *bam; + int control, data, free, deleted; + + /* Get partition size, block size */ + if (ioctl(fd, MEMGETINFO, &mtd) != 0) { + perror("get info failed"); + return; + } + + printf("Memory region info:\n"); + printf(" Region size = "); + print_size(mtd.size); + printf(" Erase block size = "); + print_size(mtd.erasesize); + printf("\n\n"); + + for (i = 0; i < mtd.size/mtd.erasesize; i++) { + if (lseek(fd, (i * mtd.erasesize), SEEK_SET) == -1) { + perror("seek failed"); + break; + } + read(fd, &hdr, sizeof(hdr)); + if ((FROM_LE32(hdr.FormattedSize) > 0) && + (FROM_LE32(hdr.FormattedSize) <= mtd.size) && + (FROM_LE16(hdr.NumEraseUnits) > 0) && + (FROM_LE16(hdr.NumEraseUnits) <= mtd.size/mtd.erasesize)) + break; + } + if (i == mtd.size/mtd.erasesize) { + fprintf(stderr, "No valid erase unit headers!\n"); + return; + } + + printf("Partition header:\n"); + printf(" Formatted size = "); + print_size(FROM_LE32(hdr.FormattedSize)); + printf(", erase units = %d, transfer units = %d\n", + FROM_LE16(hdr.NumEraseUnits), hdr.NumTransferUnits); + printf(" Erase unit size = "); + print_size(1 << hdr.EraseUnitSize); + printf(", virtual block size = "); + print_size(1 << hdr.BlockSize); + printf("\n"); + + /* Create basic block allocation table for control blocks */ + nbam = (mtd.erasesize >> hdr.BlockSize); + bam = malloc(nbam * sizeof(u_int)); + + for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { + if (lseek(fd, (i << hdr.EraseUnitSize), SEEK_SET) == -1) { + perror("seek failed"); + break; + } + if (read(fd, &hdr2, sizeof(hdr2)) == -1) { + perror("read failed"); + break; + } + printf("\nErase unit %d:\n", i); + if ((hdr2.FormattedSize != hdr.FormattedSize) || + (hdr2.NumEraseUnits != hdr.NumEraseUnits) || + (hdr2.SerialNumber != hdr.SerialNumber)) + printf(" Erase unit header is corrupt.\n"); + else if (FROM_LE16(hdr2.LogicalEUN) == 0xffff) + printf(" Transfer unit, erase count = %d\n", FROM_LE32(hdr2.EraseCount)); + else { + printf(" Logical unit %d, erase count = %d\n", + FROM_LE16(hdr2.LogicalEUN), FROM_LE32(hdr2.EraseCount)); + if (lseek(fd, (i << hdr.EraseUnitSize)+FROM_LE32(hdr.BAMOffset), + SEEK_SET) == -1) { + perror("seek failed"); + break; + } + if (read(fd, bam, nbam * sizeof(u_int)) == -1) { + perror("read failed"); + break; + } + free = deleted = control = data = 0; + for (j = 0; j < nbam; j++) { + if (BLOCK_FREE(FROM_LE32(bam[j]))) + free++; + else if (BLOCK_DELETED(FROM_LE32(bam[j]))) + deleted++; + else switch (BLOCK_TYPE(FROM_LE32(bam[j]))) { + case BLOCK_CONTROL: control++; break; + case BLOCK_DATA: data++; break; + default: break; + } + } + printf(" Block allocation: %d control, %d data, %d free," + " %d deleted\n", control, data, free, deleted); + } + } +} /* format_partition */ + +/* Show usage information */ +void showusage(char *pname) +{ + fprintf(stderr, "usage: %s [-v] device\n", pname); + fprintf(stderr, "-v verbose messages\n"); +} + +/*====================================================================*/ + +int main(int argc, char *argv[]) +{ + int verbose; + int optch, errflg, fd; + struct stat buf; + + errflg = 0; + verbose = 0; + while ((optch = getopt(argc, argv, "vh")) != -1) { + switch (optch) { + case 'h': + errflg = 1; break; + case 'v': + verbose = 1; break; + default: + errflg = -1; break; + } + } + if (errflg || (optind != argc-1)) { + showusage(argv[0]); + exit(errflg > 0 ? 0 : EXIT_FAILURE); + } + + if (stat(argv[optind], &buf) != 0) { + perror("status check failed"); + exit(EXIT_FAILURE); + } + if (!(buf.st_mode & S_IFCHR)) { + fprintf(stderr, "%s is not a character special device\n", + argv[optind]); + exit(EXIT_FAILURE); + } + fd = open(argv[optind], O_RDONLY); + if (fd == -1) { + perror("open failed"); + exit(EXIT_FAILURE); + } + + check_partition(fd, verbose); + close(fd); + + exit(EXIT_SUCCESS); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ftl_format.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ftl_format.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ftl_format.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ftl_format.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,342 @@ +/* Ported to MTD system. + * Based on: + */ +/*====================================================================== + + Utility to create an FTL partition in a memory region + + ftl_format.c 1.13 1999/10/25 20:01:35 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL"), in which + case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + + ======================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define TO_LE32(x) (x) +# define TO_LE16(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +# define TO_LE32(x) (bswap_32(x)) +# define TO_LE16(x) (bswap_16(x)) +#else +# error cannot detect endianess +#endif + +#define FROM_LE32(x) TO_LE32(x) +#define FROM_LE16(x) TO_LE16(x) + +/*====================================================================*/ + +static void print_size(u_int s) +{ + if ((s > 0x100000) && ((s % 0x100000) == 0)) + printf("%d mb", s / 0x100000); + else if ((s > 0x400) && ((s % 0x400) == 0)) + printf("%d kb", s / 0x400); + else + printf("%d bytes", s); +} + +/*====================================================================*/ + +static const char LinkTarget[] = { + 0x13, 0x03, 'C', 'I', 'S' +}; +static const char DataOrg[] = { + 0x46, 0x39, 0x00, 'F', 'T', 'L', '1', '0', '0', 0x00 +}; + +static void build_header(erase_unit_header_t *hdr, u_int RegionSize, + u_int BlockSize, u_int Spare, int Reserve, + u_int BootSize) +{ + u_int i, BootUnits, nbam, __FormattedSize; + + /* Default everything to the erased state */ + memset(hdr, 0xff, sizeof(*hdr)); + memcpy(hdr->LinkTargetTuple, LinkTarget, 5); + memcpy(hdr->DataOrgTuple, DataOrg, 10); + hdr->EndTuple[0] = hdr->EndTuple[1] = 0xff; + BootSize = (BootSize + (BlockSize-1)) & ~(BlockSize-1); + BootUnits = BootSize / BlockSize; + + /* We only support 512-byte blocks */ + hdr->BlockSize = 9; + hdr->EraseUnitSize = 0; + for (i = BlockSize; i > 1; i >>= 1) + hdr->EraseUnitSize++; + hdr->EraseCount = TO_LE32(0); + hdr->FirstPhysicalEUN = TO_LE16(BootUnits); + hdr->NumEraseUnits = TO_LE16((RegionSize - BootSize) >> hdr->EraseUnitSize); + hdr->NumTransferUnits = Spare; + __FormattedSize = RegionSize - ((Spare + BootUnits) << hdr->EraseUnitSize); + /* Leave a little bit of space between the CIS and BAM */ + hdr->BAMOffset = TO_LE32(0x80); + /* Adjust size to account for BAM space */ + nbam = ((1 << (hdr->EraseUnitSize - hdr->BlockSize)) * sizeof(u_int) + + FROM_LE32(hdr->BAMOffset) + (1 << hdr->BlockSize) - 1) >> hdr->BlockSize; + + __FormattedSize -= + (FROM_LE16(hdr->NumEraseUnits) - Spare) * (nbam << hdr->BlockSize); + __FormattedSize -= ((__FormattedSize * Reserve / 100) & ~0xfff); + + hdr->FormattedSize = TO_LE32(__FormattedSize); + + /* hdr->FirstVMAddress defaults to erased state */ + hdr->NumVMPages = TO_LE16(0); + hdr->Flags = 0; + /* hdr->Code defaults to erased state */ + hdr->SerialNumber = TO_LE32(time(NULL)); + /* hdr->AltEUHOffset defaults to erased state */ + +} /* build_header */ + +/*====================================================================*/ + +static int format_partition(int fd, int quiet, int interrogate, + u_int spare, int reserve, u_int bootsize) +{ + mtd_info_t mtd; + erase_info_t erase; + erase_unit_header_t hdr; + u_int step, lun, i, nbam, *bam; + + /* Get partition size, block size */ + if (ioctl(fd, MEMGETINFO, &mtd) != 0) { + perror("get info failed"); + return -1; + } + +#if 0 + /* Intel Series 100 Flash: skip first block */ + if ((region.JedecMfr == 0x89) && (region.JedecInfo == 0xaa) && + (bootsize == 0)) { + if (!quiet) + printf("Skipping first block to protect CIS info...\n"); + bootsize = 1; + } +#endif + + /* Create header */ + build_header(&hdr, mtd.size, mtd.erasesize, + spare, reserve, bootsize); + + if (!quiet) { + printf("Partition size = "); + print_size(mtd.size); + printf(", erase unit size = "); + print_size(mtd.erasesize); + printf(", %d transfer units\n", spare); + if (bootsize != 0) { + print_size(FROM_LE16(hdr.FirstPhysicalEUN) << hdr.EraseUnitSize); + printf(" allocated for boot image\n"); + } + printf("Reserved %d%%, formatted size = ", reserve); + print_size(FROM_LE32(hdr.FormattedSize)); + printf("\n"); + fflush(stdout); + } + + if (interrogate) { + char str[3]; + printf("This will destroy all data on the target device. " + "Confirm (y/n): "); + if (fgets(str, 3, stdin) == NULL) + return -1; + if ((strcmp(str, "y\n") != 0) && (strcmp(str, "Y\n") != 0)) + return -1; + } + + /* Create basic block allocation table for control blocks */ + nbam = ((mtd.erasesize >> hdr.BlockSize) * sizeof(u_int) + + FROM_LE32(hdr.BAMOffset) + (1 << hdr.BlockSize) - 1) >> hdr.BlockSize; + bam = malloc(nbam * sizeof(u_int)); + for (i = 0; i < nbam; i++) + bam[i] = TO_LE32(BLOCK_CONTROL); + + /* Erase partition */ + if (!quiet) { + printf("Erasing all blocks...\n"); + fflush(stdout); + } + erase.length = mtd.erasesize; + erase.start = mtd.erasesize * FROM_LE16(hdr.FirstPhysicalEUN); + for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { + if (ioctl(fd, MEMERASE, &erase) < 0) { + if (!quiet) { + putchar('\n'); + fflush(stdout); + } + perror("block erase failed"); + return -1; + } + erase.start += erase.length; + if (!quiet) { + if (mtd.size <= 0x800000) { + if (erase.start % 0x100000) { + if (!(erase.start % 0x20000)) putchar('-'); + } + else putchar('+'); + } + else { + if (erase.start % 0x800000) { + if (!(erase.start % 0x100000)) putchar('+'); + } + else putchar('*'); + } + fflush(stdout); + } + } + if (!quiet) putchar('\n'); + + /* Prepare erase units */ + if (!quiet) { + printf("Writing erase unit headers...\n"); + fflush(stdout); + } + lun = 0; + /* Distribute transfer units over the entire region */ + step = (spare) ? (FROM_LE16(hdr.NumEraseUnits)/spare) : (FROM_LE16(hdr.NumEraseUnits)+1); + for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { + u_int ofs = (i + FROM_LE16(hdr.FirstPhysicalEUN)) << hdr.EraseUnitSize; + if (lseek(fd, ofs, SEEK_SET) == -1) { + perror("seek failed"); + break; + } + /* Is this a transfer unit? */ + if (((i+1) % step) == 0) + hdr.LogicalEUN = TO_LE16(0xffff); + else { + hdr.LogicalEUN = TO_LE16(lun); + lun++; + } + if (write(fd, &hdr, sizeof(hdr)) == -1) { + perror("write failed"); + break; + } + if (lseek(fd, ofs + FROM_LE32(hdr.BAMOffset), SEEK_SET) == -1) { + perror("seek failed"); + break; + } + if (write(fd, bam, nbam * sizeof(u_int)) == -1) { + perror("write failed"); + break; + } + } + if (i < FROM_LE16(hdr.NumEraseUnits)) + return -1; + else + return 0; +} /* format_partition */ + +/*====================================================================*/ + +int main(int argc, char *argv[]) +{ + int quiet, interrogate, reserve; + int optch, errflg, fd, ret; + u_int spare, bootsize; + char *s; + extern char *optarg; + struct stat buf; + + quiet = 0; + interrogate = 0; + spare = 1; + reserve = 5; + errflg = 0; + bootsize = 0; + + while ((optch = getopt(argc, argv, "qir:s:b:")) != -1) { + switch (optch) { + case 'q': + quiet = 1; break; + case 'i': + interrogate = 1; break; + case 's': + spare = strtoul(optarg, NULL, 0); break; + case 'r': + reserve = strtoul(optarg, NULL, 0); break; + case 'b': + bootsize = strtoul(optarg, &s, 0); + if ((*s == 'k') || (*s == 'K')) + bootsize *= 1024; + break; + default: + errflg = 1; break; + } + } + if (errflg || (optind != argc-1)) { + fprintf(stderr, "usage: %s [-q] [-i] [-s spare-blocks]" + " [-r reserve-percent] [-b bootsize] device\n", argv[0]); + exit(EXIT_FAILURE); + } + + if (stat(argv[optind], &buf) != 0) { + perror("status check failed"); + exit(EXIT_FAILURE); + } + if (!(buf.st_mode & S_IFCHR)) { + fprintf(stderr, "%s is not a character special device\n", + argv[optind]); + exit(EXIT_FAILURE); + } + fd = open(argv[optind], O_RDWR); + if (fd == -1) { + perror("open failed"); + exit(EXIT_FAILURE); + } + + ret = format_partition(fd, quiet, interrogate, spare, reserve, + bootsize); + if (!quiet) { + if (ret) + printf("format failed.\n"); + else + printf("format successful.\n"); + } + close(fd); + + exit((ret) ? EXIT_FAILURE : EXIT_SUCCESS); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/.gitignore linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/.gitignore --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/.gitignore 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/.gitignore 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,26 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# Normal rules +# +.* +*.o +*.a +*.s +*.ko +*.so +*.mod.c +*~ + +# +# Top-level generic files +# + +# +# Generated include files +# + +# stgit generated dirs +patches-* diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/linux/jffs2.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/linux/jffs2.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/linux/jffs2.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/linux/jffs2.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,218 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001-2003 Red Hat, Inc. + * + * Created by David Woodhouse + * + * For licensing information, see the file 'LICENCE' in the + * jffs2 directory. + * + * $Id: jffs2.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + */ + +#ifndef __LINUX_JFFS2_H__ +#define __LINUX_JFFS2_H__ + +/* You must include something which defines the C99 uintXX_t types. + We don't do it from here because this file is used in too many + different environments. */ + +#define JFFS2_SUPER_MAGIC 0x72b6 + +/* Values we may expect to find in the 'magic' field */ +#define JFFS2_OLD_MAGIC_BITMASK 0x1984 +#define JFFS2_MAGIC_BITMASK 0x1985 +#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */ +#define JFFS2_EMPTY_BITMASK 0xffff +#define JFFS2_DIRTY_BITMASK 0x0000 + +/* Summary node MAGIC marker */ +#define JFFS2_SUM_MAGIC 0x02851885 + +/* We only allow a single char for length, and 0xFF is empty flash so + we don't want it confused with a real length. Hence max 254. +*/ +#define JFFS2_MAX_NAME_LEN 254 + +/* How small can we sensibly write nodes? */ +#define JFFS2_MIN_DATA_LEN 128 + +#define JFFS2_COMPR_NONE 0x00 +#define JFFS2_COMPR_ZERO 0x01 +#define JFFS2_COMPR_RTIME 0x02 +#define JFFS2_COMPR_RUBINMIPS 0x03 +#define JFFS2_COMPR_COPY 0x04 +#define JFFS2_COMPR_DYNRUBIN 0x05 +#define JFFS2_COMPR_ZLIB 0x06 +#define JFFS2_COMPR_LZO 0x07 +/* Compatibility flags. */ +#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ +#define JFFS2_NODE_ACCURATE 0x2000 +/* INCOMPAT: Fail to mount the filesystem */ +#define JFFS2_FEATURE_INCOMPAT 0xc000 +/* ROCOMPAT: Mount read-only */ +#define JFFS2_FEATURE_ROCOMPAT 0x8000 +/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */ +#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000 +/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */ +#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000 + +#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1) +#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) +#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) +#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) + +#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6) + +#define JFFS2_NODETYPE_XATTR (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 8) +#define JFFS2_NODETYPE_XREF (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 9) + +/* XATTR Related */ +#define JFFS2_XPREFIX_USER 1 /* for "user." */ +#define JFFS2_XPREFIX_SECURITY 2 /* for "security." */ +#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */ +#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */ +#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */ + +#define JFFS2_ACL_VERSION 0x0001 + +// Maybe later... +//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) +//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) + + +#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at + mount time, don't wait for it to + happen later */ +#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific + compression type */ + + +/* These can go once we've made sure we've caught all uses without + byteswapping */ + +typedef struct { + uint32_t v32; +} __attribute__((packed)) jint32_t; + +typedef struct { + uint32_t m; +} __attribute__((packed)) jmode_t; + +typedef struct { + uint16_t v16; +} __attribute__((packed)) jint16_t; + +struct jffs2_unknown_node +{ + /* All start like this */ + jint16_t magic; + jint16_t nodetype; + jint32_t totlen; /* So we can skip over nodes we don't grok */ + jint32_t hdr_crc; +} __attribute__((packed)); + +struct jffs2_raw_dirent +{ + jint16_t magic; + jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */ + jint32_t totlen; + jint32_t hdr_crc; + jint32_t pino; + jint32_t version; + jint32_t ino; /* == zero for unlink */ + jint32_t mctime; + uint8_t nsize; + uint8_t type; + uint8_t unused[2]; + jint32_t node_crc; + jint32_t name_crc; + uint8_t name[0]; +} __attribute__((packed)); + +/* The JFFS2 raw inode structure: Used for storage on physical media. */ +/* The uid, gid, atime, mtime and ctime members could be longer, but + are left like this for space efficiency. If and when people decide + they really need them extended, it's simple enough to add support for + a new type of raw node. +*/ +struct jffs2_raw_inode +{ + jint16_t magic; /* A constant magic number. */ + jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */ + jint32_t totlen; /* Total length of this node (inc data, etc.) */ + jint32_t hdr_crc; + jint32_t ino; /* Inode number. */ + jint32_t version; /* Version number. */ + jmode_t mode; /* The file's type or mode. */ + jint16_t uid; /* The file's owner. */ + jint16_t gid; /* The file's group. */ + jint32_t isize; /* Total resultant size of this inode (used for truncations) */ + jint32_t atime; /* Last access time. */ + jint32_t mtime; /* Last modification time. */ + jint32_t ctime; /* Change time. */ + jint32_t offset; /* Where to begin to write. */ + jint32_t csize; /* (Compressed) data size */ + jint32_t dsize; /* Size of the node's data. (after decompression) */ + uint8_t compr; /* Compression algorithm used */ + uint8_t usercompr; /* Compression algorithm requested by the user */ + jint16_t flags; /* See JFFS2_INO_FLAG_* */ + jint32_t data_crc; /* CRC for the (compressed) data. */ + jint32_t node_crc; /* CRC for the raw inode (excluding data) */ + uint8_t data[0]; +} __attribute__((packed)); + +struct jffs2_raw_xattr { + jint16_t magic; + jint16_t nodetype; /* = JFFS2_NODETYPE_XATTR */ + jint32_t totlen; + jint32_t hdr_crc; + jint32_t xid; /* XATTR identifier number */ + jint32_t version; + uint8_t xprefix; + uint8_t name_len; + jint16_t value_len; + jint32_t data_crc; + jint32_t node_crc; + uint8_t data[0]; +} __attribute__((packed)); + +struct jffs2_raw_xref +{ + jint16_t magic; + jint16_t nodetype; /* = JFFS2_NODETYPE_XREF */ + jint32_t totlen; + jint32_t hdr_crc; + jint32_t ino; /* inode number */ + jint32_t xid; /* XATTR identifier number */ + jint32_t xseqno; /* xref sequencial number */ + jint32_t node_crc; +} __attribute__((packed)); + +struct jffs2_raw_summary +{ + jint16_t magic; + jint16_t nodetype; /* = JFFS2_NODETYPE_SUMMARY */ + jint32_t totlen; + jint32_t hdr_crc; + jint32_t sum_num; /* number of sum entries*/ + jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */ + jint32_t padded; /* sum of the size of padding nodes */ + jint32_t sum_crc; /* summary information crc */ + jint32_t node_crc; /* node crc */ + jint32_t sum[0]; /* inode summary info */ +} __attribute__((packed)); + +union jffs2_node_union +{ + struct jffs2_raw_inode i; + struct jffs2_raw_dirent d; + struct jffs2_raw_xattr x; + struct jffs2_raw_xref r; + struct jffs2_raw_summary s; + struct jffs2_unknown_node u; +}; + +#endif /* __LINUX_JFFS2_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ftl-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ftl-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ftl-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ftl-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,76 @@ +/* + * $Id: ftl-user.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + * Derived from (and probably identical to): + * ftl.h 1.7 1999/10/25 20:23:17 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef __MTD_FTL_USER_H__ +#define __MTD_FTL_USER_H__ + +typedef struct erase_unit_header_t { + u_int8_t LinkTargetTuple[5]; + u_int8_t DataOrgTuple[10]; + u_int8_t NumTransferUnits; + u_int32_t EraseCount; + u_int16_t LogicalEUN; + u_int8_t BlockSize; + u_int8_t EraseUnitSize; + u_int16_t FirstPhysicalEUN; + u_int16_t NumEraseUnits; + u_int32_t FormattedSize; + u_int32_t FirstVMAddress; + u_int16_t NumVMPages; + u_int8_t Flags; + u_int8_t Code; + u_int32_t SerialNumber; + u_int32_t AltEUHOffset; + u_int32_t BAMOffset; + u_int8_t Reserved[12]; + u_int8_t EndTuple[2]; +} erase_unit_header_t; + +/* Flags in erase_unit_header_t */ +#define HIDDEN_AREA 0x01 +#define REVERSE_POLARITY 0x02 +#define DOUBLE_BAI 0x04 + +/* Definitions for block allocation information */ + +#define BLOCK_FREE(b) ((b) == 0xffffffff) +#define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe)) + +#define BLOCK_TYPE(b) ((b) & 0x7f) +#define BLOCK_ADDRESS(b) ((b) & ~0x7f) +#define BLOCK_NUMBER(b) ((b) >> 9) +#define BLOCK_CONTROL 0x30 +#define BLOCK_DATA 0x40 +#define BLOCK_REPLACEMENT 0x60 +#define BLOCK_BAD 0x70 + +#endif /* __MTD_FTL_USER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/inftl-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/inftl-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/inftl-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/inftl-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,91 @@ +/* + * $Id: inftl-user.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + * Parts of INFTL headers shared with userspace + * + */ + +#ifndef __MTD_INFTL_USER_H__ +#define __MTD_INFTL_USER_H__ + +#define OSAK_VERSION 0x5120 +#define PERCENTUSED 98 + +#define SECTORSIZE 512 + +/* Block Control Information */ + +struct inftl_bci { + uint8_t ECCsig[6]; + uint8_t Status; + uint8_t Status1; +} __attribute__((packed)); + +struct inftl_unithead1 { + uint16_t virtualUnitNo; + uint16_t prevUnitNo; + uint8_t ANAC; + uint8_t NACs; + uint8_t parityPerField; + uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unithead2 { + uint8_t parityPerField; + uint8_t ANAC; + uint16_t prevUnitNo; + uint16_t virtualUnitNo; + uint8_t NACs; + uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unittail { + uint8_t Reserved[4]; + uint16_t EraseMark; + uint16_t EraseMark1; +} __attribute__((packed)); + +union inftl_uci { + struct inftl_unithead1 a; + struct inftl_unithead2 b; + struct inftl_unittail c; +}; + +struct inftl_oob { + struct inftl_bci b; + union inftl_uci u; +}; + + +/* INFTL Media Header */ + +struct INFTLPartition { + __u32 virtualUnits; + __u32 firstUnit; + __u32 lastUnit; + __u32 flags; + __u32 spareUnits; + __u32 Reserved0; + __u32 Reserved1; +} __attribute__((packed)); + +struct INFTLMediaHeader { + char bootRecordID[8]; + __u32 NoOfBootImageBlocks; + __u32 NoOfBinaryPartitions; + __u32 NoOfBDTLPartitions; + __u32 BlockMultiplierBits; + __u32 FormatFlags; + __u32 OsakVersion; + __u32 PercentUsed; + struct INFTLPartition Partitions[4]; +} __attribute__((packed)); + +/* Partition flag types */ +#define INFTL_BINARY 0x20000000 +#define INFTL_BDTL 0x40000000 +#define INFTL_LAST 0x80000000 + +#endif /* __MTD_INFTL_USER_H__ */ + + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/jffs2-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/jffs2-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/jffs2-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/jffs2-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,82 @@ +/* + * $Id: jffs2-user.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + * JFFS2 definitions for use in user space only + */ + +#ifndef __JFFS2_USER_H__ +#define __JFFS2_USER_H__ + +/* This file is blessed for inclusion by userspace */ +#include +#include +#include + +#undef cpu_to_je16 +#undef cpu_to_je32 +#undef cpu_to_jemode +#undef je16_to_cpu +#undef je32_to_cpu +#undef jemode_to_cpu + +extern int target_endian; + +#define t16(x) ({ uint16_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); }) +#define t32(x) ({ uint32_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); }) + +#define cpu_to_je16(x) ((jint16_t){t16(x)}) +#define cpu_to_je32(x) ((jint32_t){t32(x)}) +#define cpu_to_jemode(x) ((jmode_t){t32(x)}) + +#define je16_to_cpu(x) (t16((x).v16)) +#define je32_to_cpu(x) (t32((x).v32)) +#define jemode_to_cpu(x) (t32((x).m)) + +#define le16_to_cpu(x) (__BYTE_ORDER==__LITTLE_ENDIAN ? (x) : bswap_16(x)) +#define le32_to_cpu(x) (__BYTE_ORDER==__LITTLE_ENDIAN ? (x) : bswap_32(x)) +#define cpu_to_le16(x) (__BYTE_ORDER==__LITTLE_ENDIAN ? (x) : bswap_16(x)) +#define cpu_to_le32(x) (__BYTE_ORDER==__LITTLE_ENDIAN ? (x) : bswap_32(x)) + +/* XATTR/POSIX-ACL related definition */ +/* Namespaces copied from xattr.h and posix_acl_xattr.h */ +#define XATTR_USER_PREFIX "user." +#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1) +#define XATTR_SECURITY_PREFIX "security." +#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1) +#define POSIX_ACL_XATTR_ACCESS "system.posix_acl_access" +#define POSIX_ACL_XATTR_ACCESS_LEN (sizeof (POSIX_ACL_XATTR_ACCESS) - 1) +#define POSIX_ACL_XATTR_DEFAULT "system.posix_acl_default" +#define POSIX_ACL_XATTR_DEFAULT_LEN (sizeof (POSIX_ACL_XATTR_DEFAULT) - 1) +#define XATTR_TRUSTED_PREFIX "trusted." +#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1) + +struct jffs2_acl_entry { + jint16_t e_tag; + jint16_t e_perm; + jint32_t e_id; +}; + +struct jffs2_acl_entry_short { + jint16_t e_tag; + jint16_t e_perm; +}; + +struct jffs2_acl_header { + jint32_t a_version; +}; + +/* copied from include/linux/posix_acl_xattr.h */ +#define POSIX_ACL_XATTR_VERSION 0x0002 + +struct posix_acl_xattr_entry { + uint16_t e_tag; + uint16_t e_perm; + uint32_t e_id; +}; + +struct posix_acl_xattr_header { + uint32_t a_version; + struct posix_acl_xattr_entry a_entries[0]; +}; + +#endif /* __JFFS2_USER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/mtd-abi.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/mtd-abi.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/mtd-abi.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/mtd-abi.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,170 @@ +/* + * $Id: mtd-abi.h,v 1.1.1.1 2008-10-30 14:29:21 lhhuang Exp $ + * + * Portions of MTD ABI definition which are shared by kernel and user space + */ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into + separate files was to avoid #ifdef __KERNEL__ */ +#define __user +#endif + +typedef unsigned long long size_mtd_t; +typedef unsigned long long loff_mtd_t; + +struct erase_info_user { + uint64_t start; + uint64_t length; +}; + +struct mtd_oob_buf { + uint32_t start; + uint32_t length; + unsigned char __user *ptr; +}; + +struct mtd_page_buf { + uint32_t start; //page start address + uint32_t ooblength; + uint32_t datlength; + unsigned char __user *oobptr; + unsigned char __user *datptr; +}; + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_DATAFLASH 6 +#define MTD_UBIVOLUME 7 + +#define MTD_WRITEABLE 0x400 /* Device is writeable */ +#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ +#define MTD_NO_ERASE 0x1000 /* No erase necessary */ +#define MTD_STUPID_LOCK 0x2000 /* Always locked after reset */ + +// Some common devices / combinations of capabilities +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) + +/* ECC byte placement */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF 0 +#define MTD_OTP_FACTORY 1 +#define MTD_OTP_USER 2 + +struct mtd_info_user { + uint8_t type; + uint32_t flags; + uint64_t size; // Total size of the MTD + uint32_t erasesize; + uint32_t writesize; + uint32_t oobsize; // Amount of OOB data per block (e.g. 16) + /* The below two fields are obsolete and broken, do not use them + * (TODO: remove at some point) */ + uint32_t ecctype; + uint32_t eccsize; +}; + +struct region_info_user { + uint64_t offset; /* At which this region starts, + * from the beginning of the MTD */ + uint32_t erasesize; /* For this region */ + uint32_t numblocks; /* Number of blocks in this region */ + uint32_t regionindex; +}; + +struct otp_info { + uint32_t start; + uint32_t length; + uint32_t locked; +}; + +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) +#define MEMGETBADBLOCK _IOW('M', 11, loff_mtd_t) +#define MEMSETBADBLOCK _IOW('M', 12, loff_mtd_t) +#define OTPSELECT _IOR('M', 13, int) +#define OTPGETREGIONCOUNT _IOW('M', 14, int) +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) +#define OTPLOCK _IOR('M', 16, struct otp_info) +#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) +#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) +#define MTDFILEMODE _IO('M', 19) +#define MEMWRITEPAGE _IOWR('M', 20, struct mtd_page_buf) + +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */ +struct nand_oobinfo { + uint32_t useecc; + uint32_t eccbytes; + uint32_t oobfree[8][2]; + uint32_t eccpos[104]; /* more fields(13*8) are required for + * 8-bit BCH ECC and 4KB pagesize nand, by Regen */ +}; + +struct nand_oobfree { + uint32_t offset; + uint32_t length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES 8 +/* + * ECC layout control structure. Exported to userspace for + * diagnosis and to allow creation of raw images + */ +struct nand_ecclayout { + uint32_t eccbytes; + uint32_t eccpos[128]; + uint32_t oobavail; + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected: number of corrected bits + * @failed: number of uncorrectable errors + * @badblocks: number of bad blocks in this partition + * @bbtblocks: number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { + uint32_t corrected; + uint32_t failed; + uint32_t badblocks; + uint32_t bbtblocks; +}; + +/* + * Read/write file modes for access to MTD + */ +enum mtd_file_modes { + MTD_MODE_NORMAL = MTD_OTP_OFF, + MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY, + MTD_MODE_OTP_USER = MTD_OTP_USER, + MTD_MODE_RAW, +}; + +#endif /* __MTD_ABI_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/mtd-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/mtd-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/mtd-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/mtd-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,21 @@ +/* + * $Id: mtd-user.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + * MTD ABI header for use by user space only. + */ + +#ifndef __MTD_USER_H__ +#define __MTD_USER_H__ + +#include + +/* This file is blessed for inclusion by userspace */ +#include + +typedef struct mtd_info_user mtd_info_t; +typedef struct erase_info_user erase_info_t; +typedef struct region_info_user region_info_t; +typedef struct nand_oobinfo nand_oobinfo_t; +typedef struct nand_ecclayout nand_ecclayout_t; + +#endif /* __MTD_USER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/nftl-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/nftl-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/nftl-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/nftl-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,76 @@ +/* + * $Id: nftl-user.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * + * Parts of NFTL headers shared with userspace + * + */ + +#ifndef __MTD_NFTL_USER_H__ +#define __MTD_NFTL_USER_H__ + +/* Block Control Information */ + +struct nftl_bci { + unsigned char ECCSig[6]; + uint8_t Status; + uint8_t Status1; +}__attribute__((packed)); + +/* Unit Control Information */ + +struct nftl_uci0 { + uint16_t VirtUnitNum; + uint16_t ReplUnitNum; + uint16_t SpareVirtUnitNum; + uint16_t SpareReplUnitNum; +} __attribute__((packed)); + +struct nftl_uci1 { + uint32_t WearInfo; + uint16_t EraseMark; + uint16_t EraseMark1; +} __attribute__((packed)); + +struct nftl_uci2 { + uint16_t FoldMark; + uint16_t FoldMark1; + uint32_t unused; +} __attribute__((packed)); + +union nftl_uci { + struct nftl_uci0 a; + struct nftl_uci1 b; + struct nftl_uci2 c; +}; + +struct nftl_oob { + struct nftl_bci b; + union nftl_uci u; +}; + +/* NFTL Media Header */ + +struct NFTLMediaHeader { + char DataOrgID[6]; + uint16_t NumEraseUnits; + uint16_t FirstPhysicalEUN; + uint32_t FormattedSize; + unsigned char UnitSizeFactor; +} __attribute__((packed)); + +#define MAX_ERASE_ZONES (8192 - 512) + +#define ERASE_MARK 0x3c69 +#define SECTOR_FREE 0xff +#define SECTOR_USED 0x55 +#define SECTOR_IGNORE 0x11 +#define SECTOR_DELETED 0x00 + +#define FOLD_MARK_IN_PROGRESS 0x5555 + +#define ZONE_GOOD 0xff +#define ZONE_BAD_ORIGINAL 0 +#define ZONE_BAD_MARKED 7 + + +#endif /* __MTD_NFTL_USER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ubi-header.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ubi-header.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ubi-header.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ubi-header.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,372 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (Битюцкий Ðртём) + * Thomas Gleixner + * Frank Haverkamp + * Oliver Lohmann + * Andreas Arnez + */ + +/* + * This file defines the layout of UBI headers and all the other UBI on-flash + * data structures. May be included by user-space. + */ + +#ifndef __UBI_HEADER_H__ +#define __UBI_HEADER_H__ + +#include + +/* The version of UBI images supported by this implementation */ +#define UBI_VERSION 1 + +/* The highest erase counter value supported by this implementation */ +#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF + +/* The initial CRC32 value used when calculating CRC checksums */ +#define UBI_CRC32_INIT 0xFFFFFFFFU + +/* Erase counter header magic number (ASCII "UBI#") */ +#define UBI_EC_HDR_MAGIC 0x55424923 +/* Volume identifier header magic number (ASCII "UBI!") */ +#define UBI_VID_HDR_MAGIC 0x55424921 + +/* + * Volume type constants used in the volume identifier header. + * + * @UBI_VID_DYNAMIC: dynamic volume + * @UBI_VID_STATIC: static volume + */ +enum { + UBI_VID_DYNAMIC = 1, + UBI_VID_STATIC = 2 +}; + +/* + * Volume flags used in the volume table record. + * + * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume + * + * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume + * table. UBI automatically re-sizes the volume which has this flag and makes + * the volume to be of largest possible size. This means that if after the + * initialization UBI finds out that there are available physical eraseblocks + * present on the device, it automatically appends all of them to the volume + * (the physical eraseblocks reserved for bad eraseblocks handling and other + * reserved physical eraseblocks are not taken). So, if there is a volume with + * the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical + * eraseblocks will be zero after UBI is loaded, because all of them will be + * reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared + * after the volume had been initialized. + * + * The auto-resize feature is useful for device production purposes. For + * example, different NAND flash chips may have different amount of initial bad + * eraseblocks, depending of particular chip instance. Manufacturers of NAND + * chips usually guarantee that the amount of initial bad eraseblocks does not + * exceed certain percent, e.g. 2%. When one creates an UBI image which will be + * flashed to the end devices in production, he does not know the exact amount + * of good physical eraseblocks the NAND chip on the device will have, but this + * number is required to calculate the volume sized and put them to the volume + * table of the UBI image. In this case, one of the volumes (e.g., the one + * which will store the root file system) is marked as "auto-resizable", and + * UBI will adjust its size on the first boot if needed. + * + * Note, first UBI reserves some amount of physical eraseblocks for bad + * eraseblock handling, and then re-sizes the volume, not vice-versa. This + * means that the pool of reserved physical eraseblocks will always be present. + */ +enum { + UBI_VTBL_AUTORESIZE_FLG = 0x01, +}; + +/* + * Compatibility constants used by internal volumes. + * + * @UBI_COMPAT_DELETE: delete this internal volume before anything is written + * to the flash + * @UBI_COMPAT_RO: attach this device in read-only mode + * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its + * physical eraseblocks, don't allow the wear-leveling unit to move them + * @UBI_COMPAT_REJECT: reject this UBI image + */ +enum { + UBI_COMPAT_DELETE = 1, + UBI_COMPAT_RO = 2, + UBI_COMPAT_PRESERVE = 4, + UBI_COMPAT_REJECT = 5 +}; + +/* Sizes of UBI headers */ +#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) +#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) + +/* Sizes of UBI headers without the ending CRC */ +#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(uint32_t)) +#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(uint32_t)) + +/** + * struct ubi_ec_hdr - UBI erase counter header. + * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) + * @version: version of UBI implementation which is supposed to accept this + * UBI image + * @padding1: reserved for future, zeroes + * @ec: the erase counter + * @vid_hdr_offset: where the VID header starts + * @data_offset: where the user data start + * @padding2: reserved for future, zeroes + * @hdr_crc: erase counter header CRC checksum + * + * The erase counter header takes 64 bytes and has a plenty of unused space for + * future usage. The unused fields are zeroed. The @version field is used to + * indicate the version of UBI implementation which is supposed to be able to + * work with this UBI image. If @version is greater then the current UBI + * version, the image is rejected. This may be useful in future if something + * is changed radically. This field is duplicated in the volume identifier + * header. + * + * The @vid_hdr_offset and @data_offset fields contain the offset of the the + * volume identifier header and user data, relative to the beginning of the + * physical eraseblock. These values have to be the same for all physical + * eraseblocks. + */ +struct ubi_ec_hdr { + uint32_t magic; + uint8_t version; + uint8_t padding1[3]; + uint64_t ec; /* Warning: the current limit is 31-bit anyway! */ + uint32_t vid_hdr_offset; + uint32_t data_offset; + uint8_t padding2[36]; + uint32_t hdr_crc; +} __attribute__ ((packed)); + +/** + * struct ubi_vid_hdr - on-flash UBI volume identifier header. + * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) + * @version: UBI implementation version which is supposed to accept this UBI + * image (%UBI_VERSION) + * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @copy_flag: if this logical eraseblock was copied from another physical + * eraseblock (for wear-leveling reasons) + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @vol_id: ID of this volume + * @lnum: logical eraseblock number + * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be + * removed, kept only for not breaking older UBI users) + * @data_size: how many bytes of data this logical eraseblock contains + * @used_ebs: total number of used logical eraseblocks in this volume + * @data_pad: how many bytes at the end of this physical eraseblock are not + * used + * @data_crc: CRC checksum of the data stored in this logical eraseblock + * @padding1: reserved for future, zeroes + * @sqnum: sequence number + * @padding2: reserved for future, zeroes + * @hdr_crc: volume identifier header CRC checksum + * + * The @sqnum is the value of the global sequence counter at the time when this + * VID header was created. The global sequence counter is incremented each time + * UBI writes a new VID header to the flash, i.e. when it maps a logical + * eraseblock to a new physical eraseblock. The global sequence counter is an + * unsigned 64-bit integer and we assume it never overflows. The @sqnum + * (sequence number) is used to distinguish between older and newer versions of + * logical eraseblocks. + * + * There are 2 situations when there may be more then one physical eraseblock + * corresponding to the same logical eraseblock, i.e., having the same @vol_id + * and @lnum values in the volume identifier header. Suppose we have a logical + * eraseblock L and it is mapped to the physical eraseblock P. + * + * 1. Because UBI may erase physical eraseblocks asynchronously, the following + * situation is possible: L is asynchronously erased, so P is scheduled for + * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, + * so P1 is written to, then an unclean reboot happens. Result - there are 2 + * physical eraseblocks P and P1 corresponding to the same logical eraseblock + * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the + * flash. + * + * 2. From time to time UBI moves logical eraseblocks to other physical + * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P + * to P1, and an unclean reboot happens before P is physically erased, there + * are two physical eraseblocks P and P1 corresponding to L and UBI has to + * select one of them when the flash is attached. The @sqnum field says which + * PEB is the original (obviously P will have lower @sqnum) and the copy. But + * it is not enough to select the physical eraseblock with the higher sequence + * number, because the unclean reboot could have happen in the middle of the + * copying process, so the data in P is corrupted. It is also not enough to + * just select the physical eraseblock with lower sequence number, because the + * data there may be old (consider a case if more data was added to P1 after + * the copying). Moreover, the unclean reboot may happen when the erasure of P + * was just started, so it result in unstable P, which is "mostly" OK, but + * still has unstable bits. + * + * UBI uses the @copy_flag field to indicate that this logical eraseblock is a + * copy. UBI also calculates data CRC when the data is moved and stores it at + * the @data_crc field of the copy (P1). So when UBI needs to pick one physical + * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is + * examined. If it is cleared, the situation* is simple and the newer one is + * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC + * checksum is correct, this physical eraseblock is selected (P1). Otherwise + * the older one (P) is selected. + * + * Note, there is an obsolete @leb_ver field which was used instead of @sqnum + * in the past. But it is not used anymore and we keep it in order to be able + * to deal with old UBI images. It will be removed at some point. + * + * There are 2 sorts of volumes in UBI: user volumes and internal volumes. + * Internal volumes are not seen from outside and are used for various internal + * UBI purposes. In this implementation there is only one internal volume - the + * layout volume. Internal volumes are the main mechanism of UBI extensions. + * For example, in future one may introduce a journal internal volume. Internal + * volumes have their own reserved range of IDs. + * + * The @compat field is only used for internal volumes and contains the "degree + * of their compatibility". It is always zero for user volumes. This field + * provides a mechanism to introduce UBI extensions and to be still compatible + * with older UBI binaries. For example, if someone introduced a journal in + * future, he would probably use %UBI_COMPAT_DELETE compatibility for the + * journal volume. And in this case, older UBI binaries, which know nothing + * about the journal volume, would just delete this volume and work perfectly + * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image + * - it just ignores the Ext3fs journal. + * + * The @data_crc field contains the CRC checksum of the contents of the logical + * eraseblock if this is a static volume. In case of dynamic volumes, it does + * not contain the CRC checksum as a rule. The only exception is when the + * data of the physical eraseblock was moved by the wear-leveling unit, then + * the wear-leveling unit calculates the data CRC and stores it in the + * @data_crc field. And of course, the @copy_flag is %in this case. + * + * The @data_size field is used only for static volumes because UBI has to know + * how many bytes of data are stored in this eraseblock. For dynamic volumes, + * this field usually contains zero. The only exception is when the data of the + * physical eraseblock was moved to another physical eraseblock for + * wear-leveling reasons. In this case, UBI calculates CRC checksum of the + * contents and uses both @data_crc and @data_size fields. In this case, the + * @data_size field contains data size. + * + * The @used_ebs field is used only for static volumes and indicates how many + * eraseblocks the data of the volume takes. For dynamic volumes this field is + * not used and always contains zero. + * + * The @data_pad is calculated when volumes are created using the alignment + * parameter. So, effectively, the @data_pad field reduces the size of logical + * eraseblocks of this volume. This is very handy when one uses block-oriented + * software (say, cramfs) on top of the UBI volume. + */ +struct ubi_vid_hdr { + uint32_t magic; + uint8_t version; + uint8_t vol_type; + uint8_t copy_flag; + uint8_t compat; + uint32_t vol_id; + uint32_t lnum; + uint32_t leb_ver; /* obsolete, to be removed, don't use */ + uint32_t data_size; + uint32_t used_ebs; + uint32_t data_pad; + uint32_t data_crc; + uint8_t padding1[4]; + uint64_t sqnum; + uint8_t padding2[12]; + uint32_t hdr_crc; +} __attribute__ ((packed)); + +/* Internal UBI volumes count */ +#define UBI_INT_VOL_COUNT 1 + +/* + * Starting ID of internal volumes. There is reserved room for 4096 internal + * volumes. + */ +#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) + +/* The layout volume contains the volume table */ + +#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START +#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC +#define UBI_LAYOUT_VOLUME_ALIGN 1 +#define UBI_LAYOUT_VOLUME_EBS 2 +#define UBI_LAYOUT_VOLUME_NAME "layout volume" +#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT + +/* The maximum number of volumes per one UBI device */ +#define UBI_MAX_VOLUMES 128 + +/* The maximum volume name length */ +#define UBI_VOL_NAME_MAX 127 + +/* Size of the volume table record */ +#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) + +/* Size of the volume table record without the ending CRC */ +#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(uint32_t)) + +/** + * struct ubi_vtbl_record - a record in the volume table. + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @upd_marker: if volume update was started but not finished + * @name_len: volume name length + * @name: the volume name + * @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG) + * @padding: reserved, zeroes + * @crc: a CRC32 checksum of the record + * + * The volume table records are stored in the volume table, which is stored in + * the layout volume. The layout volume consists of 2 logical eraseblock, each + * of which contains a copy of the volume table (i.e., the volume table is + * duplicated). The volume table is an array of &struct ubi_vtbl_record + * objects indexed by the volume ID. + * + * If the size of the logical eraseblock is large enough to fit + * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES + * records. Otherwise, it contains as many records as it can fit (i.e., size of + * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). + * + * The @upd_marker flag is used to implement volume update. It is set to %1 + * before update and set to %0 after the update. So if the update operation was + * interrupted, UBI knows that the volume is corrupted. + * + * The @alignment field is specified when the volume is created and cannot be + * later changed. It may be useful, for example, when a block-oriented file + * system works on top of UBI. The @data_pad field is calculated using the + * logical eraseblock size and @alignment. The alignment must be multiple to the + * minimal flash I/O unit. If @alignment is 1, all the available space of + * the physical eraseblocks is used. + * + * Empty records contain all zeroes and the CRC checksum of those zeroes. + */ +struct ubi_vtbl_record { + uint32_t reserved_pebs; + uint32_t alignment; + uint32_t data_pad; + uint8_t vol_type; + uint8_t upd_marker; + uint16_t name_len; + uint8_t name[UBI_VOL_NAME_MAX+1]; + uint8_t flags; + uint8_t padding[23]; + uint32_t crc; +} __attribute__ ((packed)); + +#endif /* !__UBI_HEADER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ubi-user.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ubi-user.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd/ubi-user.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd/ubi-user.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,284 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Ðртём) + */ + +#ifndef __UBI_USER_H__ +#define __UBI_USER_H__ + +#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into + separate files was to avoid #ifdef __KERNEL__ */ +#define __user +#endif +/* + * UBI device creation (the same as MTD device attachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * MTD devices may be attached using %UBI_IOCATT ioctl command of the UBI + * control device. The caller has to properly fill and pass + * &struct ubi_attach_req object - UBI will attach the MTD device specified in + * the request and return the newly created UBI device number as the ioctl + * return value. + * + * UBI device deletion (the same as MTD device detachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * An UBI device maybe deleted with %UBI_IOCDET ioctl command of the UBI + * control device. + * + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * + * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a + * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * + * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed + * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * + * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly + * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * + * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update + * size should be passed to the IOCTL. After this, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: + * + * fd = open("/dev/my_volume"); + * ioctl(fd, UBI_IOCVOLUP, &image_size); + * write(fd, buf, image_size); + * close(fd); + * + * Atomic eraseblock change + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL + * command of the corresponding UBI volume character device. A pointer to + * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is + * expected to write the requested amount of bytes. This is similar to the + * "volume update" IOCTL. + */ + +/* + * When a new UBI volume or UBI device is created, users may either specify the + * volume/device number they want to create or to let UBI automatically assign + * the number using these constants. + */ +#define UBI_VOL_NUM_AUTO (-1) +#define UBI_DEV_NUM_AUTO (-1) + +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + +/* IOCTL commands of UBI character devices */ + +#define UBI_IOC_MAGIC 'o' + +/* Create an UBI volume */ +#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) +/* Remove an UBI volume */ +#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) +/* Re-size an UBI volume */ +#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) + +/* IOCTL commands of the UBI control character device */ + +#define UBI_CTRL_IOC_MAGIC 'o' + +/* Attach an MTD device */ +#define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req) +/* Detach an MTD device */ +#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t) + +/* IOCTL commands of UBI volume character devices */ + +#define UBI_VOL_IOC_MAGIC 'O' + +/* Start UBI volume update */ +#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +/* An eraseblock erasure command, used for debugging, disabled by default */ +#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) +/* An atomic eraseblock change command */ +#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) +/* Start UBI leb read */ +#define UBI_IOCLEBREAD _IOWR(UBI_VOL_IOC_MAGIC, 3, struct ubi_leb) + +/* Maximum MTD device name length supported by UBI */ +#define MAX_UBI_MTD_NAME_LEN 127 + +/* + * UBI data type hint constants. + * + * UBI_LONGTERM: long-term data + * UBI_SHORTTERM: short-term data + * UBI_UNKNOWN: data persistence is unknown + * + * These constants are used when data is written to UBI volumes in order to + * help the UBI wear-leveling unit to find more appropriate physical + * eraseblocks. + */ +enum { + UBI_LONGTERM = 1, + UBI_SHORTTERM = 2, + UBI_UNKNOWN = 3, +}; + +/* + * UBI volume type constants. + * + * @UBI_DYNAMIC_VOLUME: dynamic volume + * @UBI_STATIC_VOLUME: static volume + */ +enum { + UBI_DYNAMIC_VOLUME = 3, + UBI_STATIC_VOLUME = 4, +}; + +/** + * struct ubi_attach_req - attach MTD device request. + * @ubi_num: UBI device number to create + * @mtd_num: MTD device number to attach + * @vid_hdr_offset: VID header offset (use defaults if %0) + * @padding: reserved for future, not used, has to be zeroed + * + * This data structure is used to specify MTD device UBI has to attach and the + * parameters it has to use. The number which should be assigned to the new UBI + * device is passed in @ubi_num. UBI may automatically assign the number if + * @UBI_DEV_NUM_AUTO is passed. In this case, the device number is returned in + * @ubi_num. + * + * Most applications should pass %0 in @vid_hdr_offset to make UBI use default + * offset of the VID header within physical eraseblocks. The default offset is + * the next min. I/O unit after the EC header. For example, it will be offset + * 512 in case of a 512 bytes page NAND flash with no sub-page support. Or + * it will be 512 in case of a 2KiB page NAND flash with 4 512-byte sub-pages. + * + * But in rare cases, if this optimizes things, the VID header may be placed to + * a different offset. For example, the boot-loader might do things faster if the + * VID header sits at the end of the first 2KiB NAND page with 4 sub-pages. As + * the boot-loader would not normally need to read EC headers (unless it needs + * UBI in RW mode), it might be faster to calculate ECC. This is weird example, + * but it real-life example. So, in this example, @vid_hdr_offer would be + * 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes + * aligned, which is OK, as UBI is clever enough to realize this is 4th sub-page + * of the first page and add needed padding. + */ +struct ubi_attach_req { + int32_t ubi_num; + int32_t mtd_num; + int32_t vid_hdr_offset; + uint8_t padding[12]; +}; + +/** + * struct ubi_mkvol_req - volume description data structure used in + * volume creation requests. + * @vol_id: volume number + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @padding1: reserved for future, not used, has to be zeroed + * @name_len: volume name length + * @padding2: reserved for future, not used, has to be zeroed + * @name: volume name + * + * This structure is used by user-space programs when creating new volumes. The + * @used_bytes field is only necessary when creating static volumes. + * + * The @alignment field specifies the required alignment of the volume logical + * eraseblock. This means, that the size of logical eraseblocks will be aligned + * to this number, i.e., + * (UBI device logical eraseblock size) mod (@alignment) = 0. + * + * To put it differently, the logical eraseblock of this volume may be slightly + * shortened in order to make it properly aligned. The alignment has to be + * multiple of the flash minimal input/output unit, or %1 to utilize the entire + * available space of logical eraseblocks. + * + * The @alignment field may be useful, for example, when one wants to maintain + * a block device on top of an UBI volume. In this case, it is desirable to fit + * an integer number of blocks in logical eraseblocks of this UBI volume. With + * alignment it is possible to update this volume using plane UBI volume image + * BLOBs, without caring about how to properly align them. + */ +struct ubi_mkvol_req { + int32_t vol_id; + int32_t alignment; + int64_t bytes; + int8_t vol_type; + int8_t padding1; + int16_t name_len; + int8_t padding2[4]; + char name[UBI_MAX_VOLUME_NAME + 1]; +} __attribute__ ((packed)); + +/** + * struct ubi_rsvol_req - a data structure used in volume re-size requests. + * @vol_id: ID of the volume to re-size + * @bytes: new size of the volume in bytes + * + * Re-sizing is possible for both dynamic and static volumes. But while dynamic + * volumes may be re-sized arbitrarily, static volumes cannot be made to be + * smaller then the number of bytes they bear. To arbitrarily shrink a static + * volume, it must be wiped out first (by means of volume update operation with + * zero number of bytes). + */ +struct ubi_rsvol_req { + int64_t bytes; + int32_t vol_id; +} __attribute__ ((packed)); + +/** + * struct ubi_leb_change_req - a data structure used in atomic logical + * eraseblock change requests. + * @lnum: logical eraseblock number to change + * @bytes: how many bytes will be written to the logical eraseblock + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * @padding: reserved for future, not used, has to be zeroed + */ +struct ubi_leb_change_req { + int32_t lnum; + int32_t bytes; + uint8_t dtype; + uint8_t padding[7]; +} __attribute__ ((packed)); + +/** + * struct ubi_leb - a data structure describe LEB. + * @lnum: logical eraseblock number to dump + * @lebbuf: LEB data buffer + */ +struct ubi_leb{ + unsigned int lnum; + char __user *buf; +}; + +#endif /* __UBI_USER_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd_swab.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd_swab.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/include/mtd_swab.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/include/mtd_swab.h 2010-03-03 19:04:35.000000000 -0800 @@ -0,0 +1,51 @@ +#ifndef MTD_SWAB_H +#define MTD_SWAB_H + +#include + +#define swab16(x) \ + ((uint16_t)( \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) +#define swab32(x) \ + ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) + +#define swab64(x) \ + ((uint64_t)( \ + (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) + + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16(x) ({ uint16_t _x = x; swab16(_x); }) +#define cpu_to_le32(x) ({ uint32_t _x = x; swab32(_x); }) +#define cpu_to_le64(x) ({ uint64_t _x = x; swab64(_x); }) +#define cpu_to_be16(x) (x) +#define cpu_to_be32(x) (x) +#define cpu_to_be64(x) (x) +#else +#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) +#define cpu_to_le64(x) (x) +#define cpu_to_be16(x) ({ uint16_t _x = x; swab16(_x); }) +#define cpu_to_be32(x) ({ uint32_t _x = x; swab32(_x); }) +#define cpu_to_be64(x) ({ uint64_t _x = x; swab64(_x); }) +#endif +#define le16_to_cpu(x) cpu_to_le16(x) +#define be16_to_cpu(x) cpu_to_be16(x) +#define le32_to_cpu(x) cpu_to_le32(x) +#define be32_to_cpu(x) cpu_to_be32(x) +#define le64_to_cpu(x) cpu_to_le64(x) +#define be64_to_cpu(x) cpu_to_be64(x) + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs2dump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs2dump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs2dump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs2dump.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,690 @@ +/* + * dumpjffs2.c + * + * Copyright (C) 2003 Thomas Gleixner (tglx@linutronix.de) + * + * 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. + * + * Overview: + * This utility dumps the contents of a binary JFFS2 image + * + * + * Bug/ToDo: + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crc32.h" +#include "summary.h" + +#define PROGRAM "jffs2dump" +#define VERSION "$Revision: 1.1.1.1 $" + +#define PAD(x) (((x)+3)&~3) + +/* For outputting a byte-swapped version of the input image. */ +#define cnv_e32(x) ((jint32_t){bswap_32(x.v32)}) +#define cnv_e16(x) ((jint16_t){bswap_16(x.v16)}) + +#define t32_backwards(x) ({ uint32_t __b = (x); (target_endian==__BYTE_ORDER)?bswap_32(__b):__b; }) +#define cpu_to_e32(x) ((jint32_t){t32_backwards(x)}) + +// Global variables +long imglen; // length of image +char *data; // image data + +void display_help (void) +{ + printf("Usage: dumpjffs2 [OPTION] INPUTFILE\n" + "Dumps the contents of a binary JFFS2 image.\n" + "\n" + " --help display this help and exit\n" + " --version output version information and exit\n" + "-b --bigendian image is big endian\n" + "-l --littleendian image is little endian\n" + "-c --content dump image contents\n" + "-e fname --endianconvert=fname convert image endianness, output to file fname\n" + "-r --recalccrc recalc name and data crc on endian conversion\n" + "-d len --datsize=len size of data chunks, when oob data in binary image (NAND only)\n" + "-o len --oobsize=len size of oob data chunk in binary image (NAND only)\n" + "-v --verbose verbose output\n"); + exit(0); +} + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "Copyright (C) 2003 Thomas Gleixner \n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} + +// Option variables + +int verbose; // verbose output +char *img; // filename of image +int dumpcontent; // dump image content +int target_endian = __BYTE_ORDER; // image endianess +int convertendian; // convert endianness +int recalccrc; // recalc name and data crc's on endian conversion +char cnvfile[256]; // filename for conversion output +int datsize; // Size of data chunks, when oob data is inside the binary image +int oobsize; // Size of oob chunks, when oob data is inside the binary image + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "blce:rd:o:v"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"bigendian", no_argument, 0, 'b'}, + {"littleendian", no_argument, 0, 'l'}, + {"content", no_argument, 0, 'c'}, + {"endianconvert", required_argument, 0, 'e'}, + {"datsize", required_argument, 0, 'd'}, + {"oobsize", required_argument, 0, 'o'}, + {"recalccrc", required_argument, 0, 'r'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'v': + verbose = 1; + break; + case 'b': + target_endian = __BIG_ENDIAN; + break; + case 'l': + target_endian = __LITTLE_ENDIAN; + break; + case 'c': + dumpcontent = 1; + break; + case 'd': + datsize = atoi(optarg); + break; + case 'o': + oobsize = atoi(optarg); + break; + case 'e': + convertendian = 1; + strcpy (cnvfile, optarg); + break; + case 'r': + recalccrc = 1; + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 1 || error) + display_help (); + + img = argv[optind]; +} + + +/* + * Dump image contents + */ +void do_dumpcontent (void) +{ + char *p = data, *p_free_begin; + union jffs2_node_union *node; + int empty = 0, dirty = 0; + char name[256]; + uint32_t crc; + uint16_t type; + int bitchbitmask = 0; + int obsolete; + + p_free_begin = NULL; + while ( p < (data + imglen)) { + node = (union jffs2_node_union*) p; + + /* Skip empty space */ + if (!p_free_begin) + p_free_begin = p; + if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { + p += 4; + empty += 4; + continue; + } + + if (p != p_free_begin) + printf("Empty space found from 0x%08x to 0x%08x\n", p_free_begin-data, p-data); + p_free_begin = NULL; + + if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { + if (!bitchbitmask++) + printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - data, je16_to_cpu (node->u.magic)); + p += 4; + dirty += 4; + continue; + } + bitchbitmask = 0; + + type = je16_to_cpu(node->u.nodetype); + if ((type & JFFS2_NODE_ACCURATE) != JFFS2_NODE_ACCURATE) { + obsolete = 1; + type |= JFFS2_NODE_ACCURATE; + } else + obsolete = 0; + /* Set accurate for CRC check */ + node->u.nodetype = cpu_to_je16(type); + + crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); + if (crc != je32_to_cpu (node->u.hdr_crc)) { + printf ("Wrong hdr_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->u.hdr_crc), crc); + p += 4; + dirty += 4; + continue; + } + + switch(je16_to_cpu(node->u.nodetype)) { + + case JFFS2_NODETYPE_INODE: + printf ("%8s Inode node at 0x%08x, totlen 0x%08x, #ino %5d, version %5d, isize %8d, csize %8d, dsize %8d, offset %8d\n", + obsolete ? "Obsolete" : "", + p - data, je32_to_cpu (node->i.totlen), je32_to_cpu (node->i.ino), + je32_to_cpu ( node->i.version), je32_to_cpu (node->i.isize), + je32_to_cpu (node->i.csize), je32_to_cpu (node->i.dsize), je32_to_cpu (node->i.offset)); + + crc = crc32 (0, node, sizeof (struct jffs2_raw_inode) - 8); + if (crc != je32_to_cpu (node->i.node_crc)) { + printf ("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->i.node_crc), crc); + p += PAD(je32_to_cpu (node->i.totlen)); + dirty += PAD(je32_to_cpu (node->i.totlen));; + continue; + } + + crc = crc32(0, p + sizeof (struct jffs2_raw_inode), je32_to_cpu(node->i.csize)); + if (crc != je32_to_cpu(node->i.data_crc)) { + printf ("Wrong data_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->i.data_crc), crc); + p += PAD(je32_to_cpu (node->i.totlen)); + dirty += PAD(je32_to_cpu (node->i.totlen));; + continue; + } + + p += PAD(je32_to_cpu (node->i.totlen)); + break; + + case JFFS2_NODETYPE_DIRENT: + memcpy (name, node->d.name, node->d.nsize); + name [node->d.nsize] = 0x0; + printf ("%8s Dirent node at 0x%08x, totlen 0x%08x, #pino %5d, version %5d, #ino %8d, nsize %8d, name %s\n", + obsolete ? "Obsolete" : "", + p - data, je32_to_cpu (node->d.totlen), je32_to_cpu (node->d.pino), + je32_to_cpu ( node->d.version), je32_to_cpu (node->d.ino), + node->d.nsize, name); + + crc = crc32 (0, node, sizeof (struct jffs2_raw_dirent) - 8); + if (crc != je32_to_cpu (node->d.node_crc)) { + printf ("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->d.node_crc), crc); + p += PAD(je32_to_cpu (node->d.totlen)); + dirty += PAD(je32_to_cpu (node->d.totlen));; + continue; + } + + crc = crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize); + if (crc != je32_to_cpu(node->d.name_crc)) { + printf ("Wrong name_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->d.name_crc), crc); + p += PAD(je32_to_cpu (node->d.totlen)); + dirty += PAD(je32_to_cpu (node->d.totlen));; + continue; + } + + p += PAD(je32_to_cpu (node->d.totlen)); + break; + + case JFFS2_NODETYPE_SUMMARY: { + + int i; + struct jffs2_sum_marker * sm; + + printf("%8s Inode Sum node at 0x%08x, totlen 0x%08x, sum_num %5d, cleanmarker size %5d\n", + obsolete ? "Obsolete" : "", + p - data, + je32_to_cpu (node->s.totlen), + je32_to_cpu (node->s.sum_num), + je32_to_cpu (node->s.cln_mkr)); + + crc = crc32 (0, node, sizeof (struct jffs2_raw_summary) - 8); + if (crc != je32_to_cpu (node->s.node_crc)) { + printf ("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->s.node_crc), crc); + p += PAD(je32_to_cpu (node->s.totlen)); + dirty += PAD(je32_to_cpu (node->s.totlen));; + continue; + } + + crc = crc32(0, p + sizeof (struct jffs2_raw_summary), je32_to_cpu (node->s.totlen) - sizeof(struct jffs2_raw_summary)); + if (crc != je32_to_cpu(node->s.sum_crc)) { + printf ("Wrong data_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->s.sum_crc), crc); + p += PAD(je32_to_cpu (node->s.totlen)); + dirty += PAD(je32_to_cpu (node->s.totlen));; + continue; + } + + if (verbose) { + void *sp; + sp = (p + sizeof(struct jffs2_raw_summary)); + + for(i=0; is.sum_num); i++) { + + switch(je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { + case JFFS2_NODETYPE_INODE : { + + struct jffs2_sum_inode_flash *spi; + spi = sp; + + printf ("%14s #ino %5d, version %5d, offset 0x%08x, totlen 0x%08x\n", + "", + je32_to_cpu (spi->inode), + je32_to_cpu (spi->version), + je32_to_cpu (spi->offset), + je32_to_cpu (spi->totlen)); + + sp += JFFS2_SUMMARY_INODE_SIZE; + break; + } + + case JFFS2_NODETYPE_DIRENT : { + + char name[255]; + struct jffs2_sum_dirent_flash *spd; + spd = sp; + + memcpy(name,spd->name,spd->nsize); + name [spd->nsize] = 0x0; + + printf ("%14s dirent offset 0x%08x, totlen 0x%08x, #pino %5d, version %5d, #ino %8d, nsize %8d, name %s \n", + "", + je32_to_cpu (spd->offset), + je32_to_cpu (spd->totlen), + je32_to_cpu (spd->pino), + je32_to_cpu (spd->version), + je32_to_cpu (spd->ino), + spd->nsize, + name); + + sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize); + break; + } + + default : + printf("Unknown summary node!\n"); + break; + } + } + + sm = (struct jffs2_sum_marker *) ((char *)p + je32_to_cpu(node->s.totlen) - sizeof(struct jffs2_sum_marker)); + + printf("%14s Sum Node Offset 0x%08x, Magic 0x%08x, Padded size 0x%08x\n", + "", + je32_to_cpu(sm->offset), + je32_to_cpu(sm->magic), + je32_to_cpu(node->s.padded)); + } + + p += PAD(je32_to_cpu (node->s.totlen)); + break; + } + + case JFFS2_NODETYPE_CLEANMARKER: + if (verbose) { + printf ("%8s Cleanmarker at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - data, je32_to_cpu (node->u.totlen)); + } + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case JFFS2_NODETYPE_PADDING: + if (verbose) { + printf ("%8s Padding node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - data, je32_to_cpu (node->u.totlen)); + } + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case 0xffff: + p += 4; + empty += 4; + break; + + default: + if (verbose) { + printf ("%8s Unknown node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - data, je32_to_cpu (node->u.totlen)); + } + p += PAD(je32_to_cpu (node->u.totlen)); + dirty += PAD(je32_to_cpu (node->u.totlen)); + + } + } + + if (verbose) + printf ("Empty space: %d, dirty space: %d\n", empty, dirty); +} + +/* + * Convert endianess + */ +void do_endianconvert (void) +{ + char *p = data; + union jffs2_node_union *node, newnode; + int fd, len; + jint32_t mode; + uint32_t crc; + + fd = open (cnvfile, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + fprintf (stderr, "Cannot open / create file: %s\n", cnvfile); + return; + } + + while ( p < (data + imglen)) { + node = (union jffs2_node_union*) p; + + /* Skip empty space */ + if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { + write (fd, p, 4); + p += 4; + continue; + } + + if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { + printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - data, je16_to_cpu (node->u.magic)); + newnode.u.magic = cnv_e16 (node->u.magic); + newnode.u.nodetype = cnv_e16 (node->u.nodetype); + write (fd, &newnode, 4); + p += 4; + continue; + } + + crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); + if (crc != je32_to_cpu (node->u.hdr_crc)) { + printf ("Wrong hdr_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->u.hdr_crc), crc); + } + + switch(je16_to_cpu(node->u.nodetype)) { + + case JFFS2_NODETYPE_INODE: + + newnode.i.magic = cnv_e16 (node->i.magic); + newnode.i.nodetype = cnv_e16 (node->i.nodetype); + newnode.i.totlen = cnv_e32 (node->i.totlen); + newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); + newnode.i.ino = cnv_e32 (node->i.ino); + newnode.i.version = cnv_e32 (node->i.version); + mode.v32 = node->i.mode.m; + mode = cnv_e32 (mode); + newnode.i.mode.m = mode.v32; + newnode.i.uid = cnv_e16 (node->i.uid); + newnode.i.gid = cnv_e16 (node->i.gid); + newnode.i.isize = cnv_e32 (node->i.isize); + newnode.i.atime = cnv_e32 (node->i.atime); + newnode.i.mtime = cnv_e32 (node->i.mtime); + newnode.i.ctime = cnv_e32 (node->i.ctime); + newnode.i.offset = cnv_e32 (node->i.offset); + newnode.i.csize = cnv_e32 (node->i.csize); + newnode.i.dsize = cnv_e32 (node->i.dsize); + newnode.i.compr = node->i.compr; + newnode.i.usercompr = node->i.usercompr; + newnode.i.flags = cnv_e16 (node->i.flags); + if (recalccrc) { + len = je32_to_cpu(node->i.csize); + newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len)); + } else + newnode.i.data_crc = cnv_e32 (node->i.data_crc); + + newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8)); + + write (fd, &newnode, sizeof (struct jffs2_raw_inode)); + write (fd, p + sizeof (struct jffs2_raw_inode), PAD (je32_to_cpu (node->i.totlen) - sizeof (struct jffs2_raw_inode))); + + p += PAD(je32_to_cpu (node->i.totlen)); + break; + + case JFFS2_NODETYPE_DIRENT: + newnode.d.magic = cnv_e16 (node->d.magic); + newnode.d.nodetype = cnv_e16 (node->d.nodetype); + newnode.d.totlen = cnv_e32 (node->d.totlen); + newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); + newnode.d.pino = cnv_e32 (node->d.pino); + newnode.d.version = cnv_e32 (node->d.version); + newnode.d.ino = cnv_e32 (node->d.ino); + newnode.d.mctime = cnv_e32 (node->d.mctime); + newnode.d.nsize = node->d.nsize; + newnode.d.type = node->d.type; + newnode.d.unused[0] = node->d.unused[0]; + newnode.d.unused[1] = node->d.unused[1]; + newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8)); + if (recalccrc) + newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize)); + else + newnode.d.name_crc = cnv_e32 (node->d.name_crc); + + write (fd, &newnode, sizeof (struct jffs2_raw_dirent)); + write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (je32_to_cpu (node->d.totlen) - sizeof (struct jffs2_raw_dirent))); + p += PAD(je32_to_cpu (node->d.totlen)); + break; + + case JFFS2_NODETYPE_CLEANMARKER: + case JFFS2_NODETYPE_PADDING: + newnode.u.magic = cnv_e16 (node->u.magic); + newnode.u.nodetype = cnv_e16 (node->u.nodetype); + newnode.u.totlen = cnv_e32 (node->u.totlen); + newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); + + write (fd, &newnode, sizeof (struct jffs2_unknown_node)); + len = PAD(je32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node)); + if (len > 0) + write (fd, p + sizeof (struct jffs2_unknown_node), len); + + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case JFFS2_NODETYPE_SUMMARY : { + struct jffs2_sum_marker *sm_ptr; + int i,sum_len; + int counter = 0; + + newnode.s.magic = cnv_e16 (node->s.magic); + newnode.s.nodetype = cnv_e16 (node->s.nodetype); + newnode.s.totlen = cnv_e32 (node->s.totlen); + newnode.s.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); + newnode.s.sum_num = cnv_e32 (node->s.sum_num); + newnode.s.cln_mkr = cnv_e32 (node->s.cln_mkr); + newnode.s.padded = cnv_e32 (node->s.padded); + + newnode.s.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_summary) - 8)); + + // summary header + p += sizeof (struct jffs2_raw_summary); + + // summary data + sum_len = je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary) - sizeof (struct jffs2_sum_marker); + + for (i=0; is.sum_num); i++) { + union jffs2_sum_flash *fl_ptr; + + fl_ptr = (union jffs2_sum_flash *) p; + + switch (je16_to_cpu (fl_ptr->u.nodetype)) { + case JFFS2_NODETYPE_INODE: + + fl_ptr->i.nodetype = cnv_e16 (fl_ptr->i.nodetype); + fl_ptr->i.inode = cnv_e32 (fl_ptr->i.inode); + fl_ptr->i.version = cnv_e32 (fl_ptr->i.version); + fl_ptr->i.offset = cnv_e32 (fl_ptr->i.offset); + fl_ptr->i.totlen = cnv_e32 (fl_ptr->i.totlen); + p += sizeof (struct jffs2_sum_inode_flash); + counter += sizeof (struct jffs2_sum_inode_flash); + break; + + case JFFS2_NODETYPE_DIRENT: + fl_ptr->d.nodetype = cnv_e16 (fl_ptr->d.nodetype); + fl_ptr->d.totlen = cnv_e32 (fl_ptr->d.totlen); + fl_ptr->d.offset = cnv_e32 (fl_ptr->d.offset); + fl_ptr->d.pino = cnv_e32 (fl_ptr->d.pino); + fl_ptr->d.version = cnv_e32 (fl_ptr->d.version); + fl_ptr->d.ino = cnv_e32 (fl_ptr->d.ino); + p += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize; + counter += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize; + break; + + default : + printf("Unknown node in summary information!!! nodetype(%x)\n", je16_to_cpu (fl_ptr->u.nodetype)); + exit(EXIT_FAILURE); + break; + } + + } + + //pad + p += sum_len - counter; + + // summary marker + sm_ptr = (struct jffs2_sum_marker *) p; + sm_ptr->offset = cnv_e32 (sm_ptr->offset); + sm_ptr->magic = cnv_e32 (sm_ptr->magic); + p += sizeof (struct jffs2_sum_marker); + + // generate new crc on sum data + newnode.s.sum_crc = cpu_to_e32 ( crc32(0, ((char *) node) + sizeof (struct jffs2_raw_summary), + je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary))); + + // write out new node header + write(fd, &newnode, sizeof (struct jffs2_raw_summary)); + // write out new summary data + write(fd, &node->s.sum, sum_len + sizeof (struct jffs2_sum_marker)); + + break; + } + + case 0xffff: + write (fd, p, 4); + p += 4; + break; + + default: + printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", je16_to_cpu (node->u.nodetype), p - data, je32_to_cpu (node->u.totlen)); + p += PAD(je32_to_cpu (node->u.totlen)); + + } + } + + close (fd); + +} + +/* + * Main program + */ +int main(int argc, char **argv) +{ + int fd; + + process_options(argc, argv); + + /* Open the input file */ + if ((fd = open(img, O_RDONLY)) == -1) { + perror("open input file"); + exit(1); + } + + // get image length + imglen = lseek(fd, 0, SEEK_END); + lseek (fd, 0, SEEK_SET); + + data = malloc (imglen); + if (!data) { + perror("out of memory"); + close (fd); + exit(1); + } + + if (datsize && oobsize) { + int idx = 0; + long len = imglen; + uint8_t oob[oobsize]; + printf ("Peeling data out of combined data/oob image\n"); + while (len) { + // read image data + read (fd, &data[idx], datsize); + read (fd, oob, oobsize); + idx += datsize; + imglen -= oobsize; + len -= datsize + oobsize; + } + + } else { + // read image data + read (fd, data, imglen); + } + // Close the input file + close(fd); + + if (dumpcontent) + do_dumpcontent (); + + if (convertendian) + do_endianconvert (); + + // free memory + free (data); + + // Return happy + exit (0); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs2reader.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs2reader.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs2reader.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs2reader.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,939 @@ +/* vi: set sw=4 ts=4: */ +/* + * jffs2reader v0.0.18 A jffs2 image reader + * + * Copyright (c) 2001 Jari Kirma + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must + * not claim that you wrote the original software. If you use this + * software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must + * not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + * + ********* + * This code was altered September 2001 + * Changes are Copyright (c) Erik Andersen + * + * In compliance with (2) above, this is hereby marked as an altered + * version of this software. It has been altered as follows: + * *) Listing a directory now mimics the behavior of 'ls -l' + * *) Support for recursive listing has been added + * *) Without options, does a recursive 'ls' on the whole filesystem + * *) option parsing now uses getopt() + * *) Now uses printf, and error messages go to stderr. + * *) The copyright notice has been cleaned up and reformatted + * *) The code has been reformatted + * *) Several twisty code paths have been fixed so I can understand them. + * -Erik, 1 September 2001 + * + * *) Made it show major/minor numbers for device nodes + * *) Made it show symlink targets + * -Erik, 13 September 2001 + */ + + +/* +TODO: + +- Add CRC checking code to places marked with XXX. +- Add support for other node compression types. + +- Test with real life images. +- Maybe port into bootloader. + */ + +/* +BUGS: + +- Doesn't check CRC checksums. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCRATCH_SIZE (5*1024*1024) + +#ifndef MAJOR +/* FIXME: I am using illicit insider knowledge of + * kernel major/minor representation... */ +#define MAJOR(dev) (((dev)>>8)&0xff) +#define MINOR(dev) ((dev)&0xff) +#endif + + +#define DIRENT_INO(dirent) ((dirent)!=NULL?(dirent)->ino:0) +#define DIRENT_PINO(dirent) ((dirent)!=NULL?(dirent)->pino:0) + +struct dir { + struct dir *next; + uint8_t type; + uint8_t nsize; + uint32_t ino; + char name[256]; +}; + +void putblock(char *, size_t, size_t *, struct jffs2_raw_inode *); +struct dir *putdir(struct dir *, struct jffs2_raw_dirent *); +void printdir(char *o, size_t size, struct dir *d, char *path, + int recurse); +void freedir(struct dir *); + +struct jffs2_raw_inode *find_raw_inode(char *o, size_t size, uint32_t ino); +struct jffs2_raw_dirent *resolvedirent(char *, size_t, uint32_t, uint32_t, + char *, uint8_t); +struct jffs2_raw_dirent *resolvename(char *, size_t, uint32_t, char *, uint8_t); +struct jffs2_raw_dirent *resolveinode(char *, size_t, uint32_t); + +struct jffs2_raw_dirent *resolvepath0(char *, size_t, uint32_t, char *, + uint32_t *, int); +struct jffs2_raw_dirent *resolvepath(char *, size_t, uint32_t, char *, + uint32_t *); + +void lsdir(char *, size_t, char *, int); +void catfile(char *, size_t, char *, char *, size_t, size_t *); + +int main(int, char **); + +/* writes file node into buffer, to the proper position. */ +/* reading all valid nodes in version order reconstructs the file. */ + +/* + b - buffer + bsize - buffer size + rsize - result size + n - node + */ + +void putblock(char *b, size_t bsize, size_t * rsize, + struct jffs2_raw_inode *n) +{ + uLongf dlen = n->dsize; + + if (n->isize > bsize || (n->offset + dlen) > bsize) { + fprintf(stderr, "File does not fit into buffer!\n"); + exit(EXIT_FAILURE); + } + + if (*rsize < n->isize) + bzero(b + *rsize, n->isize - *rsize); + + switch (n->compr) { + case JFFS2_COMPR_ZLIB: + uncompress((Bytef *) b + n->offset, &dlen, + (Bytef *) ((char *) n) + sizeof(struct jffs2_raw_inode), + (uLongf) n->csize); + break; + + case JFFS2_COMPR_NONE: + memcpy(b + n->offset, + ((char *) n) + sizeof(struct jffs2_raw_inode), dlen); + break; + + case JFFS2_COMPR_ZERO: + bzero(b + n->offset, dlen); + break; + + /* [DYN]RUBIN support required! */ + + default: + fprintf(stderr, "Unsupported compression method!\n"); + exit(EXIT_FAILURE); + } + + *rsize = n->isize; +} + +/* adds/removes directory node into dir struct. */ +/* reading all valid nodes in version order reconstructs the directory. */ + +/* + dd - directory struct being processed + n - node + + return value: directory struct value replacing dd + */ + +struct dir *putdir(struct dir *dd, struct jffs2_raw_dirent *n) +{ + struct dir *o, *d, *p; + + o = dd; + + if (n->ino) { + if (dd == NULL) { + d = malloc(sizeof(struct dir)); + d->type = n->type; + memcpy(d->name, n->name, n->nsize); + d->nsize = n->nsize; + d->ino = n->ino; + d->next = NULL; + + return d; + } + + while (1) { + if (n->nsize == dd->nsize && + !memcmp(n->name, dd->name, n->nsize)) { + dd->type = n->type; + dd->ino = n->ino; + + return o; + } + + if (dd->next == NULL) { + dd->next = malloc(sizeof(struct dir)); + dd->next->type = n->type; + memcpy(dd->next->name, n->name, n->nsize); + dd->next->nsize = n->nsize; + dd->next->ino = n->ino; + dd->next->next = NULL; + + return o; + } + + dd = dd->next; + } + } else { + if (dd == NULL) + return NULL; + + if (n->nsize == dd->nsize && !memcmp(n->name, dd->name, n->nsize)) { + d = dd->next; + free(dd); + return d; + } + + while (1) { + p = dd; + dd = dd->next; + + if (dd == NULL) + return o; + + if (n->nsize == dd->nsize && + !memcmp(n->name, dd->name, n->nsize)) { + p->next = dd->next; + free(dd); + + return o; + } + } + } +} + + +#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) +#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) + +/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ +static const mode_t SBIT[] = { + 0, 0, S_ISUID, + 0, 0, S_ISGID, + 0, 0, S_ISVTX +}; + +/* The 9 mode bits to test */ +static const mode_t MBIT[] = { + S_IRUSR, S_IWUSR, S_IXUSR, + S_IRGRP, S_IWGRP, S_IXGRP, + S_IROTH, S_IWOTH, S_IXOTH +}; + +static const char MODE1[] = "rwxrwxrwx"; +static const char MODE0[] = "---------"; +static const char SMODE1[] = "..s..s..t"; +static const char SMODE0[] = "..S..S..T"; + +/* + * Return the standard ls-like mode string from a file mode. + * This is static and so is overwritten on each call. + */ +const char *mode_string(int mode) +{ + static char buf[12]; + + int i; + + buf[0] = TYPECHAR(mode); + for (i = 0; i < 9; i++) { + if (mode & SBIT[i]) + buf[i + 1] = (mode & MBIT[i]) ? SMODE1[i] : SMODE0[i]; + else + buf[i + 1] = (mode & MBIT[i]) ? MODE1[i] : MODE0[i]; + } + return buf; +} + +/* prints contents of directory structure */ + +/* + d - dir struct + */ + +void printdir(char *o, size_t size, struct dir *d, char *path, int recurse) +{ + char m; + char *filetime; + time_t age; + struct jffs2_raw_inode *ri; + + if (!path) + return; + if (strlen(path) == 1 && *path == '/') + path++; + + while (d != NULL) { + switch (d->type) { + case DT_REG: + m = ' '; + break; + + case DT_FIFO: + m = '|'; + break; + + case DT_CHR: + m = ' '; + break; + + case DT_BLK: + m = ' '; + break; + + case DT_DIR: + m = '/'; + break; + + case DT_LNK: + m = ' '; + break; + + case DT_SOCK: + m = '='; + break; + + default: + m = '?'; + } + ri = find_raw_inode(o, size, d->ino); + if (!ri) { + fprintf(stderr, "bug: raw_inode missing!\n"); + d = d->next; + continue; + } + + filetime = ctime((const time_t *) &(ri->ctime)); + age = time(NULL) - ri->ctime; + printf("%s %-4d %-8d %-8d ", mode_string(ri->mode), + 1, ri->uid, ri->gid); + if ( d->type==DT_BLK || d->type==DT_CHR ) { + dev_t rdev; + size_t devsize; + putblock((char*)&rdev, sizeof(rdev), &devsize, ri); + printf("%4d, %3d ", (int)MAJOR(rdev), (int)MINOR(rdev)); + } else { + printf("%9ld ", (long)ri->dsize); + } + d->name[d->nsize]='\0'; + if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { + /* hh:mm if less than 6 months old */ + printf("%6.6s %5.5s %s/%s%c", filetime + 4, filetime + 11, path, d->name, m); + } else { + printf("%6.6s %4.4s %s/%s%c", filetime + 4, filetime + 20, path, d->name, m); + } + if (d->type == DT_LNK) { + char symbuf[1024]; + size_t symsize; + putblock(symbuf, sizeof(symbuf), &symsize, ri); + symbuf[symsize] = 0; + printf(" -> %s", symbuf); + } + printf("\n"); + + if (d->type == DT_DIR && recurse) { + char *tmp; + tmp = malloc(BUFSIZ); + if (!tmp) { + fprintf(stderr, "memory exhausted\n"); + exit(EXIT_FAILURE); + } + sprintf(tmp, "%s/%s", path, d->name); + lsdir(o, size, tmp, recurse); /* Go recursive */ + free(tmp); + } + + d = d->next; + } +} + +/* frees memory used by directory structure */ + +/* + d - dir struct + */ + +void freedir(struct dir *d) +{ + struct dir *t; + + while (d != NULL) { + t = d->next; + free(d); + d = t; + } +} + +/* collects directory/file nodes in version order. */ + +/* + f - file flag. + if zero, collect file, compare ino to inode + otherwise, collect directory, compare ino to parent inode + o - filesystem image pointer + size - size of filesystem image + ino - inode to compare against. see f. + + return value: a jffs2_raw_inode that corresponds the the specified + inode, or NULL + */ + +struct jffs2_raw_inode *find_raw_inode(char *o, size_t size, uint32_t ino) +{ + /* aligned! */ + union jffs2_node_union *n; + union jffs2_node_union *e = (union jffs2_node_union *) (o + size); + union jffs2_node_union *lr; /* last block position */ + union jffs2_node_union *mp = NULL; /* minimum position */ + + uint32_t vmin, vmint, vmaxt, vmax, vcur, v; + + vmin = 0; /* next to read */ + vmax = ~((uint32_t) 0); /* last to read */ + vmint = ~((uint32_t) 0); + vmaxt = 0; /* found maximum */ + vcur = 0; /* XXX what is smallest version number used? */ + /* too low version number can easily result excess log rereading */ + + n = (union jffs2_node_union *) o; + lr = n; + + do { + while (n < e && n->u.magic != JFFS2_MAGIC_BITMASK) + ((char *) n) += 4; + + if (n < e && n->u.magic == JFFS2_MAGIC_BITMASK) { + if (n->u.nodetype == JFFS2_NODETYPE_INODE && + n->i.ino == ino && (v = n->i.version) > vcur) { + /* XXX crc check */ + + if (vmaxt < v) + vmaxt = v; + if (vmint > v) { + vmint = v; + mp = n; + } + + if (v == (vcur + 1)) + return (&(n->i)); + } + + ((char *) n) += ((n->u.totlen + 3) & ~3); + } else + n = (union jffs2_node_union *) o; /* we're at the end, rewind to the beginning */ + + if (lr == n) { /* whole loop since last read */ + vmax = vmaxt; + vmin = vmint; + vmint = ~((uint32_t) 0); + + if (vcur < vmax && vcur < vmin) + return (&(mp->i)); + } + } while (vcur < vmax); + + return NULL; +} + +/* collects dir struct for selected inode */ + +/* + o - filesystem image pointer + size - size of filesystem image + pino - inode of the specified directory + d - input directory structure + + return value: result directory structure, replaces d. + */ + +struct dir *collectdir(char *o, size_t size, uint32_t ino, struct dir *d) +{ + /* aligned! */ + union jffs2_node_union *n; + union jffs2_node_union *e = (union jffs2_node_union *) (o + size); + union jffs2_node_union *lr; /* last block position */ + union jffs2_node_union *mp = NULL; /* minimum position */ + + uint32_t vmin, vmint, vmaxt, vmax, vcur, v; + + vmin = 0; /* next to read */ + vmax = ~((uint32_t) 0); /* last to read */ + vmint = ~((uint32_t) 0); + vmaxt = 0; /* found maximum */ + vcur = 0; /* XXX what is smallest version number used? */ + /* too low version number can easily result excess log rereading */ + + n = (union jffs2_node_union *) o; + lr = n; + + do { + while (n < e && n->u.magic != JFFS2_MAGIC_BITMASK) + ((char *) n) += 4; + + if (n < e && n->u.magic == JFFS2_MAGIC_BITMASK) { + if (n->u.nodetype == JFFS2_NODETYPE_DIRENT && + n->d.pino == ino && (v = n->d.version) > vcur) { + /* XXX crc check */ + + if (vmaxt < v) + vmaxt = v; + if (vmint > v) { + vmint = v; + mp = n; + } + + if (v == (vcur + 1)) { + d = putdir(d, &(n->d)); + + lr = n; + vcur++; + vmint = ~((uint32_t) 0); + } + } + + ((char *) n) += ((n->u.totlen + 3) & ~3); + } else + n = (union jffs2_node_union *) o; /* we're at the end, rewind to the beginning */ + + if (lr == n) { /* whole loop since last read */ + vmax = vmaxt; + vmin = vmint; + vmint = ~((uint32_t) 0); + + if (vcur < vmax && vcur < vmin) { + d = putdir(d, &(mp->d)); + + lr = n = + (union jffs2_node_union *) (((char *) mp) + + ((mp->u.totlen + 3) & ~3)); + + vcur = vmin; + } + } + } while (vcur < vmax); + + return d; +} + + + +/* resolve dirent based on criteria */ + +/* + o - filesystem image pointer + size - size of filesystem image + ino - if zero, ignore, + otherwise compare against dirent inode + pino - if zero, ingore, + otherwise compare against parent inode + and use name and nsize as extra criteria + name - name of wanted dirent, used if pino!=0 + nsize - length of name of wanted dirent, used if pino!=0 + + return value: pointer to relevant dirent structure in + filesystem image or NULL + */ + +struct jffs2_raw_dirent *resolvedirent(char *o, size_t size, + uint32_t ino, uint32_t pino, + char *name, uint8_t nsize) +{ + /* aligned! */ + union jffs2_node_union *n; + union jffs2_node_union *e = (union jffs2_node_union *) (o + size); + + struct jffs2_raw_dirent *dd = NULL; + + uint32_t vmax, v; + + if (!pino && ino <= 1) + return dd; + + vmax = 0; + + n = (union jffs2_node_union *) o; + + do { + while (n < e && n->u.magic != JFFS2_MAGIC_BITMASK) + ((char *) n) += 4; + + if (n < e && n->u.magic == JFFS2_MAGIC_BITMASK) { + if (n->u.nodetype == JFFS2_NODETYPE_DIRENT && + (!ino || n->d.ino == ino) && + (v = n->d.version) > vmax && + (!pino || (n->d.pino == pino && + nsize == n->d.nsize && + !memcmp(name, n->d.name, nsize)))) { + /* XXX crc check */ + + if (vmax < v) { + vmax = v; + dd = &(n->d); + } + } + + ((char *) n) += ((n->u.totlen + 3) & ~3); + } else + return dd; + } while (1); +} + +/* resolve name under certain parent inode to dirent */ + +/* + o - filesystem image pointer + size - size of filesystem image + pino - requested parent inode + name - name of wanted dirent + nsize - length of name of wanted dirent + + return value: pointer to relevant dirent structure in + filesystem image or NULL + */ + +struct jffs2_raw_dirent *resolvename(char *o, size_t size, uint32_t pino, + char *name, uint8_t nsize) +{ + return resolvedirent(o, size, 0, pino, name, nsize); +} + +/* resolve inode to dirent */ + +/* + o - filesystem image pointer + size - size of filesystem image + ino - compare against dirent inode + + return value: pointer to relevant dirent structure in + filesystem image or NULL + */ + +struct jffs2_raw_dirent *resolveinode(char *o, size_t size, uint32_t ino) +{ + return resolvedirent(o, size, ino, 0, NULL, 0); +} + +/* resolve slash-style path into dirent and inode. + slash as first byte marks absolute path (root=inode 1). + . and .. are resolved properly, and symlinks are followed. + */ + +/* + o - filesystem image pointer + size - size of filesystem image + ino - root inode, used if path is relative + p - path to be resolved + inos - result inode, zero if failure + recc - recursion count, to detect symlink loops + + return value: pointer to dirent struct in file system image. + note that root directory doesn't have dirent struct + (return value is NULL), but it has inode (*inos=1) + */ + +struct jffs2_raw_dirent *resolvepath0(char *o, size_t size, uint32_t ino, + char *p, uint32_t * inos, int recc) +{ + struct jffs2_raw_dirent *dir = NULL; + + int d = 1; + uint32_t tino; + + char *next; + + char *path, *pp; + + char symbuf[1024]; + size_t symsize; + + if (recc > 16) { + /* probably symlink loop */ + *inos = 0; + return NULL; + } + + pp = path = strdup(p); + + if (*path == '/') { + path++; + ino = 1; + } + + if (ino > 1) { + dir = resolveinode(o, size, ino); + + ino = DIRENT_INO(dir); + } + + next = path - 1; + + while (ino && next != NULL && next[1] != 0 && d) { + path = next + 1; + next = strchr(path, '/'); + + if (next != NULL) + *next = 0; + + if (*path == '.' && path[1] == 0) + continue; + if (*path == '.' && path[1] == '.' && path[2] == 0) { + if (DIRENT_PINO(dir) == 1) { + ino = 1; + dir = NULL; + } else { + dir = resolveinode(o, size, DIRENT_PINO(dir)); + ino = DIRENT_INO(dir); + } + + continue; + } + + dir = resolvename(o, size, ino, path, (uint8_t) strlen(path)); + + if (DIRENT_INO(dir) == 0 || + (next != NULL && + !(dir->type == DT_DIR || dir->type == DT_LNK))) { + free(pp); + + *inos = 0; + + return NULL; + } + + if (dir->type == DT_LNK) { + struct jffs2_raw_inode *ri; + ri = find_raw_inode(o, size, DIRENT_INO(dir)); + putblock(symbuf, sizeof(symbuf), &symsize, ri); + symbuf[symsize] = 0; + + tino = ino; + ino = 0; + + dir = resolvepath0(o, size, tino, symbuf, &ino, ++recc); + + if (dir != NULL && next != NULL && + !(dir->type == DT_DIR || dir->type == DT_LNK)) { + free(pp); + + *inos = 0; + return NULL; + } + } + if (dir != NULL) + ino = DIRENT_INO(dir); + } + + free(pp); + + *inos = ino; + + return dir; +} + +/* resolve slash-style path into dirent and inode. + slash as first byte marks absolute path (root=inode 1). + . and .. are resolved properly, and symlinks are followed. + */ + +/* + o - filesystem image pointer + size - size of filesystem image + ino - root inode, used if path is relative + p - path to be resolved + inos - result inode, zero if failure + + return value: pointer to dirent struct in file system image. + note that root directory doesn't have dirent struct + (return value is NULL), but it has inode (*inos=1) + */ + +struct jffs2_raw_dirent *resolvepath(char *o, size_t size, uint32_t ino, + char *p, uint32_t * inos) +{ + return resolvepath0(o, size, ino, p, inos, 0); +} + +/* lists files on directory specified by path */ + +/* + o - filesystem image pointer + size - size of filesystem image + p - path to be resolved + */ + +void lsdir(char *o, size_t size, char *path, int recurse) +{ + struct jffs2_raw_dirent *dd; + struct dir *d = NULL; + + uint32_t ino; + + dd = resolvepath(o, size, 1, path, &ino); + + if (ino == 0 || + (dd == NULL && ino == 0) || (dd != NULL && dd->type != DT_DIR)) { + fprintf(stderr, "jffs2reader: %s: No such file or directory\n", + path); + exit(EXIT_FAILURE); + } + + d = collectdir(o, size, ino, d); + printdir(o, size, d, path, recurse); + freedir(d); +} + +/* writes file specified by path to the buffer */ + +/* + o - filesystem image pointer + size - size of filesystem image + p - path to be resolved + b - file buffer + bsize - file buffer size + rsize - file result size + */ + +void catfile(char *o, size_t size, char *path, char *b, size_t bsize, + size_t * rsize) +{ + struct jffs2_raw_dirent *dd; + struct jffs2_raw_inode *ri; + uint32_t ino; + + dd = resolvepath(o, size, 1, path, &ino); + + if (ino == 0) { + fprintf(stderr, "%s: No such file or directory\n", path); + exit(EXIT_FAILURE); + } + + if (dd == NULL || dd->type != DT_REG) { + fprintf(stderr, "%s: Not a regular file\n", path); + exit(EXIT_FAILURE); + } + + ri = find_raw_inode(o, size, ino); + putblock(b, bsize, rsize, ri); + + write(1, b, *rsize); +} + +/* usage example */ + +int main(int argc, char **argv) +{ + int fd, opt, recurse = 0; + struct stat st; + + char *scratch, *dir = NULL, *file = NULL; + size_t ssize = 0; + + char *buf; + + while ((opt = getopt(argc, argv, "rd:f:")) > 0) { + switch (opt) { + case 'd': + dir = optarg; + break; + case 'f': + file = optarg; + break; + case 'r': + recurse++; + break; + default: + fprintf(stderr, + "Usage: jffs2reader [-d|-f] < path > \n"); + exit(EXIT_FAILURE); + } + } + + fd = open(argv[optind], O_RDONLY); + if (fd == -1) { + fprintf(stderr, "%s: %s\n", argv[optind], strerror(errno)); + exit(2); + } + + if (fstat(fd, &st)) { + fprintf(stderr, "%s: %s\n", argv[optind], strerror(errno)); + exit(3); + } + + buf = malloc((size_t) st.st_size); + if (buf == NULL) { + fprintf(stderr, "%s: memory exhausted\n", argv[optind]); + exit(4); + } + + if (read(fd, buf, st.st_size) != (ssize_t) st.st_size) { + fprintf(stderr, "%s: %s\n", argv[optind], strerror(errno)); + exit(5); + } + + if (dir) + lsdir(buf, st.st_size, dir, recurse); + + if (file) { + scratch = malloc(SCRATCH_SIZE); + if (scratch == NULL) { + fprintf(stderr, "%s: memory exhausted\n", argv[optind]); + exit(6); + } + + catfile(buf, st.st_size, file, scratch, SCRATCH_SIZE, &ssize); + free(scratch); + } + + if (!dir && !file) + lsdir(buf, st.st_size, "/", 1); + + + free(buf); + exit(EXIT_SUCCESS); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs-dump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs-dump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/jffs-dump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/jffs-dump.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,359 @@ +/* + * Dump JFFS filesystem. + * Useful when it buggers up. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 1024 +#define JFFS_MAGIC 0x34383931 /* "1984" */ +#define JFFS_MAX_NAME_LEN 256 +#define JFFS_MIN_INO 1 +#define JFFS_TRACE_INDENT 4 +#define JFFS_ALIGN_SIZE 4 +#define MAX_CHUNK_SIZE 32768 + +/* How many padding bytes should be inserted between two chunks of data + on the flash? */ +#define JFFS_GET_PAD_BYTES(size) ((JFFS_ALIGN_SIZE \ + - ((uint32_t)(size) % JFFS_ALIGN_SIZE)) \ + % JFFS_ALIGN_SIZE) + +#define JFFS_EMPTY_BITMASK 0xffffffff +#define JFFS_MAGIC_BITMASK 0x34383931 +#define JFFS_DIRTY_BITMASK 0x00000000 + +#define min(x,y) (x) > (y) ? (y) : (x) + +struct jffs_raw_inode +{ + uint32_t magic; /* A constant magic number. */ + uint32_t ino; /* Inode number. */ + uint32_t pino; /* Parent's inode number. */ + uint32_t version; /* Version number. */ + uint32_t mode; /* file_type, mode */ + uint16_t uid; + uint16_t gid; + uint32_t atime; + uint32_t mtime; + uint32_t ctime; + uint32_t offset; /* Where to begin to write. */ + uint32_t dsize; /* Size of the file data. */ + uint32_t rsize; /* How much are going to be replaced? */ + uint8_t nsize; /* Name length. */ + uint8_t nlink; /* Number of links. */ + uint8_t spare : 6; /* For future use. */ + uint8_t rename : 1; /* Is this a special rename? */ + uint8_t deleted : 1; /* Has this file been deleted? */ + uint8_t accurate; /* The inode is obsolete if accurate == 0. */ + uint32_t dchksum; /* Checksum for the data. */ + uint16_t nchksum; /* Checksum for the name. */ + uint16_t chksum; /* Checksum for the raw_inode. */ +}; + + +struct jffs_file +{ + struct jffs_raw_inode inode; + char *name; + unsigned char *data; +}; + + +char *root_directory_name = NULL; +int fs_pos = 0; +int verbose = 0; + +#define ENDIAN_HOST 0 +#define ENDIAN_BIG 1 +#define ENDIAN_LITTLE 2 +int endian = ENDIAN_HOST; + +static uint32_t jffs_checksum(void *data, int size); +void jffs_print_trace(const char *path, int depth); +int make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, + int depth); +void write_file(struct jffs_file *f, FILE *fs, struct stat st); +void read_data(struct jffs_file *f, const char *path, int offset); +int mkfs(FILE *fs, const char *path, int ino, int parent, int depth); + + + static uint32_t +jffs_checksum(void *data, int size) +{ + uint32_t sum = 0; + uint8_t *ptr = (uint8_t *)data; + + while (size-- > 0) + { + sum += *ptr++; + } + + return sum; +} + + + void +jffs_print_trace(const char *path, int depth) +{ + int path_len = strlen(path); + int out_pos = depth * JFFS_TRACE_INDENT; + int pos = path_len - 1; + char *out = (char *)alloca(depth * JFFS_TRACE_INDENT + path_len + 1); + + if (verbose >= 2) + { + fprintf(stderr, "jffs_print_trace(): path: \"%s\"\n", path); + } + + if (!out) { + fprintf(stderr, "jffs_print_trace(): Allocation failed.\n"); + fprintf(stderr, " path: \"%s\"\n", path); + fprintf(stderr, "depth: %d\n", depth); + exit(1); + } + + memset(out, ' ', depth * JFFS_TRACE_INDENT); + + if (path[pos] == '/') + { + pos--; + } + while (path[pos] && (path[pos] != '/')) + { + pos--; + } + for (pos++; path[pos] && (path[pos] != '/'); pos++) + { + out[out_pos++] = path[pos]; + } + out[out_pos] = '\0'; + fprintf(stderr, "%s\n", out); +} + + +/* Print the contents of a raw inode. */ + void +jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) +{ + fprintf(stdout, "jffs_raw_inode: inode number: %u, version %u\n", raw_inode->ino, raw_inode->version); + fprintf(stdout, "{\n"); + fprintf(stdout, " 0x%08x, /* magic */\n", raw_inode->magic); + fprintf(stdout, " 0x%08x, /* ino */\n", raw_inode->ino); + fprintf(stdout, " 0x%08x, /* pino */\n", raw_inode->pino); + fprintf(stdout, " 0x%08x, /* version */\n", raw_inode->version); + fprintf(stdout, " 0x%08x, /* mode */\n", raw_inode->mode); + fprintf(stdout, " 0x%04x, /* uid */\n", raw_inode->uid); + fprintf(stdout, " 0x%04x, /* gid */\n", raw_inode->gid); + fprintf(stdout, " 0x%08x, /* atime */\n", raw_inode->atime); + fprintf(stdout, " 0x%08x, /* mtime */\n", raw_inode->mtime); + fprintf(stdout, " 0x%08x, /* ctime */\n", raw_inode->ctime); + fprintf(stdout, " 0x%08x, /* offset */\n", raw_inode->offset); + fprintf(stdout, " 0x%08x, /* dsize */\n", raw_inode->dsize); + fprintf(stdout, " 0x%08x, /* rsize */\n", raw_inode->rsize); + fprintf(stdout, " 0x%02x, /* nsize */\n", raw_inode->nsize); + fprintf(stdout, " 0x%02x, /* nlink */\n", raw_inode->nlink); + fprintf(stdout, " 0x%02x, /* spare */\n", + raw_inode->spare); + fprintf(stdout, " %u, /* rename */\n", + raw_inode->rename); + fprintf(stdout, " %u, /* deleted */\n", + raw_inode->deleted); + fprintf(stdout, " 0x%02x, /* accurate */\n", + raw_inode->accurate); + fprintf(stdout, " 0x%08x, /* dchksum */\n", raw_inode->dchksum); + fprintf(stdout, " 0x%04x, /* nchksum */\n", raw_inode->nchksum); + fprintf(stdout, " 0x%04x, /* chksum */\n", raw_inode->chksum); + fprintf(stdout, "}\n"); +} + +static void write_val32(uint32_t *adr, uint32_t val) +{ + switch(endian) { + case ENDIAN_HOST: + *adr = val; + break; + case ENDIAN_LITTLE: + *adr = __cpu_to_le32(val); + break; + case ENDIAN_BIG: + *adr = __cpu_to_be32(val); + break; + } +} + +static void write_val16(uint16_t *adr, uint16_t val) +{ + switch(endian) { + case ENDIAN_HOST: + *adr = val; + break; + case ENDIAN_LITTLE: + *adr = __cpu_to_le16(val); + break; + case ENDIAN_BIG: + *adr = __cpu_to_be16(val); + break; + } +} + +static uint32_t read_val32(uint32_t *adr) +{ + uint32_t val; + + switch(endian) { + case ENDIAN_HOST: + val = *adr; + break; + case ENDIAN_LITTLE: + val = __le32_to_cpu(*adr); + break; + case ENDIAN_BIG: + val = __be32_to_cpu(*adr); + break; + } + return val; +} + +static uint16_t read_val16(uint16_t *adr) +{ + uint16_t val; + + switch(endian) { + case ENDIAN_HOST: + val = *adr; + break; + case ENDIAN_LITTLE: + val = __le16_to_cpu(*adr); + break; + case ENDIAN_BIG: + val = __be16_to_cpu(*adr); + break; + } + return val; +} + + int +main(int argc, char **argv) +{ + int fs; + struct stat sb; + uint32_t wordbuf; + off_t pos = 0; + off_t end; + struct jffs_raw_inode ino; + unsigned char namebuf[4096]; + int myino = -1; + + if (argc < 2) { + printf("no filesystem given\n"); + exit(1); + } + + fs = open(argv[1], O_RDONLY); + if (fs < 0) { + perror("open"); + exit(1); + } + + if (argc > 2) { + myino = atol(argv[2]); + printf("Printing ino #%d\n" , myino); + } + + if (fstat(fs, &sb) < 0) { + perror("stat"); + close(fs); + exit(1); + } + end = sb.st_size; + + while (pos < end) { + if (pread(fs, &wordbuf, 4, pos) < 0) { + perror("pread"); + exit(1); + } + + switch(wordbuf) { + case JFFS_EMPTY_BITMASK: + // printf("0xff started at 0x%lx\n", pos); + for (; pos < end && wordbuf == JFFS_EMPTY_BITMASK; pos += 4) { + if (pread(fs, &wordbuf, 4, pos) < 0) { + perror("pread"); + exit(1); + } + } + if (pos < end) + pos -= 4; + // printf("0xff ended at 0x%lx\n", pos); + continue; + + case JFFS_DIRTY_BITMASK: + // printf("0x00 started at 0x%lx\n", pos); + for (; pos < end && wordbuf == JFFS_DIRTY_BITMASK; pos += 4) { + if (pread(fs, &wordbuf, 4, pos) < 0) { + perror("pread"); + exit(1); + } + } + if (pos < end) + pos -=4; + // printf("0x00 ended at 0x%lx\n", pos); + continue; + + default: + printf("Argh. Dirty memory at 0x%lx\n", pos); + // file_hexdump(fs, pos, 128); + for (pos += 4; pos < end; pos += 4) { + if (pread(fs, &wordbuf, 4, pos) < 0) { + perror("pread"); + exit(1); + } + if (wordbuf == JFFS_MAGIC_BITMASK) + break; + } + + case JFFS_MAGIC_BITMASK: + if (pread(fs, &ino, sizeof(ino), pos) < 0) { + perror("pread"); + exit(1); + } + if (myino == -1 || ino.ino == myino) { + printf("Magic found at 0x%lx\n", pos); + jffs_print_raw_inode(&ino); + } + pos += sizeof(ino); + + if (myino == -1 || ino.ino == myino) { + if (ino.nsize) { + if (pread(fs, namebuf, min(ino.nsize, 4095), pos) < 0) { + perror("pread"); + exit(1); + } + if (ino.nsize < 4095) + namebuf[ino.nsize] = 0; + else + namebuf[4095] = 0; + printf("Name: \"%s\"\n", namebuf); + } else { + printf("No Name\n"); + } + } + pos += (ino.nsize + 3) & ~3; + + pos += (ino.dsize + 3) & ~3; + } + + + + } +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/load_nandsim.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/load_nandsim.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/load_nandsim.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/load_nandsim.sh 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,123 @@ +#!/bin/bash + +# +# This script inserts NAND simulator module to emulate NAND flash of specified +# size. +# +# Author: Artem Bityutskiy +# + +# Check if nandsim module is loaded +function nandsim_loaded() +{ + local NANDSIM=`lsmod | grep nandsim` + if [ -n "$NANDSIM" ]; then + return 1 + fi + return 0 +} + +nandsim_loaded +if (( $? != 0 )); then + echo "Error: nandsim is already loaded" + exit 1 +fi + +if (( $# < 1 )); then + echo "Load NAND simulator to simulate flash of a specified size." + echo "" + echo "Usage: ./load_nandsim.sh " + echo " " + echo "" + echo "Only the first parameter is mandatory. Default eraseblock size" + echo "is 16KiB, default NAND page size is 512 bytes." + echo "" + echo "Only the following combinations are supported:" + echo "--------------------------------------------------" + echo "| size (MiB) | EB size (KiB) | Page size (bytes) |" + echo "--------------------------------------------------" + echo "| 16 | 16 | 512 |" + echo "| 32 | 16 | 512 |" + echo "| 64 | 16 | 512 |" + echo "| 128 | 16 | 512 |" + echo "| 256 | 16 | 512 |" + echo "| 64 | 64 | 2048 |" + echo "| 64 | 128 | 2048 |" + echo "| 64 | 256 | 2048 |" + echo "| 64 | 512 | 2048 |" + echo "| 128 | 64 | 2048 |" + echo "| 128 | 128 | 2048 |" + echo "| 128 | 256 | 2048 |" + echo "| 128 | 512 | 2048 |" + echo "| 256 | 64 | 2048 |" + echo "| 256 | 128 | 2048 |" + echo "| 256 | 256 | 2048 |" + echo "| 256 | 512 | 2048 |" + echo "| 512 | 64 | 2048 |" + echo "| 512 | 128 | 2048 |" + echo "| 512 | 256 | 2048 |" + echo "| 512 | 512 | 2048 |" + echo "| 1024 | 64 | 2048 |" + echo "| 1024 | 128 | 2048 |" + echo "| 1024 | 256 | 2048 |" + echo "| 1024 | 512 | 2048 |" + echo "--------------------------------------------------" + exit 1 +fi + +SZ=$1 +EBSZ=$2 +PGSZ=$3 +if [[ $# == '1' ]]; then + EBSZ=16 + PGSZ=512 +elif [[ $# == '2' ]]; then + PGSZ=512 +fi + +if (( $PGSZ == 512 && $EBSZ != 16 )); then + echo "Error: only 16KiB eraseblocks are possible in case of 512 bytes page" + exit 1 +fi + +if (( $PGSZ == 512 )); then + case $SZ in + 16) modprobe nandsim first_id_byte=0x20 second_id_byte=0x33 ;; + 32) modprobe nandsim first_id_byte=0x20 second_id_byte=0x35 ;; + 64) modprobe nandsim first_id_byte=0x20 second_id_byte=0x36 ;; + 128) modprobe nandsim first_id_byte=0x20 second_id_byte=0x78 ;; + 256) modprobe nandsim first_id_byte=0x20 second_id_byte=0x71 ;; + *) echo "Flash size ${SZ}MiB is not supported, try 16, 32, 64 or 256" + exit 1 ;; + esac +elif (( $PGSZ == 2048 )); then + case $EBSZ in + 64) FOURTH=0x05 ;; + 128) FOURTH=0x15 ;; + 256) FOURTH=0x25 ;; + 512) FOURTH=0x35 ;; + *) echo "Eraseblock ${EBSZ}KiB is not supported" + exit 1 + esac + + case $SZ in + 64) modprobe nandsim first_id_byte=0x20 second_id_byte=0xa2 third_id_byte=0x00 fourth_id_byte=$FOURTH ;; + 128) modprobe nandsim first_id_byte=0xec second_id_byte=0xa1 third_id_byte=0x00 fourth_id_byte=$FOURTH ;; + 256) modprobe nandsim first_id_byte=0x20 second_id_byte=0xaa third_id_byte=0x00 fourth_id_byte=$FOURTH ;; + 512) modprobe nandsim first_id_byte=0x20 second_id_byte=0xac third_id_byte=0x00 fourth_id_byte=$FOURTH ;; + 1024) modprobe nandsim first_id_byte=0xec second_id_byte=0xd3 third_id_byte=0x51 fourth_id_byte=$FOURTH ;; + *) echo "Unable to emulate ${SZ}MiB flash with ${EBSZ}KiB eraseblock" + exit 1 + esac +else + echo "Error: bad NAND page size ${PGSZ}KiB, it has to be either 512 or 2048" + exit 1 +fi + +if (( $? != 0 )); then + echo "Error: cannot load nandsim" + exit 1 +fi + +echo "Loaded NAND simulator (${SZ}MiB, ${EBSZ}KiB eraseblock, $PGSZ bytes NAND page)" +exit 0 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/MAKEDEV linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/MAKEDEV --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/MAKEDEV 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/MAKEDEV 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,42 @@ +#!/bin/bash + +function mkftl () { + mknod /dev/ftl$1 b 44 $2 + for a in `seq 1 15`; do + mknod /dev/ftl$1$a b 44 `expr $2 + $a` + done +} +function mknftl () { + mknod /dev/nftl$1 b 93 $2 + for a in `seq 1 15`; do + mknod /dev/nftl$1$a b 93 `expr $2 + $a` + done +} +function mkrfd () { + mknod /dev/rfd$1 b 256 $2 + for a in `seq 1 15`; do + mknod /dev/rfd$1$a b 256 `expr $2 + $a` + done +} +function mkinftl () { + mknod /dev/inftl$1 b 96 $2 + for a in `seq 1 15`; do + mknod /dev/inftl$1$a b 96 `expr $2 + $a` + done +} + +M=0 +for C in a b c d e f g h i j k l m n o p; do + mkftl $C $M + mknftl $C $M + mkrfd $C $M + mkinftl $C $M + let M=M+16 +done + +for a in `seq 0 16` ; do + mknod /dev/mtd$a c 90 `expr $a + $a` + mknod /dev/mtdr$a c 90 `expr $a + $a + 1` + mknod /dev/mtdblock$a b 31 $a +done + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/Makefile 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,105 @@ + +# -*- sh -*- + +OPTFLAGS := -O2 -Wall +SBINDIR=/usr/sbin +MANDIR=/usr/share/man +INCLUDEDIR=/usr/include +CROSS=mipsel-linux- +CC := $(CROSS)gcc +CFLAGS := -I./include $(OPTFLAGS) + +ifeq ($(origin CROSS),undefined) + BUILDDIR := . +else +# Remove the trailing slash to make the directory name + BUILDDIR := .#$(CROSS:-=) +endif + +ifeq ($(WITHOUT_XATTR), 1) + CFLAGS += -DWITHOUT_XATTR +endif + +#RAWTARGETS = ftl_format flash_erase flash_eraseall nanddump doc_loadbios \ +# ftl_check mkfs.jffs2 flash_lock flash_unlock flash_info \ +# flash_otp_info flash_otp_dump mtd_debug flashcp nandwrite nandtest \ +# jffs2dump \ +# nftldump nftl_format docfdisk \ +# rfddump rfdformat \ +# serve_image recv_image \ +# sumtool #jffs2reader + +RAWTARGETS = flash_erase flash_eraseall nanddump nanddump_vfat \ + flash_info \ + flash_otp_info flash_otp_dump nandwrite nandwrite_mlc \ + nandtest \ + sumtool #jffs2reader + +TARGETS = $(foreach target,$(RAWTARGETS),$(BUILDDIR)/$(target)) + +SYMLINKS = + +%: %.o + $(CC) $(CFLAGS) $(LDFLAGS) -g -o $@ $^ + +$(BUILDDIR)/%.o: %.c + mkdir -p $(BUILDDIR) + $(CC) $(CFLAGS) -g -c -o $@ $< -g -Wp,-MD,$(BUILDDIR)/.$( ${DESTDIR}/${MANDIR}/man1/mkfs.jffs2.1.gz + make -C $(BUILDDIR)/ubi-utils install diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mcast_image.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mcast_image.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mcast_image.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mcast_image.h 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,54 @@ +#include + +#define PKT_SIZE 2820 + +struct image_pkt_hdr { + uint32_t resend; + uint32_t totcrc; + uint32_t nr_blocks; + uint32_t blocksize; + uint32_t block_crc; + uint32_t block_nr; + uint32_t pkt_sequence; + uint16_t pkt_nr; + uint16_t nr_pkts; + uint32_t thislen; + uint32_t thiscrc; +}; + +struct image_pkt { + struct image_pkt_hdr hdr; + unsigned char data[PKT_SIZE]; +}; + +struct fec_parms; + +/* k - number of actual data packets + * n - total number of packets including data and redundant packets + * (actual packet size isn't relevant here) */ +struct fec_parms *fec_new(int k, int n); +void fec_free(struct fec_parms *p); + +/* src - array of (n) pointers to data packets + * fec - buffer for packet to be generated + * index - index of packet to be generated (0 <= index < n) + * sz - data packet size + * + * _linear version just takes a pointer to the raw data; no + * mucking about with packet pointers. + */ +void fec_encode(struct fec_parms *code, unsigned char *src[], + unsigned char *fec, int index, int sz); +void fec_encode_linear(struct fec_parms *code, unsigned char *src, + unsigned char *fec, int index, int sz); + +/* data - array of (k) pointers to data packets, in arbitrary order (see i) + * i - indices of (data) packets + * sz - data packet size + * + * Will never fail as long as you give it (k) individual data packets. + * Will re-order the (data) pointers but not the indices -- data packets + * are ordered on return. + */ +int fec_decode(struct fec_parms *code, unsigned char *data[], + int i[], int sz); diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mkfs.jffs2.1 linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mkfs.jffs2.1 --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mkfs.jffs2.1 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mkfs.jffs2.1 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,259 @@ +.TH MKFS.JFFS2 1 +.SH NAME +mkfs.jffs2 \- Create a JFFS2 file system image from directory +.SH SYNOPSIS +.B mkfs.jffs2 +[ +.B -p,--pad[=SIZE] +] +[ +.B -r,-d,--root +.I directory +] +[ +.B -s,--pagesize=SIZE +] +[ +.B -e,--eraseblock=SIZE +] +[ +.B -c,--cleanmarker=SIZE +] +[ +.B -n,--no-cleanmarkers +] +[ +.B -o,--output +.I image.jffs2 +] +[ +.B -l,--little-endian +] +[ +.B -b,--big-endian +] +[ +.B -D,--devtable=FILE +] +[ +.B -f,--faketime +] +[ +.B -q,--squash +] +[ +.B -U,--squash-uids +] +[ +.B -P,--squash-perms +] +[ +.B --with-xattr +] +[ +.B --with-selinux +] +[ +.B --with-posix-acl +] +[ +.B -m,--compression-mode=MODE +] +[ +.B -x,--disable-compressor=NAME +] +[ +.B -X,--enable-compressor=NAME +] +[ +.B -y,--compressor-priority=PRIORITY:NAME +] +[ +.B -L,--list-compressors +] +[ +.B -t,--test-compression +] +[ +.B -h,--help +] +[ +.B -v,--verbose +] +[ +.B -V,--version +] +[ +.B -i,--incremental +.I image.jffs2 +] + +.SH DESCRIPTION +The program +.B mkfs.jffs2 +creates a JFFS2 (Second Journalling Flash File System) file system +image and writes the resulting image to the file specified by the +.B -o +option or by default to the standard output, unless the standard +output is a terminal device in which case mkfs.jffs2 will abort. + +The file system image is created using the files and directories +contained in the directory specified by the option +.B -r +or the present directory, if the +.B -r +option is not specified. + +Each block of the files to be placed into the file system image +are compressed using one of the avaiable compressors depending +on the selected compression mode. + +File systems are created with the same endianness as the host, +unless the +.B -b +or +.B -l +options are specified. JFFS2 driver in the 2.4 Linux kernel only +supported images having the same endianness as the CPU. As of 2.5.48, +the kernel can be changed with a #define to accept images of the +non-native endianness. Full bi-endian support in the kernel is not +planned. + +It is unlikely that JFFS2 images are useful except in conjuction +with the MTD (Memory Technology Device) drivers in the Linux +kernel, since the JFFS2 file system driver in the kernel requires +MTD devices. +.SH OPTIONS +Options that take SIZE arguments can be specified as either +decimal (e.g., 65536), octal (0200000), or hexidecimal (0x1000). +.TP +.B -p, --pad[=SIZE] +Pad output to SIZE bytes with 0xFF. If SIZE is not specified, +the output is padded to the end of the final erase block. +.TP +.B -r, -d, --root=DIR +Build file system from directory DIR. The default is the current +directory. +.TP +.B -s, --pagesize=SIZE +Use page size SIZE. The default is 4 KiB. This size is the +maximum size of a data node. +.TP +.B -e, --eraseblock=SIZE +Use erase block size SIZE. The default is 64 KiB. If you use a erase +block size different than the erase block size of the target MTD +device, JFFS2 may not perform optimally. If the SIZE specified is +below 4096, the units are assumed to be KiB. +.TP +.B -c, --cleanmarker=SIZE +Write \'CLEANMARKER\' nodes with the size specified. It is not +normally appropriate to specify a size other than the default 12 +bytes. +.TP +.B -n, --no-cleanmarkers +Do not write \'CLEANMARKER\' nodes to the beginning of each erase +block. This option can be useful for creating JFFS2 images for +use on NAND flash, and for creating images which are to be used +on a variety of hardware with differing eraseblock sizes. +.TP +.B -o, --output=FILE +Write JFFS2 image to file FILE. Default is the standard output. +.TP +.B -l, --little-endian +Create a little-endian JFFS2 image. Default is to make an image +with the same endianness as the host. +.TP +.B -b, --big-endian +Create a big-endian JFFS2 image. Default is to make an image +with the same endianness as the host. +.TP +.B -D, --devtable=FILE +Use the named FILE as a device table file, for including devices and +changing permissions in the created image when the user does not have +appropriate permissions to create them on the file system used as +source. +.TP +.B -f, --faketime +Change all file timestamps to \'0\' for regression testing. +.TP +.B -q, --squash +Squash permissions and owners, making all files be owned by root and +removing write permission for \'group\' and \'other\'. +.TP +.B -U, --squash-uids +Squash owners making all files be owned by root. +.TP +.B -P, --squash-perms +Squash permissions, removing write permission for \'group\' and \'other\'. +.TP +.B --with-xattr +Enables xattr, stuff all xattr entries into jffs2 image file. +.TP +.B --with-selinux +Enables xattr, stuff only SELinux Labels into jffs2 image file. +.TP +.B --with-posix-acl +Enable xattr, stuff only POSIX ACL entries into jffs2 image file. +.TP +.B -m, --compression-mode=MODE +Set the default compression mode. The default mode is +.B priority +which tries the compressors in a predefinied order and chooses the first +successful one. The alternatives are: +.B none +(mkfs will not compress) and +.B size +(mkfs will try all compressor and chooses the one which have the smallest result). +.TP +.B -x, --disable-compressor=NAME +Disable a compressor. Use +.B -L +to see the list of the avaiable compressors and their default states. +.TP +.B -X, --enable-compressor=NAME +Enable a compressor. Use +.B -L +to see the list of the avaiable compressors and their default states. +.TP +.B -y, --compressor-priority=PRIORITY:NAME +Set the priority of a compressor. Use +.B -L +to see the list of the avaiable compressors and their default priority. +Priorities are used by priority compression mode. +.TP +.B -L, --list-compressors +Show the list of the avaiable compressors and their states. +.TP +.B -t, --test-compression +Call decompress after every compress - and compare the result with the original data -, and +some other check. +.TP +.B -h, --help +Display help text. +.TP +.B -v, --verbose +Verbose operation. +.TP +.B -V, --version +Display version information. +.TP +.B -i, --incremental=FILE +Generate an appendage image for FILE. If FILE is written to flash and flash +is appended with the output, then it seems as if it was one thing. + +.SH BUGS +JFFS2 limits device major and minor numbers to 8 bits each. Some +consider this a bug. + +.B mkfs.jffs2 +does not properly handle hard links in the input directory structure. +Currently, hard linked files will be expanded to multiple identical +files in the output image. +.SH AUTHORS +David Woodhouse +.br +Manual page written by David Schleef +.SH SEE ALSO +.BR mkfs (8), +.BR mkfs.jffs (1), +.BR fakeroot (1) diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mkfs.jffs2.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mkfs.jffs2.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mkfs.jffs2.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mkfs.jffs2.c 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,1902 @@ +/* vi: set sw=4 ts=4: */ +/* + * Build a JFFS2 image in a file, from a given directory tree. + * + * Copyright 2001, 2002 Red Hat, Inc. + * 2001 David A. Schleef + * 2002 Axis Communications AB + * 2001, 2002 Erik Andersen + * 2004 University of Szeged, Hungary + * 2006 KaiGai Kohei + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Cross-endian support added by David Schleef . + * + * Major architectural rewrite by Erik Andersen + * to allow support for making hard links (though hard links support is + * not yet implemented), and for munging file permissions and ownership + * on the fly using --faketime, --squash, --devtable. And I plugged a + * few memory leaks, adjusted the error handling and fixed some little + * nits here and there. + * + * I also added a sample device table file. See device_table.txt + * -Erik, September 2001 + * + * Cleanmarkers support added by Axis Communications AB + * + * Rewritten again. Cleanly separated host and target filsystem + * activities (mainly so I can reuse all the host handling stuff as I + * rewrite other mkfs utils). Added a verbose option to list types + * and attributes as files are added to the file system. Major cleanup + * and scrubbing of the code so it can be read, understood, and + * modified by mere mortals. + * + * -Erik, November 2002 + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef WITHOUT_XATTR +#include +#include +#endif +#include +#define crc32 __complete_crap +#include +#undef crc32 +#include "crc32.h" +#include "rbtree.h" + +/* Do not use the weird XPG version of basename */ +#undef basename + +//#define DMALLOC +//#define mkfs_debug_msg error_msg +#define mkfs_debug_msg(a...) { } +#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; }) + +#define PAD(x) (((x)+3)&~3) + +struct filesystem_entry { + char *name; /* Name of this directory (think basename) */ + char *path; /* Path of this directory (think dirname) */ + char *fullname; /* Full name of this directory (i.e. path+name) */ + char *hostname; /* Full path to this file on the host filesystem */ + uint32_t ino; /* Inode number of this file in JFFS2 */ + struct stat sb; /* Stores directory permissions and whatnot */ + char *link; /* Target a symlink points to. */ + struct filesystem_entry *parent; /* Parent directory */ + struct filesystem_entry *prev; /* Only relevant to non-directories */ + struct filesystem_entry *next; /* Only relevant to non-directories */ + struct filesystem_entry *files; /* Only relevant to directories */ + struct rb_node hardlink_rb; +}; + +struct rb_root hardlinks; +static int out_fd = -1; +static int in_fd = -1; +static char default_rootdir[] = "."; +static char *rootdir = default_rootdir; +static int verbose = 0; +static int squash_uids = 0; +static int squash_perms = 0; +static int fake_times = 0; +int target_endian = __BYTE_ORDER; +static const char *const app_name = "mkfs.jffs2"; +static const char *const memory_exhausted = "memory exhausted"; + +uint32_t find_hardlink(struct filesystem_entry *e) +{ + struct filesystem_entry *f; + struct rb_node **n = &hardlinks.rb_node; + struct rb_node *parent = NULL; + + while (*n) { + parent = *n; + f = rb_entry(parent, struct filesystem_entry, hardlink_rb); + + if ((f->sb.st_dev < e->sb.st_dev) || + (f->sb.st_dev == e->sb.st_dev && + f->sb.st_ino < e->sb.st_ino)) + n = &parent->rb_left; + else if ((f->sb.st_dev > e->sb.st_dev) || + (f->sb.st_dev == e->sb.st_dev && + f->sb.st_ino > e->sb.st_ino)) { + n = &parent->rb_right; + } else + return f->ino; + } + + rb_link_node(&e->hardlink_rb, parent, n); + rb_insert_color(&e->hardlink_rb, &hardlinks); + return 0; +} + +static void verror_msg(const char *s, va_list p) +{ + fflush(stdout); + fprintf(stderr, "%s: ", app_name); + vfprintf(stderr, s, p); +} +static void error_msg(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg(s, p); + va_end(p); + putc('\n', stderr); +} + +static void error_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg(s, p); + va_end(p); + putc('\n', stderr); + exit(EXIT_FAILURE); +} + +static void vperror_msg(const char *s, va_list p) +{ + int err = errno; + + if (s == 0) + s = ""; + verror_msg(s, p); + if (*s) + s = ": "; + fprintf(stderr, "%s%s\n", s, strerror(err)); +} + +static void perror_msg(const char *s, ...) +{ + va_list p; + + va_start(p, s); + vperror_msg(s, p); + va_end(p); +} + +static void perror_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + vperror_msg(s, p); + va_end(p); + exit(EXIT_FAILURE); +} + +#ifndef DMALLOC +extern void *xmalloc(size_t size) +{ + void *ptr = malloc(size); + + if (ptr == NULL && size != 0) + error_msg_and_die(memory_exhausted); + return ptr; +} + +extern void *xcalloc(size_t nmemb, size_t size) +{ + void *ptr = calloc(nmemb, size); + + if (ptr == NULL && nmemb != 0 && size != 0) + error_msg_and_die(memory_exhausted); + return ptr; +} + +extern void *xrealloc(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr == NULL && size != 0) + error_msg_and_die(memory_exhausted); + return ptr; +} + +extern char *xstrdup(const char *s) +{ + char *t; + + if (s == NULL) + return NULL; + t = strdup(s); + if (t == NULL) + error_msg_and_die(memory_exhausted); + return t; +} +#endif + +extern char *xreadlink(const char *path) +{ + static const int GROWBY = 80; /* how large we will grow strings by */ + + char *buf = NULL; + int bufsize = 0, readsize = 0; + + do { + buf = xrealloc(buf, bufsize += GROWBY); + readsize = readlink(path, buf, bufsize); /* 1st try */ + if (readsize == -1) { + perror_msg("%s:%s", app_name, path); + return NULL; + } + } + while (bufsize < readsize + 1); + + buf[readsize] = '\0'; + + return buf; +} +static FILE *xfopen(const char *path, const char *mode) +{ + FILE *fp; + if ((fp = fopen(path, mode)) == NULL) + perror_msg_and_die("%s", path); + return fp; +} + +static struct filesystem_entry *find_filesystem_entry( + struct filesystem_entry *dir, char *fullname, uint32_t type) +{ + struct filesystem_entry *e = dir; + + if (S_ISDIR(dir->sb.st_mode)) { + e = dir->files; + } + while (e) { + /* Only bother to do the expensive strcmp on matching file types */ + if (type == (e->sb.st_mode & S_IFMT)) { + if (S_ISDIR(e->sb.st_mode)) { + int len = strlen(e->fullname); + + /* Check if we are a parent of the correct path */ + if (strncmp(e->fullname, fullname, len) == 0) { + /* Is this an _exact_ match? */ + if (strcmp(fullname, e->fullname) == 0) { + return (e); + } + /* Looks like we found a parent of the correct path */ + if (fullname[len] == '/') { + if (e->files) { + return (find_filesystem_entry (e, fullname, type)); + } else { + return NULL; + } + } + } + } else { + if (strcmp(fullname, e->fullname) == 0) { + return (e); + } + } + } + e = e->next; + } + return (NULL); +} + +static struct filesystem_entry *add_host_filesystem_entry( + char *name, char *path, unsigned long uid, unsigned long gid, + unsigned long mode, dev_t rdev, struct filesystem_entry *parent) +{ + int status; + char *tmp; + struct stat sb; + time_t timestamp = time(NULL); + struct filesystem_entry *entry; + + memset(&sb, 0, sizeof(struct stat)); + status = lstat(path, &sb); + + if (status >= 0) { + /* It is ok for some types of files to not exit on disk (such as + * device nodes), but if they _do_ exist the specified mode had + * better match the actual file or strange things will happen.... */ + if ((mode & S_IFMT) != (sb.st_mode & S_IFMT)) { + error_msg_and_die ("%s: file type does not match specified type!", path); + } + timestamp = sb.st_mtime; + } else { + /* If this is a regular file, it _must_ exist on disk */ + if ((mode & S_IFMT) == S_IFREG) { + error_msg_and_die("%s: does not exist!", path); + } + } + + /* Squash all permissions so files are owned by root, all + * timestamps are _right now_, and file permissions + * have group and other write removed */ + if (squash_uids) { + uid = gid = 0; + } + if (squash_perms) { + if (!S_ISLNK(mode)) { + mode &= ~(S_IWGRP | S_IWOTH); + mode &= ~(S_ISUID | S_ISGID); + } + } + if (fake_times) { + timestamp = 0; + } + + entry = xcalloc(1, sizeof(struct filesystem_entry)); + + entry->hostname = xstrdup(path); + entry->fullname = xstrdup(name); + tmp = xstrdup(name); + entry->name = xstrdup(basename(tmp)); + free(tmp); + tmp = xstrdup(name); + entry->path = xstrdup(dirname(tmp)); + free(tmp); + + entry->sb.st_ino = sb.st_ino; + entry->sb.st_dev = sb.st_dev; + entry->sb.st_nlink = sb.st_nlink; + + entry->sb.st_uid = uid; + entry->sb.st_gid = gid; + entry->sb.st_mode = mode; + entry->sb.st_rdev = rdev; + entry->sb.st_atime = entry->sb.st_ctime = + entry->sb.st_mtime = timestamp; + if (S_ISREG(mode)) { + entry->sb.st_size = sb.st_size; + } + if (S_ISLNK(mode)) { + entry->link = xreadlink(path); + entry->sb.st_size = strlen(entry->link); + } + + /* This happens only for root */ + if (!parent) + return (entry); + + /* Hook the file into the parent directory */ + entry->parent = parent; + if (!parent->files) { + parent->files = entry; + } else { + struct filesystem_entry *prev; + for (prev = parent->files; prev->next; prev = prev->next); + prev->next = entry; + entry->prev = prev; + } + + return (entry); +} + +static struct filesystem_entry *recursive_add_host_directory( + struct filesystem_entry *parent, char *targetpath, char *hostpath) +{ + int i, n; + struct stat sb; + char *hpath, *tpath; + struct dirent *dp, **namelist; + struct filesystem_entry *entry; + + + if (lstat(hostpath, &sb)) { + perror_msg_and_die("%s", hostpath); + } + + entry = add_host_filesystem_entry(targetpath, hostpath, + sb.st_uid, sb.st_gid, sb.st_mode, 0, parent); + + n = scandir(hostpath, &namelist, 0, alphasort); + if (n < 0) { + perror_msg_and_die("opening directory %s", hostpath); + } + + for (i=0; id_name[0] == '.' && (dp->d_name[1] == 0 || + (dp->d_name[1] == '.' && dp->d_name[2] == 0))) + { + free(dp); + continue; + } + + asprintf(&hpath, "%s/%s", hostpath, dp->d_name); + if (lstat(hpath, &sb)) { + perror_msg_and_die("%s", hpath); + } + if (strcmp(targetpath, "/") == 0) { + asprintf(&tpath, "%s%s", targetpath, dp->d_name); + } else { + asprintf(&tpath, "%s/%s", targetpath, dp->d_name); + } + + switch (sb.st_mode & S_IFMT) { + case S_IFDIR: + recursive_add_host_directory(entry, tpath, hpath); + break; + + case S_IFREG: + case S_IFSOCK: + case S_IFIFO: + case S_IFLNK: + case S_IFCHR: + case S_IFBLK: + add_host_filesystem_entry(tpath, hpath, sb.st_uid, + sb.st_gid, sb.st_mode, sb.st_rdev, entry); + break; + + default: + error_msg("Unknown file type %o for %s", sb.st_mode, hpath); + break; + } + free(dp); + free(hpath); + free(tpath); + } + free(namelist); + return (entry); +} + +/* the GNU C library has a wonderful scanf("%as", string) which will + allocate the string with the right size, good to avoid buffer overruns. + the following macros use it if available or use a hacky workaround... + */ + +#ifdef __GNUC__ +#define SCANF_PREFIX "a" +#define SCANF_STRING(s) (&s) +#define GETCWD_SIZE 0 +#else +#define SCANF_PREFIX "511" +#define SCANF_STRING(s) (s = malloc(512)) +#define GETCWD_SIZE -1 +inline int snprintf(char *str, size_t n, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vsprintf(str, fmt, ap); + va_end(ap); + return ret; +} +#endif + +/* device table entries take the form of: + + /dev/mem c 640 0 0 1 1 0 0 - + + type can be one of: + f A regular file + d Directory + c Character special device file + b Block special device file + p Fifo (named pipe) + + I don't bother with symlinks (permissions are irrelevant), hard + links (special cases of regular files), or sockets (why bother). + + Regular files must exist in the target root directory. If a char, + block, fifo, or directory does not exist, it will be created. + */ +static int interpret_table_entry(struct filesystem_entry *root, char *line) +{ + char *hostpath; + char type, *name = NULL, *tmp, *dir; + unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0; + unsigned long start = 0, increment = 1, count = 0; + struct filesystem_entry *parent, *entry; + + if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu", + SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor, + &start, &increment, &count) < 0) + { + return 1; + } + + if (!strcmp(name, "/")) { + error_msg_and_die("Device table entries require absolute paths"); + } + + asprintf(&hostpath, "%s%s", rootdir, name); + + /* Check if this file already exists... */ + switch (type) { + case 'd': + mode |= S_IFDIR; + break; + case 'f': + mode |= S_IFREG; + break; + case 'p': + mode |= S_IFIFO; + break; + case 'c': + mode |= S_IFCHR; + break; + case 'b': + mode |= S_IFBLK; + break; + default: + error_msg_and_die("Unsupported file type"); + } + entry = find_filesystem_entry(root, name, mode); + if (entry) { + /* Ok, we just need to fixup the existing entry + * and we will be all done... */ + entry->sb.st_uid = uid; + entry->sb.st_gid = gid; + entry->sb.st_mode = mode; + if (major && minor) { + entry->sb.st_rdev = makedev(major, minor); + } + } else { + /* If parent is NULL (happens with device table entries), + * try and find our parent now) */ + tmp = strdup(name); + dir = dirname(tmp); + parent = find_filesystem_entry(root, dir, S_IFDIR); + free(tmp); + if (parent == NULL) { + error_msg ("skipping device_table entry '%s': no parent directory!", name); + free(name); + free(hostpath); + return 1; + } + + switch (type) { + case 'd': + add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent); + break; + case 'f': + add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent); + break; + case 'p': + add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent); + break; + case 'c': + case 'b': + if (count > 0) { + dev_t rdev; + unsigned long i; + char *dname, *hpath; + + for (i = start; i < count; i++) { + asprintf(&dname, "%s%lu", name, i); + asprintf(&hpath, "%s/%s%lu", rootdir, name, i); + rdev = makedev(major, minor + (i * increment - start)); + add_host_filesystem_entry(dname, hpath, uid, gid, + mode, rdev, parent); + free(dname); + free(hpath); + } + } else { + dev_t rdev = makedev(major, minor); + add_host_filesystem_entry(name, hostpath, uid, gid, + mode, rdev, parent); + } + break; + default: + error_msg_and_die("Unsupported file type"); + } + } + free(name); + free(hostpath); + return 0; +} + +static int parse_device_table(struct filesystem_entry *root, FILE * file) +{ + char *line; + int status = 0; + size_t length = 0; + + /* Turn off squash, since we must ensure that values + * entered via the device table are not squashed */ + squash_uids = 0; + squash_perms = 0; + + /* Looks ok so far. The general plan now is to read in one + * line at a time, check for leading comment delimiters ('#'), + * then try and parse the line as a device table. If we fail + * to parse things, try and help the poor fool to fix their + * device table with a useful error msg... */ + line = NULL; + while (getline(&line, &length, file) != -1) { + /* First trim off any whitespace */ + int len = strlen(line); + + /* trim trailing whitespace */ + while (len > 0 && isspace(line[len - 1])) + line[--len] = '\0'; + /* trim leading whitespace */ + memmove(line, &line[strspn(line, " \n\r\t\v")], len); + + /* How long are we after trimming? */ + len = strlen(line); + + /* If this is NOT a comment line, try to interpret it */ + if (len && *line != '#') { + if (interpret_table_entry(root, line)) + status = 1; + } + + free(line); + line = NULL; + } + fclose(file); + + return status; +} + +static void cleanup(struct filesystem_entry *dir) +{ + struct filesystem_entry *e, *prev; + + e = dir->files; + while (e) { + if (e->name) + free(e->name); + if (e->path) + free(e->path); + if (e->fullname) + free(e->fullname); + e->next = NULL; + e->name = NULL; + e->path = NULL; + e->fullname = NULL; + e->prev = NULL; + prev = e; + if (S_ISDIR(e->sb.st_mode)) { + cleanup(e); + } + e = e->next; + free(prev); + } +} + +/* Here is where we do the actual creation of the file system */ +#include "mtd/jffs2-user.h" + +#define JFFS2_MAX_FILE_SIZE 0xFFFFFFFF +#ifndef JFFS2_MAX_SYMLINK_LEN +#define JFFS2_MAX_SYMLINK_LEN 254 +#endif + +static uint32_t ino = 0; +static uint8_t *file_buffer = NULL; /* file buffer contains the actual erase block*/ +static int out_ofs = 0; +static int erase_block_size = 65536; +static int pad_fs_size = 0; +static int add_cleanmarkers = 1; +static struct jffs2_unknown_node cleanmarker; +static int cleanmarker_size = sizeof(cleanmarker); +static unsigned char ffbuf[16] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +}; + +/* We set this at start of main() using sysconf(), -1 means we don't know */ +/* When building an fs for non-native systems, use --pagesize=SIZE option */ +int page_size = -1; + +#include "compr.h" + +static void full_write(int fd, const void *buf, int len) +{ + int ret; + + while (len > 0) { + ret = write(fd, buf, len); + + if (ret < 0) + perror_msg_and_die("write"); + + if (ret == 0) + perror_msg_and_die("write returned zero"); + + len -= ret; + buf += ret; + out_ofs += ret; + } +} + +static void padblock(void) +{ + while (out_ofs % erase_block_size) { + full_write(out_fd, ffbuf, min(sizeof(ffbuf), + erase_block_size - (out_ofs % erase_block_size))); + } +} + +static void pad(int req) +{ + while (req) { + if (req > sizeof(ffbuf)) { + full_write(out_fd, ffbuf, sizeof(ffbuf)); + req -= sizeof(ffbuf); + } else { + full_write(out_fd, ffbuf, req); + req = 0; + } + } +} + +static inline void padword(void) +{ + if (out_ofs % 4) { + full_write(out_fd, ffbuf, 4 - (out_ofs % 4)); + } +} + +static inline void pad_block_if_less_than(int req) +{ + if (add_cleanmarkers) { + if ((out_ofs % erase_block_size) == 0) { + full_write(out_fd, &cleanmarker, sizeof(cleanmarker)); + pad(cleanmarker_size - sizeof(cleanmarker)); + padword(); + } + } + if ((out_ofs % erase_block_size) + req > erase_block_size) { + padblock(); + } + if (add_cleanmarkers) { + if ((out_ofs % erase_block_size) == 0) { + full_write(out_fd, &cleanmarker, sizeof(cleanmarker)); + pad(cleanmarker_size - sizeof(cleanmarker)); + padword(); + } + } +} + +static void write_dirent(struct filesystem_entry *e) +{ + char *name = e->name; + struct jffs2_raw_dirent rd; + struct stat *statbuf = &(e->sb); + static uint32_t version = 0; + + memset(&rd, 0, sizeof(rd)); + + rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); + rd.totlen = cpu_to_je32(sizeof(rd) + strlen(name)); + rd.hdr_crc = cpu_to_je32(crc32(0, &rd, + sizeof(struct jffs2_unknown_node) - 4)); + rd.pino = cpu_to_je32((e->parent) ? e->parent->ino : 1); + rd.version = cpu_to_je32(version++); + rd.ino = cpu_to_je32(e->ino); + rd.mctime = cpu_to_je32(statbuf->st_mtime); + rd.nsize = strlen(name); + rd.type = IFTODT(statbuf->st_mode); + //rd.unused[0] = 0; + //rd.unused[1] = 0; + rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd) - 8)); + rd.name_crc = cpu_to_je32(crc32(0, name, strlen(name))); + + pad_block_if_less_than(sizeof(rd) + rd.nsize); + full_write(out_fd, &rd, sizeof(rd)); + full_write(out_fd, name, rd.nsize); + padword(); +} + +static unsigned int write_regular_file(struct filesystem_entry *e) +{ + int fd, len; + uint32_t ver; + unsigned int offset; + unsigned char *buf, *cbuf, *wbuf; + struct jffs2_raw_inode ri; + struct stat *statbuf; + unsigned int totcomp = 0; + + statbuf = &(e->sb); + if (statbuf->st_size >= JFFS2_MAX_FILE_SIZE) { + error_msg("Skipping file \"%s\" too large.", e->path); + return -1; + } + fd = open(e->hostname, O_RDONLY); + if (fd == -1) { + perror_msg_and_die("%s: open file", e->hostname); + } + + e->ino = ++ino; + mkfs_debug_msg("writing file '%s' ino=%lu parent_ino=%lu", + e->name, (unsigned long) e->ino, + (unsigned long) e->parent->ino); + write_dirent(e); + + buf = xmalloc(page_size); + cbuf = NULL; + + ver = 0; + offset = 0; + + memset(&ri, 0, sizeof(ri)); + ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); + + ri.ino = cpu_to_je32(e->ino); + ri.mode = cpu_to_jemode(statbuf->st_mode); + ri.uid = cpu_to_je16(statbuf->st_uid); + ri.gid = cpu_to_je16(statbuf->st_gid); + ri.atime = cpu_to_je32(statbuf->st_atime); + ri.ctime = cpu_to_je32(statbuf->st_ctime); + ri.mtime = cpu_to_je32(statbuf->st_mtime); + ri.isize = cpu_to_je32(statbuf->st_size); + + while ((len = read(fd, buf, page_size))) { + unsigned char *tbuf = buf; + + if (len < 0) { + perror_msg_and_die("read"); + } + + while (len) { + uint32_t dsize, space; + uint16_t compression; + + pad_block_if_less_than(sizeof(ri) + JFFS2_MIN_DATA_LEN); + + dsize = len; + space = + erase_block_size - (out_ofs % erase_block_size) - + sizeof(ri); + if (space > dsize) + space = dsize; + + compression = jffs2_compress(tbuf, &cbuf, &dsize, &space); + + ri.compr = compression & 0xff; + ri.usercompr = (compression >> 8) & 0xff; + + if (ri.compr) { + wbuf = cbuf; + } else { + wbuf = tbuf; + dsize = space; + } + + ri.totlen = cpu_to_je32(sizeof(ri) + space); + ri.hdr_crc = cpu_to_je32(crc32(0, + &ri, sizeof(struct jffs2_unknown_node) - 4)); + + ri.version = cpu_to_je32(++ver); + ri.offset = cpu_to_je32(offset); + ri.csize = cpu_to_je32(space); + ri.dsize = cpu_to_je32(dsize); + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri) - 8)); + ri.data_crc = cpu_to_je32(crc32(0, wbuf, space)); + + full_write(out_fd, &ri, sizeof(ri)); + totcomp += sizeof(ri); + full_write(out_fd, wbuf, space); + totcomp += space; + padword(); + + if (tbuf != cbuf) { + free(cbuf); + cbuf = NULL; + } + + tbuf += dsize; + len -= dsize; + offset += dsize; + + } + } + if (!je32_to_cpu(ri.version)) { + /* Was empty file */ + pad_block_if_less_than(sizeof(ri)); + + ri.version = cpu_to_je32(++ver); + ri.totlen = cpu_to_je32(sizeof(ri)); + ri.hdr_crc = cpu_to_je32(crc32(0, + &ri, sizeof(struct jffs2_unknown_node) - 4)); + ri.csize = cpu_to_je32(0); + ri.dsize = cpu_to_je32(0); + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri) - 8)); + + full_write(out_fd, &ri, sizeof(ri)); + padword(); + } + free(buf); + close(fd); + return totcomp; +} + +static void write_symlink(struct filesystem_entry *e) +{ + int len; + struct stat *statbuf; + struct jffs2_raw_inode ri; + + statbuf = &(e->sb); + e->ino = ++ino; + mkfs_debug_msg("writing symlink '%s' ino=%lu parent_ino=%lu", + e->name, (unsigned long) e->ino, + (unsigned long) e->parent->ino); + write_dirent(e); + + len = strlen(e->link); + if (len > JFFS2_MAX_SYMLINK_LEN) { + error_msg("symlink too large. Truncated to %d chars.", + JFFS2_MAX_SYMLINK_LEN); + len = JFFS2_MAX_SYMLINK_LEN; + } + + memset(&ri, 0, sizeof(ri)); + + ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); + ri.totlen = cpu_to_je32(sizeof(ri) + len); + ri.hdr_crc = cpu_to_je32(crc32(0, + &ri, sizeof(struct jffs2_unknown_node) - 4)); + + ri.ino = cpu_to_je32(e->ino); + ri.mode = cpu_to_jemode(statbuf->st_mode); + ri.uid = cpu_to_je16(statbuf->st_uid); + ri.gid = cpu_to_je16(statbuf->st_gid); + ri.atime = cpu_to_je32(statbuf->st_atime); + ri.ctime = cpu_to_je32(statbuf->st_ctime); + ri.mtime = cpu_to_je32(statbuf->st_mtime); + ri.isize = cpu_to_je32(statbuf->st_size); + ri.version = cpu_to_je32(1); + ri.csize = cpu_to_je32(len); + ri.dsize = cpu_to_je32(len); + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri) - 8)); + ri.data_crc = cpu_to_je32(crc32(0, e->link, len)); + + pad_block_if_less_than(sizeof(ri) + len); + full_write(out_fd, &ri, sizeof(ri)); + full_write(out_fd, e->link, len); + padword(); +} + +static void write_pipe(struct filesystem_entry *e) +{ + struct stat *statbuf; + struct jffs2_raw_inode ri; + + statbuf = &(e->sb); + e->ino = ++ino; + if (S_ISDIR(statbuf->st_mode)) { + mkfs_debug_msg("writing dir '%s' ino=%lu parent_ino=%lu", + e->name, (unsigned long) e->ino, + (unsigned long) (e->parent) ? e->parent->ino : 1); + } + write_dirent(e); + + memset(&ri, 0, sizeof(ri)); + + ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); + ri.totlen = cpu_to_je32(sizeof(ri)); + ri.hdr_crc = cpu_to_je32(crc32(0, + &ri, sizeof(struct jffs2_unknown_node) - 4)); + + ri.ino = cpu_to_je32(e->ino); + ri.mode = cpu_to_jemode(statbuf->st_mode); + ri.uid = cpu_to_je16(statbuf->st_uid); + ri.gid = cpu_to_je16(statbuf->st_gid); + ri.atime = cpu_to_je32(statbuf->st_atime); + ri.ctime = cpu_to_je32(statbuf->st_ctime); + ri.mtime = cpu_to_je32(statbuf->st_mtime); + ri.isize = cpu_to_je32(0); + ri.version = cpu_to_je32(1); + ri.csize = cpu_to_je32(0); + ri.dsize = cpu_to_je32(0); + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri) - 8)); + ri.data_crc = cpu_to_je32(0); + + pad_block_if_less_than(sizeof(ri)); + full_write(out_fd, &ri, sizeof(ri)); + padword(); +} + +static void write_special_file(struct filesystem_entry *e) +{ + jint16_t kdev; + struct stat *statbuf; + struct jffs2_raw_inode ri; + + statbuf = &(e->sb); + e->ino = ++ino; + write_dirent(e); + + kdev = cpu_to_je16((major(statbuf->st_rdev) << 8) + + minor(statbuf->st_rdev)); + + memset(&ri, 0, sizeof(ri)); + + ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); + ri.totlen = cpu_to_je32(sizeof(ri) + sizeof(kdev)); + ri.hdr_crc = cpu_to_je32(crc32(0, + &ri, sizeof(struct jffs2_unknown_node) - 4)); + + ri.ino = cpu_to_je32(e->ino); + ri.mode = cpu_to_jemode(statbuf->st_mode); + ri.uid = cpu_to_je16(statbuf->st_uid); + ri.gid = cpu_to_je16(statbuf->st_gid); + ri.atime = cpu_to_je32(statbuf->st_atime); + ri.ctime = cpu_to_je32(statbuf->st_ctime); + ri.mtime = cpu_to_je32(statbuf->st_mtime); + ri.isize = cpu_to_je32(statbuf->st_size); + ri.version = cpu_to_je32(1); + ri.csize = cpu_to_je32(sizeof(kdev)); + ri.dsize = cpu_to_je32(sizeof(kdev)); + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri) - 8)); + ri.data_crc = cpu_to_je32(crc32(0, &kdev, sizeof(kdev))); + + pad_block_if_less_than(sizeof(ri) + sizeof(kdev)); + full_write(out_fd, &ri, sizeof(ri)); + full_write(out_fd, &kdev, sizeof(kdev)); + padword(); +} + +#ifndef WITHOUT_XATTR +typedef struct xattr_entry { + struct xattr_entry *next; + uint32_t xid; + int xprefix; + char *xname; + char *xvalue; + int name_len; + int value_len; +} xattr_entry_t; + +#define XATTR_BUFFER_SIZE (64 * 1024) /* 64KB */ +static uint32_t enable_xattr = 0; +static uint32_t highest_xid = 0; +static uint32_t highest_xseqno = 0; + +static struct { + int xprefix; + char *string; + int length; +} xprefix_tbl[] = { + { JFFS2_XPREFIX_USER, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN }, + { JFFS2_XPREFIX_SECURITY, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, + { JFFS2_XPREFIX_ACL_ACCESS, POSIX_ACL_XATTR_ACCESS, POSIX_ACL_XATTR_ACCESS_LEN }, + { JFFS2_XPREFIX_ACL_DEFAULT, POSIX_ACL_XATTR_DEFAULT, POSIX_ACL_XATTR_DEFAULT_LEN }, + { JFFS2_XPREFIX_TRUSTED, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN }, + { 0, NULL, 0 } +}; + +static void formalize_posix_acl(void *xvalue, int *value_len) +{ + struct posix_acl_xattr_header *pacl_header; + struct posix_acl_xattr_entry *pent, *plim; + struct jffs2_acl_header *jacl_header; + struct jffs2_acl_entry *jent; + struct jffs2_acl_entry_short *jent_s; + char buffer[XATTR_BUFFER_SIZE]; + int offset = 0; + + pacl_header = xvalue;; + pent = pacl_header->a_entries; + plim = xvalue + *value_len; + + jacl_header = (struct jffs2_acl_header *)buffer; + offset += sizeof(struct jffs2_acl_header); + jacl_header->a_version = cpu_to_je32(JFFS2_ACL_VERSION); + + while (pent < plim) { + switch(le16_to_cpu(pent->e_tag)) { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_MASK: + case ACL_OTHER: + jent_s = (struct jffs2_acl_entry_short *)(buffer + offset); + offset += sizeof(struct jffs2_acl_entry_short); + jent_s->e_tag = cpu_to_je16(le16_to_cpu(pent->e_tag)); + jent_s->e_perm = cpu_to_je16(le16_to_cpu(pent->e_perm)); + break; + case ACL_USER: + case ACL_GROUP: + jent = (struct jffs2_acl_entry *)(buffer + offset); + offset += sizeof(struct jffs2_acl_entry); + jent->e_tag = cpu_to_je16(le16_to_cpu(pent->e_tag)); + jent->e_perm = cpu_to_je16(le16_to_cpu(pent->e_perm)); + jent->e_id = cpu_to_je32(le32_to_cpu(pent->e_id)); + break; + default: + printf("%04x : Unknown XATTR entry tag.\n", le16_to_cpu(pent->e_tag)); + exit(1); + } + pent++; + } + if (offset > *value_len) { + printf("Length of JFFS2 ACL expression(%u) is longer than general one(%u).\n", + offset, *value_len); + exit(1); + } + memcpy(xvalue, buffer, offset); + *value_len = offset; +} + +static xattr_entry_t *create_xattr_entry(int xprefix, char *xname, char *xvalue, int value_len) +{ + xattr_entry_t *xe; + struct jffs2_raw_xattr rx; + int name_len; + + /* create xattr entry */ + name_len = strlen(xname); + xe = xcalloc(1, sizeof(xattr_entry_t) + name_len + 1 + value_len); + xe->next = NULL; + xe->xid = ++highest_xid; + xe->xprefix = xprefix; + xe->xname = ((char *)xe) + sizeof(xattr_entry_t); + xe->xvalue = xe->xname + name_len + 1; + xe->name_len = name_len; + xe->value_len = value_len; + strcpy(xe->xname, xname); + memcpy(xe->xvalue, xvalue, value_len); + + /* write xattr node */ + memset(&rx, 0, sizeof(rx)); + rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR); + rx.totlen = cpu_to_je32(PAD(sizeof(rx) + xe->name_len + 1 + xe->value_len)); + rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4)); + + rx.xid = cpu_to_je32(xe->xid); + rx.version = cpu_to_je32(1); /* initial version */ + rx.xprefix = xprefix; + rx.name_len = xe->name_len; + rx.value_len = cpu_to_je16(xe->value_len); + rx.data_crc = cpu_to_je32(crc32(0, xe->xname, xe->name_len + 1 + xe->value_len)); + rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(rx) - 4)); + + pad_block_if_less_than(sizeof(rx) + xe->name_len + 1 + xe->value_len); + full_write(out_fd, &rx, sizeof(rx)); + full_write(out_fd, xe->xname, xe->name_len + 1 + xe->value_len); + padword(); + + return xe; +} + +#define XATTRENTRY_HASHSIZE 57 +static xattr_entry_t *find_xattr_entry(int xprefix, char *xname, char *xvalue, int value_len) +{ + static xattr_entry_t **xentry_hash = NULL; + xattr_entry_t *xe; + int index, name_len; + + /* create hash table */ + if (!xentry_hash) + xentry_hash = xcalloc(1, sizeof(xe) * XATTRENTRY_HASHSIZE); + + if (xprefix == JFFS2_XPREFIX_ACL_ACCESS + || xprefix == JFFS2_XPREFIX_ACL_DEFAULT) + formalize_posix_acl(xvalue, &value_len); + + name_len = strlen(xname); + index = (crc32(0, xname, name_len) ^ crc32(0, xvalue, value_len)) % XATTRENTRY_HASHSIZE; + for (xe = xentry_hash[index]; xe; xe = xe->next) { + if (xe->xprefix == xprefix + && xe->value_len == value_len + && !strcmp(xe->xname, xname) + && !memcmp(xe->xvalue, xvalue, value_len)) + break; + } + if (!xe) { + xe = create_xattr_entry(xprefix, xname, xvalue, value_len); + xe->next = xentry_hash[index]; + xentry_hash[index] = xe; + } + return xe; +} + +static void write_xattr_entry(struct filesystem_entry *e) +{ + struct jffs2_raw_xref ref; + struct xattr_entry *xe; + char xlist[XATTR_BUFFER_SIZE], xvalue[XATTR_BUFFER_SIZE]; + char *xname, *prefix_str; + int i, xprefix, prefix_len; + int list_sz, offset, name_len, value_len; + + if (!enable_xattr) + return; + + list_sz = llistxattr(e->hostname, xlist, XATTR_BUFFER_SIZE); + if (list_sz < 0) { + if (verbose) + printf("llistxattr('%s') = %d : %s\n", + e->hostname, errno, strerror(errno)); + return; + } + + for (offset = 0; offset < list_sz; offset += name_len) { + xname = xlist + offset; + name_len = strlen(xname) + 1; + + for (i = 0; (xprefix = xprefix_tbl[i].xprefix); i++) { + prefix_str = xprefix_tbl[i].string; + prefix_len = xprefix_tbl[i].length; + if (prefix_str[prefix_len - 1] == '.') { + if (!strncmp(xname, prefix_str, prefix_len - 1)) + break; + } else { + if (!strcmp(xname, prefix_str)) + break; + } + } + if (!xprefix) { + if (verbose) + printf("%s: xattr '%s' is not supported.\n", + e->hostname, xname); + continue; + } + if ((enable_xattr & (1 << xprefix)) == 0) + continue; + + value_len = lgetxattr(e->hostname, xname, xvalue, XATTR_BUFFER_SIZE); + if (value_len < 0) { + if (verbose) + printf("lgetxattr('%s', '%s') = %d : %s\n", + e->hostname, xname, errno, strerror(errno)); + continue; + } + xe = find_xattr_entry(xprefix, xname + prefix_len, xvalue, value_len); + if (!xe) { + if (verbose) + printf("%s : xattr '%s' was ignored.\n", + e->hostname, xname); + continue; + } + + memset(&ref, 0, sizeof(ref)); + ref.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ref.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF); + ref.totlen = cpu_to_je32(sizeof(ref)); + ref.hdr_crc = cpu_to_je32(crc32(0, &ref, sizeof(struct jffs2_unknown_node) - 4)); + ref.ino = cpu_to_je32(e->ino); + ref.xid = cpu_to_je32(xe->xid); + ref.xseqno = cpu_to_je32(highest_xseqno += 2); + ref.node_crc = cpu_to_je32(crc32(0, &ref, sizeof(ref) - 4)); + + pad_block_if_less_than(sizeof(ref)); + full_write(out_fd, &ref, sizeof(ref)); + padword(); + } +} + +#else /* WITHOUT_XATTR */ +#define write_xattr_entry(x) +#endif + +static void recursive_populate_directory(struct filesystem_entry *dir) +{ + struct filesystem_entry *e; + unsigned int wrote; + + if (verbose) { + printf("%s\n", dir->fullname); + } + write_xattr_entry(dir); /* for '/' */ + + e = dir->files; + while (e) { + if (e->sb.st_nlink >= 1 && + (e->ino = find_hardlink(e))) { + + write_dirent(e); + if (verbose) { + printf("\tL %04o %9lu %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, (unsigned long) e->ino, + (int) (e->sb.st_uid), (int) (e->sb.st_gid), + e->name); + } + } else switch (e->sb.st_mode & S_IFMT) { + case S_IFDIR: + if (verbose) { + printf("\td %04o %9lu %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, e->sb.st_size, + (int) (e->sb.st_uid), (int) (e->sb.st_gid), + e->name); + } + write_pipe(e); + write_xattr_entry(e); + break; + case S_IFSOCK: + if (verbose) { + printf("\ts %04o %9lu %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, e->sb.st_size, + (int) e->sb.st_uid, (int) e->sb.st_gid, e->name); + } + write_pipe(e); + write_xattr_entry(e); + break; + case S_IFIFO: + if (verbose) { + printf("\tp %04o %9lu %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, e->sb.st_size, + (int) e->sb.st_uid, (int) e->sb.st_gid, e->name); + } + write_pipe(e); + write_xattr_entry(e); + break; + case S_IFCHR: + if (verbose) { + printf("\tc %04o %4d,%4d %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, major(e->sb.st_rdev), + minor(e->sb.st_rdev), (int) e->sb.st_uid, + (int) e->sb.st_gid, e->name); + } + write_special_file(e); + write_xattr_entry(e); + break; + case S_IFBLK: + if (verbose) { + printf("\tb %04o %4d,%4d %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, major(e->sb.st_rdev), + minor(e->sb.st_rdev), (int) e->sb.st_uid, + (int) e->sb.st_gid, e->name); + } + write_special_file(e); + write_xattr_entry(e); + break; + case S_IFLNK: + if (verbose) { + printf("\tl %04o %9lu %5d:%-3d %s -> %s\n", + e->sb.st_mode & ~S_IFMT, e->sb.st_size, + (int) e->sb.st_uid, (int) e->sb.st_gid, e->name, + e->link); + } + write_symlink(e); + write_xattr_entry(e); + break; + case S_IFREG: + wrote = write_regular_file(e); + write_xattr_entry(e); + if (verbose) { + printf("\tf %04o %9lu (%9u) %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, e->sb.st_size, wrote, + (int) e->sb.st_uid, (int) e->sb.st_gid, e->name); + } + break; + default: + error_msg("Unknown mode %o for %s", e->sb.st_mode, + e->fullname); + break; + } + e = e->next; + } + + e = dir->files; + while (e) { + if (S_ISDIR(e->sb.st_mode)) { + if (e->files) { + recursive_populate_directory(e); + } else if (verbose) { + printf("%s\n", e->fullname); + } + } + e = e->next; + } +} + +static void create_target_filesystem(struct filesystem_entry *root) +{ + cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); + cleanmarker.totlen = cpu_to_je32(cleanmarker_size); + cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node)-4)); + + if (ino == 0) + ino = 1; + + root->ino = 1; + recursive_populate_directory(root); + + if (pad_fs_size == -1) { + padblock(); + } else { + if (pad_fs_size && add_cleanmarkers){ + padblock(); + while (out_ofs < pad_fs_size) { + full_write(out_fd, &cleanmarker, sizeof(cleanmarker)); + pad(cleanmarker_size - sizeof(cleanmarker)); + padblock(); + } + } else { + while (out_ofs < pad_fs_size) { + full_write(out_fd, ffbuf, min(sizeof(ffbuf), pad_fs_size - out_ofs)); + } + + } + } +} + +static struct option long_options[] = { + {"pad", 2, NULL, 'p'}, + {"root", 1, NULL, 'r'}, + {"pagesize", 1, NULL, 's'}, + {"eraseblock", 1, NULL, 'e'}, + {"output", 1, NULL, 'o'}, + {"help", 0, NULL, 'h'}, + {"verbose", 0, NULL, 'v'}, + {"version", 0, NULL, 'V'}, + {"big-endian", 0, NULL, 'b'}, + {"little-endian", 0, NULL, 'l'}, + {"no-cleanmarkers", 0, NULL, 'n'}, + {"cleanmarker", 1, NULL, 'c'}, + {"squash", 0, NULL, 'q'}, + {"squash-uids", 0, NULL, 'U'}, + {"squash-perms", 0, NULL, 'P'}, + {"faketime", 0, NULL, 'f'}, + {"devtable", 1, NULL, 'D'}, + {"compression-mode", 1, NULL, 'm'}, + {"disable-compressor", 1, NULL, 'x'}, + {"test-compression", 0, NULL, 't'}, + {"compressor-priority", 1, NULL, 'y'}, + {"incremental", 1, NULL, 'i'}, +#ifndef WITHOUT_XATTR + {"with-xattr", 0, NULL, 1000 }, + {"with-selinux", 0, NULL, 1001 }, + {"with-posix-acl", 0, NULL, 1002 }, +#endif + {NULL, 0, NULL, 0} +}; + +static char *helptext = +"Usage: mkfs.jffs2 [OPTIONS]\n" +"Make a JFFS2 file system image from an existing directory tree\n\n" +"Options:\n" +" -p, --pad[=SIZE] Pad output to SIZE bytes with 0xFF. If SIZE is\n" +" not specified, the output is padded to the end of\n" +" the final erase block\n" +" -r, -d, --root=DIR Build file system from directory DIR (default: cwd)\n" +" -s, --pagesize=SIZE Use page size (max data node size) SIZE (default: 4KiB)\n" +" -e, --eraseblock=SIZE Use erase block size SIZE (default: 64KiB)\n" +" -c, --cleanmarker=SIZE Size of cleanmarker (default 12)\n" +" -m, --compr-mode=MODE Select compression mode (default: priortiry)\n" +" -x, --disable-compressor=COMPRESSOR_NAME\n" +" Disable a compressor\n" +" -X, --enable-compressor=COMPRESSOR_NAME\n" +" Enable a compressor\n" +" -y, --compressor-priority=PRIORITY:COMPRESSOR_NAME\n" +" Set the priority of a compressor\n" +" -L, --list-compressors Show the list of the avaiable compressors\n" +" -t, --test-compression Call decompress and compare with the original (for test)\n" +" -n, --no-cleanmarkers Don't add a cleanmarker to every eraseblock\n" +" -o, --output=FILE Output to FILE (default: stdout)\n" +" -l, --little-endian Create a little-endian filesystem\n" +" -b, --big-endian Create a big-endian filesystem\n" +" -D, --devtable=FILE Use the named FILE as a device table file\n" +" -f, --faketime Change all file times to '0' for regression testing\n" +" -q, --squash Squash permissions and owners making all files be owned by root\n" +" -U, --squash-uids Squash owners making all files be owned by root\n" +" -P, --squash-perms Squash permissions on all files\n" +#ifndef WITHOUT_XATTR +" --with-xattr stuff all xattr entries into image\n" +" --with-selinux stuff only SELinux Labels into jffs2 image\n" +" --with-posix-acl stuff only POSIX ACL entries into jffs2 image\n" +#endif +" -h, --help Display this help text\n" +" -v, --verbose Verbose operation\n" +" -V, --version Display version information\n" +" -i, --incremental=FILE Parse FILE and generate appendage output for it\n\n"; + +static char *revtext = "1.60"; + +int load_next_block() { + + int ret; + ret = read(in_fd, file_buffer, erase_block_size); + + if(verbose) + printf("Load next block : %d bytes read\n",ret); + + return ret; +} + +void process_buffer(int inp_size) { + uint8_t *p = file_buffer; + union jffs2_node_union *node; + uint16_t type; + int bitchbitmask = 0; + int obsolete; + + char name[256]; + + while ( p < (file_buffer + inp_size)) { + + node = (union jffs2_node_union *) p; + + /* Skip empty space */ + if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { + p += 4; + continue; + } + + if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { + if (!bitchbitmask++) + printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - file_buffer, je16_to_cpu (node->u.magic)); + p += 4; + continue; + } + + bitchbitmask = 0; + + type = je16_to_cpu(node->u.nodetype); + if ((type & JFFS2_NODE_ACCURATE) != JFFS2_NODE_ACCURATE) { + obsolete = 1; + type |= JFFS2_NODE_ACCURATE; + } else + obsolete = 0; + + node->u.nodetype = cpu_to_je16(type); + + switch(je16_to_cpu(node->u.nodetype)) { + + case JFFS2_NODETYPE_INODE: + if(verbose) + printf ("%8s Inode node at 0x%08x, totlen 0x%08x, #ino %5d, version %5d, isize %8d, csize %8d, dsize %8d, offset %8d\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->i.totlen), je32_to_cpu (node->i.ino), + je32_to_cpu ( node->i.version), je32_to_cpu (node->i.isize), + je32_to_cpu (node->i.csize), je32_to_cpu (node->i.dsize), je32_to_cpu (node->i.offset)); + + if ( je32_to_cpu (node->i.ino) > ino ) + ino = je32_to_cpu (node->i.ino); + + p += PAD(je32_to_cpu (node->i.totlen)); + break; + + case JFFS2_NODETYPE_DIRENT: + memcpy (name, node->d.name, node->d.nsize); + name [node->d.nsize] = 0x0; + + if(verbose) + printf ("%8s Dirent node at 0x%08x, totlen 0x%08x, #pino %5d, version %5d, #ino %8d, nsize %8d, name %s\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->d.totlen), je32_to_cpu (node->d.pino), + je32_to_cpu ( node->d.version), je32_to_cpu (node->d.ino), + node->d.nsize, name); + + p += PAD(je32_to_cpu (node->d.totlen)); + break; + + case JFFS2_NODETYPE_CLEANMARKER: + if (verbose) { + printf ("%8s Cleanmarker at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case JFFS2_NODETYPE_PADDING: + if (verbose) { + printf ("%8s Padding node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case 0xffff: + p += 4; + break; + + default: + if (verbose) { + printf ("%8s Unknown node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + + p += PAD(je32_to_cpu (node->u.totlen)); + } + } +} + +void parse_image(){ + int ret; + + file_buffer = malloc(erase_block_size); + + if (!file_buffer) { + perror("out of memory"); + close (in_fd); + close (out_fd); + exit(1); + } + + while ((ret = load_next_block())) { + process_buffer(ret); + } + + if (file_buffer) + free(file_buffer); + + close(in_fd); +} + +int main(int argc, char **argv) +{ + int c, opt; + char *cwd; + struct stat sb; + FILE *devtable = NULL; + struct filesystem_entry *root; + char *compr_name = NULL; + int compr_prior = -1; + int warn_page_size = 0; + + page_size = sysconf(_SC_PAGESIZE); + if (page_size < 0) /* System doesn't know so ... */ + page_size = 4096; /* ... we make an educated guess */ + if (page_size != 4096) + warn_page_size = 1; /* warn user if page size not 4096 */ + + jffs2_compressors_init(); + + while ((opt = getopt_long(argc, argv, + "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0) + { + switch (opt) { + case 'D': + devtable = xfopen(optarg, "r"); + if (fstat(fileno(devtable), &sb) < 0) + perror_msg_and_die(optarg); + if (sb.st_size < 10) + error_msg_and_die("%s: not a proper device table file", optarg); + break; + + case 'r': + case 'd': /* for compatibility with mkfs.jffs, genext2fs, etc... */ + if (rootdir != default_rootdir) { + error_msg_and_die("root directory specified more than once"); + } + rootdir = xstrdup(optarg); + break; + + case 's': + page_size = strtol(optarg, NULL, 0); + warn_page_size = 0; /* set by user, so don't need to warn */ + break; + + case 'o': + if (out_fd != -1) { + error_msg_and_die("output filename specified more than once"); + } + out_fd = open(optarg, O_CREAT | O_TRUNC | O_RDWR, 0644); + if (out_fd == -1) { + perror_msg_and_die("open output file"); + } + break; + + case 'q': + squash_uids = 1; + squash_perms = 1; + break; + + case 'U': + squash_uids = 1; + break; + + case 'P': + squash_perms = 1; + break; + + case 'f': + fake_times = 1; + break; + + case 'h': + case '?': + error_msg_and_die(helptext); + + case 'v': + verbose = 1; + break; + + case 'V': + error_msg_and_die("revision %s\n", revtext); + + case 'e': { + char *next; + unsigned units = 0; + erase_block_size = strtol(optarg, &next, 0); + if (!erase_block_size) + error_msg_and_die("Unrecognisable erase size\n"); + + if (*next) { + if (!strcmp(next, "KiB")) { + units = 1024; + } else if (!strcmp(next, "MiB")) { + units = 1024 * 1024; + } else { + error_msg_and_die("Unknown units in erasesize\n"); + } + } else { + if (erase_block_size < 0x1000) + units = 1024; + else + units = 1; + } + erase_block_size *= units; + + /* If it's less than 8KiB, they're not allowed */ + if (erase_block_size < 0x2000) { + fprintf(stderr, "Erase size 0x%x too small. Increasing to 8KiB minimum\n", + erase_block_size); + erase_block_size = 0x2000; + } + break; + } + + case 'l': + target_endian = __LITTLE_ENDIAN; + break; + + case 'b': + target_endian = __BIG_ENDIAN; + break; + + case 'p': + if (optarg) + pad_fs_size = strtol(optarg, NULL, 0); + else + pad_fs_size = -1; + break; + case 'n': + add_cleanmarkers = 0; + break; + case 'c': + cleanmarker_size = strtol(optarg, NULL, 0); + if (cleanmarker_size < sizeof(cleanmarker)) { + error_msg_and_die("cleanmarker size must be >= 12"); + } + if (cleanmarker_size >= erase_block_size) { + error_msg_and_die("cleanmarker size must be < eraseblock size"); + } + break; + case 'm': + if (jffs2_set_compression_mode_name(optarg)) { + error_msg_and_die("Unknown compression mode %s", optarg); + } + break; + case 'x': + if (jffs2_disable_compressor_name(optarg)) { + error_msg_and_die("Unknown compressor name %s",optarg); + } + break; + case 'X': + if (jffs2_enable_compressor_name(optarg)) { + error_msg_and_die("Unknown compressor name %s",optarg); + } + break; + case 'L': + error_msg_and_die("\n%s",jffs2_list_compressors()); + break; + case 't': + jffs2_compression_check_set(1); + break; + case 'y': + compr_name = malloc(strlen(optarg)); + sscanf(optarg,"%d:%s",&compr_prior,compr_name); + if ((compr_prior>=0)&&(compr_name)) { + if (jffs2_set_compressor_priority(compr_name, compr_prior)) + exit(EXIT_FAILURE); + } + else { + error_msg_and_die("Cannot parse %s",optarg); + } + free(compr_name); + break; + case 'i': + if (in_fd != -1) { + error_msg_and_die("(incremental) filename specified more than once"); + } + in_fd = open(optarg, O_RDONLY); + if (in_fd == -1) { + perror_msg_and_die("cannot open (incremental) file"); + } + break; +#ifndef WITHOUT_XATTR + case 1000: /* --with-xattr */ + enable_xattr |= (1 << JFFS2_XPREFIX_USER) + | (1 << JFFS2_XPREFIX_SECURITY) + | (1 << JFFS2_XPREFIX_ACL_ACCESS) + | (1 << JFFS2_XPREFIX_ACL_DEFAULT) + | (1 << JFFS2_XPREFIX_TRUSTED); + break; + case 1001: /* --with-selinux */ + enable_xattr |= (1 << JFFS2_XPREFIX_SECURITY); + break; + case 1002: /* --with-posix-acl */ + enable_xattr |= (1 << JFFS2_XPREFIX_ACL_ACCESS) + | (1 << JFFS2_XPREFIX_ACL_DEFAULT); + break; +#endif + } + } + if (warn_page_size) { + error_msg("Page size for this system is by default %d", page_size); + error_msg("Use the --pagesize=SIZE option if this is not what you want"); + } + if (out_fd == -1) { + if (isatty(1)) { + error_msg_and_die(helptext); + } + out_fd = 1; + } + if (lstat(rootdir, &sb)) { + perror_msg_and_die("%s", rootdir); + } + if (chdir(rootdir)) + perror_msg_and_die("%s", rootdir); + + if (!(cwd = getcwd(0, GETCWD_SIZE))) + perror_msg_and_die("getcwd failed"); + + if(in_fd != -1) + parse_image(); + + root = recursive_add_host_directory(NULL, "/", cwd); + + if (devtable) + parse_device_table(root, devtable); + + create_target_filesystem(root); + + cleanup(root); + + if (rootdir != default_rootdir) + free(rootdir); + + close(out_fd); + + if (verbose) { + char *s = jffs2_stats(); + fprintf(stderr,"\n\n%s",s); + free(s); + } + if ((verbose)||(jffs2_compression_check_get()&&(jffs2_compression_check_errorcnt_get()))) { + fprintf(stderr,"Compression errors: %d\n",jffs2_compression_check_errorcnt_get()); + } + + jffs2_compressors_exit(); + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mtd_debug.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mtd_debug.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mtd_debug.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mtd_debug.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2d3D, Inc. + * Written by Abraham vd Merwe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * MEMGETINFO + */ +static int getmeminfo (int fd,struct mtd_info_user *mtd) +{ + return (ioctl (fd,MEMGETINFO,mtd)); +} + +/* + * MEMERASE + */ +static int memerase (int fd,struct erase_info_user *erase) +{ + return (ioctl (fd,MEMERASE,erase)); +} + +/* + * MEMGETREGIONCOUNT + * MEMGETREGIONINFO + */ +static int getregions (int fd,struct region_info_user *regions,int *n) +{ + int i,err; + err = ioctl (fd,MEMGETREGIONCOUNT,n); + if (err) return (err); + for (i = 0; i < *n; i++) + { + regions[i].regionindex = i; + err = ioctl (fd,MEMGETREGIONINFO,®ions[i]); + if (err) return (err); + } + return (0); +} + +int erase_flash (int fd,u_int32_t offset,u_int32_t bytes) +{ + int err; + struct erase_info_user erase; + erase.start = offset; + erase.length = bytes; + err = memerase (fd,&erase); + if (err < 0) + { + perror ("MEMERASE"); + return (1); + } + fprintf (stderr,"Erased %d bytes from address 0x%.8x in flash\n",bytes,offset); + return (0); +} + +void printsize (u_int32_t x) +{ + int i; + static const char *flags = "KMGT"; + printf ("%u ",x); + for (i = 0; x >= 1024 && flags[i] != '\0'; i++) x /= 1024; + i--; + if (i >= 0) printf ("(%u%c)",x,flags[i]); +} + +int flash_to_file (int fd,u_int32_t offset,size_t len,const char *filename) +{ + u_int8_t *buf = NULL; + int outfd,err; + int size = len * sizeof (u_int8_t); + int n = len; + + if (offset != lseek (fd,offset,SEEK_SET)) + { + perror ("lseek()"); + goto err0; + } + outfd = creat (filename,O_WRONLY); + if (outfd < 0) + { + perror ("creat()"); + goto err1; + } + +retry: + if ((buf = (u_int8_t *) malloc (size)) == NULL) + { +#define BUF_SIZE (64 * 1024 * sizeof (u_int8_t)) + fprintf (stderr, "%s: malloc(%#x)\n", __FUNCTION__, size); + if (size != BUF_SIZE) { + size = BUF_SIZE; + fprintf (stderr, "%s: trying buffer size %#x\n", __FUNCTION__, size); + goto retry; + } + perror ("malloc()"); + goto err0; + } + do { + if (n <= size) + size = n; + err = read (fd,buf,size); + if (err < 0) + { + fprintf (stderr, "%s: read, size %#x, n %#x\n", __FUNCTION__, size, n); + perror ("read()"); + goto err2; + } + err = write (outfd,buf,size); + if (err < 0) + { + fprintf (stderr, "%s: write, size %#x, n %#x\n", __FUNCTION__, size, n); + perror ("write()"); + goto err2; + } + if (err != size) + { + fprintf (stderr,"Couldn't copy entire buffer to %s. (%d/%d bytes copied)\n",filename,err,size); + goto err2; + } + n -= size; + } while (n > 0); + + if (buf != NULL) + free (buf); + close (outfd); + printf ("Copied %d bytes from address 0x%.8x in flash to %s\n",len,offset,filename); + return (0); + +err2: + close (outfd); +err1: + if (buf != NULL) + free (buf); +err0: + return (1); +} + +int file_to_flash (int fd,u_int32_t offset,u_int32_t len,const char *filename) +{ + u_int8_t *buf = NULL; + FILE *fp; + int err; + int size = len * sizeof (u_int8_t); + int n = len; + + if (offset != lseek (fd,offset,SEEK_SET)) + { + perror ("lseek()"); + return (1); + } + if ((fp = fopen (filename,"r")) == NULL) + { + perror ("fopen()"); + return (1); + } +retry: + if ((buf = (u_int8_t *) malloc (size)) == NULL) + { + fprintf (stderr, "%s: malloc(%#x) failed\n", __FUNCTION__, size); + if (size != BUF_SIZE) { + size = BUF_SIZE; + fprintf (stderr, "%s: trying buffer size %#x\n", __FUNCTION__, size); + goto retry; + } + perror ("malloc()"); + fclose (fp); + return (1); + } + do { + if (n <= size) + size = n; + if (fread (buf,size,1,fp) != 1 || ferror (fp)) + { + fprintf (stderr, "%s: fread, size %#x, n %#x\n", __FUNCTION__, size, n); + perror ("fread()"); + free (buf); + fclose (fp); + return (1); + } + err = write (fd,buf,size); + if (err < 0) + { + fprintf (stderr, "%s: write, size %#x, n %#x\n", __FUNCTION__, size, n); + perror ("write()"); + free (buf); + fclose (fp); + return (1); + } + n -= size; + } while (n > 0); + + if (buf != NULL) + free (buf); + fclose (fp); + printf ("Copied %d bytes from %s to address 0x%.8x in flash\n",len,filename,offset); + return (0); +} + +int showinfo (int fd) +{ + int i,err,n; + struct mtd_info_user mtd; + static struct region_info_user region[1024]; + + err = getmeminfo (fd,&mtd); + if (err < 0) + { + perror ("MEMGETINFO"); + return (1); + } + + err = getregions (fd,region,&n); + if (err < 0) + { + perror ("MEMGETREGIONCOUNT"); + return (1); + } + + printf ("mtd.type = "); + switch (mtd.type) + { + case MTD_ABSENT: + printf ("MTD_ABSENT"); + break; + case MTD_RAM: + printf ("MTD_RAM"); + break; + case MTD_ROM: + printf ("MTD_ROM"); + break; + case MTD_NORFLASH: + printf ("MTD_NORFLASH"); + break; + case MTD_NANDFLASH: + printf ("MTD_NANDFLASH"); + break; + case MTD_DATAFLASH: + printf ("MTD_DATAFLASH"); + break; + case MTD_UBIVOLUME: + printf ("MTD_UBIVOLUME"); + default: + printf ("(unknown type - new MTD API maybe?)"); + } + + printf ("\nmtd.flags = "); + if (mtd.flags == MTD_CAP_ROM) + printf ("MTD_CAP_ROM"); + else if (mtd.flags == MTD_CAP_RAM) + printf ("MTD_CAP_RAM"); + else if (mtd.flags == MTD_CAP_NORFLASH) + printf ("MTD_CAP_NORFLASH"); + else if (mtd.flags == MTD_CAP_NANDFLASH) + printf ("MTD_CAP_NANDFLASH"); + else if (mtd.flags == MTD_WRITEABLE) + printf ("MTD_WRITEABLE"); + else + { + int first = 1; + static struct + { + const char *name; + int value; + } flags[] = + { + { "MTD_WRITEABLE", MTD_WRITEABLE }, + { "MTD_BIT_WRITEABLE", MTD_BIT_WRITEABLE }, + { "MTD_NO_ERASE", MTD_NO_ERASE }, + { "MTD_STUPID_LOCK", MTD_STUPID_LOCK }, + { NULL, -1 } + }; + for (i = 0; flags[i].name != NULL; i++) + if (mtd.flags & flags[i].value) + { + if (first) + { + printf (flags[i].name); + first = 0; + } + else printf (" | %s",flags[i].name); + } + } + + printf ("\nmtd.size = "); + printsize (mtd.size); + + printf ("\nmtd.erasesize = "); + printsize (mtd.erasesize); + + printf ("\nmtd.writesize = "); + printsize (mtd.writesize); + + printf ("\nmtd.oobsize = "); + printsize (mtd.oobsize); + + printf ("\n" + "regions = %d\n" + "\n", + n); + + for (i = 0; i < n; i++) + { + printf ("region[%d].offset = 0x%.8x\n" + "region[%d].erasesize = ", + i,region[i].offset,i); + printsize (region[i].erasesize); + printf ("\nregion[%d].numblocks = %d\n" + "region[%d].regionindex = %d\n", + i,region[i].numblocks, + i,region[i].regionindex); + } + return (0); +} + +void showusage (const char *progname) +{ + fprintf (stderr, + "usage: %s info \n" + " %s read \n" + " %s write \n" + " %s erase \n", + progname, + progname, + progname, + progname); + exit (1); +} + +#define OPT_INFO 1 +#define OPT_READ 2 +#define OPT_WRITE 3 +#define OPT_ERASE 4 + +int main (int argc,char *argv[]) +{ + const char *progname; + int err = 0,fd,option = OPT_INFO; + int open_flag; + (progname = strrchr (argv[0],'/')) ? progname++ : (progname = argv[0]); + + /* parse command-line options */ + if (argc == 3 && !strcmp (argv[1],"info")) + option = OPT_INFO; + else if (argc == 6 && !strcmp (argv[1],"read")) + option = OPT_READ; + else if (argc == 6 && !strcmp (argv[1],"write")) + option = OPT_WRITE; + else if (argc == 5 && !strcmp (argv[1],"erase")) + option = OPT_ERASE; + else + showusage (progname); + + /* open device */ + open_flag = (option==OPT_INFO || option==OPT_READ) ? O_RDONLY : O_RDWR; + if ((fd = open (argv[2],O_SYNC | open_flag)) < 0) + { + perror ("open()"); + exit (1); + } + + switch (option) + { + case OPT_INFO: + showinfo (fd); + break; + case OPT_READ: + err = flash_to_file (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0),argv[5]); + break; + case OPT_WRITE: + err = file_to_flash (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0),argv[5]); + break; + case OPT_ERASE: + err = erase_flash (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0)); + break; + } + + /* close device */ + if (close (fd) < 0) + perror ("close()"); + + exit (err); +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mtd-utils.spec linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mtd-utils.spec --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/mtd-utils.spec 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/mtd-utils.spec 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,40 @@ +Summary: Tools for maintaining Memory Technology Devices +Name: mtd-utils +Version: 1.0 +Release: 1 +License: GPL +Group: Applications/System +URL: http://www.linux-mtd.infradead.org/ +Source0: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%description +This package contains tools for erasing and formatting flash devices, +including JFFS2, M-Systems DiskOnChip devices, etc. + +%prep +%setup -q + +%build +make -C util + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT -C util install + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,-) +/usr/sbin +/usr/man/man1/mkfs.jffs2.1.gz +/usr/include/mtd +%doc + + +%changelog +* Wed May 5 2004 - 1.0 +- Initial build. + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nanddump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nanddump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nanddump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nanddump.c 2010-03-03 19:04:35.000000000 -0800 @@ -0,0 +1,403 @@ +/* + * nanddump.c + * + * Copyright (C) 2000 David Woodhouse (dwmw2@infradead.org) + * Steven J. Hill (sjhill@realitydiluted.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. + * + * Overview: + * This utility dumps the contents of raw NAND chips or NAND + * chips contained in DoC devices. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PROGRAM "nanddump" +#define VERSION "$Revision: 1.1.1.1 $" + +struct nand_oobinfo none_oobinfo = { + .useecc = MTD_NANDECC_OFF, +}; + +void display_help (void) +{ + printf("Usage: nanddump [OPTIONS] MTD-device\n" + "Dumps the contents of a nand mtd partition.\n" + "\n" + " --help display this help and exit\n" + " --version output version information and exit\n" + "-f file --file=file dump to file\n" + "-i --ignoreerrors ignore errors\n" + "-l length --length=length length\n" + "-n --noecc read without error correction\n" + "-o --omitoob omit oob data\n" + "-b --omitbad omit bad blocks from the dump\n" + "-p --prettyprint print nice (hexdump)\n" + "-s addr --startaddress=addr start address\n"); + exit(0); +} + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} + +// Option variables + +int ignoreerrors; // ignore errors +int pretty_print; // print nice in ascii +int noecc; // don't error correct +int omitoob; // omit oob data +unsigned long start_addr; // start address +unsigned long length; // dump length +char *mtddev; // mtd device name +char *dumpfile; // dump file name +int omitbad; + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "bs:f:il:opn"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"file", required_argument, 0, 'f'}, + {"ignoreerrors", no_argument, 0, 'i'}, + {"prettyprint", no_argument, 0, 'p'}, + {"omitoob", no_argument, 0, 'o'}, + {"omitbad", no_argument, 0, 'b'}, + {"startaddress", required_argument, 0, 's'}, + {"length", required_argument, 0, 'l'}, + {"noecc", no_argument, 0, 'n'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'b': + omitbad = 1; + break; + case 's': + start_addr = strtol(optarg, NULL, 0); + break; + case 'f': + if (!(dumpfile = strdup(optarg))) { + perror("stddup"); + exit(1); + } + break; + case 'i': + ignoreerrors = 1; + break; + case 'l': + length = strtol(optarg, NULL, 0); + break; + case 'o': + omitoob = 1; + break; + case 'p': + pretty_print = 1; + break; + case 'n': + noecc = 1; + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 1 || error) + display_help (); + + mtddev = argv[optind]; +} + +/* + * Buffers for reading data from flash + */ +unsigned char readbuf[8192]; +unsigned char oobbuf[256]; + +/* + * Main program + */ +int main(int argc, char **argv) +{ + unsigned long ofs, end_addr = 0; + unsigned long long blockstart = 1; + int ret, i, fd, ofd, bs, badblock = 0; + struct mtd_oob_buf oob = {0, 16, oobbuf}; + mtd_info_t meminfo; + char pretty_buf[80]; + int oobinfochanged = 0 ; + struct nand_oobinfo old_oobinfo; + struct mtd_ecc_stats stat1, stat2; + int eccstats = 0; + + process_options(argc, argv); + + /* Open MTD device */ + if ((fd = open(mtddev, O_RDONLY)) == -1) { + perror("open flash"); + exit (1); + } + + /* Fill in MTD device capability structure */ + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("MEMGETINFO"); + close(fd); + exit (1); + } + + /* Make sure device page sizes are valid */ + if (!(meminfo.oobsize == 256 && meminfo.writesize == 8192) && + !(meminfo.oobsize == 128 && meminfo.writesize == 4096) && + !(meminfo.oobsize == 64 && meminfo.writesize == 2048) && + !(meminfo.oobsize == 32 && meminfo.writesize == 1024) && + !(meminfo.oobsize == 16 && meminfo.writesize == 512) && + !(meminfo.oobsize == 8 && meminfo.writesize == 256)) { + fprintf(stderr, "Unknown flash (not normal NAND)\n"); + close(fd); + exit(1); + } + /* Read the real oob length */ + oob.length = meminfo.oobsize; + + if (noecc) { + ret = ioctl(fd, MTDFILEMODE, (void *) MTD_MODE_RAW); + if (ret == 0) { + oobinfochanged = 2; + } else { + switch (errno) { + case ENOTTY: + if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMGETOOBSEL"); + close (fd); + exit (1); + } + if (ioctl (fd, MEMSETOOBSEL, &none_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + oobinfochanged = 1; + break; + default: + perror ("MTDFILEMODE"); + close (fd); + exit (1); + } + } + } else { + + /* check if we can read ecc stats */ + if (!ioctl(fd, ECCGETSTATS, &stat1)) { + eccstats = 1; + fprintf(stderr, "ECC failed: %d\n", stat1.failed); + fprintf(stderr, "ECC corrected: %d\n", stat1.corrected); + fprintf(stderr, "Number of bad blocks: %d\n", stat1.badblocks); + fprintf(stderr, "Number of bbt blocks: %d\n", stat1.bbtblocks); + } else + perror("No ECC status information available"); + } + + /* Open output file for writing. If file name is "-", write to standard + * output. */ + if (!dumpfile) { + ofd = STDOUT_FILENO; + } else if ((ofd = open(dumpfile, O_WRONLY | O_TRUNC | O_CREAT, 0644))== -1) { + perror ("open outfile"); + close(fd); + exit(1); + } + + /* Initialize start/end addresses and block size */ + if (length) + end_addr = start_addr + length; + if (!length || end_addr > meminfo.size) + end_addr = meminfo.size; + + bs = meminfo.writesize; + + /* Print informative message */ + fprintf(stderr, "Block size %u, page size %u, OOB size %u\n", + meminfo.erasesize, meminfo.writesize, meminfo.oobsize); + fprintf(stderr, + "Dumping data starting at 0x%08x and ending at 0x%08x...\n", + (unsigned int) start_addr, (unsigned int) end_addr); + + /* Dump the flash contents */ + for (ofs = start_addr; ofs < end_addr ; ofs+=bs) { + + // new eraseblock , check for bad block + if (blockstart != (ofs & (~meminfo.erasesize + 1))) { + blockstart = ofs & (~meminfo.erasesize + 1); + if ((badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart)) < 0) { + perror("ioctl(MEMGETBADBLOCK)"); + goto closeall; + } + } + + if (badblock) { + if (omitbad) + continue; + memset (readbuf, 0xff, bs); + } else { + /* Read page data and exit on failure */ + if (pread(fd, readbuf, bs, ofs) != bs) { + perror("pread"); + goto closeall; + } + } + + /* ECC stats available ? */ + if (eccstats) { + if (ioctl(fd, ECCGETSTATS, &stat2)) { + perror("ioctl(ECCGETSTATS)"); + goto closeall; + } + if (stat1.failed != stat2.failed) + fprintf(stderr, "ECC: %d uncorrectable bitflip(s)" + " at offset 0x%08lx\n", + stat2.failed - stat1.failed, ofs); + if (stat1.corrected != stat2.corrected) + fprintf(stderr, "ECC: %d corrected bitflip(s) at" + " offset 0x%08lx\n", + stat2.corrected - stat1.corrected, ofs); + stat1 = stat2; + } + + /* Write out page data */ + if (pretty_print) { + for (i = 0; i < bs; i += 16) { + sprintf(pretty_buf, + "0x%08x: %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + (unsigned int) (ofs + i), readbuf[i], + readbuf[i+1], readbuf[i+2], + readbuf[i+3], readbuf[i+4], + readbuf[i+5], readbuf[i+6], + readbuf[i+7], readbuf[i+8], + readbuf[i+9], readbuf[i+10], + readbuf[i+11], readbuf[i+12], + readbuf[i+13], readbuf[i+14], + readbuf[i+15]); + write(ofd, pretty_buf, 60); + } + } else + write(ofd, readbuf, bs); + + + + if (omitoob) + continue; + + if (badblock) { + memset (readbuf, 0xff, meminfo.oobsize); + } else { + /* Read OOB data and exit on failure */ + oob.start = ofs; + if (ioctl(fd, MEMREADOOB, &oob) != 0) { + perror("ioctl(MEMREADOOB)"); + goto closeall; + } + } + + /* Write out OOB data */ + if (pretty_print) { + if (meminfo.oobsize < 16) { + sprintf(pretty_buf, " OOB Data: %02x %02x %02x %02x %02x %02x " + "%02x %02x\n", + oobbuf[0], oobbuf[1], oobbuf[2], + oobbuf[3], oobbuf[4], oobbuf[5], + oobbuf[6], oobbuf[7]); + write(ofd, pretty_buf, 48); + continue; + } + + for (i = 0; i < meminfo.oobsize; i += 16) { + sprintf(pretty_buf, " OOB Data: %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + oobbuf[i], oobbuf[i+1], oobbuf[i+2], + oobbuf[i+3], oobbuf[i+4], oobbuf[i+5], + oobbuf[i+6], oobbuf[i+7], oobbuf[i+8], + oobbuf[i+9], oobbuf[i+10], oobbuf[i+11], + oobbuf[i+12], oobbuf[i+13], oobbuf[i+14], + oobbuf[i+15]); + write(ofd, pretty_buf, 60); + } + } else + write(ofd, oobbuf, meminfo.oobsize); + } + + /* reset oobinfo */ + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close(fd); + close(ofd); + return 1; + } + } + /* Close the output file and MTD device */ + close(fd); + close(ofd); + + /* Exit happy */ + return 0; + +closeall: + /* The new mode change is per file descriptor ! */ + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + } + } + close(fd); + close(ofd); + exit(1); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nanddump_vfat.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nanddump_vfat.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nanddump_vfat.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nanddump_vfat.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,365 @@ +/* + * nanddump.c + * + * Copyright (C) 2000 David Woodhouse (dwmw2@infradead.org) + * Steven J. Hill (sjhill@realitydiluted.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. + * + * Overview: + * This utility dumps the contents of raw NAND chips or NAND + * chips contained in DoC devices. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PROGRAM "nanddump" +#define VERSION "$Revision: 1.1.1.1 $" + +struct nand_oobinfo none_oobinfo = { + .useecc = MTD_NANDECC_OFF, +}; + +void display_help (void) +{ + printf("Usage: nanddump [OPTIONS] MTD-device\n" + "Dumps the contents of a nand mtd partition.\n" + "\n" + " --help display this help and exit\n" + " --version output version information and exit\n" + "-f file --file=file dump to file\n" + "-i --ignoreerrors ignore errors\n" + "-l length --length=length length\n" + "-n --noecc read without error correction\n" + "-o --omitoob omit oob data\n" + "-b --omitbad omit bad blocks from the dump\n" + "-p --prettyprint print nice (hexdump)\n" + "-s addr --startaddress=addr start address\n"); + exit(0); +} + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} + +// Option variables + +int ignoreerrors; // ignore errors +int pretty_print; // print nice in ascii +int noecc; // don't error correct +int omitoob; // omit oob data +unsigned long start_addr; // start address +unsigned long length; // dump length +char *mtddev; // mtd device name +char *dumpfile; // dump file name +int omitbad; + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "bs:f:il:opn"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"file", required_argument, 0, 'f'}, + {"ignoreerrors", no_argument, 0, 'i'}, + {"prettyprint", no_argument, 0, 'p'}, + {"omitoob", no_argument, 0, 'o'}, + {"omitbad", no_argument, 0, 'b'}, + {"startaddress", required_argument, 0, 's'}, + {"length", required_argument, 0, 'l'}, + {"noecc", no_argument, 0, 'n'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'b': + omitbad = 1; + break; + case 's': + start_addr = strtol(optarg, NULL, 0); + break; + case 'f': + if (!(dumpfile = strdup(optarg))) { + perror("stddup"); + exit(1); + } + break; + case 'i': + ignoreerrors = 1; + break; + case 'l': + length = strtol(optarg, NULL, 0); + break; + case 'o': + omitoob = 1; + break; + case 'p': + pretty_print = 1; + break; + case 'n': + noecc = 1; + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 1 || error) + display_help (); + + mtddev = argv[optind]; +} + +/* + * Buffers for reading data from flash + */ +unsigned char readbuf[8192]; +unsigned char oobbuf[256]; + +/* + * Main program + */ +int main(int argc, char **argv) +{ + unsigned long ofs, end_addr = 0; + unsigned long long blockstart = 1; + int ret, fd, ofd, bs, badblock = 0; + struct mtd_oob_buf oob = {0, 16, oobbuf}; + mtd_info_t meminfo; + int oobinfochanged = 0 ; + struct nand_oobinfo old_oobinfo; + struct mtd_ecc_stats stat1, stat2; + int eccstats = 0; + + process_options(argc, argv); + + /* Open MTD device */ + if ((fd = open(mtddev, O_RDONLY)) == -1) { + perror("open flash"); + exit (1); + } + + /* Fill in MTD device capability structure */ + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("MEMGETINFO"); + close(fd); + exit (1); + } + + /* Make sure device page sizes are valid */ + if (!(meminfo.oobsize == 256 && meminfo.writesize == 8192) && + !(meminfo.oobsize == 128 && meminfo.writesize == 4096) && + !(meminfo.oobsize == 64 && meminfo.writesize == 2048) && + !(meminfo.oobsize == 32 && meminfo.writesize == 1024) && + !(meminfo.oobsize == 16 && meminfo.writesize == 512) && + !(meminfo.oobsize == 8 && meminfo.writesize == 256)) { + fprintf(stderr, "Unknown flash (not normal NAND)\n"); + close(fd); + exit(1); + } + /* Read the real oob length */ + oob.length = meminfo.oobsize; + + if (noecc) { + ret = ioctl(fd, MTDFILEMODE, (void *) MTD_MODE_RAW); + if (ret == 0) { + oobinfochanged = 2; + } else { + switch (errno) { + case ENOTTY: + if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMGETOOBSEL"); + close (fd); + exit (1); + } + if (ioctl (fd, MEMSETOOBSEL, &none_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + oobinfochanged = 1; + break; + default: + perror ("MTDFILEMODE"); + close (fd); + exit (1); + } + } + } else { + + /* check if we can read ecc stats */ + if (!ioctl(fd, ECCGETSTATS, &stat1)) { + eccstats = 1; + fprintf(stderr, "ECC failed: %d\n", stat1.failed); + fprintf(stderr, "ECC corrected: %d\n", stat1.corrected); + fprintf(stderr, "Number of bad blocks: %d\n", stat1.badblocks); + fprintf(stderr, "Number of bbt blocks: %d\n", stat1.bbtblocks); + } else + perror("No ECC status information available"); + } + + /* Open output file for writing. If file name is "-", write to standard + * output. */ + if (!dumpfile) { + ofd = STDOUT_FILENO; + } else if ((ofd = open(dumpfile, O_WRONLY | O_TRUNC | O_CREAT, 0644))== -1) { + perror ("open outfile"); + close(fd); + exit(1); + } + + /* Initialize start/end addresses and block size */ + if (length) + end_addr = start_addr + length; + if (!length || end_addr > meminfo.size) + end_addr = meminfo.size; + + bs = meminfo.writesize; + + /* Print informative message */ + fprintf(stderr, "Block size %u, page size %u, OOB size %u\n", + meminfo.erasesize, meminfo.writesize, meminfo.oobsize); + fprintf(stderr, + "Dumping data starting at 0x%08x and ending at 0x%08x...\n", + (unsigned int) start_addr, (unsigned int) end_addr); + + /* Dump the flash contents */ + for (ofs = start_addr; ofs < end_addr ; ofs+=bs) { + + // new eraseblock , check for bad block + if (blockstart != (ofs & (~meminfo.erasesize + 1))) { + blockstart = ofs & (~meminfo.erasesize + 1); + if ((badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart)) < 0) { + perror("ioctl(MEMGETBADBLOCK)"); + goto closeall; + } + } + + if (badblock) { + //skip bad block; + ofs += meminfo.erasesize - bs; + continue; + } else { + /* Read page data and exit on failure */ + if (pread(fd, readbuf, bs, ofs) != bs) { + perror("pread"); + goto closeall; + } + } + + /* ECC stats available ? */ + if (eccstats) { + if (ioctl(fd, ECCGETSTATS, &stat2)) { + perror("ioctl(ECCGETSTATS)"); + goto closeall; + } + if (stat1.failed != stat2.failed) + fprintf(stderr, "ECC: %d uncorrectable bitflip(s)" + " at offset 0x%08lx\n", + stat2.failed - stat1.failed, ofs); + if (stat1.corrected != stat2.corrected) + fprintf(stderr, "ECC: %d corrected bitflip(s) at" + " offset 0x%08lx\n", + stat2.corrected - stat1.corrected, ofs); + stat1 = stat2; + } + + if (badblock) { + memset (readbuf, 0xff, meminfo.oobsize); + } else { + /* Read OOB data and exit on failure */ + oob.start = ofs; + if (ioctl(fd, MEMREADOOB, &oob) != 0) { + perror("ioctl(MEMREADOOB)"); + goto closeall; + } + if(oobbuf[2]==0xff && oobbuf[3]==0xff && oobbuf[4]==0xff && oobbuf[5]==0xff){ + //skip free block; + ofs += meminfo.erasesize - bs; + continue; + } + } + + /* Write out page data */ + write(ofd, readbuf, bs); + + if (omitoob) + continue; + + /* Write out OOB data */ + write(ofd, oobbuf, meminfo.oobsize); + } + + /* reset oobinfo */ + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close(fd); + close(ofd); + return 1; + } + } + /* Close the output file and MTD device */ + close(fd); + close(ofd); + + /* Exit happy */ + return 0; + +closeall: + /* The new mode change is per file descriptor ! */ + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + } + } + close(fd); + close(ofd); + exit(1); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nandtest.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nandtest.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nandtest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nandtest.c 2010-03-03 19:04:35.000000000 -0800 @@ -0,0 +1,284 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mtd/mtd-user.h" + +void usage(void) +{ + fprintf(stderr, "usage: nandtest [OPTIONS] \n\n" + " -h, --help Display this help output\n" + " -m, --markbad Mark blocks bad if they appear so\n" + " -s, --seed Supply random seed\n" + " -p, --passes Number of passes\n" + " -o, --offset Start offset on flash\n" + " -l, --length Length of flash to test\n" + " -k, --keep Restore existing contents after test\n" + "Warning: it is just used for SLC NAND!\n"); + + exit(1); +} + +struct mtd_info_user meminfo; +struct mtd_ecc_stats oldstats, newstats; +int fd; +int markbad=0; +int seed; + +int erase_and_write(loff_mtd_t ofs, unsigned char *data, unsigned char *rbuf) +{ + struct erase_info_user er; + ssize_t len; + int i; + + printf("\r%09llx: erasing... ", (loff_mtd_t)ofs); + fflush(stdout); + + er.start = ofs; + er.length = meminfo.erasesize; + + if (ioctl(fd, MEMERASE, &er)) { + perror("MEMERASE"); + if (markbad) { + printf("Mark block bad at %09llx\n", (loff_mtd_t)ofs); + ioctl(fd, MEMSETBADBLOCK, &ofs); + } + return 1; + } + + printf("\r%09llx: writing...", (loff_mtd_t)ofs); + fflush(stdout); + + len = pwrite(fd, data, meminfo.erasesize, ofs); + if (len < 0) { + printf("\n"); + perror("write"); + if (markbad) { + printf("Mark block bad at %09llx\n", (loff_mtd_t)ofs); + ioctl(fd, MEMSETBADBLOCK, &ofs); + } + return 1; + } + if (len < meminfo.erasesize) { + printf("\n"); + fprintf(stderr, "Short write (%d bytes)\n", len); + exit(1); + } + + printf("\r%09llx: reading...", (loff_mtd_t)ofs); + fflush(stdout); + + len = pread(fd, rbuf, meminfo.erasesize, ofs); + if (len < meminfo.erasesize) { + printf("\n"); + if (len) + fprintf(stderr, "Short read (%d bytes)\n", len); + else + perror("read"); + exit(1); + } + + if (ioctl(fd, ECCGETSTATS, &newstats)) { + printf("\n"); + perror("ECCGETSTATS"); + close(fd); + exit(1); + } + + if (newstats.corrected > oldstats.corrected) { + printf("\nECC corrected at %09llx\n", (loff_mtd_t) ofs); + oldstats.corrected = newstats.corrected; + } + if (newstats.failed > oldstats.failed) { + printf("\nECC failed at %09llx\n", (loff_mtd_t) ofs); + oldstats.corrected = newstats.corrected; + } + if (len < meminfo.erasesize) + exit(1); + + printf("\r%09llx: checking...", (loff_mtd_t)ofs); + fflush(stdout); + + if (memcmp(data, rbuf, meminfo.erasesize)) { + printf("\n"); + fprintf(stderr, "compare failed. seed %d\n", seed); + for (i=0; i meminfo.size) { + fprintf(stderr, "Length %09llx + offset %09llx exceeds device size %09llx\n", + length, offset, meminfo.size); + exit(1); + } + + wbuf = malloc(meminfo.erasesize * 3); + if (!wbuf) { + fprintf(stderr, "Could not allocate %d bytes for buffer\n", + meminfo.erasesize * 2); + exit(1); + } + rbuf = wbuf + meminfo.erasesize; + kbuf = rbuf + meminfo.erasesize; + + if (ioctl(fd, ECCGETSTATS, &oldstats)) { + perror("ECCGETSTATS"); + close(fd); + exit(1); + } + + printf("ECC corrections: %d\n", oldstats.corrected); + printf("ECC failures : %d\n", oldstats.failed); + printf("Bad blocks : %d\n", oldstats.badblocks); + printf("BBT blocks : %d\n", oldstats.bbtblocks); + + for (pass = 0; pass < nr_passes; pass++) { + loff_mtd_t test_ofs; + + for (test_ofs = offset; test_ofs < offset+length; test_ofs += meminfo.erasesize) { + ssize_t len; + + seed = rand(); + srand(seed); + + if (ioctl(fd, MEMGETBADBLOCK, &test_ofs)) { + printf("\rBad block at 0x%09llx\n", test_ofs); + continue; + } + + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mtd/mtd-user.h" + +#define PROGRAM "nandwrite" +#define VERSION "$Revision: 1.1.1.1 $" + +#define MAX_PAGE_SIZE 4096 +#define MAX_OOB_SIZE 128 + +/* + * Buffer array used for writing data + */ +unsigned char writebuf[MAX_PAGE_SIZE]; +unsigned char oobbuf[MAX_OOB_SIZE]; +unsigned char oobreadbuf[MAX_OOB_SIZE]; + +// oob layouts to pass into the kernel as default +struct nand_oobinfo none_oobinfo = { + .useecc = MTD_NANDECC_OFF, +}; + +struct nand_oobinfo jffs2_oobinfo = { + .useecc = MTD_NANDECC_PLACE, + .eccbytes = 6, + .eccpos = { 0, 1, 2, 3, 6, 7 } +}; + +struct nand_oobinfo yaffs_oobinfo = { + .useecc = MTD_NANDECC_PLACE, + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15} +}; + +struct nand_oobinfo autoplace_oobinfo = { + .useecc = MTD_NANDECC_AUTOPLACE +}; + +void display_help (void) +{ + printf("Usage: nandwrite [OPTION] MTD_DEVICE INPUTFILE\n" + "Writes to the specified MTD device.\n" + "\n" + " -a, --autoplace Use auto oob layout\n" + " -j, --jffs2 force jffs2 oob layout (legacy support)\n" + " -y, --yaffs force yaffs oob layout (legacy support)\n" + " -f, --forcelegacy force legacy support on autoplacement enabled mtd device\n" + " -m, --markbad mark blocks bad if write fails\n" + " -n, --noecc write without ecc\n" + " -o, --oob image contains oob data\n" + " -s addr, --start=addr set start address (default is 0)\n" + " -p, --pad pad to page size\n" + " -b, --blockalign=1|2|4 set multiple of eraseblocks to align to\n" + " -q, --quiet don't display progress messages\n" + " --help display this help and exit\n" + " --version output version information and exit\n"); + exit(0); +} + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "Copyright (C) 2003 Thomas Gleixner \n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} + +char *mtd_device, *img; +int mtdoffset = 0; +int quiet = 0; +int writeoob = 0; +int markbad = 0; +int autoplace = 0; +int forcejffs2 = 0; +int forceyaffs = 0; +int forcelegacy = 0; +int noecc = 0; +int pad = 0; +int blockalign = 1; /*default to using 16K block size */ + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "ab:fjmnopqs:y"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"autoplace", no_argument, 0, 'a'}, + {"blockalign", required_argument, 0, 'b'}, + {"forcelegacy", no_argument, 0, 'f'}, + {"jffs2", no_argument, 0, 'j'}, + {"markbad", no_argument, 0, 'm'}, + {"noecc", no_argument, 0, 'n'}, + {"oob", no_argument, 0, 'o'}, + {"pad", no_argument, 0, 'p'}, + {"quiet", no_argument, 0, 'q'}, + {"start", required_argument, 0, 's'}, + {"yaffs", no_argument, 0, 'y'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'q': + quiet = 1; + break; + case 'a': + autoplace = 1; + break; + case 'j': + forcejffs2 = 1; + break; + case 'y': + forceyaffs = 1; + break; + case 'f': + forcelegacy = 1; + break; + case 'n': + noecc = 1; + break; + case 'm': + markbad = 1; + break; + case 'o': + writeoob = 1; + break; + case 'p': + pad = 1; + break; + case 's': + mtdoffset = strtol (optarg, NULL, 0); + break; + case 'b': + blockalign = atoi (optarg); + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 2 || error) + display_help (); + + mtd_device = argv[optind++]; + img = argv[optind]; +} + +/* + * Main program + */ +int main(int argc, char **argv) +{ + int cnt, fd, ifd, imglen = 0, pagelen, baderaseblock, blockstart = -1; + struct mtd_info_user meminfo; + struct mtd_oob_buf oob; + loff_mtd_t offs; + int ret, readlen; + int oobinfochanged = 0; + struct nand_oobinfo old_oobinfo; + + printf("Warning: nandwrite_mlc instead of nandwrite is used for MLC NAND!\n"); + + process_options(argc, argv); + + memset(oobbuf, 0xff, sizeof(oobbuf)); + + if (pad && writeoob) { + fprintf(stderr, "Can't pad when oob data is present.\n"); + exit(1); + } + + /* Open the device */ + if ((fd = open(mtd_device, O_RDWR)) == -1) { + perror("open flash"); + exit(1); + } + + /* Fill in MTD device capability structure */ + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("MEMGETINFO"); + close(fd); + exit(1); + } + + /* Set erasesize to specified number of blocks - to match jffs2 + * (virtual) block size */ + meminfo.erasesize *= blockalign; + + /* Make sure device page sizes are valid */ + if (!(meminfo.oobsize == 16 && meminfo.writesize == 512) && + !(meminfo.oobsize == 8 && meminfo.writesize == 256) && + !(meminfo.oobsize == 64 && meminfo.writesize == 2048) && + !(meminfo.oobsize == 128 && meminfo.writesize == 4096)) { + fprintf(stderr, "Unknown flash (not normal NAND)\n"); + close(fd); + exit(1); + } + + if (autoplace) { + /* Read the current oob info */ + if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMGETOOBSEL"); + close (fd); + exit (1); + } + + // autoplace ECC ? + if (autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) { + + if (ioctl (fd, MEMSETOOBSEL, &autoplace_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + oobinfochanged = 1; + } + } + + if (noecc) { + ret = ioctl(fd, MTDFILEMODE, (void *) MTD_MODE_RAW); + if (ret == 0) { + oobinfochanged = 2; + } else { + switch (errno) { + case ENOTTY: + if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMGETOOBSEL"); + close (fd); + exit (1); + } + if (ioctl (fd, MEMSETOOBSEL, &none_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + oobinfochanged = 1; + break; + default: + perror ("MTDFILEMODE"); + close (fd); + exit (1); + } + } + } + + /* + * force oob layout for jffs2 or yaffs ? + * Legacy support + */ + if (forcejffs2 || forceyaffs) { + struct nand_oobinfo *oobsel = forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo; + + if (autoplace) { + fprintf(stderr, "Autoplacement is not possible for legacy -j/-y options\n"); + goto restoreoob; + } + if ((old_oobinfo.useecc == MTD_NANDECC_AUTOPLACE) && !forcelegacy) { + fprintf(stderr, "Use -f option to enforce legacy placement on autoplacement enabled mtd device\n"); + goto restoreoob; + } + if (meminfo.oobsize == 8) { + if (forceyaffs) { + fprintf (stderr, "YAFSS cannot operate on 256 Byte page size"); + goto restoreoob; + } + /* Adjust number of ecc bytes */ + jffs2_oobinfo.eccbytes = 3; + } + + if (ioctl (fd, MEMSETOOBSEL, oobsel) != 0) { + perror ("MEMSETOOBSEL"); + goto restoreoob; + } + } + + oob.length = meminfo.oobsize; + oob.ptr = noecc ? oobreadbuf : oobbuf; + + /* Open the input file */ + if ((ifd = open(img, O_RDONLY)) == -1) { + perror("open input file"); + goto restoreoob; + } + + // get image length + imglen = lseek(ifd, 0, SEEK_END); + lseek (ifd, 0, SEEK_SET); + + pagelen = meminfo.writesize + ((writeoob == 1) ? meminfo.oobsize : 0); + + // Check, if file is pagealigned + if ((!pad) && ((imglen % pagelen) != 0)) { + fprintf (stderr, "Input file is not page aligned\n"); + goto closeall; + } + + // Check, if length fits into device + if ( ((imglen / pagelen) * meminfo.writesize) > (meminfo.size - mtdoffset)) { + fprintf (stderr, "Image %d bytes, NAND page %d bytes, OOB area %u bytes, device size %llu bytes\n", + imglen, pagelen, meminfo.writesize, meminfo.size); + perror ("Input file does not fit into device"); + goto closeall; + } + + /* Get data from input and write to the device */ + while (imglen && (mtdoffset < meminfo.size)) { + // new eraseblock , check for bad block(s) + // Stay in the loop to be sure if the mtdoffset changes because + // of a bad block, that the next block that will be written to + // is also checked. Thus avoiding errors if the block(s) after the + // skipped block(s) is also bad (number of blocks depending on + // the blockalign + while (blockstart != (mtdoffset & (~meminfo.erasesize + 1))) { + blockstart = mtdoffset & (~meminfo.erasesize + 1); + offs = blockstart; + baderaseblock = 0; + if (!quiet) + fprintf (stdout, "Writing data to block %x\n", blockstart); + + /* Check all the blocks in an erase block for bad blocks */ + do { + if ((ret = ioctl(fd, MEMGETBADBLOCK, &offs)) < 0) { + perror("ioctl(MEMGETBADBLOCK)"); + goto closeall; + } + + if (ret == 1) { + baderaseblock = 1; + if (!quiet) + fprintf (stderr, "Bad block at %x, %u block(s) " + "from %x will be skipped\n", + (int) offs, blockalign, blockstart); + } + + if (baderaseblock) { + mtdoffset = blockstart + meminfo.erasesize; + } + offs += meminfo.erasesize / blockalign ; + } while ( offs < blockstart + meminfo.erasesize ); + + } + + readlen = meminfo.writesize; + if (pad && (imglen < readlen)) + { + readlen = imglen; + memset(writebuf + readlen, 0xff, meminfo.writesize - readlen); + } + + /* Read Page Data from input file */ + if ((cnt = read(ifd, writebuf, readlen)) != readlen) { + if (cnt == 0) // EOF + break; + perror ("File I/O error on input file"); + goto closeall; + } + + if (writeoob) { + /* Read OOB data from input file, exit on failure */ + if ((cnt = read(ifd, oobreadbuf, meminfo.oobsize)) != meminfo.oobsize) { + perror ("File I/O error on input file"); + goto closeall; + } + if (!noecc) { + int i, start, len; + /* + * We use autoplacement and have the oobinfo with the autoplacement + * information from the kernel available + * + * Modified to support out of order oobfree segments, + * such as the layout used by diskonchip.c + */ + if (!oobinfochanged && (old_oobinfo.useecc == MTD_NANDECC_AUTOPLACE)) { + for (i = 0;old_oobinfo.oobfree[i][1]; i++) { + /* Set the reserved bytes to 0xff */ + start = old_oobinfo.oobfree[i][0]; + len = old_oobinfo.oobfree[i][1]; + memcpy(oobbuf + start, + oobreadbuf + start, + len); + } + } else { + /* Set at least the ecc byte positions to 0xff */ + start = old_oobinfo.eccbytes; + len = meminfo.oobsize - start; + memcpy(oobbuf + start, + oobreadbuf + start, + len); + } + } + /* Write OOB data first, as ecc will be placed in there*/ + oob.start = mtdoffset; + if (ioctl(fd, MEMWRITEOOB, &oob) != 0) { + perror ("ioctl(MEMWRITEOOB)"); + goto closeall; + } + imglen -= meminfo.oobsize; + } + + /* Write out the Page data */ + if (pwrite(fd, writebuf, meminfo.writesize, mtdoffset) != meminfo.writesize) { + int rewind_blocks; + off_t rewind_bytes; + erase_info_t erase; + + perror ("pwrite"); + /* Must rewind to blockstart if we can */ + rewind_blocks = (mtdoffset - blockstart) / meminfo.writesize; /* Not including the one we just attempted */ + rewind_bytes = (rewind_blocks * meminfo.writesize) + readlen; + if (writeoob) + rewind_bytes += (rewind_blocks + 1) * meminfo.oobsize; + if (lseek(ifd, -rewind_bytes, SEEK_CUR) == -1) { + perror("lseek"); + fprintf(stderr, "Failed to seek backwards to recover from write error\n"); + goto closeall; + } + erase.start = blockstart; + erase.length = meminfo.erasesize; + fprintf(stderr, "Erasing failed write from 0x%09llx-0x%09llx\n", + erase.start, erase.start+erase.length-1); + if (ioctl(fd, MEMERASE, &erase) != 0) { + perror("MEMERASE"); + goto closeall; + } + + if (markbad) { + loff_mtd_t bad_addr = mtdoffset & (~(meminfo.erasesize / blockalign) + 1); + fprintf(stderr, "Marking block at %09llx bad\n", (long long)bad_addr); + if (ioctl(fd, MEMSETBADBLOCK, &bad_addr)) { + perror("MEMSETBADBLOCK"); + /* But continue anyway */ + } + } + mtdoffset = blockstart + meminfo.erasesize; + imglen += rewind_blocks * meminfo.writesize; + + continue; + } + imglen -= readlen; + mtdoffset += meminfo.writesize; + } + +closeall: + close(ifd); + +restoreoob: + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + } + + close(fd); + + if (imglen > 0) { + perror ("Data was only partially written due to error\n"); + exit (1); + } + + /* Return happy */ + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nandwrite_mlc.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nandwrite_mlc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nandwrite_mlc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nandwrite_mlc.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,446 @@ +/* + * nandwrite.c + * + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * 2003 Thomas Gleixner (tglx@linutronix.de) + * + * 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. + * + * Overview: + * This utility writes a binary image directly to a NAND flash + * chip or NAND chips contained in DoC devices. This is the + * "inverse operation" of nanddump. + * + * tglx: Major rewrite to handle bad blocks, write data with or without ECC + * write oob data only on request + * + * Bug/ToDo: + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mtd/mtd-user.h" + +#define PROGRAM "nandwrite" +#define VERSION "$Revision: 1.1.1.1 $" + +#define MAX_PAGE_SIZE 8192 +#define MAX_OOB_SIZE 256 +/* + * Buffer array used for writing data + */ +unsigned char writebuf[MAX_PAGE_SIZE]; +unsigned char oobreadbuf[MAX_OOB_SIZE]; + +// oob layouts to pass into the kernel as default +struct nand_oobinfo none_oobinfo = { + .useecc = MTD_NANDECC_OFF, +}; + +struct nand_oobinfo jffs2_oobinfo = { + .useecc = MTD_NANDECC_PLACE, + .eccbytes = 6, + .eccpos = { 0, 1, 2, 3, 6, 7 } +}; + +struct nand_oobinfo yaffs_oobinfo = { + .useecc = MTD_NANDECC_PLACE, + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15} +}; + +struct nand_oobinfo autoplace_oobinfo = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 36 +}; + +void display_help (void) +{ + printf("Usage: nandwrite [OPTION] MTD_DEVICE INPUTFILE\n" + "Writes to the specified MTD device.\n" + "\n" + " -a, --autoplace Use auto oob layout\n" + " -j, --jffs2 force jffs2 oob layout (legacy support)\n" + " -y, --yaffs force yaffs oob layout (legacy support)\n" + " -f, --forcelegacy force legacy support on autoplacement enabled mtd device\n" + " -m, --markbad mark blocks bad if write fails\n" + " -n, --noecc write without ecc\n" + " -o, --oob image contains oob data\n" + " -s addr, --start=addr set start address (default is 0)\n" + " -p, --pad pad to page size\n" + " -b, --blockalign=1|2|4 set multiple of eraseblocks to align to\n" + " -q, --quiet don't display progress messages\n" + " --help display this help and exit\n" + " --version output version information and exit\n"); + exit(0); +} + +void display_version (void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "Copyright (C) 2003 Thomas Gleixner \n" + "\n" + PROGRAM " comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of " PROGRAM "\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n"); + exit(0); +} + +char *mtd_device, *img; +unsigned long long mtdoffset = 0; +int quiet = 0; +int writeoob = 0; +int markbad = 1; +int autoplace = 0; +int forcejffs2 = 0; +int forceyaffs = 0; +int forcelegacy = 0; +int noecc = 0; +int pad = 0; +int blockalign = 1; /*default to using 16K block size */ + +void process_options (int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "ab:fjmnopqs:y"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"autoplace", no_argument, 0, 'a'}, + {"blockalign", required_argument, 0, 'b'}, + {"forcelegacy", no_argument, 0, 'f'}, + {"jffs2", no_argument, 0, 'j'}, + {"markbad", no_argument, 0, 'm'}, + {"noecc", no_argument, 0, 'n'}, + {"oob", no_argument, 0, 'o'}, + {"pad", no_argument, 0, 'p'}, + {"quiet", no_argument, 0, 'q'}, + {"start", required_argument, 0, 's'}, + {"yaffs", no_argument, 0, 'y'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) { + break; + } + + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + break; + case 1: + display_version(); + break; + } + break; + case 'q': + quiet = 1; + break; + case 'a': + autoplace = 1; + break; + case 'j': + forcejffs2 = 1; + break; + case 'y': + forceyaffs = 1; + break; + case 'f': + forcelegacy = 1; + break; + case 'n': + noecc = 1; + break; + case 'm': + markbad = 1; + break; + case 'o': + writeoob = 1; + break; + case 'p': + pad = 1; + break; + case 's': + mtdoffset = strtol (optarg, NULL, 0); + break; + case 'b': + blockalign = atoi (optarg); + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 2 || error) + display_help (); + + mtd_device = argv[optind++]; + img = argv[optind]; +} + +/* + * Main program + */ +int main(int argc, char **argv) +{ + int cnt, fd, ifd, imglen = 0, pagelen, baderaseblock, blockstart = -1; + struct mtd_info_user meminfo; + struct mtd_page_buf oob; + loff_mtd_t offs; + int ret, readlen; + int oobinfochanged = 0; + struct nand_oobinfo old_oobinfo; + int i; + + process_options(argc, argv); + + if (pad && writeoob) { + fprintf(stderr, "Can't pad when oob data is present.\n"); + exit(1); + } + + /* Open the device */ + if ((fd = open(mtd_device, O_RDWR)) == -1) { + perror("open flash"); + exit(1); + } + + /* Fill in MTD device capability structure */ + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("MEMGETINFO"); + close(fd); + exit(1); + } + + /* Set erasesize to specified number of blocks - to match jffs2 + * (virtual) block size */ + meminfo.erasesize *= blockalign; + + /* Make sure device page sizes are valid */ + if (!(meminfo.oobsize == 16 && meminfo.writesize == 512) && + !(meminfo.oobsize == 8 && meminfo.writesize == 256) && + !(meminfo.oobsize == 64 && meminfo.writesize == 2048) && + !(meminfo.oobsize == 128 && meminfo.writesize == 4096) && + !(meminfo.oobsize == 256 && meminfo.writesize == 8192)) { + fprintf(stderr, "Unknown flash (not normal NAND)\n"); + close(fd); + exit(1); + } + + if (autoplace) { + /* Read the current oob info */ + if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMGETOOBSEL"); + close (fd); + exit (1); + } + + // autoplace ECC ? + if (autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) { + + if (ioctl (fd, MEMSETOOBSEL, &autoplace_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + oobinfochanged = 1; + } + } + + memset(oobreadbuf, 0xff, MAX_OOB_SIZE); + + if (autoplace) { + oob.ooblength = meminfo.oobsize-old_oobinfo.eccbytes; /* Get ooblength from kernel */ + printf("oobsize=%d eccbytes=%d\n", meminfo.oobsize, old_oobinfo.eccbytes); + } else { + oob.ooblength = meminfo.oobsize-autoplace_oobinfo.eccbytes; + printf("oobsize=%d eccbytes=%d\n", meminfo.oobsize, autoplace_oobinfo.eccbytes); + } + + oob.oobptr = oobreadbuf; + oob.datptr = writebuf; + + /* Open the input file */ + if ((ifd = open(img, O_RDONLY)) == -1) { + perror("open input file"); + goto restoreoob; + } + + // get image length + imglen = lseek(ifd, 0, SEEK_END); + lseek (ifd, 0, SEEK_SET); + + pagelen = meminfo.writesize + ((writeoob == 1) ? meminfo.oobsize : 0); + + // Check, if file is pagealigned + if ((!pad) && ((imglen % pagelen) != 0)) { + fprintf (stderr, "Input file is not page aligned\n"); + goto closeall; + } + + // Check, if length fits into device + if ( ((imglen / pagelen) * meminfo.writesize) > (meminfo.size - mtdoffset)) { + fprintf (stderr, "Image %d bytes, NAND page %d bytes, OOB area %u bytes, device size %lld bytes\n", + imglen, pagelen, meminfo.writesize, meminfo.size); + perror ("Input file does not fit into device"); + goto closeall; + } + + /* Get data from input and write to the device */ + while (imglen && (mtdoffset < meminfo.size)) { + // new eraseblock , check for bad block(s) + // Stay in the loop to be sure if the mtdoffset changes because + // of a bad block, that the next block that will be written to + // is also checked. Thus avoiding errors if the block(s) after the + // skipped block(s) is also bad (number of blocks depending on + // the blockalign + while (blockstart != (mtdoffset & (~meminfo.erasesize + 1))) { + blockstart = mtdoffset & (~meminfo.erasesize + 1); + offs = blockstart; + baderaseblock = 0; + i=0; + if (!quiet) + fprintf (stdout, "Writing data to block 0x%x\n", blockstart); + + /* Check all the blocks in an erase block for bad blocks */ + do { + if ((ret = ioctl(fd, MEMGETBADBLOCK, &offs)) < 0) { + perror("ioctl(MEMGETBADBLOCK)"); + goto closeall; + } + if (ret == 1) { + baderaseblock = 1; + if (!quiet) + fprintf (stderr, "Bad block at 0x%llx, %u block(s) " + "from 0x%x will be skipped\n", + offs, blockalign, blockstart); + } + + if (baderaseblock) { + mtdoffset = blockstart + meminfo.erasesize; + } + offs += meminfo.erasesize / blockalign ; + } while ( offs < blockstart + meminfo.erasesize ); + + } + + readlen = meminfo.writesize; + if (pad && (imglen < readlen)) + { + readlen = imglen; + memset(writebuf + readlen, 0xff, meminfo.writesize - readlen); + } + + /* Read Page Data from input file */ + if ((cnt = read(ifd, writebuf, readlen)) != readlen) { + if (cnt == 0) // EOF + break; + perror ("File I/O error 1 on input file"); + goto closeall; + } + + /* Read OOB data from input file, exit on failure */ + if(writeoob) { + if ((cnt = read(ifd, oobreadbuf, meminfo.oobsize)) != meminfo.oobsize) { + perror ("File I/O error 2 on input file"); + goto closeall; + } + } + oob.start = mtdoffset; + + // write a page include its oob to nand + ioctl(fd, MEMWRITEPAGE, &oob); + if(oob.datlength != meminfo.writesize){ + perror ("ioctl(MEMWRITEPAGE)"); + + int rewind_blocks; + off_t rewind_bytes; + erase_info_t erase; + + /* Must rewind to blockstart if we can */ + rewind_blocks = (mtdoffset - blockstart) / meminfo.writesize; /* Not including the one we just attempted */ + rewind_bytes = (rewind_blocks * meminfo.writesize) + readlen; + if (writeoob) + rewind_bytes += (rewind_blocks + 1) * meminfo.oobsize; + if (lseek(ifd, -rewind_bytes, SEEK_CUR) == -1) { + perror("lseek"); + fprintf(stderr, "Failed to seek backwards to recover from write error\n"); + goto closeall; + } + erase.start = blockstart; + erase.length = meminfo.erasesize; + fprintf(stderr, "Erasing failed write from 0x%09llx-0x%09llx\n", + erase.start, erase.start+erase.length-1); + if (ioctl(fd, MEMERASE, &erase) != 0) { + perror("MEMERASE"); + goto closeall; + } + + if (markbad) { + loff_mtd_t bad_addr = mtdoffset & (~(meminfo.erasesize / blockalign) + 1); + fprintf(stderr, "Marking block at %09llx bad\n", (long long)bad_addr); + if (ioctl(fd, MEMSETBADBLOCK, &bad_addr)) { + perror("MEMSETBADBLOCK"); + /* But continue anyway */ + } + } + mtdoffset = blockstart + meminfo.erasesize; + imglen += rewind_blocks * meminfo.writesize; + + continue; + } + if(writeoob) + imglen -= meminfo.oobsize; + imglen -= readlen; + mtdoffset += meminfo.writesize; + } + +closeall: + close(ifd); + +restoreoob: + if (oobinfochanged == 1) { + if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { + perror ("MEMSETOOBSEL"); + close (fd); + exit (1); + } + } + + close(fd); + + if (imglen > 0) { + perror ("Data was only partially written due to error\n"); + exit (1); + } + + /* Return happy */ + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nftldump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nftldump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nftldump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nftldump.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,281 @@ +/* + * nftldump.c: Dumping the content of NFTL partitions on a "Physical Disk" + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ToDo: + * 1. UnitSizeFactor != 0xFF cases + * 2. test, test, and test !!! + */ + +#define _XOPEN_SOURCE 500 /* For pread */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct NFTLMediaHeader MedHead[2]; +static mtd_info_t meminfo; + +static struct nftl_oob oobbuf; +static struct mtd_oob_buf oob = {0, 16, (unsigned char *)&oobbuf}; + +static int fd, ofd = -1;; +static int NumMedHeads; + +static unsigned char BadUnitTable[MAX_ERASE_ZONES]; + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define SWAP16(x) do { ; } while(0) +#define SWAP32(x) do { ; } while(0) +#else +#define SWAP16(x) do { x = swab16(x); } while(0) +#define SWAP32(x) do { x = swab32(x); } while(0) +#endif + +/* VUCtable, store the Erase Unit Number of the first Erase Unit in the chain */ +static unsigned short *VUCtable; + +/* FixMe: make this dynamic allocated */ +#define ERASESIZE 0x2000 +#define NUMVUNITS ((40*1024*1024) / ERASESIZE) +static union nftl_uci UCItable[NUMVUNITS][3]; + +static unsigned short nextEUN(unsigned short curEUN) +{ + return UCItable[curEUN][0].a.ReplUnitNum; +} + +static unsigned int find_media_headers(void) +{ + int i; + static unsigned long ofs = 0; + + NumMedHeads = 0; + while (ofs < meminfo.size) { + pread(fd, &MedHead[NumMedHeads], sizeof(struct NFTLMediaHeader), ofs); + if (!strncmp(MedHead[NumMedHeads].DataOrgID, "ANAND", 6)) { + SWAP16(MedHead[NumMedHeads].NumEraseUnits); + SWAP16(MedHead[NumMedHeads].FirstPhysicalEUN); + SWAP32(MedHead[NumMedHeads].FormattedSize); + + if (NumMedHeads == 0) { + printf("NFTL Media Header found at offset 0x%08lx:\n", ofs); + printf("NumEraseUnits: %d\n", + MedHead[NumMedHeads].NumEraseUnits); + printf("FirstPhysicalEUN: %d\n", + MedHead[NumMedHeads].FirstPhysicalEUN); + printf("Formatted Size: %d\n", + MedHead[NumMedHeads].FormattedSize); + printf("UnitSizeFactor: 0x%x\n", + MedHead[NumMedHeads].UnitSizeFactor); + + /* read BadUnitTable, I don't know why pread() does not work for + larger (7680 bytes) chunks */ + for (i = 0; i < MAX_ERASE_ZONES; i += 512) + pread(fd, &BadUnitTable[i], 512, ofs + 512 + i); + } else + printf("Second NFTL Media Header found at offset 0x%08lx\n",ofs); + NumMedHeads++; + } + + ofs += meminfo.erasesize; + if (NumMedHeads == 2) { + if (strncmp((char *)&MedHead[0], (char *)&MedHead[1], sizeof(struct NFTLMediaHeader)) != 0) { + printf("warning: NFTL Media Header is not consistent with " + "Spare NFTL Media Header\n"); + } + break; + } + } + + /* allocate Virtual Unit Chain table for this NFTL partition */ + VUCtable = calloc(MedHead[0].NumEraseUnits, sizeof(unsigned short)); + return NumMedHeads; +} + +static void dump_erase_units(void) +{ + int i, j; + unsigned long ofs; + + for (i = MedHead[0].FirstPhysicalEUN; i < MedHead[0].FirstPhysicalEUN + + MedHead[0].NumEraseUnits; i++) { + /* For each Erase Unit */ + ofs = i * meminfo.erasesize; + + /* read the Unit Control Information */ + for (j = 0; j < 3; j++) { + oob.start = ofs + (j * 512); + if (ioctl(fd, MEMREADOOB, &oob)) + printf("MEMREADOOB at %lx: %s\n", + (unsigned long) oob.start, strerror(errno)); + memcpy(&UCItable[i][j], &oobbuf.u, 8); + } + if (UCItable[i][1].b.EraseMark != cpu_to_le16(0x3c69)) { + printf("EraseMark not present in unit %d: %x\n", + i, UCItable[i][1].b.EraseMark); + } else { + /* a properly formatted unit */ + SWAP16(UCItable[i][0].a.VirtUnitNum); + SWAP16(UCItable[i][0].a.ReplUnitNum); + SWAP16(UCItable[i][0].a.SpareVirtUnitNum); + SWAP16(UCItable[i][0].a.SpareReplUnitNum); + SWAP32(UCItable[i][1].b.WearInfo); + SWAP16(UCItable[i][1].b.EraseMark); + SWAP16(UCItable[i][1].b.EraseMark1); + SWAP16(UCItable[i][2].c.FoldMark); + SWAP16(UCItable[i][2].c.FoldMark1); + + if (!(UCItable[i][0].a.VirtUnitNum & 0x8000)) { + /* If this is the first in a chain, store the EUN in the VUC table */ + if (VUCtable[UCItable[i][0].a.VirtUnitNum & 0x7fff]) { + printf("Duplicate start of chain for VUC %d: " + "Unit %d replaces Unit %d\n", + UCItable[i][0].a.VirtUnitNum & 0x7fff, + i, VUCtable[UCItable[i][0].a.VirtUnitNum & 0x7fff]); + } + VUCtable[UCItable[i][0].a.VirtUnitNum & 0x7fff] = i; + } + } + + switch (BadUnitTable[i]) { + case ZONE_BAD_ORIGINAL: + printf("Unit %d is marked as ZONE_BAD_ORIGINAL\n", i); + continue; + case ZONE_BAD_MARKED: + printf("Unit %d is marked as ZONE_BAD_MARKED\n", i); + continue; + } + + /* ZONE_GOOD */ + if (UCItable[i][0].a.VirtUnitNum == 0xffff) + printf("Unit %d is free\n", i); + else + printf("Unit %d is in chain %d and %s a replacement\n", i, + UCItable[i][0].a.VirtUnitNum & 0x7fff, + UCItable[i][0].a.VirtUnitNum & 0x8000 ? "is" : "is not"); + } +} + +static void dump_virtual_units(void) +{ + int i, j; + char readbuf[512]; + + for (i = 0; i < (MedHead[0].FormattedSize / meminfo.erasesize); i++) { + unsigned short curEUN = VUCtable[i]; + + printf("Virtual Unit #%d: ", i); + if (!curEUN) { + printf("Not present\n"); + continue; + } + printf("%d", curEUN); + + /* walk through the Virtual Unit Chain */ + while ((curEUN = nextEUN(curEUN)) != 0xffff) { + printf(", %d", curEUN & 0x7fff); + } + printf("\n"); + + if (ofd != -1) { + /* Actually write out the data */ + for (j = 0; j < meminfo.erasesize / 512; j++) { + /* For each sector in the block */ + unsigned short lastgoodEUN = 0xffff, thisEUN = VUCtable[i]; + unsigned int status; + + if (thisEUN == 0xffff) thisEUN = 0; + + while (thisEUN && (thisEUN & 0x7fff) != 0x7fff) { + oob.start = (thisEUN * ERASESIZE) + (j * 512); + ioctl(fd, MEMREADOOB, &oob); + status = oobbuf.b.Status | oobbuf.b.Status1; + + switch (status) { + case SECTOR_FREE: + /* This is still free. Don't look any more */ + thisEUN = 0; + break; + + case SECTOR_USED: + /* SECTOR_USED. This is a good one. */ + lastgoodEUN = thisEUN; + break; + } + + /* Find the next erase unit in this chain, if any */ + if (thisEUN) + thisEUN = nextEUN(thisEUN) & 0x7fff; + } + + if (lastgoodEUN == 0xffff) + memset(readbuf, 0, 512); + else + pread(fd, readbuf, 512, + (lastgoodEUN * ERASESIZE) + (j * 512)); + + write(ofd, readbuf, 512); + } + + } + } +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + printf("Usage: %s []\n", argv[0]); + exit(1); + } + fd = open(argv[1], O_RDONLY); + if (fd == -1) { + perror("open flash"); + exit (1); + } + + if (argc > 2) { + ofd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (ofd == -1) + perror ("open outfile"); + } + + /* get size information of the MTD device */ + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("ioctl(MEMGETINFO)"); + close(fd); + return 1; + } + + while (find_media_headers() != 0) { + dump_erase_units(); + dump_virtual_units(); + free(VUCtable); + } + + exit(0); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nftl_format.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nftl_format.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/nftl_format.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/nftl_format.c 2010-03-03 19:04:35.000000000 -0800 @@ -0,0 +1,419 @@ +/* + * nftl_format.c: Creating a NFTL/INFTL partition on an MTD device + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ToDo: + * 1. UnitSizeFactor != 0xFF cases + * 2. test, test, and test !!! + */ + +#define _XOPEN_SOURCE 500 /* for pread/pwrite */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +unsigned char BadUnitTable[MAX_ERASE_ZONES]; +unsigned char *readbuf; +unsigned char *writebuf[4]; + +mtd_info_t meminfo; +erase_info_t erase; +int fd; +struct NFTLMediaHeader *NFTLhdr; +struct INFTLMediaHeader *INFTLhdr; + +static int do_oobcheck = 1; +static int do_rwecheck = 1; + +static unsigned char check_block_1(unsigned long block) +{ + unsigned char oobbuf[16]; + struct mtd_oob_buf oob = { 0, 16, oobbuf }; + + oob.start = block * meminfo.erasesize; + if (ioctl(fd, MEMREADOOB, &oob)) + return ZONE_BAD_ORIGINAL; + + if(oobbuf[5] == 0) + return ZONE_BAD_ORIGINAL; + + oob.start = block * meminfo.erasesize + 512 /* FIXME */; + if (ioctl(fd, MEMREADOOB, &oob)) + return ZONE_BAD_ORIGINAL; + + if(oobbuf[5] == 0) + return ZONE_BAD_ORIGINAL; + + return ZONE_GOOD; +} + +static unsigned char check_block_2(unsigned long block) +{ + unsigned long ofs = block * meminfo.erasesize; + unsigned long blockofs; + + /* Erase test */ + erase.start = ofs; + + for (blockofs = 0; blockofs < meminfo.erasesize; blockofs += 512) { + pread(fd, readbuf, 512, ofs + blockofs); + if (memcmp(readbuf, writebuf[0], 512)) { + /* Block wasn't 0xff after erase */ + printf(": Block not 0xff after erase\n"); + return ZONE_BAD_ORIGINAL; + } + + pwrite(fd, writebuf[1], 512, blockofs + ofs); + pread(fd, readbuf, 512, blockofs + ofs); + if (memcmp(readbuf, writebuf[1], 512)) { + printf(": Block not zero after clearing\n"); + return ZONE_BAD_ORIGINAL; + } + } + + /* Write test */ + if (ioctl(fd, MEMERASE, &erase) != 0) { + printf(": Second erase failed (%s)\n", strerror(errno)); + return ZONE_BAD_ORIGINAL; + } + for (blockofs = 0; blockofs < meminfo.erasesize; blockofs += 512) { + pwrite(fd, writebuf[2], 512, blockofs + ofs); + pread(fd, readbuf, 512, blockofs + ofs); + if (memcmp(readbuf, writebuf[2], 512)) { + printf(": Block not 0x5a after writing\n"); + return ZONE_BAD_ORIGINAL; + } + } + + if (ioctl(fd, MEMERASE, &erase) != 0) { + printf(": Third erase failed (%s)\n", strerror(errno)); + return ZONE_BAD_ORIGINAL; + } + for (blockofs = 0; blockofs < meminfo.erasesize; blockofs += 512) { + pwrite(fd, writebuf[3], 512, blockofs + ofs); + pread(fd, readbuf, 512, blockofs + ofs); + if (memcmp(readbuf, writebuf[3], 512)) { + printf(": Block not 0xa5 after writing\n"); + return ZONE_BAD_ORIGINAL; + } + } + if (ioctl(fd, MEMERASE, &erase) != 0) { + printf(": Fourth erase failed (%s)\n", strerror(errno)); + return ZONE_BAD_ORIGINAL; + } + return ZONE_GOOD; +} + +static unsigned char erase_block(unsigned long block) +{ + unsigned char status; + int ret; + + status = (do_oobcheck) ? check_block_1(block) : ZONE_GOOD; + erase.start = block * meminfo.erasesize; + + if (status != ZONE_GOOD) { + printf("\rSkipping bad zone (factory marked) #%ld @ 0x%x\n", block, erase.start); + fflush(stdout); + return status; + } + + printf("\r\t Erasing Zone #%ld @ 0x%x", block, erase.start); + fflush(stdout); + + if ((ret=ioctl(fd, MEMERASE, &erase)) != 0) { + printf(": Erase failed (%s)\n", strerror(errno)); + return ZONE_BAD_ORIGINAL; + } + + if (do_rwecheck) { + printf("\r\tChecking Zone #%ld @ 0x%x", block, erase.start); + fflush(stdout); + status = check_block_2(block); + if (status != ZONE_GOOD) { + printf("\rSkipping bad zone (RWE test failed) #%ld @ 0x%x\n", block, erase.start); + fflush(stdout); + } + } + return status; +} + +static int checkbbt(void) +{ + unsigned char bbt[512]; + unsigned char bits; + int i, addr; + + if (pread(fd, bbt, 512, 0x800) < 0) { + printf("nftl_format: failed to read BBT, errno=%d\n", errno); + return (-1); + } + + + for (i = 0; (i < 512); i++) { + addr = i / 4; + bits = 0x3 << ((i % 4) * 2); + if ((bbt[addr] & bits) == 0) { + BadUnitTable[i] = ZONE_BAD_ORIGINAL; + } + } + + return (0); +} + +void usage(int rc) +{ + fprintf(stderr, "Usage: nftl_format [-ib] [ []]\n"); + exit(rc); +} + +int main(int argc, char **argv) +{ + unsigned long startofs = 0, part_size = 0; + unsigned long ezones = 0, ezone = 0, bad_zones = 0; + unsigned char unit_factor = 0xFF; + long MediaUnit1 = -1, MediaUnit2 = -1; + long MediaUnitOff1 = 0, MediaUnitOff2 = 0; + unsigned char oobbuf[16]; + struct mtd_oob_buf oob = {0, 16, oobbuf}; + char *mtddevice, *nftl; + int c, do_inftl = 0, do_bbt = 0; + + + printf("version 1.24 2005/11/07 11:15:13 gleixner\n"); + + if (argc < 2) + usage(1); + + nftl = "NFTL"; + + while ((c = getopt(argc, argv, "?hib")) > 0) { + switch (c) { + case 'i': + nftl = "INFTL"; + do_inftl = 1; + break; + case 'b': + do_bbt = 1; + break; + case 'h': + case '?': + usage(0); + break; + default: + usage(1); + break; + } + } + + mtddevice = argv[optind++]; + if (argc > optind) { + startofs = strtoul(argv[optind++], NULL, 0); + } + if (argc > optind) { + part_size = strtoul(argv[optind++], NULL, 0); + } + + // Open and size the device + if ((fd = open(mtddevice, O_RDWR)) < 0) { + perror("Open flash device"); + return 1; + } + + if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { + perror("ioctl(MEMGETINFO)"); + close(fd); + return 1; + } + + switch (meminfo.erasesize) { + case 0x1000: + case 0x2000: + case 0x4000: + case 0x8000: + break; + default: + printf("Unrecognized Erase size, 0x%x - I'm confused\n", + meminfo.erasesize); + close(fd); + return 1; + } + writebuf[0] = malloc(meminfo.erasesize * 5); + if (!writebuf[0]) { + printf("Malloc failed\n"); + close(fd); + return 1; + } + writebuf[1] = writebuf[0] + meminfo.erasesize; + writebuf[2] = writebuf[1] + meminfo.erasesize; + writebuf[3] = writebuf[2] + meminfo.erasesize; + readbuf = writebuf[3] + meminfo.erasesize; + memset(writebuf[0], 0xff, meminfo.erasesize); + memset(writebuf[1], 0x00, meminfo.erasesize); + memset(writebuf[2], 0x5a, meminfo.erasesize); + memset(writebuf[3], 0xa5, meminfo.erasesize); + memset(BadUnitTable, ZONE_GOOD, MAX_ERASE_ZONES); + + if (part_size == 0 || (part_size > meminfo.size - startofs)) + /* the user doest not or incorrectly specify NFTL partition size */ + part_size = meminfo.size - startofs; + + erase.length = meminfo.erasesize; + ezones = part_size / meminfo.erasesize; + + if (ezones > MAX_ERASE_ZONES) { + /* Ought to change the UnitSizeFactor. But later. */ + part_size = meminfo.erasesize * MAX_ERASE_ZONES; + ezones = MAX_ERASE_ZONES; + unit_factor = 0xFF; + } + + /* If using device BBT then parse that now */ + if (do_bbt) { + checkbbt(); + do_oobcheck = 0; + do_rwecheck = 0; + } + + /* Phase 1. Erasing and checking each erase zones in the NFTL partition. + N.B. Erase Zones not used by the NFTL partition are untouched and marked ZONE_GOOD */ + printf("Phase 1. Checking and erasing Erase Zones from 0x%08lx to 0x%08lx\n", + startofs, startofs + part_size); + for (ezone = startofs / meminfo.erasesize; + ezone < (ezones + startofs / meminfo.erasesize); ezone++) { + if (BadUnitTable[ezone] != ZONE_GOOD) + continue; + if ((BadUnitTable[ezone] = erase_block(ezone)) == ZONE_GOOD) { + if (MediaUnit1 == -1) { + MediaUnit1 = ezone; + } else if (MediaUnit2 == -1) { + MediaUnit2 = ezone; + } + } else { + bad_zones++; + } + } + printf("\n"); + + /* N.B. from dump of M-System original chips, NumEraseUnits counts the 2 Erase Unit used + by MediaHeader and the FirstPhysicalEUN starts from the MediaHeader */ + if (do_inftl) { + unsigned long maxzones, pezstart, pezend, numvunits; + + INFTLhdr = (struct INFTLMediaHeader *) (writebuf[0]); + strcpy(INFTLhdr->bootRecordID, "BNAND"); + INFTLhdr->NoOfBootImageBlocks = cpu_to_le32(0); + INFTLhdr->NoOfBinaryPartitions = cpu_to_le32(0); + INFTLhdr->NoOfBDTLPartitions = cpu_to_le32(1); + INFTLhdr->BlockMultiplierBits = cpu_to_le32(0); + INFTLhdr->FormatFlags = cpu_to_le32(0); + INFTLhdr->OsakVersion = cpu_to_le32(OSAK_VERSION); + INFTLhdr->PercentUsed = cpu_to_le32(PERCENTUSED); + /* + * Calculate number of virtual units we will have to work + * with. I am calculating out the known bad units here, not + * sure if that is what M-Systems do... + */ + MediaUnit2 = MediaUnit1; + MediaUnitOff2 = 4096; + maxzones = meminfo.size / meminfo.erasesize; + pezstart = startofs / meminfo.erasesize + 1; + pezend = startofs / meminfo.erasesize + ezones - 1; + numvunits = (ezones - 2) * PERCENTUSED / 100; + for (ezone = pezstart; ezone < maxzones; ezone++) { + if (BadUnitTable[ezone] != ZONE_GOOD) { + if (numvunits > 1) + numvunits--; + } + } + + INFTLhdr->Partitions[0].virtualUnits = cpu_to_le32(numvunits); + INFTLhdr->Partitions[0].firstUnit = cpu_to_le32(pezstart); + INFTLhdr->Partitions[0].lastUnit = cpu_to_le32(pezend); + INFTLhdr->Partitions[0].flags = cpu_to_le32(INFTL_BDTL); + INFTLhdr->Partitions[0].spareUnits = cpu_to_le32(0); + INFTLhdr->Partitions[0].Reserved0 = INFTLhdr->Partitions[0].firstUnit; + INFTLhdr->Partitions[0].Reserved1 = cpu_to_le32(0); + + } else { + + NFTLhdr = (struct NFTLMediaHeader *) (writebuf[0]); + strcpy(NFTLhdr->DataOrgID, "ANAND"); + NFTLhdr->NumEraseUnits = cpu_to_le16(part_size / meminfo.erasesize); + NFTLhdr->FirstPhysicalEUN = cpu_to_le16(MediaUnit1); + /* N.B. we reserve 2 more Erase Units for "folding" of Virtual Unit Chain */ + NFTLhdr->FormattedSize = cpu_to_le32(part_size - ( (5+bad_zones) * meminfo.erasesize)); + NFTLhdr->UnitSizeFactor = unit_factor; + } + + /* Phase 2. Writing NFTL Media Headers and Bad Unit Table */ + printf("Phase 2.a Writing %s Media Header and Bad Unit Table\n", nftl); + pwrite(fd, writebuf[0], 512, MediaUnit1 * meminfo.erasesize + MediaUnitOff1); + for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { + pwrite(fd, BadUnitTable + ezone, 512, + (MediaUnit1 * meminfo.erasesize) + 512 * (1 + ezone / 512)); + } + +#if 0 + printf(" MediaHeader contents:\n"); + printf(" NumEraseUnits: %d\n", le16_to_cpu(NFTLhdr->NumEraseUnits)); + printf(" FirstPhysicalEUN: %d\n", le16_to_cpu(NFTLhdr->FirstPhysicalEUN)); + printf(" FormattedSize: %d (%d sectors)\n", le32_to_cpu(NFTLhdr->FormattedSize), + le32_to_cpu(NFTLhdr->FormattedSize)/512); +#endif + printf("Phase 2.b Writing Spare %s Media Header and Spare Bad Unit Table\n", nftl); + pwrite(fd, writebuf[0], 512, MediaUnit2 * meminfo.erasesize + MediaUnitOff2); + for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { + pwrite(fd, BadUnitTable + ezone, 512, + (MediaUnit2 * meminfo.erasesize + MediaUnitOff2) + 512 * (1 + ezone / 512)); + } + + /* UCI #1 for newly erased Erase Unit */ + memset(oobbuf, 0xff, 16); + oobbuf[11] = oobbuf[10] = oobbuf[9] = 0; + oobbuf[8] = (do_inftl) ? 0x00 : 0x03; + oobbuf[12] = oobbuf[14] = 0x69; + oobbuf[13] = oobbuf[15] = 0x3c; + + /* N.B. The Media Header and Bad Erase Unit Table are considered as Free Erase Unit + by M-System i.e. their Virtual Unit Number == 0xFFFF in the Unit Control Information #0, + but their Block Status is BLOCK_USED (0x5555) in their Block Control Information */ + /* Phase 3. Writing Unit Control Information for each Erase Unit */ + printf("Phase 3. Writing Unit Control Information to each Erase Unit\n"); + for (ezone = MediaUnit1; ezone < (ezones + startofs / meminfo.erasesize); ezone++) { + /* write UCI #1 to each Erase Unit */ + if (BadUnitTable[ezone] != ZONE_GOOD) + continue; + oob.start = (ezone * meminfo.erasesize) + 512 + (do_inftl * 512); + if (ioctl(fd, MEMWRITEOOB, &oob)) + printf("MEMWRITEOOB at %lx: %s\n", (unsigned long)oob.start, strerror(errno)); + } + + exit(0); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rbtree.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rbtree.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rbtree.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rbtree.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,390 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + (C) 2002 David Woodhouse + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/lib/rbtree.c +*/ + +#include +#include "rbtree.h" + +static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *right = node->rb_right; + struct rb_node *parent = rb_parent(node); + + if ((node->rb_right = right->rb_left)) + rb_set_parent(right->rb_left, node); + right->rb_left = node; + + rb_set_parent(right, parent); + + if (parent) + { + if (node == parent->rb_left) + parent->rb_left = right; + else + parent->rb_right = right; + } + else + root->rb_node = right; + rb_set_parent(node, right); +} + +static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *left = node->rb_left; + struct rb_node *parent = rb_parent(node); + + if ((node->rb_left = left->rb_right)) + rb_set_parent(left->rb_right, node); + left->rb_right = node; + + rb_set_parent(left, parent); + + if (parent) + { + if (node == parent->rb_right) + parent->rb_right = left; + else + parent->rb_left = left; + } + else + root->rb_node = left; + rb_set_parent(node, left); +} + +void rb_insert_color(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *parent, *gparent; + + while ((parent = rb_parent(node)) && rb_is_red(parent)) + { + gparent = rb_parent(parent); + + if (parent == gparent->rb_left) + { + { + register struct rb_node *uncle = gparent->rb_right; + if (uncle && rb_is_red(uncle)) + { + rb_set_black(uncle); + rb_set_black(parent); + rb_set_red(gparent); + node = gparent; + continue; + } + } + + if (parent->rb_right == node) + { + register struct rb_node *tmp; + __rb_rotate_left(parent, root); + tmp = parent; + parent = node; + node = tmp; + } + + rb_set_black(parent); + rb_set_red(gparent); + __rb_rotate_right(gparent, root); + } else { + { + register struct rb_node *uncle = gparent->rb_left; + if (uncle && rb_is_red(uncle)) + { + rb_set_black(uncle); + rb_set_black(parent); + rb_set_red(gparent); + node = gparent; + continue; + } + } + + if (parent->rb_left == node) + { + register struct rb_node *tmp; + __rb_rotate_right(parent, root); + tmp = parent; + parent = node; + node = tmp; + } + + rb_set_black(parent); + rb_set_red(gparent); + __rb_rotate_left(gparent, root); + } + } + + rb_set_black(root->rb_node); +} + +static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, + struct rb_root *root) +{ + struct rb_node *other; + + while ((!node || rb_is_black(node)) && node != root->rb_node) + { + if (parent->rb_left == node) + { + other = parent->rb_right; + if (rb_is_red(other)) + { + rb_set_black(other); + rb_set_red(parent); + __rb_rotate_left(parent, root); + other = parent->rb_right; + } + if ((!other->rb_left || rb_is_black(other->rb_left)) && + (!other->rb_right || rb_is_black(other->rb_right))) + { + rb_set_red(other); + node = parent; + parent = rb_parent(node); + } + else + { + if (!other->rb_right || rb_is_black(other->rb_right)) + { + struct rb_node *o_left; + if ((o_left = other->rb_left)) + rb_set_black(o_left); + rb_set_red(other); + __rb_rotate_right(other, root); + other = parent->rb_right; + } + rb_set_color(other, rb_color(parent)); + rb_set_black(parent); + if (other->rb_right) + rb_set_black(other->rb_right); + __rb_rotate_left(parent, root); + node = root->rb_node; + break; + } + } + else + { + other = parent->rb_left; + if (rb_is_red(other)) + { + rb_set_black(other); + rb_set_red(parent); + __rb_rotate_right(parent, root); + other = parent->rb_left; + } + if ((!other->rb_left || rb_is_black(other->rb_left)) && + (!other->rb_right || rb_is_black(other->rb_right))) + { + rb_set_red(other); + node = parent; + parent = rb_parent(node); + } + else + { + if (!other->rb_left || rb_is_black(other->rb_left)) + { + register struct rb_node *o_right; + if ((o_right = other->rb_right)) + rb_set_black(o_right); + rb_set_red(other); + __rb_rotate_left(other, root); + other = parent->rb_left; + } + rb_set_color(other, rb_color(parent)); + rb_set_black(parent); + if (other->rb_left) + rb_set_black(other->rb_left); + __rb_rotate_right(parent, root); + node = root->rb_node; + break; + } + } + } + if (node) + rb_set_black(node); +} + +void rb_erase(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *child, *parent; + int color; + + if (!node->rb_left) + child = node->rb_right; + else if (!node->rb_right) + child = node->rb_left; + else + { + struct rb_node *old = node, *left; + + node = node->rb_right; + while ((left = node->rb_left) != NULL) + node = left; + child = node->rb_right; + parent = rb_parent(node); + color = rb_color(node); + + if (child) + rb_set_parent(child, parent); + if (parent == old) { + parent->rb_right = child; + parent = node; + } else + parent->rb_left = child; + + node->rb_parent_color = old->rb_parent_color; + node->rb_right = old->rb_right; + node->rb_left = old->rb_left; + + if (rb_parent(old)) + { + if (rb_parent(old)->rb_left == old) + rb_parent(old)->rb_left = node; + else + rb_parent(old)->rb_right = node; + } else + root->rb_node = node; + + rb_set_parent(old->rb_left, node); + if (old->rb_right) + rb_set_parent(old->rb_right, node); + goto color; + } + + parent = rb_parent(node); + color = rb_color(node); + + if (child) + rb_set_parent(child, parent); + if (parent) + { + if (parent->rb_left == node) + parent->rb_left = child; + else + parent->rb_right = child; + } + else + root->rb_node = child; + + color: + if (color == RB_BLACK) + __rb_erase_color(child, parent, root); +} + +/* + * This function returns the first node (in sort order) of the tree. + */ +struct rb_node *rb_first(struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_left) + n = n->rb_left; + return n; +} + +struct rb_node *rb_last(struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_right) + n = n->rb_right; + return n; +} + +struct rb_node *rb_next(struct rb_node *node) +{ + struct rb_node *parent; + + if (rb_parent(node) == node) + return NULL; + + /* If we have a right-hand child, go down and then left as far + as we can. */ + if (node->rb_right) { + node = node->rb_right; + while (node->rb_left) + node=node->rb_left; + return node; + } + + /* No right-hand children. Everything down and left is + smaller than us, so any 'next' node must be in the general + direction of our parent. Go up the tree; any time the + ancestor is a right-hand child of its parent, keep going + up. First time it's a left-hand child of its parent, said + parent is our 'next' node. */ + while ((parent = rb_parent(node)) && node == parent->rb_right) + node = parent; + + return parent; +} + +struct rb_node *rb_prev(struct rb_node *node) +{ + struct rb_node *parent; + + if (rb_parent(node) == node) + return NULL; + + /* If we have a left-hand child, go down and then right as far + as we can. */ + if (node->rb_left) { + node = node->rb_left; + while (node->rb_right) + node=node->rb_right; + return node; + } + + /* No left-hand children. Go up till we find an ancestor which + is a right-hand child of its parent */ + while ((parent = rb_parent(node)) && node == parent->rb_left) + node = parent; + + return parent; +} + +void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root) +{ + struct rb_node *parent = rb_parent(victim); + + /* Set the surrounding nodes to point to the replacement */ + if (parent) { + if (victim == parent->rb_left) + parent->rb_left = new; + else + parent->rb_right = new; + } else { + root->rb_node = new; + } + if (victim->rb_left) + rb_set_parent(victim->rb_left, new); + if (victim->rb_right) + rb_set_parent(victim->rb_right, new); + + /* Copy the pointers/colour from the victim to the replacement */ + *new = *victim; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rbtree.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rbtree.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rbtree.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rbtree.h 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,168 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/include/linux/rbtree.h + + To use rbtrees you'll have to implement your own insert and search cores. + This will avoid us to use callbacks and to drop drammatically performances. + I know it's not the cleaner way, but in C (not in C++) to get + performances and genericity... + + Some example of insert and search follows here. The search is a plain + normal search over an ordered tree. The insert instead must be implemented + int two steps: as first thing the code must insert the element in + order as a red leaf in the tree, then the support library function + rb_insert_color() must be called. Such function will do the + not trivial work to rebalance the rbtree if necessary. + +----------------------------------------------------------------------- +static inline struct page * rb_search_page_cache(struct inode * inode, + unsigned long offset) +{ + struct rb_node * n = inode->i_rb_page_cache.rb_node; + struct page * page; + + while (n) + { + page = rb_entry(n, struct page, rb_page_cache); + + if (offset < page->offset) + n = n->rb_left; + else if (offset > page->offset) + n = n->rb_right; + else + return page; + } + return NULL; +} + +static inline struct page * __rb_insert_page_cache(struct inode * inode, + unsigned long offset, + struct rb_node * node) +{ + struct rb_node ** p = &inode->i_rb_page_cache.rb_node; + struct rb_node * parent = NULL; + struct page * page; + + while (*p) + { + parent = *p; + page = rb_entry(parent, struct page, rb_page_cache); + + if (offset < page->offset) + p = &(*p)->rb_left; + else if (offset > page->offset) + p = &(*p)->rb_right; + else + return page; + } + + rb_link_node(node, parent, p); + + return NULL; +} + +static inline struct page * rb_insert_page_cache(struct inode * inode, + unsigned long offset, + struct rb_node * node) +{ + struct page * ret; + if ((ret = __rb_insert_page_cache(inode, offset, node))) + goto out; + rb_insert_color(node, &inode->i_rb_page_cache); + out: + return ret; +} +----------------------------------------------------------------------- +*/ + +#ifndef _LINUX_RBTREE_H +#define _LINUX_RBTREE_H + +#include +#include + +struct rb_node +{ + unsigned long rb_parent_color; +#define RB_RED 0 +#define RB_BLACK 1 + struct rb_node *rb_right; + struct rb_node *rb_left; +} __attribute__((aligned(sizeof(long)))); + /* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct rb_root +{ + struct rb_node *rb_node; +}; + + +#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) +#define rb_color(r) ((r)->rb_parent_color & 1) +#define rb_is_red(r) (!rb_color(r)) +#define rb_is_black(r) rb_color(r) +#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) +#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) + +static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) +{ + rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; +} +static inline void rb_set_color(struct rb_node *rb, int color) +{ + rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; +} + +#define RB_ROOT (struct rb_root) { NULL, } + +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define rb_entry(ptr, type, member) container_of(ptr, type, member) + +#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) +#define RB_EMPTY_NODE(node) (rb_parent(node) == node) +#define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) + +extern void rb_insert_color(struct rb_node *, struct rb_root *); +extern void rb_erase(struct rb_node *, struct rb_root *); + +/* Find logical next and previous nodes in a tree */ +extern struct rb_node *rb_next(struct rb_node *); +extern struct rb_node *rb_prev(struct rb_node *); +extern struct rb_node *rb_first(struct rb_root *); +extern struct rb_node *rb_last(struct rb_root *); + +/* Fast replacement of a single node without remove/rebalance/add/rebalance */ +extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root); + +static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, + struct rb_node ** rb_link) +{ + node->rb_parent_color = (unsigned long )parent; + node->rb_left = node->rb_right = NULL; + + *rb_link = node; +} + +#endif /* _LINUX_RBTREE_H */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/recv_image.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/recv_image.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/recv_image.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/recv_image.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,484 @@ + +#define _XOPEN_SOURCE 500 +#define _USE_MISC + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crc32.h" +#include "mtd/mtd-user.h" +#include "mcast_image.h" + +#define min(x,y) ( (x)>(y)?(y):(x) ) + +#define WBUF_SIZE 4096 +struct eraseblock { + uint32_t flash_offset; + unsigned char wbuf[WBUF_SIZE]; + int wbuf_ofs; + int nr_pkts; + int *pkt_indices; + uint32_t crc; +}; + +int main(int argc, char **argv) +{ + struct addrinfo *ai; + struct addrinfo hints; + struct addrinfo *runp; + int ret; + int sock; + size_t len; + int flfd; + struct mtd_info_user meminfo; + unsigned char *eb_buf, *decode_buf, **src_pkts; + int nr_blocks = 0; + int pkts_per_block; + int block_nr = -1; + uint32_t image_crc; + int total_pkts = 0; + int ignored_pkts = 0; + loff_t mtdoffset = 0; + int badcrcs = 0; + int duplicates = 0; + int file_mode = 0; + struct fec_parms *fec; + int i; + struct eraseblock *eraseblocks = NULL; + uint32_t start_seq; + struct timeval start, now; + unsigned long fec_time = 0, flash_time = 0, crc_time = 0, + rflash_time = 0, erase_time = 0, net_time = 0; + + if (argc != 4) { + fprintf(stderr, "usage: %s \n", + (strrchr(argv[0], '/')?:argv[0]-1)+1); + exit(1); + } + /* Open the device */ + flfd = open(argv[3], O_RDWR); + + if (flfd >= 0) { + /* Fill in MTD device capability structure */ + if (ioctl(flfd, MEMGETINFO, &meminfo) != 0) { + perror("MEMGETINFO"); + close(flfd); + flfd = -1; + } else { + printf("Receive to MTD device %s with erasesize %d\n", + argv[3], meminfo.erasesize); + } + } + if (flfd == -1) { + /* Try again, as if it's a file */ + flfd = open(argv[3], O_CREAT|O_TRUNC|O_RDWR, 0644); + if (flfd < 0) { + perror("open"); + exit(1); + } + meminfo.erasesize = 131072; + file_mode = 1; + printf("Receive to file %s with (assumed) erasesize %d\n", + argv[3], meminfo.erasesize); + } + + pkts_per_block = (meminfo.erasesize + PKT_SIZE - 1) / PKT_SIZE; + + eb_buf = malloc(pkts_per_block * PKT_SIZE); + decode_buf = malloc(pkts_per_block * PKT_SIZE); + if (!eb_buf && !decode_buf) { + fprintf(stderr, "No memory for eraseblock buffer\n"); + exit(1); + } + src_pkts = malloc(sizeof(unsigned char *) * pkts_per_block); + if (!src_pkts) { + fprintf(stderr, "No memory for decode packet pointers\n"); + exit(1); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_socktype = SOCK_DGRAM; + + ret = getaddrinfo(argv[1], argv[2], &hints, &ai); + if (ret) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); + exit(1); + } + runp = ai; + for (runp = ai; runp; runp = runp->ai_next) { + sock = socket(runp->ai_family, runp->ai_socktype, + runp->ai_protocol); + if (sock == -1) { + perror("socket"); + continue; + } + if (runp->ai_family == AF_INET && + IN_MULTICAST( ntohl(((struct sockaddr_in *)runp->ai_addr)->sin_addr.s_addr))) { + struct ip_mreq rq; + rq.imr_multiaddr = ((struct sockaddr_in *)runp->ai_addr)->sin_addr; + rq.imr_interface.s_addr = INADDR_ANY; + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &rq, sizeof(rq))) { + perror("IP_ADD_MEMBERSHIP"); + close(sock); + continue; + } + + } else if (runp->ai_family == AF_INET6 && + ((struct sockaddr_in6 *)runp->ai_addr)->sin6_addr.s6_addr[0] == 0xff) { + struct ipv6_mreq rq; + rq.ipv6mr_multiaddr = ((struct sockaddr_in6 *)runp->ai_addr)->sin6_addr; + rq.ipv6mr_interface = 0; + if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &rq, sizeof(rq))) { + perror("IPV6_ADD_MEMBERSHIP"); + close(sock); + continue; + } + } + if (bind(sock, runp->ai_addr, runp->ai_addrlen)) { + perror("bind"); + close(sock); + continue; + } + break; + } + if (!runp) + exit(1); + + while (1) { + struct image_pkt thispkt; + + len = read(sock, &thispkt, sizeof(thispkt)); + + if (len < 0) { + perror("read socket"); + break; + } + if (len < sizeof(thispkt)) { + fprintf(stderr, "Wrong length %d bytes (expected %d)\n", + len, sizeof(thispkt)); + continue; + } + if (!eraseblocks) { + image_crc = thispkt.hdr.totcrc; + start_seq = ntohl(thispkt.hdr.pkt_sequence); + + if (meminfo.erasesize != ntohl(thispkt.hdr.blocksize)) { + fprintf(stderr, "Erasesize mismatch (0x%x not 0x%x)\n", + ntohl(thispkt.hdr.blocksize), meminfo.erasesize); + exit(1); + } + nr_blocks = ntohl(thispkt.hdr.nr_blocks); + + fec = fec_new(pkts_per_block, ntohs(thispkt.hdr.nr_pkts)); + + eraseblocks = malloc(nr_blocks * sizeof(*eraseblocks)); + if (!eraseblocks) { + fprintf(stderr, "No memory for block map\n"); + exit(1); + } + for (i = 0; i < nr_blocks; i++) { + eraseblocks[i].pkt_indices = malloc(sizeof(int) * pkts_per_block); + if (!eraseblocks[i].pkt_indices) { + fprintf(stderr, "Failed to allocate packet indices\n"); + exit(1); + } + eraseblocks[i].nr_pkts = 0; + if (!file_mode) { + if (mtdoffset >= meminfo.size) { + fprintf(stderr, "Run out of space on flash\n"); + exit(1); + } +#if 1 /* Deliberately use bad blocks... test write failures */ + while (ioctl(flfd, MEMGETBADBLOCK, &mtdoffset) > 0) { + printf("Skipping flash bad block at %08x\n", (uint32_t)mtdoffset); + mtdoffset += meminfo.erasesize; + } +#endif + } + eraseblocks[i].flash_offset = mtdoffset; + mtdoffset += meminfo.erasesize; + eraseblocks[i].wbuf_ofs = 0; + } + gettimeofday(&start, NULL); + } + if (image_crc != thispkt.hdr.totcrc) { + fprintf(stderr, "\nImage CRC changed from 0x%x to 0x%x. Aborting\n", + ntohl(image_crc), ntohl(thispkt.hdr.totcrc)); + exit(1); + } + + block_nr = ntohl(thispkt.hdr.block_nr); + if (block_nr >= nr_blocks) { + fprintf(stderr, "\nErroneous block_nr %d (> %d)\n", + block_nr, nr_blocks); + exit(1); + } + for (i=0; i= pkts_per_block) { + /* We have a block which we didn't really need */ + eraseblocks[block_nr].nr_pkts++; + ignored_pkts++; + continue; + } + + if (crc32(-1, thispkt.data, PKT_SIZE) != ntohl(thispkt.hdr.thiscrc)) { + printf("\nDiscard %08x pkt %d with bad CRC (%08x not %08x)\n", + block_nr * meminfo.erasesize, ntohs(thispkt.hdr.pkt_nr), + crc32(-1, thispkt.data, PKT_SIZE), + ntohl(thispkt.hdr.thiscrc)); + badcrcs++; + continue; + } + pkt_again: + eraseblocks[block_nr].pkt_indices[eraseblocks[block_nr].nr_pkts++] = + ntohs(thispkt.hdr.pkt_nr); + total_pkts++; + if (!(total_pkts % 50) || total_pkts == pkts_per_block * nr_blocks) { + uint32_t pkts_sent = ntohl(thispkt.hdr.pkt_sequence) - start_seq + 1; + long time_msec; + gettimeofday(&now, NULL); + + time_msec = ((now.tv_usec - start.tv_usec) / 1000) + + (now.tv_sec - start.tv_sec) * 1000; + + printf("\rReceived %d/%d (%d%%) in %lds @%ldKiB/s, %d lost (%d%%), %d dup/xs ", + total_pkts, nr_blocks * pkts_per_block, + total_pkts * 100 / nr_blocks / pkts_per_block, + time_msec / 1000, + total_pkts * PKT_SIZE / 1024 * 1000 / time_msec, + pkts_sent - total_pkts - duplicates - ignored_pkts, + (pkts_sent - total_pkts - duplicates - ignored_pkts) * 100 / pkts_sent, + duplicates + ignored_pkts); + fflush(stdout); + } + + if (eraseblocks[block_nr].wbuf_ofs + PKT_SIZE < WBUF_SIZE) { + /* New packet doesn't full the wbuf */ + memcpy(eraseblocks[block_nr].wbuf + eraseblocks[block_nr].wbuf_ofs, + thispkt.data, PKT_SIZE); + eraseblocks[block_nr].wbuf_ofs += PKT_SIZE; + } else { + int fits = WBUF_SIZE - eraseblocks[block_nr].wbuf_ofs; + ssize_t wrotelen; + static int faked = 1; + + memcpy(eraseblocks[block_nr].wbuf + eraseblocks[block_nr].wbuf_ofs, + thispkt.data, fits); + wrotelen = pwrite(flfd, eraseblocks[block_nr].wbuf, WBUF_SIZE, + eraseblocks[block_nr].flash_offset); + + if (wrotelen < WBUF_SIZE || (block_nr == 5 && eraseblocks[block_nr].nr_pkts == 5 && !faked)) { + faked = 1; + if (wrotelen < 0) + perror("\npacket write"); + else + fprintf(stderr, "\nshort write of packet wbuf\n"); + + if (!file_mode) { + struct erase_info_user erase; + /* FIXME: Perhaps we should store pkt crcs and try + to recover data from the offending eraseblock */ + + /* We have increased nr_pkts but not yet flash_offset */ + erase.start = eraseblocks[block_nr].flash_offset & + ~(meminfo.erasesize - 1); + erase.length = meminfo.erasesize; + + printf("Will erase at %08lx len %08lx (bad write was at %08lx)\n", + erase.start, erase.length, eraseblocks[block_nr].flash_offset); + if (ioctl(flfd, MEMERASE, &erase)) { + perror("MEMERASE"); + exit(1); + } + if (mtdoffset >= meminfo.size) { + fprintf(stderr, "Run out of space on flash\n"); + exit(1); + } + while (ioctl(flfd, MEMGETBADBLOCK, &mtdoffset) > 0) { + printf("Skipping flash bad block at %08x\n", (uint32_t)mtdoffset); + mtdoffset += meminfo.erasesize; + if (mtdoffset >= meminfo.size) { + fprintf(stderr, "Run out of space on flash\n"); + exit(1); + } + } + eraseblocks[block_nr].flash_offset = mtdoffset; + printf("Block #%d will now be at %08lx\n", block_nr, (long)mtdoffset); + total_pkts -= eraseblocks[block_nr].nr_pkts; + eraseblocks[block_nr].nr_pkts = 0; + eraseblocks[block_nr].wbuf_ofs = 0; + mtdoffset += meminfo.erasesize; + goto pkt_again; + } + else /* Usually nothing we can do in file mode */ + exit(1); + } + eraseblocks[block_nr].flash_offset += WBUF_SIZE; + /* Copy the remainder into the wbuf */ + memcpy(eraseblocks[block_nr].wbuf, &thispkt.data[fits], PKT_SIZE - fits); + eraseblocks[block_nr].wbuf_ofs = PKT_SIZE - fits; + } + + if (eraseblocks[block_nr].nr_pkts == pkts_per_block) { + eraseblocks[block_nr].crc = ntohl(thispkt.hdr.block_crc); + + if (total_pkts == nr_blocks * pkts_per_block) + break; + } + } + printf("\n"); + gettimeofday(&now, NULL); + net_time = (now.tv_usec - start.tv_usec) / 1000; + net_time += (now.tv_sec - start.tv_sec) * 1000; + close(sock); + for (block_nr = 0; block_nr < nr_blocks; block_nr++) { + ssize_t rwlen; + gettimeofday(&start, NULL); + eraseblocks[block_nr].flash_offset -= meminfo.erasesize; + rwlen = pread(flfd, eb_buf, meminfo.erasesize, eraseblocks[block_nr].flash_offset); + + gettimeofday(&now, NULL); + rflash_time += (now.tv_usec - start.tv_usec) / 1000; + rflash_time += (now.tv_sec - start.tv_sec) * 1000; + if (rwlen < 0) { + perror("read"); + /* Argh. Perhaps we could go back and try again, but if the flash is + going to fail to read back what we write to it, and the whole point + in this program is to write to it, what's the point? */ + fprintf(stderr, "Packets we wrote to flash seem to be unreadable. Aborting\n"); + exit(1); + } + + memcpy(eb_buf + meminfo.erasesize, eraseblocks[block_nr].wbuf, + eraseblocks[block_nr].wbuf_ofs); + + for (i=0; i < pkts_per_block; i++) + src_pkts[i] = &eb_buf[i * PKT_SIZE]; + + gettimeofday(&start, NULL); + if (fec_decode(fec, src_pkts, eraseblocks[block_nr].pkt_indices, PKT_SIZE)) { + /* Eep. This cannot happen */ + printf("The world is broken. fec_decode() returned error\n"); + exit(1); + } + gettimeofday(&now, NULL); + fec_time += (now.tv_usec - start.tv_usec) / 1000; + fec_time += (now.tv_sec - start.tv_sec) * 1000; + + for (i=0; i < pkts_per_block; i++) + memcpy(&decode_buf[i*PKT_SIZE], src_pkts[i], PKT_SIZE); + + /* Paranoia */ + gettimeofday(&start, NULL); + if (crc32(-1, decode_buf, meminfo.erasesize) != eraseblocks[block_nr].crc) { + printf("\nCRC mismatch for block #%d: want %08x got %08x\n", + block_nr, eraseblocks[block_nr].crc, + crc32(-1, decode_buf, meminfo.erasesize)); + exit(1); + } + gettimeofday(&now, NULL); + crc_time += (now.tv_usec - start.tv_usec) / 1000; + crc_time += (now.tv_sec - start.tv_sec) * 1000; + start = now; + + if (!file_mode) { + struct erase_info_user erase; + + erase.start = eraseblocks[block_nr].flash_offset; + erase.length = meminfo.erasesize; + + printf("\rErasing block at %08x...", erase.start); + + if (ioctl(flfd, MEMERASE, &erase)) { + perror("MEMERASE"); + /* This block has dirty data on it. If the erase failed, we're screwed */ + fprintf(stderr, "Erase to clean FEC data from flash failed. Aborting\n"); + exit(1); + } + gettimeofday(&now, NULL); + erase_time += (now.tv_usec - start.tv_usec) / 1000; + erase_time += (now.tv_sec - start.tv_sec) * 1000; + start = now; + } + else printf("\r"); + write_again: + rwlen = pwrite(flfd, decode_buf, meminfo.erasesize, eraseblocks[block_nr].flash_offset); + if (rwlen < meminfo.erasesize) { + if (rwlen < 0) { + perror("\ndecoded data write"); + } else + fprintf(stderr, "\nshort write of decoded data\n"); + + if (!file_mode) { + struct erase_info_user erase; + erase.start = eraseblocks[block_nr].flash_offset; + erase.length = meminfo.erasesize; + + printf("Erasing failed block at %08x\n", + eraseblocks[block_nr].flash_offset); + + if (ioctl(flfd, MEMERASE, &erase)) { + perror("MEMERASE"); + exit(1); + } + if (mtdoffset >= meminfo.size) { + fprintf(stderr, "Run out of space on flash\n"); + exit(1); + } + while (ioctl(flfd, MEMGETBADBLOCK, &mtdoffset) > 0) { + printf("Skipping flash bad block at %08x\n", (uint32_t)mtdoffset); + mtdoffset += meminfo.erasesize; + if (mtdoffset >= meminfo.size) { + fprintf(stderr, "Run out of space on flash\n"); + exit(1); + } + } + printf("Will try again at %08lx...", (long)mtdoffset); + eraseblocks[block_nr].flash_offset = mtdoffset; + + goto write_again; + } + else /* Usually nothing we can do in file mode */ + exit(1); + } + gettimeofday(&now, NULL); + flash_time += (now.tv_usec - start.tv_usec) / 1000; + flash_time += (now.tv_sec - start.tv_sec) * 1000; + + printf("wrote image block %08x (%d pkts) ", + block_nr * meminfo.erasesize, eraseblocks[block_nr].nr_pkts); + fflush(stdout); + } + close(flfd); + printf("Net rx %ld.%03lds\n", net_time / 1000, net_time % 1000); + printf("flash rd %ld.%03lds\n", rflash_time / 1000, rflash_time % 1000); + printf("FEC time %ld.%03lds\n", fec_time / 1000, fec_time % 1000); + printf("CRC time %ld.%03lds\n", crc_time / 1000, crc_time % 1000); + printf("flash wr %ld.%03lds\n", flash_time / 1000, flash_time % 1000); + printf("flash er %ld.%03lds\n", erase_time / 1000, erase_time % 1000); + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rfddump.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rfddump.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/rfddump.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/rfddump.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,336 @@ +/* + * rfddump.c + * + * Copyright (C) 2005 Sean Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#define _XOPEN_SOURCE 500 /* For pread */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* next is an array of mapping for each corresponding sector */ +#define RFD_MAGIC 0x9193 +#define HEADER_MAP_OFFSET 3 +#define SECTOR_DELETED 0x0000 +#define SECTOR_ZERO 0xfffe +#define SECTOR_FREE 0xffff + +#define SECTOR_SIZE 512 + +#define SECTORS_PER_TRACK 63 + + +struct rfd { + int block_size; + int block_count; + int header_sectors; + int data_sectors; + int header_size; + uint16_t *header; + int sector_count; + int *sector_map; + const char *mtd_filename; + const char *out_filename; + int verbose; +}; + +#define PROGRAM "rfddump" +#define VERSION "$Revision 1.0 $" + +void display_help(void) +{ + printf("Usage: " PROGRAM " [OPTIONS] MTD-device filename\n" + "Dumps the contents of a resident flash disk\n" + "\n" + "-h --help display this help and exit\n" + "-V --version output version information and exit\n" + "-v --verbose Be verbose\n" + "-b size --blocksize Block size (defaults to erase unit)\n"); + exit(0); +} + +void display_version(void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + exit(0); +} + +void process_options(int argc, char *argv[], struct rfd *rfd) +{ + int error = 0; + + rfd->block_size = 0; + rfd->verbose = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "hvVb:"; + static const struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V', }, + { "blocksize", required_argument, 0, 'b' }, + { "verbose", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) + break; + + switch (c) { + case 'h': + display_help(); + break; + case 'V': + display_version(); + break; + case 'v': + rfd->verbose = 1; + break; + case 'b': + rfd->block_size = atoi(optarg); + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 2 || error) + display_help(); + + rfd->mtd_filename = argv[optind]; + rfd->out_filename = argv[optind + 1]; +} + +int build_block_map(struct rfd *rfd, int fd, int block) +{ + int i; + int sectors; + + if (pread(fd, rfd->header, rfd->header_size, block * rfd->block_size) + != rfd->header_size) { + return -1; + } + + if (le16_to_cpu(rfd->header[0]) != RFD_MAGIC) { + if (rfd->verbose) + printf("Block #%02d: Magic missing\n", block); + + return 0; + } + + sectors = 0; + for (i=0; idata_sectors; i++) { + uint16_t entry = le16_to_cpu(rfd->header[i + HEADER_MAP_OFFSET]); + + if (entry == SECTOR_FREE || entry == SECTOR_DELETED) + continue; + + if (entry == SECTOR_ZERO) + entry = 0; + + if (entry >= rfd->sector_count) { + fprintf(stderr, "%s: warning: sector %d out of range\n", + rfd->mtd_filename, entry); + continue; + } + + if (rfd->sector_map[entry] != -1) { + fprintf(stderr, "%s: warning: more than one entry " + "for sector %d\n", rfd->mtd_filename, entry); + continue; + } + + rfd->sector_map[entry] = rfd->block_size * block + + (i + rfd->header_sectors) * SECTOR_SIZE; + sectors++; + } + + if (rfd->verbose) + printf("Block #%02d: %d sectors\n", block, sectors); + + return 1; +} + +int main(int argc, char *argv[]) +{ + int fd, sectors_per_block; + mtd_info_t mtd_info; + struct rfd rfd; + int i, blocks_found; + int out_fd = 0; + uint8_t sector[512]; + int blank, rc, cylinders; + + process_options(argc, argv, &rfd); + + fd = open(rfd.mtd_filename, O_RDONLY); + if (fd == -1) { + perror(rfd.mtd_filename); + return 1; + } + + if (rfd.block_size == 0) { + if (ioctl(fd, MEMGETINFO, &mtd_info)) { + perror(rfd.mtd_filename); + close(fd); + return 1; + } + + if (mtd_info.type != MTD_NORFLASH) { + fprintf(stderr, "%s: wrong type\n", rfd.mtd_filename); + close(fd); + return 2; + } + + sectors_per_block = mtd_info.erasesize / SECTOR_SIZE; + + rfd.block_size = mtd_info.erasesize; + rfd.block_count = mtd_info.size / mtd_info.erasesize; + } else { + struct stat st; + + if (fstat(fd, &st) == -1) { + perror(rfd.mtd_filename); + close(fd); + return 1; + } + + if (st.st_size % SECTOR_SIZE) + fprintf(stderr, "%s: warning: not a multiple of sectors (512 bytes)\n", rfd.mtd_filename); + + sectors_per_block = rfd.block_size / SECTOR_SIZE; + + if (st.st_size % rfd.block_size) + fprintf(stderr, "%s: warning: not a multiple of block size\n", rfd.mtd_filename); + + rfd.block_count = st.st_size / rfd.block_size; + + if (!rfd.block_count) { + fprintf(stderr, "%s: not large enough for one block\n", rfd.mtd_filename); + close(fd); + return 2; + } + } + + rfd.header_sectors = + ((HEADER_MAP_OFFSET + sectors_per_block) * + sizeof(uint16_t) + SECTOR_SIZE - 1) / SECTOR_SIZE; + rfd.data_sectors = sectors_per_block - rfd.header_sectors; + cylinders = ((rfd.block_count - 1) * rfd.data_sectors - 1) + / SECTORS_PER_TRACK; + rfd.sector_count = cylinders * SECTORS_PER_TRACK; + rfd.header_size = + (HEADER_MAP_OFFSET + rfd.data_sectors) * sizeof(uint16_t); + + rfd.header = malloc(rfd.header_size); + if (!rfd.header) { + perror(PROGRAM); + close(fd); + return 2; + } + rfd.sector_map = malloc(rfd.sector_count * sizeof(int)); + if (!rfd.sector_map) { + perror(PROGRAM); + close(fd); + free(rfd.sector_map); + return 2; + } + + rfd.mtd_filename = rfd.mtd_filename; + + for (i=0; i 0) + blocks_found++; + if (rc < 0) + goto err; + } + + if (!blocks_found) { + fprintf(stderr, "%s: no RFD blocks found\n", rfd.mtd_filename); + goto err; + } + + for (i=0; i + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This is very easy: just erase all the blocks and put the magic at + * the beginning of each block. + */ + +#define _XOPEN_SOURCE 500 /* For pread/pwrite */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PROGRAM "rfdformat" +#define VERSION "$Revision 1.0 $" + +void display_help(void) +{ + printf("Usage: " PROGRAM " [OPTIONS] MTD-device\n" + "Formats NOR flash for resident flash disk\n" + "\n" + "-h --help display this help and exit\n" + "-V --version output version information and exit\n"); + exit(0); +} + +void display_version(void) +{ + printf(PROGRAM " " VERSION "\n" + "\n" + "This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + exit(0); +} + +void process_options(int argc, char *argv[], const char **mtd_filename) +{ + int error = 0; + + for (;;) { + int option_index = 0; + static const char *short_options = "hV"; + static const struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V', }, + { NULL, 0, 0, 0 } + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) + break; + + switch (c) { + case 'h': + display_help(); + break; + case 'V': + display_version(); + break; + case '?': + error = 1; + break; + } + } + + if ((argc - optind) != 1 || error) + display_help(); + + *mtd_filename = argv[optind]; +} + +int main(int argc, char *argv[]) +{ + static const uint8_t magic[] = { 0x93, 0x91 }; + int fd, block_count, i; + struct mtd_info_user mtd_info; + char buf[512]; + const char *mtd_filename; + + process_options(argc, argv, &mtd_filename); + + fd = open(mtd_filename, O_RDWR); + if (fd == -1) { + perror(mtd_filename); + return 1; + } + + if (ioctl(fd, MEMGETINFO, &mtd_info)) { + perror(mtd_filename); + close(fd); + return 1; + } + + if (mtd_info.type != MTD_NORFLASH) { + fprintf(stderr, "%s: not NOR flash\n", mtd_filename); + close(fd); + return 2; + } + + if (mtd_info.size > 32*1024*1024) { + fprintf(stderr, "%s: flash larger than 32MiB not supported\n", + mtd_filename); + close(fd); + return 2; + } + + block_count = mtd_info.size / mtd_info.erasesize; + + if (block_count < 2) { + fprintf(stderr, "%s: at least two erase units required\n", + mtd_filename); + close(fd); + return 2; + } + + for (i=0; i + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crc32.h" +#include "mcast_image.h" + +int tx_rate = 80000; +int pkt_delay; + +#undef RANDOMDROP + +int main(int argc, char **argv) +{ + struct addrinfo *ai; + struct addrinfo hints; + struct addrinfo *runp; + int ret; + int sock; + struct image_pkt pktbuf; + int rfd; + struct stat st; + int writeerrors = 0; + uint32_t erasesize; + unsigned char *image, *blockptr = NULL; + uint32_t block_nr, pkt_nr; + int nr_blocks; + struct timeval then, now, nextpkt; + long time_msecs; + int pkts_per_block; + int total_pkts_per_block; + struct fec_parms *fec; + unsigned char *last_block; + uint32_t *block_crcs; + long tosleep; + uint32_t sequence = 0; + + if (argc == 6) { + tx_rate = atol(argv[5]) * 1024; + if (tx_rate < PKT_SIZE || tx_rate > 20000000) { + fprintf(stderr, "Bogus TX rate %d KiB/s\n", tx_rate); + exit(1); + } + argc = 5; + } + if (argc != 5) { + fprintf(stderr, "usage: %s []\n", + (strrchr(argv[0], '/')?:argv[0]-1)+1); + exit(1); + } + pkt_delay = (sizeof(pktbuf) * 1000000) / tx_rate; + printf("Inter-packet delay (avg): %dµs\n", pkt_delay); + printf("Transmit rate: %d KiB/s\n", tx_rate / 1024); + + erasesize = atol(argv[4]); + if (!erasesize) { + fprintf(stderr, "erasesize cannot be zero\n"); + exit(1); + } + + pkts_per_block = (erasesize + PKT_SIZE - 1) / PKT_SIZE; + total_pkts_per_block = pkts_per_block * 3 / 2; + + /* We have to pad it with zeroes, so can't use it in-place */ + last_block = malloc(pkts_per_block * PKT_SIZE); + if (!last_block) { + fprintf(stderr, "Failed to allocate last-block buffer\n"); + exit(1); + } + + fec = fec_new(pkts_per_block, total_pkts_per_block); + if (!fec) { + fprintf(stderr, "Error initialising FEC\n"); + exit(1); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_socktype = SOCK_DGRAM; + + ret = getaddrinfo(argv[1], argv[2], &hints, &ai); + if (ret) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); + exit(1); + } + runp = ai; + for (runp = ai; runp; runp = runp->ai_next) { + sock = socket(runp->ai_family, runp->ai_socktype, + runp->ai_protocol); + if (sock == -1) { + perror("socket"); + continue; + } + if (connect(sock, runp->ai_addr, runp->ai_addrlen) == 0) + break; + perror("connect"); + close(sock); + } + if (!runp) + exit(1); + + rfd = open(argv[3], O_RDONLY); + if (rfd < 0) { + perror("open"); + exit(1); + } + + if (fstat(rfd, &st)) { + perror("fstat"); + exit(1); + } + + if (st.st_size % erasesize) { + fprintf(stderr, "Image size %ld bytes is not a multiple of erasesize %d bytes\n", + st.st_size, erasesize); + exit(1); + } + image = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, rfd, 0); + if (image == MAP_FAILED) { + perror("mmap"); + exit(1); + } + + nr_blocks = st.st_size / erasesize; + + block_crcs = malloc(nr_blocks * sizeof(uint32_t)); + if (!block_crcs) { + fprintf(stderr, "Failed to allocate memory for CRCs\n"); + exit(1); + } + + memcpy(last_block, image + (nr_blocks - 1) * erasesize, erasesize); + memset(last_block + erasesize, 0, (PKT_SIZE * pkts_per_block) - erasesize); + + printf("Checking CRC...."); + fflush(stdout); + + pktbuf.hdr.resend = 0; + pktbuf.hdr.totcrc = htonl(crc32(-1, image, st.st_size)); + pktbuf.hdr.nr_blocks = htonl(nr_blocks); + pktbuf.hdr.blocksize = htonl(erasesize); + pktbuf.hdr.thislen = htonl(PKT_SIZE); + pktbuf.hdr.nr_pkts = htons(total_pkts_per_block); + + printf("%08x\n", ntohl(pktbuf.hdr.totcrc)); + printf("Checking block CRCs...."); + fflush(stdout); + for (block_nr=0; block_nr < nr_blocks; block_nr++) { + printf("\rChecking block CRCS.... %d/%d", + block_nr + 1, nr_blocks); + fflush(stdout); + block_crcs[block_nr] = crc32(-1, image + (block_nr * erasesize), erasesize); + } + + printf("\nImage size %ld KiB (0x%08lx). %d blocks at %d pkts/block\n" + "Estimated transmit time per cycle: %ds\n", + (long)st.st_size / 1024, (long) st.st_size, + nr_blocks, pkts_per_block, + nr_blocks * pkts_per_block * pkt_delay / 1000000); + gettimeofday(&then, NULL); + nextpkt = then; + +#ifdef RANDOMDROP + srand((unsigned)then.tv_usec); + printf("Random seed %u\n", (unsigned)then.tv_usec); +#endif + while (1) for (pkt_nr=0; pkt_nr < total_pkts_per_block; pkt_nr++) { + + if (blockptr && pkt_nr == 0) { + unsigned long amt_sent = total_pkts_per_block * nr_blocks * sizeof(pktbuf); + gettimeofday(&now, NULL); + + time_msecs = (now.tv_sec - then.tv_sec) * 1000; + time_msecs += ((int)(now.tv_usec - then.tv_usec)) / 1000; + printf("\n%ld KiB sent in %ldms (%ld KiB/s)\n", + amt_sent / 1024, time_msecs, + amt_sent / 1024 * 1000 / time_msecs); + then = now; + } + + for (block_nr = 0; block_nr < nr_blocks; block_nr++) { + + int actualpkt; + + /* Calculating the redundant FEC blocks is expensive; + the first $pkts_per_block are cheap enough though + because they're just copies. So alternate between + simple and complex stuff, so that we don't start + to choke and fail to keep up with the expected + bitrate in the second half of the sequence */ + if (block_nr & 1) + actualpkt = pkt_nr; + else + actualpkt = total_pkts_per_block - 1 - pkt_nr; + + blockptr = image + (erasesize * block_nr); + if (block_nr == nr_blocks - 1) + blockptr = last_block; + + fec_encode_linear(fec, blockptr, pktbuf.data, actualpkt, PKT_SIZE); + + pktbuf.hdr.thiscrc = htonl(crc32(-1, pktbuf.data, PKT_SIZE)); + pktbuf.hdr.block_crc = htonl(block_crcs[block_nr]); + pktbuf.hdr.block_nr = htonl(block_nr); + pktbuf.hdr.pkt_nr = htons(actualpkt); + pktbuf.hdr.pkt_sequence = htonl(sequence++); + + printf("\rSending data block %08x packet %3d/%d", + block_nr * erasesize, + pkt_nr, total_pkts_per_block); + + if (pkt_nr && !block_nr) { + unsigned long amt_sent = pkt_nr * nr_blocks * sizeof(pktbuf); + + gettimeofday(&now, NULL); + + time_msecs = (now.tv_sec - then.tv_sec) * 1000; + time_msecs += ((int)(now.tv_usec - then.tv_usec)) / 1000; + printf(" (%ld KiB/s) ", + amt_sent / 1024 * 1000 / time_msecs); + } + + fflush(stdout); + +#ifdef RANDOMDROP + if ((rand() % 1000) < 20) { + printf("\nDropping packet %d of block %08x\n", pkt_nr+1, block_nr * erasesize); + continue; + } +#endif + gettimeofday(&now, NULL); +#if 1 + tosleep = nextpkt.tv_usec - now.tv_usec + + (1000000 * (nextpkt.tv_sec - now.tv_sec)); + + /* We need hrtimers for this to actually work */ + if (tosleep > 0) { + struct timespec req; + + req.tv_nsec = (tosleep % 1000000) * 1000; + req.tv_sec = tosleep / 1000000; + + nanosleep(&req, NULL); + } +#else + while (now.tv_sec < nextpkt.tv_sec || + (now.tv_sec == nextpkt.tv_sec && + now.tv_usec < nextpkt.tv_usec)) { + gettimeofday(&now, NULL); + } +#endif + nextpkt.tv_usec += pkt_delay; + if (nextpkt.tv_usec >= 1000000) { + nextpkt.tv_sec += nextpkt.tv_usec / 1000000; + nextpkt.tv_usec %= 1000000; + } + + /* If the time for the next packet has already + passed (by some margin), then we've lost time + Adjust our expected timings accordingly. If + we're only a little way behind, don't slip yet */ + if (now.tv_usec > (now.tv_usec + (5 * pkt_delay) + + 1000000 * (nextpkt.tv_sec - now.tv_sec))) { + nextpkt = now; + } + + if (write(sock, &pktbuf, sizeof(pktbuf)) < 0) { + perror("write"); + writeerrors++; + if (writeerrors > 10) { + fprintf(stderr, "Too many consecutive write errors\n"); + exit(1); + } + } else + writeerrors = 0; + + + + } + } + munmap(image, st.st_size); + close(rfd); + close(sock); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/summary.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/summary.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/summary.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/summary.h 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,178 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2004 Ferenc Havasi , + * Zoltan Sogor , + * Patrik Kluba , + * University of Szeged, Hungary + * + * For licensing information, see the file 'LICENCE' in this directory. + */ + +#ifndef JFFS2_SUMMARY_H +#define JFFS2_SUMMARY_H + +#include +#include + +#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ + c->free_size -= _x; c->dirty_size += _x; \ + jeb->free_size -= _x ; jeb->dirty_size += _x; \ +}while(0) +#define USED_SPACE(x) do { typeof(x) _x = (x); \ + c->free_size -= _x; c->used_size += _x; \ + jeb->free_size -= _x ; jeb->used_size += _x; \ +}while(0) +#define WASTED_SPACE(x) do { typeof(x) _x = (x); \ + c->free_size -= _x; c->wasted_size += _x; \ + jeb->free_size -= _x ; jeb->wasted_size += _x; \ +}while(0) +#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \ + c->free_size -= _x; c->unchecked_size += _x; \ + jeb->free_size -= _x ; jeb->unchecked_size += _x; \ +}while(0) + +#define BLK_STATE_ALLFF 0 +#define BLK_STATE_CLEAN 1 +#define BLK_STATE_PARTDIRTY 2 +#define BLK_STATE_CLEANMARKER 3 +#define BLK_STATE_ALLDIRTY 4 +#define BLK_STATE_BADBLOCK 5 + +#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff +#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash)) +#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x)) +#define JFFS2_SUMMARY_XATTR_SIZE (sizeof(struct jffs2_sum_xattr_flash)) +#define JFFS2_SUMMARY_XREF_SIZE (sizeof(struct jffs2_sum_xref_flash)) + +/* Summary structures used on flash */ + +struct jffs2_sum_unknown_flash +{ + jint16_t nodetype; /* node type */ +} __attribute__((packed)); + +struct jffs2_sum_inode_flash +{ + jint16_t nodetype; /* node type */ + jint32_t inode; /* inode number */ + jint32_t version; /* inode version */ + jint32_t offset; /* offset on jeb */ + jint32_t totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_flash +{ + jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */ + jint32_t totlen; /* record length */ + jint32_t offset; /* ofset on jeb */ + jint32_t pino; /* parent inode */ + jint32_t version; /* dirent version */ + jint32_t ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_flash +{ + jint16_t nodetype; /* == JFFS2_NODETYPE_XATR */ + jint32_t xid; /* xattr identifier */ + jint32_t version; /* version number */ + jint32_t offset; /* offset on jeb */ + jint32_t totlen; /* node length */ +} __attribute__((packed)); + +struct jffs2_sum_xref_flash +{ + jint16_t nodetype; /* == JFFS2_NODETYPE_XREF */ + jint32_t offset; /* offset on jeb */ +} __attribute__((packed)); + +union jffs2_sum_flash +{ + struct jffs2_sum_unknown_flash u; + struct jffs2_sum_inode_flash i; + struct jffs2_sum_dirent_flash d; + struct jffs2_sum_xattr_flash x; + struct jffs2_sum_xref_flash r; +}; + +/* Summary structures used in the memory */ + +struct jffs2_sum_unknown_mem +{ + union jffs2_sum_mem *next; + jint16_t nodetype; /* node type */ +} __attribute__((packed)); + +struct jffs2_sum_inode_mem +{ + union jffs2_sum_mem *next; + jint16_t nodetype; /* node type */ + jint32_t inode; /* inode number */ + jint32_t version; /* inode version */ + jint32_t offset; /* offset on jeb */ + jint32_t totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_mem +{ + union jffs2_sum_mem *next; + jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */ + jint32_t totlen; /* record length */ + jint32_t offset; /* ofset on jeb */ + jint32_t pino; /* parent inode */ + jint32_t version; /* dirent version */ + jint32_t ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_mem +{ + union jffs2_sum_mem *next; + jint16_t nodetype; + jint32_t xid; + jint32_t version; + jint32_t offset; + jint32_t totlen; +} __attribute__((packed)); + +struct jffs2_sum_xref_mem +{ + union jffs2_sum_mem *next; + jint16_t nodetype; + jint32_t offset; +} __attribute__((packed)); + +union jffs2_sum_mem +{ + struct jffs2_sum_unknown_mem u; + struct jffs2_sum_inode_mem i; + struct jffs2_sum_dirent_mem d; + struct jffs2_sum_xattr_mem x; + struct jffs2_sum_xref_mem r; +}; + +struct jffs2_summary +{ + uint32_t sum_size; + uint32_t sum_num; + uint32_t sum_padded; + union jffs2_sum_mem *sum_list_head; + union jffs2_sum_mem *sum_list_tail; +}; + +/* Summary marker is stored at the end of every sumarized erase block */ + +struct jffs2_sum_marker +{ + jint32_t offset; /* offset of the summary node in the jeb */ + jint32_t magic; /* == JFFS2_SUM_MAGIC */ +}; + +#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker)) + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/sumtool.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/sumtool.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/sumtool.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/sumtool.c 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,951 @@ +/* + * sumtool.c + * + * Copyright (C) 2004 Zoltan Sogor , + * Ferenc Havasi + * University of Szeged, Hungary + * 2006 KaiGai Kohei + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Overview: + * This is a utility insert summary information into JFFS2 image for + * faster mount time + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crc32.h" +#include "summary.h" + +#define PAD(x) (((x)+3)&~3) + +static const char *const app_name = "sumtool"; + +static struct jffs2_summary *sum_collected = NULL; + +static int verbose = 0; +static int padto = 0; /* pad the output with 0xFF to the end of the final eraseblock */ +static int add_cleanmarkers = 1; /* add cleanmarker to output */ +static int use_input_cleanmarker_size = 1; /* use input file's cleanmarker size (default) */ +static int found_cleanmarkers = 0; /* cleanmarker found in input file */ +static struct jffs2_unknown_node cleanmarker; +static int cleanmarker_size = sizeof(cleanmarker); +static const char *short_options = "o:i:e:hvVblnc:p"; +static int erase_block_size = 65536; +static int out_fd = -1; +static int in_fd = -1; + +static uint8_t *data_buffer = NULL; /* buffer for inodes */ +static unsigned int data_ofs = 0; /* inode buffer offset */ + +static uint8_t *file_buffer = NULL; /* file buffer contains the actual erase block*/ +static unsigned int file_ofs = 0; /* position in the buffer */ + +int target_endian = __BYTE_ORDER; + +static struct option long_options[] = { + {"output", 1, NULL, 'o'}, + {"input", 1, NULL, 'i'}, + {"eraseblock", 1, NULL, 'e'}, + {"help", 0, NULL, 'h'}, + {"verbose", 0, NULL, 'v'}, + {"version", 0, NULL, 'V'}, + {"bigendian", 0, NULL, 'b'}, + {"littleendian", 0, NULL, 'l'}, + {"no-cleanmarkers", 0, NULL, 'n'}, + {"cleanmarker", 1, NULL, 'c'}, + {"pad", 0, NULL, 'p'}, + {NULL, 0, NULL, 0} +}; + +static char *helptext = +"Usage: sumtool [OPTIONS] -i inputfile -o outputfile\n\n" +"Convert the input JFFS2 image to a summarized JFFS2 image\n" +"Summary makes mounting faster - if summary support enabled in your kernel\n\n" +"Options:\n" +" -e, --eraseblock=SIZE Use erase block size SIZE (default: 64KiB)\n" +" (usually 16KiB on NAND)\n" +" -c, --cleanmarker=SIZE Size of cleanmarker (default 12).\n" +" (usually 16 bytes on NAND, and will be set to\n" +" this value if left at the default 12). Will be\n" +" stored in OOB after each physical page composing\n" +" a physical eraseblock.\n" +" -n, --no-cleanmarkers Don't add a cleanmarker to every eraseblock\n" +" -o, --output=FILE Output to FILE \n" +" -i, --input=FILE Input from FILE \n" +" -b, --bigendian Image is big endian\n" +" -l --littleendian Image is little endian\n" +" -h, --help Display this help text\n" +" -v, --verbose Verbose operation\n" +" -V, --version Display version information\n" +" -p, --pad Pad the OUTPUT with 0xFF to the end of the final\n" +" eraseblock\n\n"; + + +static char *revtext = "$Revision: 1.1.1.1 $"; + +static unsigned char ffbuf[16] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static void verror_msg(const char *s, va_list p) +{ + fflush(stdout); + fprintf(stderr, "%s: ", app_name); + vfprintf(stderr, s, p); +} + +static void error_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg(s, p); + va_end(p); + putc('\n', stderr); + exit(EXIT_FAILURE); +} + +static void vperror_msg(const char *s, va_list p) +{ + int err = errno; + + if (s == 0) + s = ""; + verror_msg(s, p); + if (*s) + s = ": "; + fprintf(stderr, "%s%s\n", s, strerror(err)); +} + +static void perror_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + vperror_msg(s, p); + va_end(p); + exit(EXIT_FAILURE); +} + + + +static void full_write(void *target_buff, const void *buf, int len); + +void setup_cleanmarker() +{ + cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); + cleanmarker.totlen = cpu_to_je32(cleanmarker_size); + cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node)-4)); +} + +void process_options (int argc, char **argv) +{ + int opt,c; + + while ((opt = getopt_long(argc, argv, short_options, long_options, &c)) >= 0) { + switch (opt) { + case 'o': + if (out_fd != -1) + error_msg_and_die("output filename specified more than once"); + out_fd = open(optarg, O_CREAT | O_TRUNC | O_RDWR, 0644); + if (out_fd == -1) + perror_msg_and_die("open output file"); + break; + + case 'i': + if (in_fd != -1) + error_msg_and_die("input filename specified more than once"); + in_fd = open(optarg, O_RDONLY); + if (in_fd == -1) + perror_msg_and_die("open input file"); + break; + case 'b': + target_endian = __BIG_ENDIAN; + break; + case 'l': + target_endian = __LITTLE_ENDIAN; + break; + case 'h': + case '?': + error_msg_and_die(helptext); + case 'v': + verbose = 1; + break; + + case 'V': + error_msg_and_die("revision %.*s\n", + (int) strlen(revtext) - 13, revtext + 11); + + case 'e': { + char *next; + unsigned units = 0; + erase_block_size = strtol(optarg, &next, 0); + if (!erase_block_size) + error_msg_and_die("Unrecognisable erase size\n"); + + if (*next) { + if (!strcmp(next, "KiB")) { + units = 1024; + } else if (!strcmp(next, "MiB")) { + units = 1024 * 1024; + } else { + error_msg_and_die("Unknown units in erasesize\n"); + } + } else { + if (erase_block_size < 0x1000) + units = 1024; + else + units = 1; + } + erase_block_size *= units; + + /* If it's less than 8KiB, they're not allowed */ + if (erase_block_size < 0x2000) { + fprintf(stderr, "Erase size 0x%x too small. Increasing to 8KiB minimum\n", + erase_block_size); + erase_block_size = 0x2000; + } + break; + } + + case 'n': + add_cleanmarkers = 0; + break; + case 'c': + cleanmarker_size = strtol(optarg, NULL, 0); + + if (cleanmarker_size < sizeof(cleanmarker)) { + error_msg_and_die("cleanmarker size must be >= 12"); + } + if (cleanmarker_size >= erase_block_size) { + error_msg_and_die("cleanmarker size must be < eraseblock size"); + } + + use_input_cleanmarker_size = 0; + found_cleanmarkers = 1; + setup_cleanmarker(); + + break; + case 'p': + padto = 1; + break; + } + } +} + + +void init_buffers() +{ + data_buffer = malloc(erase_block_size); + + if (!data_buffer) { + perror("out of memory"); + close (in_fd); + close (out_fd); + exit(1); + } + + file_buffer = malloc(erase_block_size); + + if (!file_buffer) { + perror("out of memory"); + close (in_fd); + close (out_fd); + exit(1); + } +} + +void init_sumlist() +{ + sum_collected = (struct jffs2_summary *) malloc (sizeof(struct jffs2_summary)); + + if (!sum_collected) + error_msg_and_die("Can't allocate memory for jffs2_summary!\n"); + + memset(sum_collected, 0, sizeof(struct jffs2_summary)); +} + +void clean_buffers() +{ + if (data_buffer) + free(data_buffer); + if (file_buffer) + free(file_buffer); +} + +void clean_sumlist() +{ + union jffs2_sum_mem *temp; + + if (sum_collected) { + + while (sum_collected->sum_list_head) { + temp = sum_collected->sum_list_head; + sum_collected->sum_list_head = sum_collected->sum_list_head->u.next; + free(temp); + sum_collected->sum_num--; + } + + if (sum_collected->sum_num != 0) + printf("Ooops, something wrong happened! sum_num != 0, but sum_list = null ???"); + + free(sum_collected); + } +} + +int load_next_block() +{ + int ret; + ret = read(in_fd, file_buffer, erase_block_size); + file_ofs = 0; + + if (verbose) + printf("Load next block : %d bytes read\n",ret); + + return ret; +} + +void write_buff_to_file() +{ + int ret; + int len = data_ofs; + + uint8_t *buf = NULL; + + buf = data_buffer; + while (len > 0) { + ret = write(out_fd, buf, len); + + if (ret < 0) + perror_msg_and_die("write"); + + if (ret == 0) + perror_msg_and_die("write returned zero"); + + len -= ret; + buf += ret; + } + + data_ofs = 0; +} + +void dump_sum_records() +{ + + struct jffs2_raw_summary isum; + struct jffs2_sum_marker *sm; + union jffs2_sum_mem *temp; + jint32_t offset; + jint32_t *tpage; + void *wpage; + int datasize, infosize, padsize; + jint32_t magic = cpu_to_je32(JFFS2_SUM_MAGIC); + + if (!sum_collected->sum_num || !sum_collected->sum_list_head) + return; + + datasize = sum_collected->sum_size + sizeof(struct jffs2_sum_marker); + infosize = sizeof(struct jffs2_raw_summary) + datasize; + padsize = erase_block_size - data_ofs - infosize; + infosize += padsize; datasize += padsize; + offset = cpu_to_je32(data_ofs); + + tpage = (jint32_t *) malloc(datasize); + + if(!tpage) + error_msg_and_die("Can't allocate memory to dump summary information!\n"); + + memset(tpage, 0xff, datasize); + memset(&isum, 0, sizeof(isum)); + + isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY); + isum.totlen = cpu_to_je32(infosize); + isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4)); + isum.padded = cpu_to_je32(0); + + if (add_cleanmarkers && found_cleanmarkers) { + isum.cln_mkr = cpu_to_je32(cleanmarker_size); + } else { + isum.cln_mkr = cpu_to_je32(0); + } + + isum.sum_num = cpu_to_je32(sum_collected->sum_num); + wpage = tpage; + + while (sum_collected->sum_num) { + switch(je16_to_cpu(sum_collected->sum_list_head->u.nodetype)) { + + case JFFS2_NODETYPE_INODE : { + struct jffs2_sum_inode_flash *sino_ptr = wpage; + + sino_ptr->nodetype = sum_collected->sum_list_head->i.nodetype; + sino_ptr->inode = sum_collected->sum_list_head->i.inode; + sino_ptr->version = sum_collected->sum_list_head->i.version; + sino_ptr->offset = sum_collected->sum_list_head->i.offset; + sino_ptr->totlen = sum_collected->sum_list_head->i.totlen; + + wpage += JFFS2_SUMMARY_INODE_SIZE; + break; + } + + case JFFS2_NODETYPE_DIRENT : { + struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage; + + sdrnt_ptr->nodetype = sum_collected->sum_list_head->d.nodetype; + sdrnt_ptr->totlen = sum_collected->sum_list_head->d.totlen; + sdrnt_ptr->offset = sum_collected->sum_list_head->d.offset; + sdrnt_ptr->pino = sum_collected->sum_list_head->d.pino; + sdrnt_ptr->version = sum_collected->sum_list_head->d.version; + sdrnt_ptr->ino = sum_collected->sum_list_head->d.ino; + sdrnt_ptr->nsize = sum_collected->sum_list_head->d.nsize; + sdrnt_ptr->type = sum_collected->sum_list_head->d.type; + + memcpy(sdrnt_ptr->name, sum_collected->sum_list_head->d.name, + sum_collected->sum_list_head->d.nsize); + + wpage += JFFS2_SUMMARY_DIRENT_SIZE(sum_collected->sum_list_head->d.nsize); + break; + } + + case JFFS2_NODETYPE_XATTR: { + struct jffs2_sum_xattr_flash *sxattr_ptr = wpage; + + sxattr_ptr->nodetype = sum_collected->sum_list_head->x.nodetype; + sxattr_ptr->xid = sum_collected->sum_list_head->x.xid; + sxattr_ptr->version = sum_collected->sum_list_head->x.version; + sxattr_ptr->offset = sum_collected->sum_list_head->x.offset; + sxattr_ptr->totlen = sum_collected->sum_list_head->x.totlen; + + wpage += JFFS2_SUMMARY_XATTR_SIZE; + break; + } + + case JFFS2_NODETYPE_XREF: { + struct jffs2_sum_xref_flash *sxref_ptr = wpage; + + sxref_ptr->nodetype = sum_collected->sum_list_head->r.nodetype; + sxref_ptr->offset = sum_collected->sum_list_head->r.offset; + + wpage += JFFS2_SUMMARY_XREF_SIZE; + break; + } + + default : { + printf("Unknown node type!\n"); + } + } + + temp = sum_collected->sum_list_head; + sum_collected->sum_list_head = sum_collected->sum_list_head->u.next; + free(temp); + + sum_collected->sum_num--; + } + + sum_collected->sum_size = 0; + sum_collected->sum_num = 0; + sum_collected->sum_list_tail = NULL; + + wpage += padsize; + + sm = wpage; + sm->offset = offset; + sm->magic = magic; + + isum.sum_crc = cpu_to_je32(crc32(0, tpage, datasize)); + isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8)); + + full_write(data_buffer + data_ofs, &isum, sizeof(isum)); + full_write(data_buffer + data_ofs, tpage, datasize); + + free(tpage); +} + +static void full_write(void *target_buff, const void *buf, int len) +{ + memcpy(target_buff, buf, len); + data_ofs += len; +} + +static void pad(int req) +{ + while (req) { + if (req > sizeof(ffbuf)) { + full_write(data_buffer + data_ofs, ffbuf, sizeof(ffbuf)); + req -= sizeof(ffbuf); + } else { + full_write(data_buffer + data_ofs, ffbuf, req); + req = 0; + } + } +} + +static inline void padword() +{ + if (data_ofs % 4) + full_write(data_buffer + data_ofs, ffbuf, 4 - (data_ofs % 4)); +} + + +static inline void pad_block_if_less_than(int req,int plus) +{ + + int datasize = req + plus + sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; + datasize += (4 - (datasize % 4)) % 4; + + if (data_ofs + req > erase_block_size - datasize) { + dump_sum_records(); + write_buff_to_file(); + } + + if (add_cleanmarkers && found_cleanmarkers) { + if (!data_ofs) { + full_write(data_buffer, &cleanmarker, sizeof(cleanmarker)); + pad(cleanmarker_size - sizeof(cleanmarker)); + padword(); + } + } +} + +void flush_buffers() +{ + + if ((add_cleanmarkers == 1) && (found_cleanmarkers == 1)) { /* CLEANMARKER */ + if (data_ofs != cleanmarker_size) { /* INODE BUFFER */ + + int datasize = sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; + datasize += (4 - (datasize % 4)) % 4; + + /* If we have a full inode buffer, then write out inode and summary data */ + if (data_ofs + sizeof(struct jffs2_raw_inode) + 2*JFFS2_MIN_DATA_LEN > erase_block_size - datasize) { + dump_sum_records(); + write_buff_to_file(); + } else { /* else just write out inode data */ + if (padto) + pad(erase_block_size - data_ofs); + write_buff_to_file(); + } + } + } else { /* NO CLEANMARKER */ + if (data_ofs != 0) { /* INODE BUFFER */ + + int datasize = sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; + datasize += (4 - (datasize % 4)) % 4; + + /* If we have a full inode buffer, then write out inode and summary data */ + if (data_ofs + sizeof(struct jffs2_raw_inode) + 2*JFFS2_MIN_DATA_LEN > erase_block_size - datasize) { + dump_sum_records(); + write_buff_to_file(); + } else { /* Else just write out inode data */ + if(padto) + pad(erase_block_size - data_ofs); + write_buff_to_file(); + } + } + } +} + +int add_sum_mem(union jffs2_sum_mem *item) +{ + + if (!sum_collected->sum_list_head) + sum_collected->sum_list_head = (union jffs2_sum_mem *) item; + if (sum_collected->sum_list_tail) + sum_collected->sum_list_tail->u.next = (union jffs2_sum_mem *) item; + sum_collected->sum_list_tail = (union jffs2_sum_mem *) item; + + switch (je16_to_cpu(item->u.nodetype)) { + case JFFS2_NODETYPE_INODE: + sum_collected->sum_size += JFFS2_SUMMARY_INODE_SIZE; + sum_collected->sum_num++; + break; + + case JFFS2_NODETYPE_DIRENT: + sum_collected->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize); + sum_collected->sum_num++; + break; + + case JFFS2_NODETYPE_XATTR: + sum_collected->sum_size += JFFS2_SUMMARY_XATTR_SIZE; + sum_collected->sum_num++; + break; + + case JFFS2_NODETYPE_XREF: + sum_collected->sum_size += JFFS2_SUMMARY_XREF_SIZE; + sum_collected->sum_num++; + break; + + default: + error_msg_and_die("__jffs2_add_sum_mem(): UNKNOWN node type %d\n", je16_to_cpu(item->u.nodetype)); + } + return 0; +} + +void add_sum_inode_mem(union jffs2_node_union *node) +{ + struct jffs2_sum_inode_mem *temp = (struct jffs2_sum_inode_mem *) malloc(sizeof(struct jffs2_sum_inode_mem)); + + if (!temp) + error_msg_and_die("Can't allocate memory for summary information!\n"); + + temp->nodetype = node->i.nodetype; + temp->inode = node->i.ino; + temp->version = node->i.version; + temp->offset = cpu_to_je32(data_ofs); + temp->totlen = node->i.totlen; + temp->next = NULL; + + add_sum_mem((union jffs2_sum_mem *) temp); +} + +void add_sum_dirent_mem(union jffs2_node_union *node) +{ + struct jffs2_sum_dirent_mem *temp = (struct jffs2_sum_dirent_mem *) + malloc(sizeof(struct jffs2_sum_dirent_mem) + node->d.nsize); + + if (!temp) + error_msg_and_die("Can't allocate memory for summary information!\n"); + + temp->nodetype = node->d.nodetype; + temp->totlen = node->d.totlen; + temp->offset = cpu_to_je32(data_ofs); + temp->pino = node->d.pino; + temp->version = node->d.version; + temp->ino = node->d.ino; + temp->nsize = node->d.nsize; + temp->type = node->d.type; + temp->next = NULL; + + memcpy(temp->name,node->d.name,node->d.nsize); + add_sum_mem((union jffs2_sum_mem *) temp); +} + +void add_sum_xattr_mem(union jffs2_node_union *node) +{ + struct jffs2_sum_xattr_mem *temp = (struct jffs2_sum_xattr_mem *) + malloc(sizeof(struct jffs2_sum_xattr_mem)); + if (!temp) + error_msg_and_die("Can't allocate memory for summary information!\n"); + + temp->nodetype = node->x.nodetype; + temp->xid = node->x.xid; + temp->version = node->x.version; + temp->offset = cpu_to_je32(data_ofs); + temp->totlen = node->x.totlen; + temp->next = NULL; + + add_sum_mem((union jffs2_sum_mem *) temp); +} + +void add_sum_xref_mem(union jffs2_node_union *node) +{ + struct jffs2_sum_xref_mem *temp = (struct jffs2_sum_xref_mem *) + malloc(sizeof(struct jffs2_sum_xref_mem)); + if (!temp) + error_msg_and_die("Can't allocate memory for summary information!\n"); + + temp->nodetype = node->r.nodetype; + temp->offset = cpu_to_je32(data_ofs); + temp->next = NULL; + + add_sum_mem((union jffs2_sum_mem *) temp); +} + +void write_dirent_to_buff(union jffs2_node_union *node) +{ + pad_block_if_less_than(je32_to_cpu (node->d.totlen),JFFS2_SUMMARY_DIRENT_SIZE(node->d.nsize)); + add_sum_dirent_mem(node); + full_write(data_buffer + data_ofs, &(node->d), je32_to_cpu (node->d.totlen)); + padword(); +} + + +void write_inode_to_buff(union jffs2_node_union *node) +{ + pad_block_if_less_than(je32_to_cpu (node->i.totlen),JFFS2_SUMMARY_INODE_SIZE); + add_sum_inode_mem(node); /* Add inode summary mem to summary list */ + full_write(data_buffer + data_ofs, &(node->i), je32_to_cpu (node->i.totlen)); /* Write out the inode to inode_buffer */ + padword(); +} + +void write_xattr_to_buff(union jffs2_node_union *node) +{ + pad_block_if_less_than(je32_to_cpu(node->x.totlen), JFFS2_SUMMARY_XATTR_SIZE); + add_sum_xattr_mem(node); /* Add xdatum summary mem to summary list */ + full_write(data_buffer + data_ofs, &(node->x), je32_to_cpu(node->x.totlen)); + padword(); +} + +void write_xref_to_buff(union jffs2_node_union *node) +{ + pad_block_if_less_than(je32_to_cpu(node->r.totlen), JFFS2_SUMMARY_XREF_SIZE); + add_sum_xref_mem(node); /* Add xref summary mem to summary list */ + full_write(data_buffer + data_ofs, &(node->r), je32_to_cpu(node->r.totlen)); + padword(); +} + +void create_summed_image(int inp_size) +{ + uint8_t *p = file_buffer; + union jffs2_node_union *node; + uint32_t crc, length; + uint16_t type; + int bitchbitmask = 0; + int obsolete; + char name[256]; + + while ( p < (file_buffer + inp_size)) { + + node = (union jffs2_node_union *) p; + + /* Skip empty space */ + if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { + p += 4; + continue; + } + + if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { + if (!bitchbitmask++) + printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - file_buffer, je16_to_cpu (node->u.magic)); + p += 4; + continue; + } + + bitchbitmask = 0; + + type = je16_to_cpu(node->u.nodetype); + if ((type & JFFS2_NODE_ACCURATE) != JFFS2_NODE_ACCURATE) { + obsolete = 1; + type |= JFFS2_NODE_ACCURATE; + } else { + obsolete = 0; + } + + node->u.nodetype = cpu_to_je16(type); + + crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); + if (crc != je32_to_cpu (node->u.hdr_crc)) { + printf ("Wrong hdr_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - file_buffer, je32_to_cpu (node->u.hdr_crc), crc); + p += 4; + continue; + } + + switch(je16_to_cpu(node->u.nodetype)) { + case JFFS2_NODETYPE_INODE: + if (verbose) + printf ("%8s Inode node at 0x%08x, totlen 0x%08x, #ino %5d, version %5d, isize %8d, csize %8d, dsize %8d, offset %8d\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->i.totlen), je32_to_cpu (node->i.ino), + je32_to_cpu ( node->i.version), je32_to_cpu (node->i.isize), + je32_to_cpu (node->i.csize), je32_to_cpu (node->i.dsize), je32_to_cpu (node->i.offset)); + + crc = crc32 (0, node, sizeof (struct jffs2_raw_inode) - 8); + if (crc != je32_to_cpu (node->i.node_crc)) { + printf ("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - file_buffer, je32_to_cpu (node->i.node_crc), crc); + p += PAD(je32_to_cpu (node->i.totlen)); + continue; + } + + crc = crc32(0, p + sizeof (struct jffs2_raw_inode), je32_to_cpu(node->i.csize)); + if (crc != je32_to_cpu(node->i.data_crc)) { + printf ("Wrong data_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - file_buffer, je32_to_cpu (node->i.data_crc), crc); + p += PAD(je32_to_cpu (node->i.totlen)); + continue; + } + + write_inode_to_buff(node); + + p += PAD(je32_to_cpu (node->i.totlen)); + break; + + case JFFS2_NODETYPE_DIRENT: + memcpy (name, node->d.name, node->d.nsize); + name [node->d.nsize] = 0x0; + + if (verbose) + printf ("%8s Dirent node at 0x%08x, totlen 0x%08x, #pino %5d, version %5d, #ino %8d, nsize %8d, name %s\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->d.totlen), je32_to_cpu (node->d.pino), + je32_to_cpu ( node->d.version), je32_to_cpu (node->d.ino), + node->d.nsize, name); + + crc = crc32 (0, node, sizeof (struct jffs2_raw_dirent) - 8); + if (crc != je32_to_cpu (node->d.node_crc)) { + printf ("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - file_buffer, je32_to_cpu (node->d.node_crc), crc); + p += PAD(je32_to_cpu (node->d.totlen)); + continue; + } + + crc = crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize); + if (crc != je32_to_cpu(node->d.name_crc)) { + printf ("Wrong name_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - file_buffer, je32_to_cpu (node->d.name_crc), crc); + p += PAD(je32_to_cpu (node->d.totlen)); + continue; + } + + write_dirent_to_buff(node); + + p += PAD(je32_to_cpu (node->d.totlen)); + break; + + case JFFS2_NODETYPE_XATTR: + if (je32_to_cpu(node->x.node_crc) == 0xffffffff) + obsolete = 1; + if (verbose) + printf("%8s Xdatum node at 0x%08x, totlen 0x%08x, " + "#xid %5u, version %5u\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->x.totlen), + je32_to_cpu(node->x.xid), je32_to_cpu(node->x.version)); + crc = crc32(0, node, sizeof (struct jffs2_raw_xattr) - 4); + if (crc != je32_to_cpu(node->x.node_crc)) { + printf("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", + p - file_buffer, je32_to_cpu(node->x.node_crc), crc); + p += PAD(je32_to_cpu (node->x.totlen)); + continue; + } + length = node->x.name_len + 1 + je16_to_cpu(node->x.value_len); + crc = crc32(0, node->x.data, length); + if (crc != je32_to_cpu(node->x.data_crc)) { + printf("Wrong data_crc at 0x%08x, 0x%08x instead of 0x%08x\n", + p - file_buffer, je32_to_cpu(node->x.data_crc), crc); + p += PAD(je32_to_cpu (node->x.totlen)); + continue; + } + + write_xattr_to_buff(node); + p += PAD(je32_to_cpu (node->x.totlen)); + break; + + case JFFS2_NODETYPE_XREF: + if (je32_to_cpu(node->r.node_crc) == 0xffffffff) + obsolete = 1; + if (verbose) + printf("%8s Xref node at 0x%08x, totlen 0x%08x, " + "#ino %5u, xid %5u\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu(node->r.totlen), + je32_to_cpu(node->r.ino), je32_to_cpu(node->r.xid)); + crc = crc32(0, node, sizeof (struct jffs2_raw_xref) - 4); + if (crc != je32_to_cpu(node->r.node_crc)) { + printf("Wrong node_crc at 0x%08x, 0x%08x instead of 0x%08x\n", + p - file_buffer, je32_to_cpu(node->r.node_crc), crc); + p += PAD(je32_to_cpu (node->r.totlen)); + continue; + } + + write_xref_to_buff(node); + p += PAD(je32_to_cpu (node->r.totlen)); + break; + + case JFFS2_NODETYPE_CLEANMARKER: + if (verbose) { + printf ("%8s Cleanmarker at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + + if (!found_cleanmarkers) { + found_cleanmarkers = 1; + + if (add_cleanmarkers == 1 && use_input_cleanmarker_size == 1){ + cleanmarker_size = je32_to_cpu (node->u.totlen); + setup_cleanmarker(); + } + } + + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case JFFS2_NODETYPE_PADDING: + if (verbose) { + printf ("%8s Padding node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + p += PAD(je32_to_cpu (node->u.totlen)); + break; + + case 0xffff: + p += 4; + break; + + default: + if (verbose) { + printf ("%8s Unknown node at 0x%08x, totlen 0x%08x\n", + obsolete ? "Obsolete" : "", + p - file_buffer, je32_to_cpu (node->u.totlen)); + } + + p += PAD(je32_to_cpu (node->u.totlen)); + } + } +} + +int main(int argc, char **argv) +{ + int ret; + + process_options(argc,argv); + + if ((in_fd == -1) || (out_fd == -1)) { + if(in_fd != -1) + close(in_fd); + if(out_fd != -1) + close(out_fd); + fprintf(stderr,helptext); + error_msg_and_die("You must specify input and output files!\n"); + } + + init_buffers(); + init_sumlist(); + + while ((ret = load_next_block())) { + create_summed_image(ret); + } + + flush_buffers(); + clean_buffers(); + clean_sumlist(); + + if (in_fd != -1) + close(in_fd); + if (out_fd != -1) + close(out_fd); + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/checkfs.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/checkfs.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/checkfs.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/checkfs.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,695 @@ +/* + + * Copyright Daniel Industries. + * + * Created by: Vipin Malik (vipin.malik@daniel.com) + * + * This code is released under the GPL version 2. See the file COPYING + * for more details. + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + + This program opens files in progression (file00001, file00002 etc), + upto MAX_NUM_FILES and checks their CRC. If a file is not found or the + CRC does not match it stops it's operation. + + Everything is logged in a logfile called './logfile'. + + If everything is ok this program sends a signal, via com1, to the remote + power control box to power cycle this computer. + + This program then proceeds to create new files file0....file + in a endless loop and checksum each before closing them. + + STRUCTURE OF THE FILES: + The fist int is the size of the file in bytes. + The last 2 bytes are the CRC for the entire file. + There is random data in between. + + The files are opened in the current dir. + + $Id: checkfs.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Log: not supported by cvs2svn $ + Revision 1.8 2005/11/07 11:15:17 gleixner + [MTD / JFFS2] Clean up trailing white spaces + + Revision 1.7 2001/06/21 23:04:17 dwmw2 + Initial import to MTD CVS + + Revision 1.6 2001/06/08 22:26:05 vipin + Split the modbus comm part of the program (that sends the ok to pwr me down + message) into another file "comm.c" + + Revision 1.5 2001/06/08 21:29:56 vipin + fixed small issue with write() checking for < 0 instead of < (bytes to be written). + Now it does the latter (as it should). + + Revision 1.4 2001/05/11 22:29:40 vipin + Added a test to check and err out if the first int in file (which tells us + how many bytes there are in the file) is zero. This will prevent a corrupt + file with zero's in it from passing the crc test. + + Revision 1.3 2001/05/11 21:33:54 vipin + Changed to use write() rather than fwrite() when creating new file. Additionally, + and more important, it now does a single write() for the entire data. This will + enable us to use this program to test for power fail *data* reliability when + writing over an existing file, specially on powr fail "safe" file systems as + jffs/jffs2. Also added a new cmdline parameter "-e" that specifies the max # of + errors that can be tolerated. This should be set to ZERO to test for the above, + as old data should be reliabily maintained if the newer write never "took" before + power failed. If the write did succeed, then the newer data will have its own + CRC in place when it gets checked => hence no error. In theory at least! + + + Revision 1.2 2001/05/11 19:27:33 vipin + Added cmd line args to change serial port, and specify max size of + random files created. Some cleanup. Added -Wall to Makefile. + + Revision 1.1 2001/05/11 16:06:28 vipin + Importing checkfs (the power fail test program) into CVS. This was + originally done for NEWS. NEWS had a lot of version, this is + based off the last one done for NEWS. The "makefiles" program + is run once initially to create the files in the current dir. + "checkfs" is then run on every powerup to check consistancy + of the files. See checkfs.c for more details. + + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + + + +extern int do_pwr_dn(int fd, int cycleCnt); + +#define CMDLINE_PORT "-p" +#define CMDLINE_MAXFILEBYTES "-s" +#define CMDLINE_MAXERROR "-e" +#define CMDLINE_HELPSHORT "-?" +#define CMDLINE_HELPLONG "--help" + + +int CycleCount; + +char SerialDevice[255] = "/dev/ttyS0"; /* default, can be changed + through cmd line. */ + +#define MAX_INTS_ALLOW 100000 /* max # of int's in the file written. + Statis limit to size struct. */ +float FileSizeMax = 1024.0; /*= (file size in bytes), MUST be float*/ + +int MaxErrAllowed = 1; /* default, can ge changed thru cmd line*/ + + +/* Needed for CRC generation/checking */ +static const unsigned short crc_ccitt_table[] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + + +/* + Set's up the Linux serial port. Must be passed string to device to + open. Parameters are fixed to 9600,e,1 + + [A possible enhancement to this program would be to pass these + parameters via the command line.] + + Returns file descriptor to open port. Use this fd to write to port + and close it later, when done. +*/ +int setupSerial (const char *dev) { + int i, fd; + struct termios tios; + + fd = open(dev,O_RDWR | O_NDELAY ); + if (fd < 0) { + fprintf(stderr, "%s: %s\n", dev, sys_errlist[errno]); + exit(1); + } + if (tcgetattr(fd, &tios) < 0) { + fprintf(stderr,"Could not get terminal attributes: %s",sys_errlist[errno]); + exit(1); + } + + tios.c_cflag = + CS7 | + CREAD | // Enable Receiver + HUPCL | // Hangup after close + CLOCAL | // Ignore modem control lines + PARENB; // Enable parity (even by default) + + + + tios.c_iflag = IGNBRK; // Ignore break + tios.c_oflag = 0; + tios.c_lflag = 0; + for(i = 0; i < NCCS; i++) { + tios.c_cc[i] = '\0'; // no special characters + } + tios.c_cc[VMIN] = 1; + tios.c_cc[VTIME] = 0; + + cfsetospeed (&tios, B9600); + cfsetispeed (&tios, B9600); + + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { + fprintf(stderr,"Could not set attributes: ,%s",sys_errlist[errno]); + exit(1); + } + return fd; +} + + + + + +//A portion of this code was taken from the AX.25 HDLC packet driver +//in LINUX. Once I test and have a better understanding of what +//it is doing, it will be better commented. + +//For now one can speculate that the CRC routine always expects the +//CRC to calculate out to 0xf0b8 (the hardcoded value at the end) +//and returns TRUE if it is and FALSE if it doesn't. +//Why don't people document better!!!! +int check_crc_ccitt(char *filename) +{ + FILE *fp; + FILE *logfp; + unsigned short crc = 0xffff; + int len; + char dataByte; + int retry; + char done; + + fp = fopen(filename,"rb"); + if(!fp){ + logfp = fopen("logfile","a"); /*open for appending only.*/ + fprintf(logfp, "Verify checksum:Error! Cannot open filename passed for verify checksum: %s\n",filename); + fclose(logfp); + return FALSE; + } + + + /*the first int contains an int that is the length of the file in long.*/ + if(fread(&len, sizeof(int), 1, fp) != 1){ + logfp = fopen("logfile","a"); /*open for appending only.*/ + fprintf(logfp, "verify checksum:Error reading from file: %s\n", filename); + fclose(fp); + fclose(logfp); + return FALSE; + } + + /* printf("Checking %i bytes for CRC in \"%s\".\n", len, filename); */ + + /* Make sure that we did not read 0 as the number of bytes in file. This + check prevents a corrupt file with zero's in it from passing the + CRC test. A good file will always have some data in it. */ + if(len == 0) + { + + logfp = fopen("logfile","a"); /*open for appending only.*/ + fprintf(logfp, "verify checksum: first int claims there are 0 data in file. Error!: %s\n", filename); + fclose(fp); + fclose(logfp); + return FALSE; + } + + + rewind(fp); + len+=2; /*the file has two extra bytes at the end, it's checksum. Those + two MUST also be included in the checksum calculation. + */ + + for (;len>0;len--){ + retry=5; /*retry 5 times*/ + done = FALSE; + while(!done){ + if(fread(&dataByte, sizeof(char), 1, fp) != 1){ + retry--; + }else{ + done = TRUE; + } + if(retry == 0){ + done = TRUE; + } + } + if(!retry){ + logfp = fopen("logfile","a"); /*open for appending only.*/ + fprintf(logfp, "Unexpected end of file: %s\n", filename); + fprintf(logfp, "...bytes left to be read %i.\n",len); + fclose(logfp); + fclose(fp); + return FALSE; + } + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ dataByte) & 0xff]; + } + fclose(fp); + if( (crc & 0xffff) != 0xf0b8){ + /*printf("The CRC of read file:%x\n", crc); */ + return FALSE; + } + return TRUE; +}/*end check_crc_ccitt() */ + + + +/* + Sends "OK to power me down" message to the remote + power cycling box, via the serial port. + Also updates the num power cycle count in a local + file. + This file "./cycleCnt" must be present. This is + initially (and once) created by the separate "makefiles.c" + program. +*/ +void send_pwrdn_ok(void){ + + int fd; + FILE *cyclefp; + int cycle_fd; + + cyclefp = fopen("cycleCnt","rb"); + if(!cyclefp){ + printf("expecting file \"cycleCnt\". Cannot continue.\n"); + exit(1); + } + if(fread(&CycleCount, sizeof(CycleCount),1,cyclefp) != 1){ + fprintf(stderr, "Error! Unexpected end of file cycleCnt.\n"); + exit(1); + } + fclose(cyclefp); + + CycleCount++; + + /*now write this puppy back*/ + cyclefp = fopen("cycleCnt","wb"); + cycle_fd = fileno(cyclefp); + if(!cyclefp){ + fprintf(stderr, "Error! cannot open file for write:\"cycleCnt\". Cannot continue.\n"); + exit(1); + } + if(fwrite(&CycleCount, sizeof(CycleCount), 1,cyclefp) !=1){ + fprintf(stderr, "Error writing to file cycleCnt. Cannot continue.\n"); + exit(1); + } + if(fdatasync(cycle_fd)){ + fprintf(stderr, "Error! cannot sync file buffer with disk.\n"); + exit(1); + } + + fclose(cyclefp); + (void)sync(); + + printf("\n\n Sending Power down command to the remote box.\n"); + fd = setupSerial(SerialDevice); + + if(do_pwr_dn(fd, CycleCount) < 0) + { + fprintf(stderr, "Error sending power down command.\n"); + exit(1); + } + + close(fd); +}//end send_pwrnd_ok() + + + + +/* + Appends 16bit CRC at the end of numBytes long buffer. + Make sure buf, extends at least 2 bytes beyond. + */ +void appendChecksum(char *buf, int numBytes){ + + unsigned short crc = 0xffff; + int index = 0; + + /* printf("Added CRC (2 bytes) to %i bytes.\n", numBytes); */ + + for (; numBytes > 0; numBytes--){ + + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ buf[index++]) & 0xff]; + } + crc ^= 0xffff; + /*printf("The CRC: %x\n\n", crc);*/ + + buf[index++] = crc; + buf[index++] = crc >> 8; + + + +}/*end checksum()*/ + + + + + +/* + This guy make a new "random data file" with the filename + passed to it. This file is checksummed with the checksum + stored at the end. The first "int" in the file is the + number of int's in it (this is needed to know how much + data to read and checksum later). +*/ +void make_new_file(char *filename){ + + + int dfd; /* data file descriptor */ + int rand_data; + int data_size; + int temp_size; + int dataIndex = 0; + int err; + + + struct { + int sizeInBytes; /* must be int */ + int dataInt[MAX_INTS_ALLOW+1]; /* how many int's can we write? */ + }__attribute((packed)) dataBuf; + + + fprintf(stderr, "Creating File:%s. ", filename); + + if((dfd = open(filename, O_RDWR | O_CREAT | O_SYNC)) <= 0) + { + printf("Error! Cannot open file: %s\n",filename); + perror("Error"); + exit(1); + } + + /*now write a bunch of random binary data to the file*/ + /*first figure out how much data to write. That is random also.*/ + + /*file should not be less than 5 ints long. (so that we have decent length files, + that's all)*/ + while( + ((data_size = (int)(1+(int)((FileSizeMax/sizeof(int))*rand()/(RAND_MAX+1.0)))) < 5) + ); + + /* printf("Writing %i ints to the file.\n", data_size); */ + + temp_size = data_size * sizeof(int); + + /* Make sure that all data is written in one go! This is important to + check for reliability of file systems like JFFS/JFFS that purport to + have "reliable" writes during powre fail. + */ + + dataBuf.sizeInBytes = temp_size; + + data_size--; /*one alrady written*/ + dataIndex = 0; + + while(data_size--){ + rand_data = (int)(1 + (int)(10000.0*rand()/(RAND_MAX+1.0))); + + dataBuf.dataInt[dataIndex++] = rand_data; + + } + + /*now calculate the file checksum and append it to the end*/ + appendChecksum((char *)&dataBuf, dataBuf.sizeInBytes); + + /* Don't forget to increase the size of data written by the 2 chars of CRC at end. + These 2 bytes are NOT included in the sizeInBytes field. */ + if((err = write(dfd, (void *)&dataBuf, dataBuf.sizeInBytes + sizeof(short))) < + (dataBuf.sizeInBytes + sizeof(short)) + ) + { + printf("Error writing data buffer to file. Written %i bytes rather than %i bytes.", + err, dataBuf.sizeInBytes); + perror("Error"); + exit(1); + } + + /* Now that the data is (hopefully) safely written. I can truncate the file to the new + length so that I can reclaim any unused space, if the older file was larger. + */ + if(ftruncate(dfd, dataBuf.sizeInBytes + sizeof(short)) < 0) + { + perror("Error: Unable to truncate file."); + exit(1); + } + + + close(dfd); + + +}//end make_new_file() + + + +/* + Show's help on stdout + */ +void printHelp(char **argv) +{ + printf("Usage:%s \n", argv[0]); + printf("%s : Set com port to send ok to pwr dn msg on\n", + CMDLINE_PORT); + printf("%s : Set Max size in bytes of each file to be created.\n", + CMDLINE_MAXFILEBYTES); + printf("%s : Set Max errors allowed when checking all files for CRC on start.\n", + CMDLINE_MAXERROR); + printf("%s or %s: This Help screen.\n", CMDLINE_HELPSHORT, + CMDLINE_HELPLONG); + +}/* end printHelp()*/ + + + +void processCmdLine(int argc, char **argv) +{ + + int cnt; + + /* skip past name of this program, process rest */ + for(cnt = 1; cnt < argc; cnt++) + { + if(strcmp(argv[cnt], CMDLINE_PORT) == 0) + { + strncpy(SerialDevice, argv[++cnt], sizeof(SerialDevice)); + continue; + }else + if(strcmp(argv[cnt], CMDLINE_MAXFILEBYTES) == 0) + { + FileSizeMax = (float)atoi(argv[++cnt]); + if(FileSizeMax > (MAX_INTS_ALLOW*sizeof(int))) + { + printf("Max file size allowd is %i.\n", + MAX_INTS_ALLOW*sizeof(int)); + exit(0); + } + + continue; + }else + if(strcmp(argv[cnt], CMDLINE_HELPSHORT) == 0) + { + printHelp(argv); + exit(0); + + }else + if(strcmp(argv[cnt], CMDLINE_HELPLONG) == 0) + { + printHelp(argv); + exit(0); + }else + + if(strcmp(argv[cnt], CMDLINE_MAXERROR) == 0) + { + MaxErrAllowed = atoi(argv[++cnt]); + } + else + { + printf("Unknown cmd line option:%s\n", argv[cnt]); + printHelp(argv); + exit(0); + + } + } + + +}/* end processCmdLine() */ + + + + + +int main(int argc, char **argv){ + + FILE *logfp; + int log_fd; + char filename[30]; + short filenameCounter = 0; + unsigned short counter; + unsigned short numberFiles; + char error = FALSE; + short errorCnt = 0; + time_t timep; + char * time_string; + unsigned int seed; + + + numberFiles = MAX_NUM_FILES; + + if(argc >= 1) + { + processCmdLine(argc, argv); + } + + + /* + First open MAX_NUM_FILES and make sure that the checksum is ok. + Also make an intry into the logfile. + */ + /* timestamp! */ + time(&timep); + time_string = (char *)ctime((time_t *)&timep); + + /*start a new check, make a log entry and continue*/ + logfp = fopen("logfile","a"); /*open for appending only.*/ + log_fd = fileno(logfp); + fprintf(logfp,"%s", time_string); + fprintf(logfp,"Starting new check.\n"); + if(fdatasync(log_fd) == -1){ + fprintf(stderr,"Error! Cannot sync file data with disk.\n"); + exit(1); + } + + fclose(logfp); + (void)sync(); + + /* + Now check all random data files in this dir. + */ + for(counter=0;counter MaxErrAllowed){ + logfp = fopen("logfile","a"); /*open for appending only.*/ + log_fd = fileno(logfp); + fprintf(logfp,"\nMax Error count exceed. Stopping!\n"); + if(fdatasync(log_fd) == -1){ + fprintf(stderr,"Error! Cannot sync file data with disk.\n"); + exit(1); + } + fclose(logfp); + (void)sync(); + + fprintf(stderr, "Too many errors. See \"logfile\".\n"); + exit(1); + }/* if too many errors */ + + /*we have decided to continue, however first repair this file + so that we do not cumulate errors across power cycles.*/ + make_new_file(filename); + } + }//for + + /*all files checked, make a log entry and continue*/ + logfp = fopen("logfile","a"); /*open for appending only.*/ + log_fd = fileno(logfp); + fprintf(logfp,"All files checked. Total errors found: %i\n\n", errorCnt); + if(fdatasync(log_fd)){ + fprintf(stderr, "Error! cannot sync file buffer with disk.\n"); + exit(1); + } + + fclose(logfp); + (void)sync(); + + /*now send a message to the remote power box and have it start a random + pwer down timer after which power will be killed to this unit. + */ + send_pwrdn_ok(); + + /*now go into a forever loop of writing to files and CRC'ing them on + a continious basis.*/ + + /*start from a random file #*/ + /*seed rand based on the current time*/ + seed = (unsigned int)time(NULL); + srand(seed); + + filenameCounter=(int)(1+(int)((float)(MAX_NUM_FILES-1)*rand()/(RAND_MAX+1.0))); + + while(1){ + + for(;filenameCounter +#include +#include + + + +/* + This is the routine that forms and + sends the "ok to pwr me down" message + to the remote power cycling "black box". + + */ +int do_pwr_dn(int fd, int cycleCnt) +{ + + char buf[200]; + + sprintf(buf, "ok to power me down!\nCount = %i\n", cycleCnt); + + if(write(fd, buf, strlen(buf)) < strlen(buf)) + { + perror("write error"); + return -1; + } + + return 0; +} + + + + + + + + + + + + + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/common.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/common.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/common.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/common.h 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,7 @@ +/* $Id: common.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ */ +//this .h file is common to both the file creation utility and +//the file checking utility. +#define TRUE 1 +#define FALSE 0 + +#define MAX_NUM_FILES 100 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/Makefile 2010-03-03 19:04:34.000000000 -0800 @@ -0,0 +1,14 @@ + +all: checkfs makefiles + +checkfs: checkfs.c Makefile common.h comm.o + gcc -g -Wall checkfs.c comm.o -o checkfs + +comm.o: comm.c Makefile + gcc -g -Wall -c comm.c -o comm.o + +makefiles: makefiles.c Makefile common.h + gcc -g -Wall makefiles.c -o makefiles + +clean: + rm -f makefiles checkfs *~ *.o diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/makefiles.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/makefiles.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/checkfs/makefiles.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/checkfs/makefiles.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,264 @@ +/* + + * Copyright Daniel Industries. + + * Created by: Vipin Malik (vipin.malik@daniel.com) + * + * This is GPL code. See the file COPYING for more details + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + + * $Id: makefiles.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + +This program creates MAX_NUM_FILES files (file00001, file00002 etc) and +fills them with random numbers till they are a random length. Then it checksums +the files (with the checksum as the last two bytes) and closes the file. + +The fist int is the size of the file in bytes. + +It then opens another file and the process continues. + +The files are opened in the current dir. + +*/ +#include +#include +#include +#include +#include +#include "common.h" + +#define FILESIZE_MAX 20000.0 /* for each file in sizeof(int). Must be a float # + Hence, 20000.0 = 20000*4 = 80KB max file size + */ + +static const unsigned short crc_ccitt_table[] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +//This code was taken from the AX.25 HDLC packet driver +//in LINUX. Once I test and have a better understanding of what +//it is doing, it will be better commented. + +//For now one can speculate that the CRC routine always expects the +//CRC to calculate out to 0xf0b8 (the hardcoded value at the end) +//and returns TRUE if it is and FALSE if it doesn't. +//Why don't people document better!!!! +void check_crc_ccitt(char *filename) +{ + FILE *fp; + unsigned short crc = 0xffff; + int len; + char dataByte; + int retry; + + fp = fopen(filename,"rb"); + if(!fp){ + printf("Verify checksum:Error! Cannot open filename passed for verify checksum: %s\n",filename); + exit(1); + } + /*the first int contains an int that is the length of the file in long.*/ + if(fread(&len, sizeof(int), 1, fp) != 1){ + printf("verify checksum:Error reading from file: %s", filename); + fclose(fp); + exit(1); + } + rewind(fp); + len+=2; /*the file has two extra bytes at the end, it's checksum. Those + two MUST also be included in the checksum calculation. + */ + + for (;len>0;len--){ + retry=5; /*retry 5 times*/ + while(!fread(&dataByte, sizeof(char), 1, fp) && retry--); + if(!retry){ + printf("Unexpected error reading from file: %s\n", filename); + printf("...bytes left to be read %i.\n\n",len); + fclose(fp); + exit(1); + } + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ dataByte) & 0xff]; + } + fclose(fp); + if( (crc & 0xffff) != 0xf0b8){ + printf("Verify checksum: Error in file %s.\n\n",filename); + exit(1); + } +}//end check_crc_ccitt() + + + +/*this routine opens a file 'filename' and checksumn's the entire + contents, and then appends the checksum at the end of the file, + closes the file and returns. +*/ +void checksum(char *filename){ + + FILE *fp; + unsigned short crc = 0xffff; + int len; + char dataByte; + int retry; + + fp = fopen(filename,"rb"); + if(!fp){ + printf("Error! Cannot open filename passed for checksum: %s\n",filename); + exit(1); + } + /*the first int contains an int that is the length of the file in longs.*/ + if(fread(&len, sizeof(int), 1, fp) != 1){ + printf("Error reading from file: %s", filename); + fclose(fp); + exit(1); + } + printf("Calculating checksum on %i bytes.\n",len); + rewind(fp); /*the # of bytes int is also included in the checksum.*/ + + for (;len>0;len--){ + retry=5; /*retry 5 times*/ + while(!fread(&dataByte, sizeof(char), 1, fp) && retry--); + if(!retry){ + printf("Unexpected error reading from file: %s\n", filename); + printf("...bytes left to be read %i.\n\n",len); + fclose(fp); + exit(1); + } + crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ dataByte) & 0xff]; + } + crc ^= 0xffff; + printf("The CRC: %x\n\n", crc); + + /*the CRC has been calculated. now close the file and open it in append mode*/ + fclose(fp); + + fp = fopen(filename,"ab"); /*open in append mode. CRC goes at the end.*/ + if(!fp){ + printf("Error! Cannot open filename to update checksum: %s\n",filename); + exit(1); + } + if(fwrite(&crc, sizeof(crc), 1, fp) != 1){ + printf("error! unable to update the file for checksum.\n"); + fclose(fp); + exit(1); + } + fflush(fp); + fclose(fp); + + +}/*end checksum()*/ + + + +int main(void){ + + FILE *fp, *cyclefp; + int cycleCount; + int rand_data; + int data_size; + int temp_size; + char filename[30]; + short filenameCounter = 0; + unsigned short counter; + unsigned short numberFiles; + + numberFiles = MAX_NUM_FILES; + + for(counter=0;counter +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +/* Structures to store data written to the test file system, + so that we can check whether the file system is correct. */ + +struct write_info /* Record of random data written into a file */ +{ + struct write_info *next; + off_t offset; /* Where in the file the data was written */ + size_t size; /* Number of bytes written */ + unsigned random_seed; /* Seed for rand() to create random data */ + off_t random_offset; /* Call rand() this number of times first */ +}; + +struct file_info /* Each file has one of these */ +{ + char *name; + struct dir_info *parent; /* Parent directory */ + struct write_info *writes; /* Record accumulated writes to the file */ + struct write_info *raw_writes; + /* Record in order all writes to the file */ + struct fd_info *fds; /* All open file descriptors for this file */ + off_t length; + int deleted; /* File has been deleted but is still open */ + int no_space_error; /* File has incurred a ENOSPC error */ +}; + +struct dir_info /* Each directory has one of these */ +{ + char *name; + struct dir_info *parent; /* Parent directory or null + for our top directory */ + unsigned number_of_entries; + struct dir_entry_info *first; +}; + +struct dir_entry_info /* Each entry in a directory has one of these */ +{ + struct dir_entry_info *next; + char type; /* f => file, d=> dir */ + int checked; /* Temporary flag used when checking */ + union entry_ + { + struct file_info *file; + struct dir_info *dir; + } entry; +}; + +struct fd_info /* We keep a number of files open */ +{ + struct fd_info *next; + struct file_info *file; + int fd; +}; + +struct open_file_info /* We keep a list of open files */ +{ + struct open_file_info *next; + struct fd_info *fdi; +}; + +static struct dir_info *top_dir = NULL; /* Our top directory */ + +static struct open_file_info *open_files = NULL; /* We keep a list of + open files */ +static size_t open_files_count = 0; + +static int grow = 1; /* Should we try to grow files and directories */ +static int shrink = 0; /* Should we try to shrink files and directories */ +static int full = 0; /* Flag that the file system is full */ +static uint64_t operation_count = 0; /* Number of operations used to fill + up the file system */ +static uint64_t initial_free_space = 0; /* Free space on file system when + test starts */ +static unsigned log10_initial_free_space = 0; /* log10 of initial_free_space */ + +static char *copy_string(const char *s) +{ + char *str; + + if (!s) + return NULL; + str = (char *) malloc(strlen(s) + 1); + CHECK(str != NULL); + strcpy(str, s); + return str; +} + +static char *cat_strings(const char *a, const char *b) +{ + char *str; + size_t sz; + + if (a && !b) + return copy_string(a); + if (b && !a) + return copy_string(b); + if (!a && !b) + return NULL; + sz = strlen(a) + strlen(b) + 1; + str = (char *) malloc(sz); + CHECK(str != NULL); + strcpy(str, a); + strcat(str, b); + return str; +} + +static char *cat_paths(const char *a, const char *b) +{ + char *str; + size_t sz; + int as, bs; + size_t na, nb; + + if (a && !b) + return copy_string(a); + if (b && !a) + return copy_string(b); + if (!a && !b) + return NULL; + + as = 0; + bs = 0; + na = strlen(a); + nb = strlen(b); + if (na && a[na - 1] == '/') + as = 1; + if (nb && b[0] == '/') + bs = 1; + if ((as && !bs) || (!as && bs)) + return cat_strings(a, b); + if (as && bs) + return cat_strings(a, b + 1); + + sz = na + nb + 2; + str = (char *) malloc(sz); + CHECK(str != NULL); + strcpy(str, a); + strcat(str, "/"); + strcat(str, b); + return str; +} + +static char *dir_path(struct dir_info *parent, const char *name) +{ + char *parent_path; + char *path; + + if (!parent) + return cat_paths(tests_file_system_mount_dir, name); + parent_path = dir_path(parent->parent, parent->name); + path = cat_paths(parent_path, name); + free(parent_path); + return path; +} + +static struct dir_entry_info *dir_entry_new(void) +{ + struct dir_entry_info *entry; + size_t sz; + + sz = sizeof(struct dir_entry_info); + entry = (struct dir_entry_info *) malloc(sz); + CHECK(entry != NULL); + memset(entry, 0, sz); + return entry; +} + +static void open_file_add(struct fd_info *fdi) +{ + struct open_file_info *ofi; + size_t sz; + + sz = sizeof(struct open_file_info); + ofi = (struct open_file_info *) malloc(sz); + CHECK(ofi != NULL); + memset(ofi, 0, sz); + ofi->next = open_files; + ofi->fdi = fdi; + open_files = ofi; + open_files_count += 1; +} + +static void open_file_remove(struct fd_info *fdi) +{ + struct open_file_info *ofi; + struct open_file_info **prev; + + prev = &open_files; + for (ofi = open_files; ofi; ofi = ofi->next) { + if (ofi->fdi == fdi) { + *prev = ofi->next; + free(ofi); + open_files_count -= 1; + return; + } + prev = &ofi->next; + } + CHECK(0); /* We are trying to remove something that is not there */ +} + +static struct fd_info *fd_new(struct file_info *file, int fd) +{ + struct fd_info *fdi; + size_t sz; + + sz = sizeof(struct fd_info); + fdi = (struct fd_info *) malloc(sz); + CHECK(fdi != NULL); + memset(fdi, 0, sz); + fdi->next = file->fds; + fdi->file = file; + fdi->fd = fd; + file->fds = fdi; + open_file_add(fdi); + return fdi; +} + +static struct dir_info *dir_new(struct dir_info *parent, const char *name) +{ + struct dir_info *dir; + size_t sz; + char *path; + + path = dir_path(parent, name); + if (mkdir(path, 0777) == -1) { + CHECK(errno == ENOSPC); + full = 1; + free(path); + return NULL; + } + free(path); + + sz = sizeof(struct dir_info); + dir = (struct dir_info *) malloc(sz); + CHECK(dir != NULL); + memset(dir, 0, sz); + dir->name = copy_string(name); + dir->parent = parent; + if (parent) { + struct dir_entry_info *entry; + + entry = dir_entry_new(); + entry->type = 'd'; + entry->entry.dir = dir; + entry->next = parent->first; + parent->first = entry; + parent->number_of_entries += 1; + } + return dir; +} + +static void file_delete(struct file_info *file); + +static void dir_remove(struct dir_info *dir) +{ + char *path; + struct dir_entry_info *entry; + struct dir_entry_info **prev; + int found; + + /* Remove directory contents */ + while (dir->first) { + struct dir_entry_info *entry; + + entry = dir->first; + if (entry->type == 'd') + dir_remove(entry->entry.dir); + else if (entry->type == 'f') + file_delete(entry->entry.file); + else + CHECK(0); /* Invalid struct dir_entry_info */ + } + /* Remove entry from parent directory */ + found = 0; + prev = &dir->parent->first; + for (entry = dir->parent->first; entry; entry = entry->next) { + if (entry->type == 'd' && entry->entry.dir == dir) { + dir->parent->number_of_entries -= 1; + *prev = entry->next; + free(entry); + found = 1; + break; + } + prev = &entry->next; + } + CHECK(found); /* Check the file is in the parent directory */ + /* Remove directory itself */ + path = dir_path(dir->parent, dir->name); + CHECK(rmdir(path) != -1); +} + +static struct file_info *file_new(struct dir_info *parent, const char *name) +{ + struct file_info *file = NULL; + char *path; + mode_t mode; + int fd; + size_t sz; + struct dir_entry_info *entry; + + CHECK(parent != NULL); + + path = dir_path(parent, name); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + fd = open(path, O_CREAT | O_EXCL | O_RDWR, mode); + if (fd == -1) { + CHECK(errno == ENOSPC); + free(path); + full = 1; + return NULL; + } + free(path); + + sz = sizeof(struct file_info); + file = (struct file_info *) malloc(sz); + CHECK(file != NULL); + memset(file, 0, sz); + file->name = copy_string(name); + file->parent = parent; + + fd_new(file, fd); + + entry = dir_entry_new(); + entry->type = 'f'; + entry->entry.file = file; + entry->next = parent->first; + parent->first = entry; + parent->number_of_entries += 1; + + return file; +} + +static void file_delete(struct file_info *file) +{ + char *path; + struct dir_entry_info *entry; + struct dir_entry_info **prev; + int found; + + /* Remove file entry from parent directory */ + found = 0; + prev = &file->parent->first; + for (entry = file->parent->first; entry; entry = entry->next) { + if (entry->type == 'f' && entry->entry.file == file) { + file->parent->number_of_entries -= 1; + *prev = entry->next; + free(entry); + found = 1; + break; + } + prev = &entry->next; + } + CHECK(found); /* Check the file is in the parent directory */ + + /* Delete the file */ + path = dir_path(file->parent, file->name); + CHECK(unlink(path) != -1); + free(path); + + /* Free struct file_info if file is not open */ + if (!file->fds) { + struct write_info *w, *next; + + free(file->name); + w = file->writes; + while (w) { + next = w->next; + free(w); + w = next; + } + free(file); + } else + file->deleted = 1; +} + +static void file_info_display(struct file_info *file) +{ + struct write_info *w; + unsigned wcnt; + + fprintf(stderr, "File Info:\n"); + fprintf(stderr, " Name: %s\n", file->name); + fprintf(stderr, " Directory: %s\n", file->parent->name); + fprintf(stderr, " Length: %u\n", (unsigned) file->length); + fprintf(stderr, " File was open: %s\n", + (file->fds == NULL) ? "false" : "true"); + fprintf(stderr, " File was deleted: %s\n", + (file->deleted == 0) ? "false" : "true"); + fprintf(stderr, " File was out of space: %s\n", + (file->no_space_error == 0) ? "false" : "true"); + fprintf(stderr, " Write Info:\n"); + wcnt = 0; + w = file->writes; + while (w) { + fprintf(stderr, " Offset: %u Size: %u Seed: %u" + " R.Off: %u\n", + (unsigned) w->offset, + (unsigned) w->size, + (unsigned) w->random_seed, + (unsigned) w->random_offset); + wcnt += 1; + w = w->next; + } + fprintf(stderr, " %u writes\n", wcnt); + fprintf(stderr, " ============================================\n"); + fprintf(stderr, " Raw Write Info:\n"); + wcnt = 0; + w = file->raw_writes; + while (w) { + fprintf(stderr, " Offset: %u Size: %u Seed: %u" + " R.Off: %u\n", + (unsigned) w->offset, + (unsigned) w->size, + (unsigned) w->random_seed, + (unsigned) w->random_offset); + wcnt += 1; + w = w->next; + } + fprintf(stderr, " %u writes\n", wcnt); + fprintf(stderr, " ============================================\n"); +} + +static struct fd_info *file_open(struct file_info *file) +{ + int fd; + char *path; + + path = dir_path(file->parent, file->name); + fd = open(path, O_RDWR); + CHECK(fd != -1); + free(path); + return fd_new(file, fd); +} + +#define BUFFER_SIZE 32768 + +static size_t file_write_data( struct file_info *file, + int fd, + off_t offset, + size_t size, + unsigned seed) +{ + size_t remains, actual, block; + ssize_t written; + char buf[BUFFER_SIZE]; + + srand(seed); + CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1); + remains = size; + actual = 0; + written = BUFFER_SIZE; + while (remains) { + /* Fill up buffer with random data */ + if (written < BUFFER_SIZE) + memmove(buf, buf + written, BUFFER_SIZE - written); + else + written = 0; + for (; written < BUFFER_SIZE; ++written) + buf[written] = rand(); + /* Write a block of data */ + if (remains > BUFFER_SIZE) + block = BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written < 0) { + CHECK(errno == ENOSPC); /* File system full */ + full = 1; + file->no_space_error = 1; + break; + } + remains -= written; + actual += written; + } + return actual; +} + +static void file_write_info(struct file_info *file, + off_t offset, + size_t size, + unsigned seed) +{ + struct write_info *new_write, *w, **prev, *tmp; + int inserted; + size_t sz; + off_t end, chg; + + /* Create struct write_info */ + sz = sizeof(struct write_info); + new_write = (struct write_info *) malloc(sz); + CHECK(new_write != NULL); + memset(new_write, 0, sz); + new_write->offset = offset; + new_write->size = size; + new_write->random_seed = seed; + + w = (struct write_info *) malloc(sz); + CHECK(w != NULL); + memset(w, 0, sz); + w->next = file->raw_writes; + w->offset = offset; + w->size = size; + w->random_seed = seed; + file->raw_writes = w; + + /* Insert it into file->writes */ + inserted = 0; + end = offset + size; + w = file->writes; + prev = &file->writes; + while (w) { + if (w->offset >= end) { + /* w comes after new_write, so insert before it */ + new_write->next = w; + *prev = new_write; + inserted = 1; + break; + } + /* w does not come after new_write */ + if (w->offset + w->size > offset) { + /* w overlaps new_write */ + if (w->offset < offset) { + /* w begins before new_write begins */ + if (w->offset + w->size <= end) + /* w ends before new_write ends */ + w->size = offset - w->offset; + else { + /* w ends after new_write ends */ + /* Split w */ + tmp = (struct write_info *) malloc(sz); + CHECK(tmp != NULL); + *tmp = *w; + chg = end - tmp->offset; + tmp->offset += chg; + tmp->random_offset += chg; + tmp->size -= chg; + w->size = offset - w->offset; + /* Insert new struct write_info */ + w->next = new_write; + new_write->next = tmp; + inserted = 1; + break; + } + } else { + /* w begins after new_write begins */ + if (w->offset + w->size <= end) { + /* w is completely overlapped, + so remove it */ + *prev = w->next; + tmp = w; + w = w->next; + free(tmp); + continue; + } + /* w ends after new_write ends */ + chg = end - w->offset; + w->offset += chg; + w->random_offset += chg; + w->size -= chg; + continue; + } + } + prev = &w->next; + w = w->next; + } + if (!inserted) + *prev = new_write; + /* Update file length */ + if (end > file->length) + file->length = end; +} + +/* Randomly select offset and and size to write in a file */ +static void get_offset_and_size(struct file_info *file, + off_t *offset, + size_t *size) +{ + size_t r, n; + + r = tests_random_no(100); + if (r == 0 && grow) + /* 1 time in 100, when growing, write off the end of the file */ + *offset = file->length + tests_random_no(10000000); + else if (r < 4) + /* 3 (or 4) times in 100, write at the beginning of file */ + *offset = 0; + else if (r < 52 || !grow) + /* 48 times in 100, write into the file */ + *offset = tests_random_no(file->length); + else + /* 48 times in 100, write at the end of the file */ + *offset = file->length; + /* Distribute the size logarithmically */ + if (tests_random_no(1000) == 0) + r = tests_random_no(log10_initial_free_space + 2); + else + r = tests_random_no(log10_initial_free_space); + n = 1; + while (r--) + n *= 10; + *size = tests_random_no(n); + if (!grow && *offset + *size > file->length) + *size = file->length - *offset; + if (*size == 0) + *size = 1; +} + +static void file_truncate_info(struct file_info *file, size_t new_length); +static void file_close(struct fd_info *fdi); + +static int file_ftruncate(struct file_info *file, int fd, off_t new_length) +{ + if (ftruncate(fd, new_length) == -1) { + CHECK(errno = ENOSPC); + file->no_space_error = 1; + /* Delete errored files */ + if (!file->deleted) { + struct fd_info *fdi; + + fdi = file->fds; + while (fdi) { + file_close(fdi); + fdi = file->fds; + } + file_delete(file); + } + return 0; + } + return 1; +} + +static void file_write(struct file_info *file, int fd) +{ + off_t offset; + size_t size, actual; + unsigned seed; + int truncate = 0; + + get_offset_and_size(file, &offset, &size); + seed = tests_random_no(10000000); + actual = file_write_data(file, fd, offset, size, seed); + + if (offset + actual <= file->length && shrink) + /* 1 time in 100, when shrinking + truncate after the write */ + if (tests_random_no(100) == 0) + truncate = 1; + + if (actual != 0) + file_write_info(file, offset, actual, seed); + + /* Delete errored files */ + if (file->no_space_error) { + if (!file->deleted) { + struct fd_info *fdi; + + fdi = file->fds; + while (fdi) { + file_close(fdi); + fdi = file->fds; + } + file_delete(file); + } + return; + } + + if (truncate) { + size_t new_length = offset + actual; + if (file_ftruncate(file, fd, new_length)) + file_truncate_info(file, new_length); + } +} + +static void file_write_file(struct file_info *file) +{ + int fd; + char *path; + + path = dir_path(file->parent, file->name); + fd = open(path, O_WRONLY); + CHECK(fd != -1); + file_write(file, fd); + CHECK(close(fd) != -1); + free(path); +} + +static void file_truncate_info(struct file_info *file, size_t new_length) +{ + struct write_info *w, **prev, *tmp; + + /* Remove / truncate file->writes */ + w = file->writes; + prev = &file->writes; + while (w) { + if (w->offset >= new_length) { + /* w comes after eof, so remove it */ + *prev = w->next; + tmp = w; + w = w->next; + free(tmp); + continue; + } + if (w->offset + w->size > new_length) + w->size = new_length - w->offset; + prev = &w->next; + w = w->next; + } + /* Update file length */ + file->length = new_length; +} + +static void file_truncate(struct file_info *file, int fd) +{ + size_t new_length; + + new_length = tests_random_no(file->length); + + if (file_ftruncate(file, fd, new_length)) + file_truncate_info(file, new_length); +} + +static void file_truncate_file(struct file_info *file) +{ + int fd; + char *path; + + path = dir_path(file->parent, file->name); + fd = open(path, O_WRONLY); + CHECK(fd != -1); + file_truncate(file, fd); + CHECK(close(fd) != -1); + free(path); +} + +static void file_close(struct fd_info *fdi) +{ + struct file_info *file; + struct fd_info *fdp; + struct fd_info **prev; + + /* Close file */ + CHECK(close(fdi->fd) != -1); + /* Remove struct fd_info */ + open_file_remove(fdi); + file = fdi->file; + prev = &file->fds; + for (fdp = file->fds; fdp; fdp = fdp->next) { + if (fdp == fdi) { + *prev = fdi->next; + free(fdi); + if (file->deleted && !file->fds) { + /* Closing deleted file */ + struct write_info *w, *next; + + w = file->writes; + while (w) { + next = w->next; + free(w); + w = next; + } + free(file->name); + free(file); + } + return; + } + prev = &fdp->next; + } + CHECK(0); /* Didn't find struct fd_info */ +} + +static void file_rewrite_data(int fd, struct write_info *w, char *buf) +{ + size_t remains, block; + ssize_t written; + off_t r; + + srand(w->random_seed); + for (r = 0; r < w->random_offset; ++r) + rand(); + CHECK(lseek(fd, w->offset, SEEK_SET) != (off_t) -1); + remains = w->size; + written = BUFFER_SIZE; + while (remains) { + /* Fill up buffer with random data */ + if (written < BUFFER_SIZE) + memmove(buf, buf + written, BUFFER_SIZE - written); + else + written = 0; + for (; written < BUFFER_SIZE; ++written) + buf[written] = rand(); + /* Write a block of data */ + if (remains > BUFFER_SIZE) + block = BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + CHECK(written == block); + remains -= written; + } +} + +static void save_file(int fd, struct file_info *file) +{ + int w_fd; + struct write_info *w; + char buf[BUFFER_SIZE]; + char name[256]; + + /* Open file to save contents to */ + strcpy(name, "/tmp/"); + strcat(name, file->name); + strcat(name, ".integ.sav.read"); + fprintf(stderr, "Saving %s\n", name); + w_fd = open(name, O_CREAT | O_WRONLY, 0777); + CHECK(w_fd != -1); + + /* Start at the beginning */ + CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); + + for (;;) { + ssize_t r = read(fd, buf, BUFFER_SIZE); + CHECK(r != -1); + if (!r) + break; + CHECK(write(w_fd, buf, r) == r); + } + CHECK(close(w_fd) != -1); + + /* Open file to save contents to */ + strcpy(name, "/tmp/"); + strcat(name, file->name); + strcat(name, ".integ.sav.written"); + fprintf(stderr, "Saving %s\n", name); + w_fd = open(name, O_CREAT | O_WRONLY, 0777); + CHECK(w_fd != -1); + + for (w = file->writes; w; w = w->next) + file_rewrite_data(w_fd, w, buf); + + CHECK(close(w_fd) != -1); +} + +static void file_check_hole( struct file_info *file, + int fd, off_t offset, + size_t size) +{ + size_t remains, block, i; + char buf[BUFFER_SIZE]; + + CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1); + remains = size; + while (remains) { + if (remains > BUFFER_SIZE) + block = BUFFER_SIZE; + else + block = remains; + CHECK(read(fd, buf, block) == block); + for (i = 0; i < block; ++i) { + if (buf[i] != 0) { + fprintf(stderr, "file_check_hole failed at %u " + "checking hole at %u size %u\n", + (unsigned) (size - remains + i), + (unsigned) offset, + (unsigned) size); + file_info_display(file); + save_file(fd, file); + } + CHECK(buf[i] == 0); + } + remains -= block; + } +} + +static void file_check_data( struct file_info *file, + int fd, + struct write_info *w) +{ + size_t remains, block, i; + off_t r; + char buf[BUFFER_SIZE]; + + srand(w->random_seed); + for (r = 0; r < w->random_offset; ++r) + rand(); + CHECK(lseek(fd, w->offset, SEEK_SET) != (off_t) -1); + remains = w->size; + while (remains) { + if (remains > BUFFER_SIZE) + block = BUFFER_SIZE; + else + block = remains; + CHECK(read(fd, buf, block) == block); + for (i = 0; i < block; ++i) { + char c = (char) rand(); + if (buf[i] != c) { + fprintf(stderr, "file_check_data failed at %u " + "checking data at %u size %u\n", + (unsigned) (w->size - remains + i), + (unsigned) w->offset, + (unsigned) w->size); + file_info_display(file); + save_file(fd, file); + } + CHECK(buf[i] == c); + } + remains -= block; + } +} + +static void file_check(struct file_info *file, int fd) +{ + int open_and_close = 0; + char *path = NULL; + off_t pos; + struct write_info *w; + + /* Do not check files that have errored */ + if (file->no_space_error) + return; + if (fd == -1) + open_and_close = 1; + if (open_and_close) { + /* Open file */ + path = dir_path(file->parent, file->name); + fd = open(path, O_RDONLY); + CHECK(fd != -1); + } + /* Check length */ + pos = lseek(fd, 0, SEEK_END); + if (pos != file->length) { + fprintf(stderr, "file_check failed checking length " + "expected %u actual %u\n", + (unsigned) file->length, + (unsigned) pos); + file_info_display(file); + save_file(fd, file); + } + CHECK(pos == file->length); + /* Check each write */ + pos = 0; + for (w = file->writes; w; w = w->next) { + if (w->offset > pos) + file_check_hole(file, fd, pos, w->offset - pos); + file_check_data(file, fd, w); + pos = w->offset + w->size; + } + if (file->length > pos) + file_check_hole(file, fd, pos, file->length - pos); + if (open_and_close) { + CHECK(close(fd) != -1); + free(path); + } +} + +static const char *dir_entry_name(const struct dir_entry_info *entry) +{ + CHECK(entry != NULL); + if (entry->type == 'd') + return entry->entry.dir->name; + else if (entry->type == 'f') + return entry->entry.file->name; + else { + CHECK(0); + return NULL; + } +} + +static int search_comp(const void *pa, const void *pb) +{ + const struct dirent *a = (const struct dirent *) pa; + const struct dir_entry_info *b = * (const struct dir_entry_info **) pb; + return strcmp(a->d_name, dir_entry_name(b)); +} + +static void dir_entry_check(struct dir_entry_info **entry_array, + size_t number_of_entries, + struct dirent *ent) +{ + struct dir_entry_info **found; + struct dir_entry_info *entry; + size_t sz; + + sz = sizeof(struct dir_entry_info *); + found = bsearch(ent, entry_array, number_of_entries, sz, search_comp); + CHECK(found != NULL); + entry = *found; + CHECK(!entry->checked); + entry->checked = 1; +} + +static int sort_comp(const void *pa, const void *pb) +{ + const struct dir_entry_info *a = * (const struct dir_entry_info **) pa; + const struct dir_entry_info *b = * (const struct dir_entry_info **) pb; + return strcmp(dir_entry_name(a), dir_entry_name(b)); +} + +static void dir_check(struct dir_info *dir) +{ + struct dir_entry_info **entry_array, **p; + size_t sz, n; + struct dir_entry_info *entry; + DIR *d; + struct dirent *ent; + unsigned checked = 0; + char *path; + + /* Create an array of entries */ + sz = sizeof(struct dir_entry_info *); + n = dir->number_of_entries; + entry_array = (struct dir_entry_info **) malloc(sz * n); + CHECK(entry_array != NULL); + + entry = dir->first; + p = entry_array; + while (entry) { + *p++ = entry; + entry->checked = 0; + entry = entry->next; + } + + /* Sort it by name */ + qsort(entry_array, n, sz, sort_comp); + + /* Go through directory on file system checking entries match */ + path = dir_path(dir->parent, dir->name); + d = opendir(path); + CHECK(d != NULL); + for (;;) { + errno = 0; + ent = readdir(d); + if (ent) { + if (strcmp(".",ent->d_name) != 0 && + strcmp("..",ent->d_name) != 0) { + dir_entry_check(entry_array, n, ent); + checked += 1; + } + } else { + CHECK(errno == 0); + break; + } + } + CHECK(closedir(d) != -1); + CHECK(checked == dir->number_of_entries); + free(path); + + /* Now check each entry */ + entry = dir->first; + while (entry) { + if (entry->type == 'd') + dir_check(entry->entry.dir); + else if (entry->type == 'f') + file_check(entry->entry.file, -1); + else + CHECK(0); + entry = entry->next; + } + + free(entry_array); +} + +static void check_deleted_files(void) +{ + struct open_file_info *ofi; + + for (ofi = open_files; ofi; ofi = ofi->next) + if (ofi->fdi->file->deleted) + file_check(ofi->fdi->file, ofi->fdi->fd); +} + +static void close_open_files(void) +{ + struct open_file_info *ofi; + + for (ofi = open_files; ofi; ofi = open_files) + file_close(ofi->fdi); +} + +static char *make_name(struct dir_info *dir) +{ + static char name[256]; + struct dir_entry_info *entry; + int found; + + do { + found = 0; + sprintf(name, "%u", (unsigned) tests_random_no(1000000)); + for (entry = dir->first; entry; entry = entry->next) { + if (strcmp(dir_entry_name(entry), name) == 0) { + found = 1; + break; + } + } + } while (found); + return name; +} + +static void operate_on_dir(struct dir_info *dir); +static void operate_on_file(struct file_info *file); + +/* Randomly select something to do with a directory entry */ +static void operate_on_entry(struct dir_entry_info *entry) +{ + /* If shrinking, 1 time in 50, remove a directory */ + if (entry->type == 'd') { + if (shrink && tests_random_no(50) == 0) { + dir_remove(entry->entry.dir); + return; + } + operate_on_dir(entry->entry.dir); + } + /* If shrinking, 1 time in 10, remove a file */ + if (entry->type == 'f') { + if (shrink && tests_random_no(10) == 0) { + file_delete(entry->entry.file); + return; + } + operate_on_file(entry->entry.file); + } +} + +/* Randomly select something to do with a directory */ +static void operate_on_dir(struct dir_info *dir) +{ + size_t r; + struct dir_entry_info *entry; + + r = tests_random_no(12); + if (r == 0 && grow) + /* When growing, 1 time in 12 create a file */ + file_new(dir, make_name(dir)); + else if (r == 1 && grow) + /* When growing, 1 time in 12 create a directory */ + dir_new(dir, make_name(dir)); + else { + /* Otherwise randomly select an entry to operate on */ + r = tests_random_no(dir->number_of_entries); + entry = dir->first; + while (entry && r) { + entry = entry->next; + --r; + } + if (entry) + operate_on_entry(entry); + } +} + +/* Randomly select something to do with a file */ +static void operate_on_file(struct file_info *file) +{ + /* Try to keep at least 10 files open */ + if (open_files_count < 10) { + file_open(file); + return; + } + /* Try to keep about 20 files open */ + if (open_files_count < 20 && tests_random_no(2) == 0) { + file_open(file); + return; + } + /* Try to keep up to 40 files open */ + if (open_files_count < 40 && tests_random_no(20) == 0) { + file_open(file); + return; + } + /* Occasionly truncate */ + if (shrink && tests_random_no(100) == 0) { + file_truncate_file(file); + return; + } + /* Mostly just write */ + file_write_file(file); +} + +/* Randomly select something to do with an open file */ +static void operate_on_open_file(struct fd_info *fdi) +{ + size_t r; + + r = tests_random_no(1000); + if (shrink && r == 0) + file_truncate(fdi->file, fdi->fd); + else if (r < 21) + file_close(fdi); + else if (shrink && r < 121 && !fdi->file->deleted) + file_delete(fdi->file); + else + file_write(fdi->file, fdi->fd); +} + +/* Select an open file at random */ +static void operate_on_an_open_file(void) +{ + size_t r; + struct open_file_info *ofi; + + /* Close any open files that have errored */ + ofi = open_files; + while (ofi) { + if (ofi->fdi->file->no_space_error) { + struct fd_info *fdi; + + fdi = ofi->fdi; + ofi = ofi->next; + file_close(fdi); + } else + ofi = ofi->next; + } + r = tests_random_no(open_files_count); + for (ofi = open_files; ofi; ofi = ofi->next, --r) + if (!r) { + operate_on_open_file(ofi->fdi); + return; + } +} + +static void do_an_operation(void) +{ + /* Half the time operate on already open files */ + if (tests_random_no(100) < 50) + operate_on_dir(top_dir); + else + operate_on_an_open_file(); +} + +static void create_test_data(void) +{ + uint64_t i; + + grow = 1; + shrink = 0; + full = 0; + operation_count = 0; + while (!full) { + do_an_operation(); + ++operation_count; + } + grow = 0; + shrink = 1; + /* Drop to less than 90% full */ + for (;;) { + uint64_t free; + uint64_t total; + for (i = 0; i < 10; ++i) + do_an_operation(); + free = tests_get_free_space(); + total = tests_get_total_space(); + if ((free * 100) / total >= 10) + break; + } + grow = 0; + shrink = 0; + full = 0; + for (i = 0; i < operation_count * 2; ++i) + do_an_operation(); +} + +static void update_test_data(void) +{ + uint64_t i; + + grow = 1; + shrink = 0; + full = 0; + while (!full) + do_an_operation(); + grow = 0; + shrink = 1; + /* Drop to less than 50% full */ + for (;;) { + uint64_t free; + uint64_t total; + for (i = 0; i < 10; ++i) + do_an_operation(); + free = tests_get_free_space(); + total = tests_get_total_space(); + if ((free * 100) / total >= 50) + break; + } + grow = 0; + shrink = 0; + full = 0; + for (i = 0; i < operation_count * 2; ++i) + do_an_operation(); +} + +void integck(void) +{ + pid_t pid; + int64_t rpt; + uint64_t z; + char dir_name[256]; + + /* Make our top directory */ + pid = getpid(); + printf("pid is %u\n", (unsigned) pid); + tests_cat_pid(dir_name, "integck_test_dir_", pid); + if (chdir(dir_name) != -1) { + /* Remove it if it is already there */ + tests_clear_dir("."); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); + } + initial_free_space = tests_get_free_space(); + log10_initial_free_space = 0; + for (z = initial_free_space; z >= 10; z /= 10) + ++log10_initial_free_space; + top_dir = dir_new(NULL, dir_name); + + if (!top_dir) + return; + + srand(pid); + + create_test_data(); + + if (!tests_fs_is_rootfs()) { + close_open_files(); + tests_remount(); /* Requires root access */ + } + + /* Check everything */ + dir_check(top_dir); + check_deleted_files(); + + for (rpt = 0; tests_repeat_parameter == 0 || + rpt < tests_repeat_parameter; ++rpt) { + update_test_data(); + + if (!tests_fs_is_rootfs()) { + close_open_files(); + tests_remount(); /* Requires root access */ + } + + /* Check everything */ + dir_check(top_dir); + check_deleted_files(); + } + + /* Tidy up by removing everything */ + close_open_files(); + tests_clear_dir(dir_name); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *integck_get_title(void) +{ + return "Test file system integrity"; +} + +/* Description of this test */ + +const char *integck_get_description(void) +{ + return + "Create a directory named integck_test_dir_pid " \ + "where pid is the process id. " \ + "Randomly create and delete files and directories. " \ + "Randomly write to and truncate files. " \ + "Un-mount and re-mount test file " \ + "system (if it is not the root file system ). " \ + "Check data. Make more random changes. " \ + "Un-mount and re-mount again. Check again. " \ + "Repeat some number of times. " + "The repeat count is set by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, integck_get_title(), + integck_get_description(), "n"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + integck(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/integrity/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/integrity/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/integrity/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/integrity/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,22 @@ + +ifeq ($(origin CC),default) +CC = gcc +endif + +CFLAGS := $(CFLAGS) -Wall -g -O2 -I../lib + +LDFLAGS := $(LDFLAGS) + +TARGETS = integck + +all: $(TARGETS) + +$(TARGETS): ../lib/tests.o + +../lib/tests.o: ../lib/tests.h + +clean: + rm -f *.o $(TARGETS) + +tests: all + ./integck diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,18 @@ + +ifeq ($(origin CC),default) +CC = gcc +endif + +CFLAGS := $(CFLAGS) -Wall -g -O2 + +LDFLAGS := $(LDFLAGS) + +all: tests.o + +tests.o: tests.h + +clean: + rm -f *.o + +tests: + echo diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,1091 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +char *tests_file_system_mount_dir = TESTS_DEFAULT_FILE_SYSTEM_MOUNT_DIR; + +char *tests_file_system_type = TESTS_DEFAULT_FILE_SYSTEM_TYPE; + +int tests_ok_to_sync = 0; /* Whether to use fsync */ + +/* General purpose test parameter to specify some aspect of test size. + May be used by different tests in different ways or not at all. + Set by the -z or --size option. */ +int64_t tests_size_parameter = 0; + +/* General purpose test parameter to specify some aspect of test repetition. + May be used by different tests in different ways or not at all. + Set by the -n, --repeat options. */ +int64_t tests_repeat_parameter = 0; + +/* General purpose test parameter to specify some aspect of test sleeping. + May be used by different tests in different ways or not at all. + Set by the -p, --sleep options. */ +int64_t tests_sleep_parameter = 0; + +/* Program name from argv[0] */ +char *program_name = "unknown"; + +/* General purpose test parameter to specify a file should be unlinked. + May be used by different tests in different ways or not at all. */ +int tests_unlink_flag = 0; + +/* General purpose test parameter to specify a file should be closed. + May be used by different tests in different ways or not at all. */ +int tests_close_flag = 0; + +/* General purpose test parameter to specify a file should be deleted. + May be used by different tests in different ways or not at all. */ +int tests_delete_flag = 0; + +/* General purpose test parameter to specify a file have a hole. + May be used by different tests in different ways or not at all. */ +int tests_hole_flag = 0; + +/* Whether it is ok to test on the root file system */ +static int rootok = 0; + +/* Function invoked by the CHECK macro */ +void tests_test(int test,const char *msg,const char *file,unsigned line) +{ + int eno; + time_t t; + + if (test) + return; + eno = errno; + time(&t); + fprintf(stderr, "Test failed: %s on %s" + "Test failed: %s in %s at line %u\n", + program_name, ctime(&t), msg, file, line); + if (eno) { + fprintf(stderr,"errno = %d\n",eno); + fprintf(stderr,"strerror = %s\n",strerror(eno)); + } + exit(1); +} + +static int is_zero(const char *p) +{ + for (;*p;++p) + if (*p != '0') + return 0; + return 1; +} + +static void fold(const char *text, int width) +{ + int pos, bpos = 0; + const char *p; + char line[1024]; + + if (width > 1023) { + printf("%s\n", text); + return; + } + p = text; + pos = 0; + while (p[pos]) { + while (!isspace(p[pos])) { + line[pos] = p[pos]; + if (!p[pos]) + break; + ++pos; + if (pos == width) { + line[pos] = '\0'; + printf("%s\n", line); + p += pos; + pos = 0; + } + } + while (pos < width) { + line[pos] = p[pos]; + if (!p[pos]) { + bpos = pos; + break; + } + if (isspace(p[pos])) + bpos = pos; + ++pos; + } + line[bpos] = '\0'; + printf("%s\n", line); + p += bpos; + pos = 0; + while (p[pos] && isspace(p[pos])) + ++p; + } +} + +/* Handle common program options */ +int tests_get_args(int argc, + char *argv[], + const char *title, + const char *desc, + const char *opts) +{ + int run_test = 0; + int display_help = 0; + int display_title = 0; + int display_description = 0; + int i; + char *s; + + program_name = argv[0]; + + s = getenv("TEST_FILE_SYSTEM_MOUNT_DIR"); + if (s) + tests_file_system_mount_dir = strdup(s); + s = getenv("TEST_FILE_SYSTEM_TYPE"); + if (s) + tests_file_system_type = strdup(s); + + run_test = 1; + rootok = 1; + for (i = 1; i < argc; ++i) { + if (strcmp(argv[i], "--help") == 0 || + strcmp(argv[i], "-h") == 0) + display_help = 1; + else if (strcmp(argv[i], "--title") == 0 || + strcmp(argv[i], "-t") == 0) + display_title = 1; + else if (strcmp(argv[i], "--description") == 0 || + strcmp(argv[i], "-d") == 0) + display_description = 1; + else if (strcmp(argv[i], "--sync") == 0 || + strcmp(argv[i], "-s") == 0) + tests_ok_to_sync = 1; + else if (strncmp(argv[i], "--size", 6) == 0 || + strncmp(argv[i], "-z", 2) == 0) { + int64_t n; + char *p; + if (i+1 < argc && !isdigit(argv[i][strlen(argv[i])-1])) + ++i; + p = argv[i]; + while (*p && !isdigit(*p)) + ++p; + n = atoll(p); + if (n) + tests_size_parameter = n; + else { + int all_zero = 1; + for (; all_zero && *p; ++p) + if (*p != '0') + all_zero = 0; + if (all_zero) + tests_size_parameter = 0; + else + display_help = 1; + } + } else if (strncmp(argv[i], "--repeat", 8) == 0 || + strncmp(argv[i], "-n", 2) == 0) { + int64_t n; + char *p; + if (i+1 < argc && !isdigit(argv[i][strlen(argv[i])-1])) + ++i; + p = argv[i]; + while (*p && !isdigit(*p)) + ++p; + n = atoll(p); + if (n || is_zero(p)) + tests_repeat_parameter = n; + else + display_help = 1; + } else if (strncmp(argv[i], "--sleep", 7) == 0 || + strncmp(argv[i], "-p", 2) == 0) { + int64_t n; + char *p; + if (i+1 < argc && !isdigit(argv[i][strlen(argv[i])-1])) + ++i; + p = argv[i]; + while (*p && !isdigit(*p)) + ++p; + n = atoll(p); + if (n || is_zero(p)) + tests_sleep_parameter = n; + else + display_help = 1; + } else if (strcmp(argv[i], "--unlink") == 0 || + strcmp(argv[i], "-u") == 0) + tests_unlink_flag = 1; + else if (strcmp(argv[i], "--hole") == 0 || + strcmp(argv[i], "-o") == 0) + tests_hole_flag = 1; + else if (strcmp(argv[i], "--close") == 0 || + strcmp(argv[i], "-c") == 0) + tests_close_flag = 1; + else if (strcmp(argv[i], "--delete") == 0 || + strcmp(argv[i], "-e") == 0) + tests_delete_flag = 1; + else + display_help = 1; + } + + if (display_help) { + run_test = 0; + display_title = 0; + display_description = 0; + if (!opts) + opts = ""; + printf("File System Test Program\n\n"); + printf("Test Title: %s\n\n", title); + printf("Usage is: %s [ options ]\n",argv[0]); + printf(" Options are:\n"); + printf(" -h, --help "); + printf("Display this help\n"); + printf(" -t, --title "); + printf("Display the test title\n"); + printf(" -d, --description "); + printf("Display the test description\n"); + if (strchr(opts, 's')) { + printf(" -s, --sync "); + printf("Make use of fsync\n"); + } + if (strchr(opts, 'z')) { + printf(" -z, --size "); + printf("Set size parameter\n"); + } + if (strchr(opts, 'n')) { + printf(" -n, --repeat "); + printf("Set repeat parameter\n"); + } + if (strchr(opts, 'p')) { + printf(" -p, --sleep "); + printf("Set sleep parameter\n"); + } + if (strchr(opts, 'u')) { + printf(" -u, --unlink "); + printf("Unlink file\n"); + } + if (strchr(opts, 'o')) { + printf(" -o, --hole "); + printf("Create a hole in a file\n"); + } + if (strchr(opts, 'c')) { + printf(" -c, --close "); + printf("Close file\n"); + } + if (strchr(opts, 'e')) { + printf(" -e, --delete "); + printf("Delete file\n"); + } + printf("\nBy default, testing is done in directory "); + printf("/mnt/test_file_system. To change this\nuse "); + printf("environmental variable "); + printf("TEST_FILE_SYSTEM_MOUNT_DIR. By default, "); + printf("the file\nsystem tested is jffs2. To change this "); + printf("set TEST_FILE_SYSTEM_TYPE.\n\n"); + printf("Test Description:\n"); + fold(desc, 80); + } else { + if (display_title) + printf("%s\n", title); + if (display_description) + printf("%s\n", desc); + if (display_title || display_description) + if (argc == 2 || (argc == 3 && + display_title && + display_description)) + run_test = 0; + } + return run_test; +} + +/* Return the number of files (or directories) in the given directory */ +unsigned tests_count_files_in_dir(const char *dir_name) +{ + DIR *dir; + struct dirent *entry; + unsigned count = 0; + + dir = opendir(dir_name); + CHECK(dir != NULL); + for (;;) { + errno = 0; + entry = readdir(dir); + if (entry) { + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) + ++count; + } else { + CHECK(errno == 0); + break; + } + } + CHECK(closedir(dir) != -1); + return count; +} + +/* Change to the file system mount directory, check that it is empty, + matches the file system type, and is not the root file system */ +void tests_check_test_file_system(void) +{ + struct statfs fs_info; + struct stat f_info; + struct stat root_f_info; + + if (chdir(tests_file_system_mount_dir) == -1 || + statfs(tests_file_system_mount_dir, &fs_info) == -1) { + fprintf(stderr, "Invalid test file system mount directory:" + " %s\n", tests_file_system_mount_dir); + fprintf(stderr, "Use environment variable " + "TEST_FILE_SYSTEM_MOUNT_DIR\n"); + CHECK(0); + } + if (strcmp(tests_file_system_type, "jffs2") == 0 && + fs_info.f_type != JFFS2_SUPER_MAGIC) { + fprintf(stderr, "File system type is not jffs2\n"); + CHECK(0); + } + /* Check that the test file system is not the root file system */ + if (!rootok) { + CHECK(stat(tests_file_system_mount_dir, &f_info) != -1); + CHECK(stat("/", &root_f_info) != -1); + CHECK(f_info.st_dev != root_f_info.st_dev); + } +} + +/* Get the free space for the file system of the current directory */ +uint64_t tests_get_free_space(void) +{ + struct statvfs fs_info; + + CHECK(statvfs(tests_file_system_mount_dir, &fs_info) != -1); + return (uint64_t) fs_info.f_bavail * (uint64_t) fs_info.f_frsize; +} + +/* Get the total space for the file system of the current directory */ +uint64_t tests_get_total_space(void) +{ + struct statvfs fs_info; + + CHECK(statvfs(tests_file_system_mount_dir, &fs_info) != -1); + return (uint64_t) fs_info.f_blocks * (uint64_t) fs_info.f_frsize; +} + +#define WRITE_BUFFER_SIZE 32768 + +static char write_buffer[WRITE_BUFFER_SIZE]; + +static void init_write_buffer() +{ + static int init = 0; + + if (!init) { + int i, d; + uint64_t u; + + u = RAND_MAX; + u += 1; + u /= 256; + d = (int) u; + srand(1); + for (i = 0; i < WRITE_BUFFER_SIZE; ++i) + write_buffer[i] = rand() / d; + init = 1; + } +} + +/* Write size random bytes into file descriptor fd at the current position, + returning the number of bytes actually written */ +uint64_t tests_fill_file(int fd, uint64_t size) +{ + ssize_t written; + size_t sz; + unsigned start = 0, length; + uint64_t remains; + uint64_t actual_size = 0; + + init_write_buffer(); + remains = size; + while (remains > 0) { + length = WRITE_BUFFER_SIZE - start; + if (remains > length) + sz = length; + else + sz = (size_t) remains; + written = write(fd, write_buffer + start, sz); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + actual_size += written; + if (written == sz) + start = 0; + else + start += written; + } + tests_maybe_sync(fd); + return actual_size; +} + +/* Write size random bytes into file descriptor fd at offset, + returning the number of bytes actually written */ +uint64_t tests_write_filled_file(int fd, off_t offset, uint64_t size) +{ + ssize_t written; + size_t sz; + unsigned start = 0, length; + uint64_t remains; + uint64_t actual_size = 0; + + CHECK(lseek(fd, offset, SEEK_SET) == offset); + + init_write_buffer(); + remains = size; + start = offset % WRITE_BUFFER_SIZE; + while (remains > 0) { + length = WRITE_BUFFER_SIZE - start; + if (remains > length) + sz = length; + else + sz = (size_t) remains; + written = write(fd, write_buffer + start, sz); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + actual_size += written; + if (written == sz) + start = 0; + else + start += written; + } + tests_maybe_sync(fd); + return actual_size; +} + +/* Check that a file written using tests_fill_file() and/or + tests_write_filled_file() and/or tests_create_file() + contains the expected random data */ +void tests_check_filled_file_fd(int fd) +{ + ssize_t sz; + char buf[WRITE_BUFFER_SIZE]; + + CHECK(lseek(fd, 0, SEEK_SET) == 0); + do { + sz = read(fd, buf, WRITE_BUFFER_SIZE); + CHECK(sz >= 0); + CHECK(memcmp(buf, write_buffer, sz) == 0); + } while (sz); +} + +/* Check that a file written using tests_fill_file() and/or + tests_write_filled_file() and/or tests_create_file() + contains the expected random data */ +void tests_check_filled_file(const char *file_name) +{ + int fd; + + fd = open(file_name, O_RDONLY); + CHECK(fd != -1); + tests_check_filled_file_fd(fd); + CHECK(close(fd) != -1); +} + +void tests_sync_directory(const char *file_name) +{ + char *path; + char *dir; + int fd; + + if (!tests_ok_to_sync) + return; + + path = strdup(file_name); + dir = dirname(path); + fd = open(dir,O_RDONLY | tests_maybe_sync_flag()); + CHECK(fd != -1); + CHECK(fsync(fd) != -1); + CHECK(close(fd) != -1); + free(path); +} + +/* Delete a file */ +void tests_delete_file(const char *file_name) +{ + CHECK(unlink(file_name) != -1); + tests_sync_directory(file_name); +} + +/* Create a file of size file_size */ +uint64_t tests_create_file(const char *file_name, uint64_t file_size) +{ + int fd; + int flags; + mode_t mode; + uint64_t actual_size; /* Less than size if the file system is full */ + + flags = O_CREAT | O_TRUNC | O_WRONLY | tests_maybe_sync_flag(); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + fd = open(file_name, flags, mode); + if (fd == -1 && errno == ENOSPC) { + errno = 0; + return 0; /* File system full */ + } + CHECK(fd != -1); + actual_size = tests_fill_file(fd, file_size); + CHECK(close(fd) != -1); + if (file_size != 0 && actual_size == 0) + tests_delete_file(file_name); + else + tests_sync_directory(file_name); + return actual_size; +} + +/* Calculate: free_space * numerator / denominator */ +uint64_t tests_get_big_file_size(unsigned numerator, unsigned denominator) +{ + if (denominator == 0) + denominator = 1; + if (numerator > denominator) + numerator = denominator; + return numerator * (tests_get_free_space() / denominator); +} + +/* Create file "fragment_n" where n is the file_number, and unlink it */ +int tests_create_orphan(unsigned file_number) +{ + int fd; + int flags; + mode_t mode; + char file_name[256]; + + sprintf(file_name, "fragment_%u", file_number); + flags = O_CREAT | O_TRUNC | O_RDWR | tests_maybe_sync_flag(); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + fd = open(file_name, flags, mode); + if (fd == -1 && (errno == ENOSPC || errno == EMFILE)) + return fd; /* File system full or too many open files */ + CHECK(fd != -1); + tests_sync_directory(file_name); + CHECK(unlink(file_name) != -1); + return fd; +} + +/* Write size bytes at offset to the file "fragment_n" where n is the + file_number and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_write_fragment_file(unsigned file_number, + int fd, + off_t offset, + unsigned size) +{ + int i, d; + uint64_t u; + ssize_t written; + off_t pos; + char buf[WRITE_BUFFER_SIZE]; + + if (size > WRITE_BUFFER_SIZE) + size = WRITE_BUFFER_SIZE; + + pos = lseek(fd, 0, SEEK_END); + CHECK(pos != (off_t) -1); + if (offset > pos) + offset = pos; + + pos = lseek(fd, offset, SEEK_SET); + CHECK(pos != (off_t) -1); + CHECK(pos == offset); + + srand(file_number); + while (offset--) + rand(); + + u = RAND_MAX; + u += 1; + u /= 256; + d = (int) u; + for (i = 0; i < size; ++i) + buf[i] = rand() / d; + + written = write(fd, buf, size); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + written = 0; + } + tests_maybe_sync(fd); + return (unsigned) written; +} + +/* Write size bytes to the end of file descriptor fd using file_number + to determine the random data written i.e. seed for random numbers */ +unsigned tests_fill_fragment_file(unsigned file_number, int fd, unsigned size) +{ + off_t offset; + + offset = lseek(fd, 0, SEEK_END); + CHECK(offset != (off_t) -1); + + return tests_write_fragment_file(file_number, fd, offset, size); +} + +/* Write size bytes to the end of file "fragment_n" where n is the file_number + and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_append_to_fragment_file(unsigned file_number, + unsigned size, + int create) +{ + int fd; + int flags; + mode_t mode; + unsigned actual_growth; + char file_name[256]; + + sprintf(file_name, "fragment_%u", file_number); + if (create) + flags = O_CREAT | O_EXCL | O_WRONLY | tests_maybe_sync_flag(); + else + flags = O_WRONLY | tests_maybe_sync_flag(); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + fd = open(file_name, flags, mode); + if (fd == -1 && errno == ENOSPC) { + errno = 0; + return 0; /* File system full */ + } + CHECK(fd != -1); + actual_growth = tests_fill_fragment_file(file_number, fd, size); + CHECK(close(fd) != -1); + if (create && !actual_growth) + tests_delete_fragment_file(file_number); + return actual_growth; +} + +/* Write size bytes at offset to the file "fragment_n" where n is the + file_number and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_overwite_fragment_file( unsigned file_number, + off_t offset, + unsigned size) +{ + int fd; + unsigned actual_size; + char file_name[256]; + + sprintf(file_name, "fragment_%u", file_number); + fd = open(file_name, O_RDWR | tests_maybe_sync_flag()); + if (fd == -1 && errno == ENOSPC) { + errno = 0; + return 0; /* File system full */ + } + CHECK(fd != -1); + actual_size = tests_write_fragment_file(file_number, + fd, offset, size); + CHECK(close(fd) != -1); + return actual_size; +} + +/* Delete file "fragment_n" where n is the file_number */ +void tests_delete_fragment_file(unsigned file_number) +{ + char file_name[256]; + + sprintf(file_name, "fragment_%u", file_number); + tests_delete_file(file_name); +} + +/* Check the random data in file "fragment_n" is what is expected */ +void tests_check_fragment_file_fd(unsigned file_number, int fd) +{ + ssize_t sz, i; + int d; + uint64_t u; + char buf[8192]; + + CHECK(lseek(fd, 0, SEEK_SET) == 0); + srand(file_number); + u = RAND_MAX; + u += 1; + u /= 256; + d = (int) u; + for (;;) { + sz = read(fd, buf, 8192); + if (sz == 0) + break; + CHECK(sz >= 0); + for (i = 0; i < sz; ++i) + CHECK(buf[i] == (char) (rand() / d)); + } +} + +/* Check the random data in file "fragment_n" is what is expected */ +void tests_check_fragment_file(unsigned file_number) +{ + int fd; + ssize_t sz, i; + int d; + uint64_t u; + char file_name[256]; + char buf[8192]; + + sprintf(file_name, "fragment_%u", file_number); + fd = open(file_name, O_RDONLY); + CHECK(fd != -1); + srand(file_number); + u = RAND_MAX; + u += 1; + u /= 256; + d = (int) u; + for (;;) { + sz = read(fd, buf, 8192); + if (sz == 0) + break; + CHECK(sz >= 0); + for (i = 0; i < sz; ++i) + CHECK(buf[i] == (char) (rand() / d)); + } + CHECK(close(fd) != -1); +} + +/* Central point to decide whether to use fsync */ +void tests_maybe_sync(int fd) +{ + if (tests_ok_to_sync) + CHECK(fsync(fd) != -1); +} + +/* Return O_SYNC if ok to sync otherwise return 0 */ +int tests_maybe_sync_flag(void) +{ + if (tests_ok_to_sync) + return O_SYNC; + return 0; +} + +/* Return random number from 0 to n - 1 */ +size_t tests_random_no(size_t n) +{ + uint64_t a, b; + + if (!n) + return 0; + if (n - 1 <= RAND_MAX) { + a = rand(); + b = RAND_MAX; + b += 1; + } else { + const uint64_t u = 1 + (uint64_t) RAND_MAX; + a = rand(); + a *= u; + a += rand(); + b = u * u; + CHECK(n <= b); + } + if (RAND_MAX <= UINT32_MAX && n <= UINT32_MAX) + return a * n / b; + else /*if (RAND_MAX <= UINT64_MAX && n <= UINT64_MAX)*/ { + uint64_t x, y; + if (a < n) { + x = a; + y = n; + } else { + x = n; + y = a; + } + return (x * (y / b)) + ((x * (y % b)) / b); + } +} + +/* Make a directory empty */ +void tests_clear_dir(const char *dir_name) +{ + DIR *dir; + struct dirent *entry; + char buf[4096]; + + dir = opendir(dir_name); + CHECK(dir != NULL); + CHECK(getcwd(buf, 4096) != NULL); + CHECK(chdir(dir_name) != -1); + for (;;) { + errno = 0; + entry = readdir(dir); + if (entry) { + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) { + if (entry->d_type == DT_DIR) { + tests_clear_dir(entry->d_name); + CHECK(rmdir(entry->d_name) != -1); + } else + CHECK(unlink(entry->d_name) != -1); + } + } else { + CHECK(errno == 0); + break; + } + } + CHECK(chdir(buf) != -1); + CHECK(closedir(dir) != -1); +} + +/* Create an empty sub-directory or small file in the current directory */ +int64_t tests_create_entry(char *return_name) +{ + int fd; + char name[256]; + + for (;;) { + sprintf(name, "%u", (unsigned) tests_random_no(10000000)); + fd = open(name, O_RDONLY); + if (fd == -1) + break; + close(fd); + } + if (return_name) + strcpy(return_name, name); + if (tests_random_no(2)) { + return tests_create_file(name, tests_random_no(4096)); + } else { + if (mkdir(name, 0777) == -1) { + CHECK(errno == ENOSPC); + errno = 0; + return 0; + } + return TESTS_EMPTY_DIR_SIZE; + } +} + +/* Remove a random file of empty sub-directory from the current directory */ +int64_t tests_remove_entry(void) +{ + DIR *dir; + struct dirent *entry; + unsigned count = 0, pos; + int64_t result = 0; + + dir = opendir("."); + CHECK(dir != NULL); + for (;;) { + errno = 0; + entry = readdir(dir); + if (entry) { + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) + ++count; + } else { + CHECK(errno == 0); + break; + } + } + pos = tests_random_no(count); + count = 0; + rewinddir(dir); + for (;;) { + errno = 0; + entry = readdir(dir); + if (!entry) { + CHECK(errno == 0); + break; + } + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) { + if (count == pos) { + if (entry->d_type == DT_DIR) { + tests_clear_dir(entry->d_name); + CHECK(rmdir(entry->d_name) != -1); + result = TESTS_EMPTY_DIR_SIZE; + } else { + struct stat st; + CHECK(stat(entry->d_name, &st) != -1); + result = st.st_size; + CHECK(unlink(entry->d_name) != -1); + } + } + ++count; + } + } + CHECK(closedir(dir) != -1); + return result; +} + +/* Read mount information from /proc/mounts or /etc/mtab */ +int tests_get_mount_info(struct mntent *info) +{ + FILE *f; + struct mntent *entry; + int found = 0; + + f = fopen("/proc/mounts", "rb"); + if (!f) + f = fopen("/etc/mtab", "rb"); + CHECK(f != NULL); + while (!found) { + entry = getmntent(f); + if (entry) { + if (strcmp(entry->mnt_dir, + tests_file_system_mount_dir) == 0) { + found = 1; + *info = *entry; + } + } else + break; + } + CHECK(fclose(f) == 0); + return found; +} + +/* Un-mount and re-mount test file system */ +void tests_remount(void) +{ + struct mntent mount_info; + char *source; + char *target; + char *filesystemtype; + unsigned long mountflags; + void *data; + char cwd[4096]; + + CHECK(tests_get_mount_info(&mount_info)); + + if (strcmp(mount_info.mnt_dir,"/") == 0) + return; + + CHECK(getcwd(cwd, 4096) != NULL); + CHECK(chdir("/") != -1); + + CHECK(umount(tests_file_system_mount_dir) != -1); + + source = mount_info.mnt_fsname; + target = tests_file_system_mount_dir; + filesystemtype = tests_file_system_type; + mountflags = 0; + data = NULL; + + CHECK(mount(source, target, filesystemtype, mountflags, data) != -1); + + CHECK(chdir(cwd) != -1); +} + +/* Check whether the test file system is also the root file system */ +int tests_fs_is_rootfs(void) +{ + struct stat f_info; + struct stat root_f_info; + + CHECK(stat(tests_file_system_mount_dir, &f_info) != -1); + CHECK(stat("/", &root_f_info) != -1); + if (f_info.st_dev == root_f_info.st_dev) + return 1; + else + return 0; +} + +/* Try to make a directory empty */ +void tests_try_to_clear_dir(const char *dir_name) +{ + DIR *dir; + struct dirent *entry; + char buf[4096]; + + dir = opendir(dir_name); + if (dir == NULL) + return; + if (getcwd(buf, 4096) == NULL || chdir(dir_name) == -1) { + closedir(dir); + return; + } + for (;;) { + errno = 0; + entry = readdir(dir); + if (entry) { + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) { + if (entry->d_type == DT_DIR) { + tests_try_to_clear_dir(entry->d_name); + rmdir(entry->d_name); + } else + unlink(entry->d_name); + } + } else { + CHECK(errno == 0); + break; + } + } + chdir(buf); + closedir(dir); +} + +/* Check whether the test file system is also the current file system */ +int tests_fs_is_currfs(void) +{ + struct stat f_info; + struct stat curr_f_info; + + CHECK(stat(tests_file_system_mount_dir, &f_info) != -1); + CHECK(stat(".", &curr_f_info) != -1); + if (f_info.st_dev == curr_f_info.st_dev) + return 1; + else + return 0; +} + +#define PID_BUF_SIZE 64 + +/* Concatenate a pid to a string in a signal safe way */ +void tests_cat_pid(char *buf, const char *name, pid_t pid) +{ + char *p; + unsigned x; + const char digits[] = "0123456789"; + char pid_buf[PID_BUF_SIZE]; + + x = (unsigned) pid; + p = pid_buf + PID_BUF_SIZE; + *--p = '\0'; + if (x) + while (x) { + *--p = digits[x % 10]; + x /= 10; + } + else + *--p = '0'; + buf[0] = '\0'; + strcat(buf, name); + strcat(buf, p); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/lib/tests.h 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#ifndef included_tests_tests_h__ +#define included_tests_tests_h__ + +#include + +/* Main macro for testing */ +#define CHECK(x) tests_test((x),__func__,__FILE__,__LINE__) + +/* The default directory in which tests are conducted */ +#define TESTS_DEFAULT_FILE_SYSTEM_MOUNT_DIR "/mnt/test_file_system" + +/* The default file system type to test */ +#define TESTS_DEFAULT_FILE_SYSTEM_TYPE "jffs2" + +/* Estimated size of an empty directory */ +#define TESTS_EMPTY_DIR_SIZE 128 + +/* Function invoked by the CHECK macro */ +void tests_test(int test,const char *msg,const char *file,unsigned line); + +/* Handle common program options */ +int tests_get_args(int argc, + char *argv[], + const char *title, + const char *desc, + const char *opts); + +/* Return the number of files (or directories) in the given directory */ +unsigned tests_count_files_in_dir(const char *dir_name); + +/* Change to the file system mount directory, check that it is empty, + matches the file system type, and is not the root file system */ +void tests_check_test_file_system(void); + +/* Get the free space for the file system of the current directory */ +uint64_t tests_get_free_space(void); + +/* Get the total space for the file system of the current directory */ +uint64_t tests_get_total_space(void); + +/* Write size random bytes into file descriptor fd at the current position, + returning the number of bytes actually written */ +uint64_t tests_fill_file(int fd, uint64_t size); + +/* Write size random bytes into file descriptor fd at offset, + returning the number of bytes actually written */ +uint64_t tests_write_filled_file(int fd, off_t offset, uint64_t size); + +/* Check that a file written using tests_fill_file() and/or + tests_write_filled_file() and/or tests_create_file() + contains the expected random data */ +void tests_check_filled_file_fd(int fd); + +/* Check that a file written using tests_fill_file() and/or + tests_write_filled_file() and/or tests_create_file() + contains the expected random data */ +void tests_check_filled_file(const char *file_name); + +/* Delete a file */ +void tests_delete_file(const char *file_name); + +/* Create a file of size file_size */ +uint64_t tests_create_file(const char *file_name, uint64_t file_size); + +/* Calculate: free_space * numerator / denominator */ +uint64_t tests_get_big_file_size(unsigned numerator, unsigned denominator); + +/* Create file "fragment_n" where n is the file_number, and unlink it */ +int tests_create_orphan(unsigned file_number); + +/* Write size bytes at offset to the file "fragment_n" where n is the + file_number and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_write_fragment_file(unsigned file_number, + int fd, + off_t offset, + unsigned size); + +/* Write size bytes to the end of file descriptor fd using file_number + to determine the random data written i.e. seed for random numbers */ +unsigned tests_fill_fragment_file(unsigned file_number, + int fd, + unsigned size); + +/* Write size bytes to the end of file "fragment_n" where n is the file_number + and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_append_to_fragment_file(unsigned file_number, + unsigned size, + int create); + +/* Write size bytes at offset to the file "fragment_n" where n is the + file_number and file_number also determines the random data written + i.e. seed for random numbers */ +unsigned tests_overwite_fragment_file( unsigned file_number, + off_t offset, + unsigned size); + +/* Delete file "fragment_n" where n is the file_number */ +void tests_delete_fragment_file(unsigned file_number); + +/* Check the random data in file "fragment_n" is what is expected */ +void tests_check_fragment_file_fd(unsigned file_number, int fd); + +/* Check the random data in file "fragment_n" is what is expected */ +void tests_check_fragment_file(unsigned file_number); + +/* Central point to decide whether to use fsync */ +void tests_maybe_sync(int fd); + +/* Return O_SYNC if ok to sync otherwise return 0 */ +int tests_maybe_sync_flag(void); + +/* Return random number from 0 to n - 1 */ +size_t tests_random_no(size_t n); + +/* Make a directory empty */ +void tests_clear_dir(const char *dir_name); + +/* Create an empty sub-directory or small file in the current directory */ +int64_t tests_create_entry(char *return_name); + +/* Remove a random file of empty sub-directory from the current directory */ +int64_t tests_remove_entry(void); + +/* Un-mount and re-mount test file system */ +void tests_remount(void); + +/* Check whether the test file system is also the root file system */ +int tests_fs_is_rootfs(void); + +/* Try to make a directory empty */ +void tests_try_to_clear_dir(const char *dir_name); + +/* Check whether the test file system is also the current file system */ +int tests_fs_is_currfs(void); + +/* Concatenate a pid to a string in a signal safe way */ +void tests_cat_pid(char *buf, const char *name, pid_t pid); + +extern char *tests_file_system_mount_dir; + +extern char *tests_file_system_type; + +/* General purpose test parameter to specify some aspect of test size. + May be used by different tests in different ways. + Set by the -z, --size options. */ +extern int64_t tests_size_parameter; + +/* General purpose test parameter to specify some aspect of test repetition. + May be used by different tests in different ways. + Set by the -n, --repeat options. */ +extern int64_t tests_repeat_parameter; + +/* General purpose test parameter to specify some aspect of test sleeping. + May be used by different tests in different ways. + Set by the -p, --sleep options. */ +extern int64_t tests_sleep_parameter; + +/* General purpose test parameter to specify a file should be unlinked. + May be used by different tests in different ways or not at all. */ +extern int tests_unlink_flag; + +/* General purpose test parameter to specify a file should be closed. + May be used by different tests in different ways or not at all. */ +extern int tests_close_flag; + +/* General purpose test parameter to specify a file should be deleted. + May be used by different tests in different ways or not at all. */ +extern int tests_delete_flag; + +/* General purpose test parameter to specify a file have a hole. + May be used by different tests in different ways or not at all. */ +extern int tests_hole_flag; + +/* Program name from argv[0] */ +extern char *program_name; + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,8 @@ + +SUBDIRS = lib simple stress integrity utils + +all clean tests: $(SUBDIRS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/run_all.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/run_all.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/run_all.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/run_all.sh 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,49 @@ +#!/bin/sh + +TEST_DIR=$TEST_FILE_SYSTEM_MOUNT_DIR +if test -z "$TEST_DIR"; +then + TEST_DIR="/mnt/test_file_system" +fi + +rm -rf ${TEST_DIR}/* + +./simple/test_1 || exit 1 + +rm -rf ${TEST_DIR}/* + +./simple/test_2 || exit 1 + +rm -rf ${TEST_DIR}/* + +./integrity/integck || exit 1 + +rm -rf ${TEST_DIR}/* + +./stress/atoms/rndrm00 -z0 || exit 1 + +rm -rf ${TEST_DIR}/* + +./stress/atoms/rmdir00 -z0 || exit 1 + +rm -rf ${TEST_DIR}/* + +./stress/atoms/stress_1 -z10000000 -e || exit 1 + +rm -rf ${TEST_DIR}/* + +./stress/atoms/stress_2 -z10000000 || exit 1 + +rm -rf ${TEST_DIR}/* + +./stress/atoms/stress_3 -z1000000000 -e || exit 1 + +rm -rf ${TEST_DIR}/* + +cd stress || exit 1 + +./stress00.sh 3600 || exit 1 + +./stress01.sh 3600 || exit 1 + +cd .. || exit 1 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/ftrunc.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/ftrunc.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/ftrunc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/ftrunc.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +void ftrunc(void) +{ + int fd, i; + pid_t pid; + ssize_t written; + int64_t remains; + size_t block; + char *file_name; + off_t actual; + char buf[WRITE_BUFFER_SIZE]; + + file_name = "ftrunc_test_file"; + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + pid = getpid(); + srand(pid); + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + remains = tests_size_parameter; + actual = 0; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + actual += written; + } + CHECK(ftruncate(fd, (actual ? actual - 1 : actual)) != -1); + CHECK(close(fd) != -1); + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *ftrunc_get_title(void) +{ + return "Truncate a large test file"; +} + +/* Description of this test */ + +const char *ftrunc_get_description(void) +{ + return + "Create a file named ftrunc_test_file. " \ + "Truncate the file to reduce its length by 1. " \ + "Then remove the truncated file. " + "The size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, ftrunc_get_title(), + ftrunc_get_description(), "z"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + ftrunc(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,28 @@ + +ifeq ($(origin CC),default) +CC = gcc +endif + +CFLAGS := $(CFLAGS) -Wall -g -O2 -I../lib + +LDFLAGS := $(LDFLAGS) + +TARGETS = test_1 \ + test_2 \ + ftrunc \ + orph + +all: $(TARGETS) + +$(TARGETS): ../lib/tests.o + +../lib/tests.o: ../lib/tests.h + +clean: + rm -f *.o $(TARGETS) + +tests: all + ./test_1 --sync + ./test_2 --sync + ./ftrunc + ./orph --sync diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/orph.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/orph.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/orph.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/orph.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define MAX_ORPHANS 1000000 + +void orph(void) +{ + pid_t pid; + unsigned i, j, k, n; + int fd, done, full; + int64_t repeat; + ssize_t sz; + char dir_name[256]; + int fds[MAX_ORPHANS]; + + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "orph_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + + repeat = tests_repeat_parameter; + for (;;) { + full = 0; + done = 0; + n = 0; + while (n + 100 < MAX_ORPHANS && !done) { + /* Make 100 more orphans */ + for (i = 0; i < 100; i++) { + fd = tests_create_orphan(n + i); + if (fd < 0) { + done = 1; + if (errno == ENOSPC) + full = 1; + else if (errno != EMFILE) + CHECK(0); + errno = 0; + break; + } + fds[n + i] = fd; + } + if (!full) { + /* Write to orphans just created */ + k = i; + for (i = 0; i < k; i++) { + if (tests_write_fragment_file(n + i, + fds[n+i], + 0, 1000) + != 1000) { + /* + * Out of space, so close + * remaining files + */ + for (j = i; j < k; j++) + CHECK(close(fds[n + j]) + != -1); + done = 1; + break; + } + } + } + if (!done) + CHECK(tests_count_files_in_dir(".") == 0); + n += i; + } + /* Check the data in the files */ + for (i = 0; i < n; i++) + tests_check_fragment_file_fd(i, fds[i]); + if (!full && n) { + /* Ensure the file system is full */ + n -= 1; + do { + sz = write(fds[n], fds, 4096); + if (sz == -1 && errno == ENOSPC) { + errno = 0; + break; + } + CHECK(sz >= 0); + } while (sz == 4096); + CHECK(close(fds[n]) != -1); + } + /* Check the data in the files */ + for (i = 0; i < n; i++) + tests_check_fragment_file_fd(i, fds[i]); + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + /* Close orphans */ + for (i = 0; i < n; i++) + CHECK(close(fds[i]) != -1); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + } + CHECK(tests_count_files_in_dir(".") == 0); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *orph_get_title(void) +{ + return "Create many open unlinked files"; +} + +/* Description of this test */ + +const char *orph_get_description(void) +{ + return + "Create a directory named orph_test_dir_pid, where " \ + "pid is the process id. Within that directory, " \ + "create files and keep them open and unlink them. " \ + "Create as many files as possible until the file system is " \ + "full or the maximum allowed open files is reached. " \ + "If a sleep value is specified, the process sleeps. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " \ + "Sleep is specified in milliseconds. " \ + "Then close the files. " \ + "If a repeat count is specified, then the task repeats " \ + "that number of times. " \ + "The repeat count is given by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "Finally remove the directory."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, orph_get_title(), + orph_get_description(), "nps"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + orph(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_1.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_1.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_1.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +void test_1(void) +{ + int fd; + pid_t pid; + uint64_t i; + uint64_t block; + uint64_t actual_size; + char name[256]; + char old[16]; + char buf[16]; + off_t old_len; + char dir_name[256]; + + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "test_1_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + /* Create a file that fills half the free space on the file system */ + tests_create_file("big_file", tests_get_big_file_size(1,2)); + CHECK(tests_count_files_in_dir(".") == 1); + fd = open("big_file", O_RDWR | tests_maybe_sync_flag()); + CHECK(fd != -1); + CHECK(read(fd, old, 5) == 5); + CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); + CHECK(write(fd,"start", 5) == 5); + CHECK(lseek(fd,0,SEEK_END) != (off_t) -1); + CHECK(write(fd, "end", 3) == 3); + tests_maybe_sync(fd); + /* Delete the file while it is still open */ + tests_delete_file("big_file"); + CHECK(tests_count_files_in_dir(".") == 0); + /* Create files to file up the file system */ + for (block = 1000000, i = 1; ; block /= 10) { + while (i != 0) { + sprintf(name, "fill_up_%llu", i); + actual_size = tests_create_file(name, block); + if (actual_size != 0) + ++i; + if (actual_size != block) + break; + } + if (block == 1) + break; + } + /* Check the big file */ + CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); + CHECK(read(fd, buf, 5) == 5); + CHECK(strncmp(buf, "start", 5) == 0); + CHECK(lseek(fd, -3, SEEK_END) != (off_t) -1); + CHECK(read(fd, buf, 3) == 3); + CHECK(strncmp(buf, "end", 3) == 0); + /* Check the other files and delete them */ + i -= 1; + CHECK(tests_count_files_in_dir(".") == i); + for (; i > 0; --i) { + sprintf(name, "fill_up_%llu", i); + tests_check_filled_file(name); + tests_delete_file(name); + } + CHECK(tests_count_files_in_dir(".") == 0); + /* Check the big file again */ + CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); + CHECK(read(fd, buf, 5) == 5); + CHECK(strncmp(buf, "start", 5) == 0); + CHECK(lseek(fd, -3, SEEK_END) != (off_t) -1); + CHECK(read(fd, buf, 3) == 3); + CHECK(strncmp(buf, "end", 3) == 0); + CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); + CHECK(write(fd,old, 5) == 5); + old_len = lseek(fd, -3, SEEK_END); + CHECK(old_len != (off_t) -1); + CHECK(ftruncate(fd,old_len) != -1); + tests_check_filled_file_fd(fd); + /* Close the big file*/ + CHECK(close(fd) != -1); + CHECK(tests_count_files_in_dir(".") == 0); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *test_1_get_title(void) +{ + return "Fill file system while holding deleted big file descriptor"; +} + +/* Description of this test */ + +const char *test_1_get_description(void) +{ + return + "Create a directory named test_1_test_dir_pid, where " \ + "pid is the process id. Within that directory, " \ + "create a big file (approx. half the file system in size), " \ + "open it, and unlink it. " \ + "Create many smaller files until the file system is full. " \ + "Check the big file is ok. " \ + "Delete all the smaller files. " \ + "Check the big file again. " \ + "Finally delete the big file and directory."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, test_1_get_title(), + test_1_get_description(), "s"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + test_1(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_2.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_2.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_2.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/simple/test_2.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +void test_2(void) +{ + pid_t pid; + int create, full; + unsigned i, number_of_files; + unsigned growth; + unsigned size; + uint64_t big_file_size; + int fd; + off_t offset; + char dir_name[256]; + + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "test_2_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + /* Create up to 1000 files appending 400 bytes at a time to each file */ + /* until the file system is full.*/ + create = 1; + full = 0; + number_of_files = 1000; + while (!full) { + for (i = 0; i < number_of_files; ++i) { + growth = tests_append_to_fragment_file(i, 400, create); + if (!growth) { + full = 1; + if (create) + number_of_files = i; + break; + } + } + create = 0; + } + /* Check the files */ + CHECK(tests_count_files_in_dir(".") == number_of_files); + for (i = 0; i < number_of_files; ++i) + tests_check_fragment_file(i); + /* Delete half of them */ + for (i = 1; i < number_of_files; i += 2) + tests_delete_fragment_file(i); + /* Check them again */ + CHECK(tests_count_files_in_dir(".") == (number_of_files + 1) / 2); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + CHECK(tests_count_files_in_dir(".") == (number_of_files + 1) / 2); + /* Create a big file that fills two thirds of the free space */ + big_file_size = tests_get_big_file_size(2,3); + /* Check the big file */ + tests_create_file("big_file", big_file_size); + CHECK(tests_count_files_in_dir(".") == 1 + (number_of_files + 1) / 2); + tests_check_filled_file("big_file"); + /* Open the big file */ + fd = open("big_file",O_RDWR | tests_maybe_sync_flag()); + CHECK(fd != -1); + /* Delete the big file while it is still open */ + tests_delete_file("big_file"); + /* Check the big file again */ + CHECK(tests_count_files_in_dir(".") == (number_of_files + 1) / 2); + tests_check_filled_file_fd(fd); + + /* Write parts of the files and check them */ + + offset = 100; /* Offset to write at, in the small files */ + size = 200; /* Number of bytes to write at the offset */ + + for (i = 0; i < number_of_files; i += 2) + tests_overwite_fragment_file(i, offset, size); + /* Rewrite the big file entirely */ + tests_write_filled_file(fd, 0, big_file_size); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + tests_check_filled_file_fd(fd); + + offset = 300; /* Offset to write at, in the small files */ + size = 400; /* Number of bytes to write at the offset */ + + for (i = 0; i < number_of_files; i += 2) + tests_overwite_fragment_file(i, offset, size); + /* Rewrite the big file entirely */ + tests_write_filled_file(fd, 0, big_file_size); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + tests_check_filled_file_fd(fd); + + offset = 110; /* Offset to write at, in the small files */ + size = 10; /* Number of bytes to write at the offset */ + + for (i = 0; i < number_of_files; i += 2) + tests_overwite_fragment_file(i, offset, size); + /* Rewrite the big file entirely */ + tests_write_filled_file(fd, 0, big_file_size); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + tests_check_filled_file_fd(fd); + + offset = 10; /* Offset to write at, in the small files */ + size = 1000; /* Number of bytes to write at the offset */ + + for (i = 0; i < number_of_files; i += 2) + tests_overwite_fragment_file(i, offset, size); + /* Rewrite the big file entirely */ + tests_write_filled_file(fd, 0, big_file_size); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + tests_check_filled_file_fd(fd); + + offset = 0; /* Offset to write at, in the small files */ + size = 100000; /* Number of bytes to write at the offset */ + + for (i = 0; i < number_of_files; i += 2) + tests_overwite_fragment_file(i, offset, size); + /* Rewrite the big file entirely */ + tests_write_filled_file(fd, 0, big_file_size); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + tests_check_filled_file_fd(fd); + + /* Close the big file*/ + CHECK(close(fd) != -1); + /* Check the small files */ + CHECK(tests_count_files_in_dir(".") == (number_of_files + 1) / 2); + for (i = 0; i < number_of_files; i += 2) + tests_check_fragment_file(i); + /* Delete the small files */ + for (i = 0; i < number_of_files; i += 2) + tests_delete_fragment_file(i); + CHECK(tests_count_files_in_dir(".") == 0); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *test_2_get_title(void) +{ + return "Repeated write many small files and one big deleted file"; +} + +/* Description of this test */ + +const char *test_2_get_description(void) +{ + return + "Create a directory named test_2_test_dir_pid, where " \ + "pid is the process id. Within that directory, " \ + "create about 1000 files. Append 400 bytes to each until " \ + "the file system is full. Then delete half of them. Then " \ + "create a big file that uses about 2/3 of the remaining free " \ + "space. Get a file descriptor for the big file, and delete " \ + "the big file. Then repeatedly write to the small files " \ + "and the big file. " \ + "Finally delete the big file and directory."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, test_2_get_title(), + test_2_get_description(), "s"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + test_2(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/fwrite00.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/fwrite00.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/fwrite00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/fwrite00.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +#define HOLE_BLOCK_SIZE 10000000 + +void filestress00(void) +{ + int fd, i, deleted; + pid_t pid; + ssize_t written; + int64_t remains; + int64_t repeat; + size_t block; + char file_name[256]; + char buf[WRITE_BUFFER_SIZE]; + + fd = -1; + deleted = 1; + pid = getpid(); + tests_cat_pid(file_name, "filestress00_test_file_", pid); + srand(pid); + repeat = tests_repeat_parameter; + for (;;) { + /* Open the file */ + if (fd == -1) { + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + deleted = 0; + if (tests_unlink_flag) { + CHECK(unlink(file_name) != -1); + deleted = 1; + } + } + /* Get a different set of random data */ + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + if (tests_hole_flag) { + /* Make a hole */ + CHECK(lseek(fd, tests_size_parameter, SEEK_SET) != -1); + written = write(fd, "!", 1); + if (written <= 0) { + /* File system full */ + CHECK(errno == ENOSPC); + errno = 0; + } + CHECK(lseek(fd, 0, SEEK_SET) != -1); + /* Write at set points into the hole */ + remains = tests_size_parameter; + while (remains > HOLE_BLOCK_SIZE) { + CHECK(lseek(fd, HOLE_BLOCK_SIZE, + SEEK_CUR) != -1); + written = write(fd, "!", 1); + remains -= HOLE_BLOCK_SIZE; + if (written <= 0) { + /* File system full */ + CHECK(errno == ENOSPC); + errno = 0; + break; + } + } + } else { + /* Write data into the file */ + CHECK(lseek(fd, 0, SEEK_SET) != -1); + remains = tests_size_parameter; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + /* File system full */ + CHECK(errno == ENOSPC); + errno = 0; + break; + } + remains -= written; + } + } + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + /* Close if tests_close_flag */ + if (tests_close_flag) { + CHECK(close(fd) != -1); + fd = -1; + } + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + /* Delete if tests_delete flag */ + if (!deleted && tests_delete_flag) { + CHECK(unlink(file_name) != -1); + deleted = 1; + } + } + CHECK(close(fd) != -1); + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + /* Tidy up */ + if (!deleted) + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *filestress00_get_title(void) +{ + return "File stress test 00"; +} + +/* Description of this test */ + +const char *filestress00_get_description(void) +{ + return + "Create a file named filestress00_test_file_pid, where " \ + "pid is the process id. If the unlink option " \ + "(-u or --unlink) is specified, " \ + "unlink the file while holding the open file descriptor. " \ + "If the hole option (-o or --hole) is specified, " \ + "write a single character at the end of the file, creating a " \ + "hole. " \ + "Write a single character in the hole every 10 million " \ + "bytes. " \ + "If the hole option is not specified, then the file is " \ + "filled with random data. " \ + "If the close option (-c or --close) is specified the file " \ + "is closed. " \ + "If a sleep value is specified, the process sleeps. " \ + "If the delete option (-e or --delete) is specified, then " \ + "the file is deleted. " \ + "If a repeat count is specified, then the task repeats " \ + "that number of times. " \ + "The repeat count is given by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The file size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " \ + "Sleep is specified in milliseconds."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, filestress00_get_title(), + filestress00_get_description(), "znpuoce"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + filestress00(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/gcd_hupper.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/gcd_hupper.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/gcd_hupper.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/gcd_hupper.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define MAX_NAME_SIZE 1024 + +struct gcd_pid +{ + struct gcd_pid *next; + int pid; + char *name; + int mtd_index; +}; + +struct gcd_pid *gcd_pid_list = NULL; + +int add_gcd_pid(const char *number) +{ + int pid; + FILE *f; + char file_name[MAX_NAME_SIZE]; + char program_name[MAX_NAME_SIZE]; + + pid = atoi(number); + if (pid <= 0) + return 0; + snprintf(file_name, MAX_NAME_SIZE, "/proc/%s/stat", number); + f = fopen(file_name, "r"); + if (f == NULL) + return 0; + if (fscanf(f, "%d %s", &pid, program_name) != 2) { + fclose(f); + return 0; + } + if (strncmp(program_name, "(jffs2_gcd_mtd", 14) != 0) + pid = 0; + if (pid) { + size_t sz; + struct gcd_pid *g; + + sz = sizeof(struct gcd_pid); + g = (struct gcd_pid *) malloc(sz); + g->pid = pid; + g->name = (char *) malloc(strlen(program_name) + 1); + if (g->name) + strcpy(g->name, program_name); + else + exit(1); + g->mtd_index = atoi(program_name + 14); + g->next = gcd_pid_list; + gcd_pid_list = g; + } + fclose(f); + return pid; +} + +int get_pid_list(void) +{ + DIR *dir; + struct dirent *entry; + + dir = opendir("/proc"); + if (dir == NULL) + return 1; + for (;;) { + entry = readdir(dir); + if (entry) { + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) + add_gcd_pid(entry->d_name); + } else + break; + } + closedir(dir); + return 0; +} + +int parse_index_number(const char *name) +{ + const char *p, *q; + int all_zero; + int index; + + p = name; + while (*p && !isdigit(*p)) + ++p; + if (!*p) + return -1; + all_zero = 1; + for (q = p; *q; ++q) { + if (!isdigit(*q)) + return -1; + if (*q != '0') + all_zero = 0; + } + if (all_zero) + return 0; + index = atoi(p); + if (index <= 0) + return -1; + return index; +} + +int get_mtd_index(void) +{ + FILE *f; + struct mntent *entry; + struct stat f_info; + struct stat curr_f_info; + int found; + int mtd_index = -1; + + if (stat(tests_file_system_mount_dir, &f_info) == -1) + return -1; + f = fopen("/proc/mounts", "rb"); + if (!f) + f = fopen("/etc/mtab", "rb"); + if (f == NULL) + return -1; + found = 0; + for (;;) { + entry = getmntent(f); + if (!entry) + break; + if (stat(entry->mnt_dir, &curr_f_info) == -1) + continue; + if (f_info.st_dev == curr_f_info.st_dev) { + int i; + + i = parse_index_number(entry->mnt_fsname); + if (i != -1) { + if (found && i != mtd_index) + return -1; + found = 1; + mtd_index = i; + } + } + } + fclose(f); + return mtd_index; +} + +int get_gcd_pid() +{ + struct gcd_pid *g; + int mtd_index; + + if (get_pid_list()) + return 0; + mtd_index = get_mtd_index(); + if (mtd_index == -1) + return 0; + for (g = gcd_pid_list; g; g = g->next) + if (g->mtd_index == mtd_index) + return g->pid; + return 0; +} + +void gcd_hupper(void) +{ + int64_t repeat; + int pid; + + pid = get_gcd_pid(); + CHECK(pid != 0); + repeat = tests_repeat_parameter; + for (;;) { + CHECK(kill(pid, SIGHUP) != -1); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + } +} + +/* Title of this test */ + +const char *gcd_hupper_get_title(void) +{ + return "Send HUP signals to gcd"; +} + +/* Description of this test */ + +const char *gcd_hupper_get_description(void) +{ + return + "Determine the PID of the gcd process. " \ + "Send it SIGHUP (may require root privileges). " \ + "If a sleep value is specified, the process sleeps. " \ + "If a repeat count is specified, then the task repeats " \ + "that number of times. " \ + "The repeat count is given by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 1. " + "Sleep is specified in milliseconds."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 1; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, gcd_hupper_get_title(), + gcd_hupper_get_description(), "np"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + gcd_hupper(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,40 @@ + +ifeq ($(origin CC),default) +CC = gcc +endif + +CFLAGS := $(CFLAGS) -Wall -g -O2 -I../../lib + +LDFLAGS := $(LDFLAGS) + +TARGETS = stress_1 \ + stress_2 \ + stress_3 \ + pdfrun \ + rndwrite00 \ + fwrite00 \ + rmdir00 \ + rndrm00 \ + rndrm99 \ + gcd_hupper + +all: $(TARGETS) + +$(TARGETS): ../../lib/tests.o + +../lib/tests.o: ../../lib/tests.h + +clean: + rm -f *.o $(TARGETS) run_pdf_test_file + +tests: all + ./stress_1 -e + ./stress_2 + ./stress_3 -e + ./pdfrun + ./rndwrite00 -e + ./fwrite00 + ./rmdir00 + ./rndrm00 + ./rndrm99 + ./gcd_hupper diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/pdfrun.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/pdfrun.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/pdfrun.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/pdfrun.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +void adjust_size(void) +{ + char dummy[1024]; + unsigned long total_memory; + FILE *f; + + total_memory = 0; + f = fopen("/proc/meminfo", "r"); + fscanf(f, "%s %lu", dummy, &total_memory); + fclose(f); + if (total_memory > 0 && tests_size_parameter > total_memory / 2) + tests_size_parameter = total_memory / 2; +} + +void run_pdf(void) +{ + int fd, i; + pid_t pid; + int64_t repeat; + ssize_t written; + int64_t remains; + size_t block; + char file_name[256]; + char buf[WRITE_BUFFER_SIZE]; + + if (tests_fs_is_currfs()) + return; + adjust_size(); + pid = getpid(); + tests_cat_pid(file_name, "run_pdf_test_file_", pid); + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + pid = getpid(); + srand(pid); + repeat = tests_repeat_parameter; + for (;;) { + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + remains = tests_size_parameter; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + } + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + CHECK(lseek(fd, 0, SEEK_SET) == 0); + } + CHECK(close(fd) != -1); + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *run_pdf_get_title(void) +{ + return "Create / overwrite a large file in the current directory"; +} + +/* Description of this test */ + +const char *run_pdf_get_description(void) +{ + return + "Create a file named run_pdf_test_file_pid, " \ + "where pid is the process id. The file is created " \ + "in the current directory, " \ + "if the current directory is NOT on the test " \ + "file system, otherwise no action is taken. " \ + "If a repeat count is specified, then the task repeats " \ + "that number of times. " \ + "The repeat count is given by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "The size is adjusted so that it is not more than " \ + "half the size of total memory."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, run_pdf_get_title(), + run_pdf_get_description(), "zn"); + if (!run_test) + return 1; + /* Do the actual test */ + run_pdf(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rmdir00.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rmdir00.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rmdir00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rmdir00.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +void rmdir00(void) +{ + int64_t repeat; + int64_t size, this_size; + pid_t pid; + char dir_name[256]; + + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "rmdir00_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + /* Repeat loop */ + repeat = tests_repeat_parameter; + size = 0; + for (;;) { + /* Remove everything in the directory */ + tests_clear_dir("."); + /* Fill with sub-dirs and small files */ + do { + this_size = tests_create_entry(NULL); + if (!this_size) + break; + size += this_size; + } while (this_size && + (tests_size_parameter == 0 || + size < tests_size_parameter)); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + } + /* Tidy up by removing everything */ + tests_clear_dir("."); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *rmdir00_get_title(void) +{ + return "Create and remove directories and files"; +} + +/* Description of this test */ + +const char *rmdir00_get_description(void) +{ + return + "Create a directory named rmdir00_test_dir_pid, where " \ + "pid is the process id. Within that directory, create " \ + "a number of sub-directories and small files. " \ + "The total size of all sub-directories and files " \ + "is specified by the size parameter. " \ + "The size parameter is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "A size of zero fills the file system until there is no " + "space left. " \ + "The task repeats, sleeping in between each iteration, " \ + "and then removing the sub-directories and files created " \ + "during the last iteration. " \ + "The repeat count is set by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " + "Sleep is specified in milliseconds."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, rmdir00_get_title(), + rmdir00_get_description(), "znp"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + rmdir00(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm00.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm00.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm00.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +void rndrm00(void) +{ + int64_t repeat; + int64_t size, this_size; + pid_t pid; + char dir_name[256]; + + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "rndrm00_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + /* Repeat loop */ + repeat = tests_repeat_parameter; + size = 0; + for (;;) { + /* Create and remove sub-dirs and small files, */ + /* but tending to grow */ + do { + if (tests_random_no(3)) { + this_size = tests_create_entry(NULL); + if (!this_size) + break; + size += this_size; + } else { + this_size = tests_remove_entry(); + size -= this_size; + if (size < 0) + size = 0; + if (!this_size) + this_size = 1; + } + } while (this_size && + (tests_size_parameter == 0 || + size < tests_size_parameter)); + /* Create and remove sub-dirs and small files, but */ + /* but tending to shrink */ + do { + if (!tests_random_no(3)) { + this_size = tests_create_entry(NULL); + size += this_size; + } else { + this_size = tests_remove_entry(); + size -= this_size; + if (size < 0) + size = 0; + } + } while ((tests_size_parameter != 0 && + size > tests_size_parameter / 10) || + (tests_size_parameter == 0 && size > 100000)); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + } + /* Tidy up by removing everything */ + tests_clear_dir("."); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); +} + +/* Title of this test */ + +const char *rndrm00_get_title(void) +{ + return "Randomly create and remove directories and files"; +} + +/* Description of this test */ + +const char *rndrm00_get_description(void) +{ + return + "Create a directory named rndrm00_test_dir_pid, where " \ + "pid is the process id. Within that directory, " \ + "randomly create and remove " \ + "a number of sub-directories and small files, " \ + "but do more creates than removes. " \ + "When the total size of all sub-directories and files " \ + "is greater than the size specified by the size parameter, " \ + "start to do more removes than creates. " \ + "The size parameter is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "A size of zero fills the file system until there is no " + "space left. " \ + "The task repeats, sleeping in between each iteration. " \ + "The repeat count is set by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " + "Sleep is specified in milliseconds."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, rndrm00_get_title(), + rndrm00_get_description(), "znp"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + rndrm00(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm99.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm99.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm99.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndrm99.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +uint32_t files_created = 0; +uint32_t files_removed = 0; +uint32_t dirs_created = 0; +uint32_t dirs_removed = 0; +int64_t *size_ptr = 0; + +void display_stats(void) +{ + printf( "\nrndrm99 stats:\n" + "\tNumber of files created = %u\n" + "\tNumber of files deleted = %u\n" + "\tNumber of directories created = %u\n" + "\tNumber of directories deleted = %u\n" + "\tCurrent net size of creates and deletes = %lld\n", + (unsigned) files_created, + (unsigned) files_removed, + (unsigned) dirs_created, + (unsigned) dirs_removed, + (long long) (size_ptr ? *size_ptr : 0)); + fflush(stdout); +} + +struct timeval tv_before; +struct timeval tv_after; + +void before(void) +{ + CHECK(gettimeofday(&tv_before, NULL) != -1); +} + +void after(const char *msg) +{ + time_t diff; + CHECK(gettimeofday(&tv_after, NULL) != -1); + diff = tv_after.tv_sec - tv_before.tv_sec; + if (diff >= 8) { + printf("\nrndrm99: the following fn took more than 8 seconds: %s (took %u secs)\n",msg,(unsigned) diff); + fflush(stdout); + display_stats(); + } +} + +#define WRITE_BUFFER_SIZE 32768 + +static char write_buffer[WRITE_BUFFER_SIZE]; + +static void init_write_buffer() +{ + static int init = 0; + + if (!init) { + int i, d; + uint64_t u; + + u = RAND_MAX; + u += 1; + u /= 256; + d = (int) u; + srand(1); + for (i = 0; i < WRITE_BUFFER_SIZE; ++i) + write_buffer[i] = rand() / d; + init = 1; + } +} + +/* Write size random bytes into file descriptor fd at the current position, + returning the number of bytes actually written */ +uint64_t fill_file(int fd, uint64_t size) +{ + ssize_t written; + size_t sz; + unsigned start = 0, length; + uint64_t remains; + uint64_t actual_size = 0; + + init_write_buffer(); + remains = size; + while (remains > 0) { + length = WRITE_BUFFER_SIZE - start; + if (remains > length) + sz = length; + else + sz = (size_t) remains; + before(); + written = write(fd, write_buffer + start, sz); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + after("write"); + fprintf(stderr,"\nrndrm99: write failed with ENOSPC\n");fflush(stderr); + display_stats(); + break; + } + after("write"); + remains -= written; + actual_size += written; + if ((size_t) written == sz) + start = 0; + else + start += written; + } + return actual_size; +} + +/* Create a file of size file_size */ +uint64_t create_file(const char *file_name, uint64_t file_size) +{ + int fd; + int flags; + mode_t mode; + uint64_t actual_size; /* Less than size if the file system is full */ + + flags = O_CREAT | O_TRUNC | O_WRONLY; + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + before(); + fd = open(file_name, flags, mode); + if (fd == -1 && errno == ENOSPC) { + errno = 0; + after("open"); + fprintf(stderr,"\nrndrm99: open failed with ENOSPC\n");fflush(stderr); + display_stats(); + return 0; /* File system full */ + } + CHECK(fd != -1); + after("open"); + actual_size = fill_file(fd, file_size); + before(); + CHECK(close(fd) != -1); + after("close"); + if (file_size != 0 && actual_size == 0) { + printf("\nrndrm99: unlinking zero size file\n");fflush(stdout); + before(); + CHECK(unlink(file_name) != -1); + after("unlink (create_file)"); + } + return actual_size; +} + +/* Create an empty sub-directory or small file in the current directory */ +int64_t create_entry(char *return_name) +{ + int fd; + char name[256]; + int64_t res; + + for (;;) { + sprintf(name, "%u", (unsigned) tests_random_no(10000000)); + before(); + fd = open(name, O_RDONLY); + after("open (create_entry)"); + if (fd == -1) + break; + before(); + close(fd); + after("close (create_entry)"); + } + if (return_name) + strcpy(return_name, name); + if (tests_random_no(2)) { + res = create_file(name, tests_random_no(4096)); + if (res > 0) + files_created += 1; + return res; + } else { + before(); + if (mkdir(name, 0777) == -1) { + CHECK(errno == ENOSPC); + after("mkdir"); + errno = 0; + fprintf(stderr,"\nrndrm99: mkdir failed with ENOSPC\n");fflush(stderr); + display_stats(); + return 0; + } + after("mkdir"); + dirs_created += 1; + return TESTS_EMPTY_DIR_SIZE; + } +} + +/* Remove a random file of empty sub-directory from the current directory */ +int64_t remove_entry(void) +{ + DIR *dir; + struct dirent *entry; + unsigned count = 0, pos; + int64_t result = 0; + + before(); + dir = opendir("."); + CHECK(dir != NULL); + after("opendir"); + for (;;) { + errno = 0; + before(); + entry = readdir(dir); + if (entry) { + after("readdir 1"); + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) + ++count; + } else { + CHECK(errno == 0); + after("readdir 1"); + break; + } + } + pos = tests_random_no(count); + count = 0; + before(); + rewinddir(dir); + after("rewinddir"); + for (;;) { + errno = 0; + before(); + entry = readdir(dir); + if (!entry) { + CHECK(errno == 0); + after("readdir 2"); + break; + } + after("readdir 2"); + if (strcmp(".",entry->d_name) != 0 && + strcmp("..",entry->d_name) != 0) { + if (count == pos) { + if (entry->d_type == DT_DIR) { + before(); + tests_clear_dir(entry->d_name); + after("tests_clear_dir"); + before(); + CHECK(rmdir(entry->d_name) != -1); + after("rmdir"); + result = TESTS_EMPTY_DIR_SIZE; + dirs_removed += 1; + } else { + struct stat st; + before(); + CHECK(stat(entry->d_name, &st) != -1); + after("stat"); + result = st.st_size; + before(); + CHECK(unlink(entry->d_name) != -1); + after("unlink"); + files_removed += 1; + } + } + ++count; + } + } + before(); + CHECK(closedir(dir) != -1); + after("closedir"); + return result; +} + +void rndrm99(void) +{ + int64_t repeat, loop_cnt; + int64_t size, this_size; + pid_t pid; + char dir_name[256]; + + size_ptr = &size; + /* Create a directory to test in */ + pid = getpid(); + tests_cat_pid(dir_name, "rndrm99_test_dir_", pid); + if (chdir(dir_name) == -1) + CHECK(mkdir(dir_name, 0777) != -1); + CHECK(chdir(dir_name) != -1); + /* Repeat loop */ + repeat = tests_repeat_parameter; + size = 0; + for (;;) { + /* Create and remove sub-dirs and small files, */ + /* but tending to grow */ + printf("\nrndrm99: growing\n");fflush(stdout); + loop_cnt = 0; + do { + if (loop_cnt++ % 2000 == 0) + display_stats(); + if (tests_random_no(3)) { + this_size = create_entry(NULL); + if (!this_size) + break; + size += this_size; + } else { + this_size = remove_entry(); + size -= this_size; + if (size < 0) + size = 0; + if (!this_size) + this_size = 1; + } + } while (this_size && + (tests_size_parameter == 0 || + size < tests_size_parameter)); + /* Create and remove sub-dirs and small files, but */ + /* but tending to shrink */ + printf("\nrndrm99: shrinking\n");fflush(stdout); + loop_cnt = 0; + do { + if (loop_cnt++ % 2000 == 0) + display_stats(); + if (!tests_random_no(3)) { + this_size = create_entry(NULL); + size += this_size; + } else { + this_size = remove_entry(); + size -= this_size; + if (size < 0) + size = 0; + } + } while ((tests_size_parameter != 0 && + size > tests_size_parameter / 10) || + (tests_size_parameter == 0 && size > 100000)); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + printf("\nrndrm99: sleeping\n");fflush(stdout); + usleep(s); + } + } + printf("\nrndrm99: tidying\n");fflush(stdout); + display_stats(); + /* Tidy up by removing everything */ + tests_clear_dir("."); + CHECK(chdir("..") != -1); + CHECK(rmdir(dir_name) != -1); + size_ptr = 0; +} + +/* Title of this test */ + +const char *rndrm99_get_title(void) +{ + return "Randomly create and remove directories and files"; +} + +/* Description of this test */ + +const char *rndrm99_get_description(void) +{ + return + "Create a directory named rndrm99_test_dir_pid, where " \ + "pid is the process id. Within that directory, " \ + "randomly create and remove " \ + "a number of sub-directories and small files, " \ + "but do more creates than removes. " \ + "When the total size of all sub-directories and files " \ + "is greater than the size specified by the size parameter, " \ + "start to do more removes than creates. " \ + "The size parameter is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "A size of zero fills the file system until there is no " + "space left. " \ + "The task repeats, sleeping in between each iteration. " \ + "The repeat count is set by the -n or --repeat option, " \ + "otherwise it defaults to 1. " \ + "A repeat count of zero repeats forever. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " + "Sleep is specified in milliseconds."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 1; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, rndrm99_get_title(), + rndrm99_get_description(), "znp"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + rndrm99(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndwrite00.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndwrite00.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndwrite00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/rndwrite00.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define BLOCK_SIZE 32768 +#define BUFFER_SIZE 32768 + +static void check_file(int fd, char *data, size_t length) +{ + size_t n, i; + char buf[BUFFER_SIZE]; + + CHECK(lseek(fd, 0, SEEK_SET) != -1); + n = 0; + for (;;) { + i = read(fd, buf, BUFFER_SIZE); + CHECK(i >= 0); + if (i == 0) + break; + CHECK(memcmp(buf, data + n, i) == 0); + n += i; + } + CHECK(n == length); +} + +void rndwrite00(void) +{ + int fd; + pid_t pid; + ssize_t written; + size_t remains; + size_t block; + size_t actual_size; + size_t check_every; + char *data, *p, *q; + off_t offset; + size_t size; + int64_t repeat; + char file_name[256]; + char buf[4096]; + + /* Create file */ + pid = getpid(); + tests_cat_pid(file_name, "rndwrite00_test_file_", pid); + fd = open(file_name, O_CREAT | O_RDWR | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + /* Allocate memory to hold file data */ + CHECK(tests_size_parameter > 0); + CHECK(tests_size_parameter <= SIZE_MAX); + data = (char *) malloc(tests_size_parameter); + CHECK(data != NULL); + /* Fill with random data */ + srand(pid); + for (p = data, q = data + tests_size_parameter; p != q; ++p) + *p = rand(); + /* Write to file */ + p = data; + remains = tests_size_parameter; + while (remains > 0) { + if (remains > BLOCK_SIZE) + block = BLOCK_SIZE; + else + block = remains; + written = write(fd, p, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + p += written; + } + actual_size = p - data; + /* Repeating bit */ + repeat = tests_repeat_parameter; + check_every = actual_size / 8192; + for (;;) { + offset = tests_random_no(actual_size); + size = tests_random_no(4096); + /* Don't change the file size */ + if (offset + size > actual_size) + size = actual_size - offset; + if (!size) + continue; + for (p = buf, q = p + size; p != q; ++p) + *p = rand(); + CHECK(lseek(fd, offset, SEEK_SET) != -1); + written = write(fd, buf, size); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + } else + memcpy(data + offset, buf, written); + /* Break if repeat count exceeded */ + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + if (repeat % check_every == 0) + check_file(fd, data, actual_size); + /* Sleep */ + if (tests_sleep_parameter > 0) { + unsigned us = tests_sleep_parameter * 1000; + unsigned rand_divisor = RAND_MAX / us; + unsigned s = (us / 2) + (rand() / rand_divisor); + usleep(s); + } + } + /* Check and close file */ + check_file(fd, data, actual_size); + CHECK(close(fd) != -1); + if (tests_delete_flag) + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *rndwrite00_get_title(void) +{ + return "Randomly write a large test file"; +} + +/* Description of this test */ + +const char *rndwrite00_get_description(void) +{ + return + "Create a file named rndwrite00_test_file_pid, where " \ + "pid is the process id. " \ + "The file is filled with random data. " \ + "The size of the file is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "Then a randomly sized block of random data is written at a " \ + "random location in the file. "\ + "The block size is always in the range 1 to 4095. " \ + "If a sleep value is specified, the process sleeps. " \ + "The number of writes is given by the repeat count. " \ + "The repeat count is set by the -n or --repeat option, " \ + "otherwise it defaults to 10000. " \ + "A repeat count of zero repeats forever. " \ + "The sleep value is given by the -p or --sleep option, " \ + "otherwise it defaults to 0. " + "Sleep is specified in milliseconds. " \ + "Periodically the data in the file is checked with a copy " \ + "held in memory. " \ + "If the delete option is specified the file is finally " \ + "deleted."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 10000; + + /* Set default test sleep */ + tests_sleep_parameter = 0; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, rndwrite00_get_title(), + rndwrite00_get_description(), "zne"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + rndwrite00(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_1.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_1.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_1.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +void stress_1(void) +{ + int fd, i; + pid_t pid; + ssize_t written; + int64_t remains; + size_t block; + char file_name[256]; + char buf[WRITE_BUFFER_SIZE]; + + pid = getpid(); + tests_cat_pid(file_name, "stress_1_test_file_", pid); + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + srand(pid); + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + remains = tests_size_parameter; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + } + CHECK(close(fd) != -1); + if (tests_delete_flag) + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *stress_1_get_title(void) +{ + return "Create / overwrite a large file"; +} + +/* Description of this test */ + +const char *stress_1_get_description(void) +{ + return + "Create a file named stress_1_test_file_pid, " \ + "where pid is the process id. " \ + "The size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "The file will be deleted if the delete option " \ + "is specified. "; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, stress_1_get_title(), + stress_1_get_description(), "ze"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + stress_1(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_2.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_2.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_2.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_2.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +void stress_2(void) +{ + int fd, i; + pid_t pid; + ssize_t written; + int64_t remains; + int64_t repeat; + size_t block; + char *file_name; + char buf[WRITE_BUFFER_SIZE]; + + file_name = "stress_2_test_file"; + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + CHECK(unlink(file_name) != -1); + pid = getpid(); + srand(pid); + repeat = tests_repeat_parameter; + for (;;) { + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + CHECK(lseek(fd, 0, SEEK_SET) != -1); + remains = tests_size_parameter; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + } + if (tests_repeat_parameter > 0 && --repeat <= 0) + break; + } + CHECK(close(fd) != -1); +} + +/* Title of this test */ + +const char *stress_2_get_title(void) +{ + return "Create / overwrite a large deleted file"; +} + +/* Description of this test */ + +const char *stress_2_get_description(void) +{ + return + "Create a file named stress_2_test_file. " \ + "Open it, delete it while holding the open file descriptor, " \ + "then fill it with random data. " \ + "Repeated re-write the file some number of times. " \ + "The repeat count is given by the -n or --repeat option, " \ + "otherwise it defaults to 10. " \ + "The file size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Set default test repetition */ + tests_repeat_parameter = 10; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, stress_2_get_title(), + stress_2_get_description(), "zn"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + stress_2(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_3.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_3.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_3.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/atoms/stress_3.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tests.h" + +#define WRITE_BUFFER_SIZE 32768 + +void stress_3(void) +{ + int fd, i; + pid_t pid; + ssize_t written; + int64_t remains; + size_t block; + char file_name[256]; + char buf[WRITE_BUFFER_SIZE]; + + pid = getpid(); + tests_cat_pid(file_name, "stress_3_test_file_", pid); + fd = open(file_name, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + CHECK(fd != -1); + pid = getpid(); + srand(pid); + for (i = 0; i < WRITE_BUFFER_SIZE;++i) + buf[i] = rand(); + CHECK(lseek(fd, tests_size_parameter, SEEK_SET) != -1); + CHECK(write(fd, "!", 1) == 1); + CHECK(lseek(fd, 0, SEEK_SET) != -1); + remains = tests_size_parameter; + while (remains > 0) { + if (remains > WRITE_BUFFER_SIZE) + block = WRITE_BUFFER_SIZE; + else + block = remains; + written = write(fd, buf, block); + if (written <= 0) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + break; + } + remains -= written; + } + if (ftruncate(fd, 0) == -1) { + CHECK(errno == ENOSPC); /* File system full */ + errno = 0; + } + CHECK(close(fd) != -1); + if (tests_delete_flag) + CHECK(unlink(file_name) != -1); +} + +/* Title of this test */ + +const char *stress_3_get_title(void) +{ + return "Create a file with a large hole and fill it"; +} + +/* Description of this test */ + +const char *stress_3_get_description(void) +{ + return + "Create a file named stress_3_test_file_pid, " \ + "where pid is the process id. " \ + "Write a single character past the end of the file, " \ + "based on the specified file size, " \ + "which creates a hole in the file. " + "Fill the hole with random data. " \ + "Then truncate the file length to zero. " \ + "The size is given by the -z or --size option, " \ + "otherwise it defaults to 1000000. " \ + "The file will be deleted if the delete option " \ + "is specified."; +} + +int main(int argc, char *argv[]) +{ + int run_test; + + /* Set default test file size */ + tests_size_parameter = 1000000; + + /* Handle common arguments */ + run_test = tests_get_args(argc, argv, stress_3_get_title(), + stress_3_get_description(), "ze"); + if (!run_test) + return 1; + /* Change directory to the file system and check it is ok for testing */ + tests_check_test_file_system(); + /* Do the actual test */ + stress_3(); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/Makefile 2010-03-03 19:04:32.000000000 -0800 @@ -0,0 +1,11 @@ + +SUBDIRS = atoms + +all tests: $(SUBDIRS) + +clean: $(SUBDIRS) + rm -rf run_pdf_test_file_* + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress00.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress00.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress00.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress00.sh 2010-03-03 19:04:32.000000000 -0800 @@ -0,0 +1,52 @@ +#!/bin/sh + +TEST_DIR=$TEST_FILE_SYSTEM_MOUNT_DIR +if test -z "$TEST_DIR"; +then + TEST_DIR="/mnt/test_file_system" +fi + +FREESPACE=`../utils/free_space "$TEST_DIR"` + +if test -z "$FREESPACE"; +then + echo "Failed to determine free space" + exit 1 +fi + +if test -n "$1"; +then + DURATION="-d$1"; +else + DURATION=""; +fi + +FWRITE00=atoms/fwrite00 +RNDWR=atoms/rndwrite00 +GCHUP=atoms/gcd_hupper +PDFLUSH=atoms/pdfrun +FSIZE=$(( $FREESPACE/15 )); + +../utils/fstest_monitor $DURATION \ +"$FWRITE00 -z $FSIZE -n0 -p 20" \ +"$FWRITE00 -z $FSIZE -n0 -p 10 -s" \ +"$FWRITE00 -z $FSIZE -n0 -p 20 -u" \ +"$FWRITE00 -z $FSIZE -n0 -p 70 -o" \ +"$FWRITE00 -z $FSIZE -n0 -p 15 -s -o -u" \ +"$FWRITE00 -z $FSIZE -n0 -p 10 -u -c" \ +"$FWRITE00 -z $FSIZE -n0 -p 10 -u -o -c" \ +"$FWRITE00 -z $FSIZE -n0 -p 10 -o -c" \ +"$FWRITE00 -z $FSIZE -n0 -p 100 -o -u" \ +"$FWRITE00 -z $FSIZE -n0 -p 100 -s -o -u -c" \ +"$FWRITE00 -z $FSIZE -n0 -p 100 -o -u" \ +"$FWRITE00 -z $FSIZE -n0 -p 100 -u" \ +"$FWRITE00 -z $FSIZE -n0 -p 100 -s -o" \ +"$RNDWR -z $FSIZE -n0 -p 10 -e" \ +"$RNDWR -z $FSIZE -n0 -p 100 -e" \ +"$PDFLUSH -z 1073741824 -n0" + +STATUS=$? + +rm -rf ${TEST_DIR}/* + +exit $STATUS diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress01.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress01.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress01.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/stress/stress01.sh 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,40 @@ +#!/bin/sh + +TEST_DIR=$TEST_FILE_SYSTEM_MOUNT_DIR +if test -z "$TEST_DIR"; +then + TEST_DIR="/mnt/test_file_system" +fi + +FREESPACE=`../utils/free_space "$TEST_DIR"` + +if test -z "$FREESPACE"; +then + echo "Failed to determine free space" + exit 1 +fi + +if test -n "$1"; +then + DURATION="-d$1"; +else + DURATION=""; +fi + +FWRITE00=atoms/fwrite00 +RNDWR=atoms/rndwrite00 +PDFLUSH=atoms/pdfrun +FSIZE=$(( $FREESPACE/15 )); + +../utils/fstest_monitor $DURATION \ +"$FWRITE00 -z $FSIZE -n0 -p 300" \ +"$FWRITE00 -z $FSIZE -n0 -u" \ +"$FWRITE00 -z $FSIZE -n0 -u -c" \ +"$FWRITE00 -z $FSIZE -n0 -s -o" \ +"$RNDWR -z $FSIZE -n0 -e" + +STATUS=$? + +rm -rf ${TEST_DIR}/* + +exit $STATUS diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/free_space.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/free_space.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/free_space.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/free_space.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + char *dir_name = "."; + uint64_t free_space; + struct statvfs fs_info; + + if (argc > 1) { + if (strncmp(argv[1], "--help", 6) == 0 || + strncmp(argv[1], "-h", 2) == 0) { + printf( "Usage is: " + "free_space [directory]\n" + "\n" + "Display the free space of the file system " + "of the directory given\n" + "or the current directory if no " + "directory is given.\nThe value output is " + "in bytes.\n" + ); + return 1; + } + dir_name = argv[1]; + } + if (statvfs(dir_name, &fs_info) == -1) + return 1; + + free_space = (uint64_t) fs_info.f_bavail * (uint64_t) fs_info.f_frsize; + + printf("%llu\n", (unsigned long long) free_space); + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/fstest_monitor.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/fstest_monitor.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/fstest_monitor.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/fstest_monitor.c 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct child_info { + struct child_info *next; + pid_t pid; + int terminated; + int killed; + int gone; +}; + +struct child_info *children = 0; + +void kill_children(void) +{ + struct child_info *child; + + child = children; + while (child) { + if (!child->gone) { + if (!child->terminated) { + child->terminated = 1; + kill(child->pid, SIGTERM); + } /*else if (!child->killed) { + child->killed = 1; + kill(child->pid, SIGKILL); + }*/ + } + child = child->next; + } +} + +void add_child(pid_t child_pid) +{ + struct child_info *child; + size_t sz; + + sz = sizeof(struct child_info); + child = (struct child_info *) malloc(sz); + memset(child, 0, sz); + child->pid = child_pid; + child->next = children; + children = child; +} + +void mark_child_gone(pid_t child_pid) +{ + struct child_info *child; + + child = children; + while (child) { + if (child->pid == child_pid) { + child->gone = 1; + break; + } + child = child->next; + } +} + +int have_children(void) +{ + struct child_info *child; + + child = children; + while (child) { + if (!child->gone) + return 1; + child = child->next; + } + return 0; +} + +int parse_command_line(char *cmdline, int *pargc, char ***pargv) +{ + char **tmp; + char *p, *v, *q; + size_t sz; + int argc = 0; + int state = 0; + char *argv[1024]; + + if (!cmdline) + return 1; + q = v = (char *) malloc(strlen(cmdline) + 1024); + if (!v) + return 1; + p = cmdline; + for (;;) { + char c = *p++; + if (!c) { + *v++ = 0; + break; + } + switch (state) { + case 0: /* Between args */ + if (isspace(c)) + break; + argv[argc++] = v; + if (c == '"') { + state = 2; + break; + } else if (c == '\'') { + state = 3; + break; + } + state = 1; + case 1: /* Not quoted */ + if (c == '\\') { + if (*p) + *v++ = *p; + } else if (isspace(c)) { + *v++ = 0; + state = 0; + } else + *v++ = c; + break; + case 2: /* Double quoted */ + if (c == '\\' && *p == '"') { + *v++ = '"'; + ++p; + } else if (c == '"') { + *v++ = 0; + state = 0; + } else + *v++ = c; + break; + case 3: /* Single quoted */ + if (c == '\'') { + *v++ = 0; + state = 0; + } else + *v++ = c; + break; + } + } + argv[argc] = 0; + sz = sizeof(char *) * (argc + 1); + tmp = (char **) malloc(sz); + if (!tmp) { + free(q); + return 1; + } + if (argc == 0) + free(q); + memcpy(tmp, argv, sz); + *pargc = argc; + *pargv = tmp; + return 0; +} + +void signal_handler(int signum) +{ + kill_children(); +} + +int result = 0; +int alarm_gone_off = 0; + +void alarm_handler(int signum) +{ + if (!result) + alarm_gone_off = 1; + kill_children(); +} + +int main(int argc, char *argv[], char **env) +{ + int p; + pid_t child_pid; + int status; + int duration = 0; + + p = 1; + if (argc > 1) { + if (strncmp(argv[p], "--help", 6) == 0 || + strncmp(argv[p], "-h", 2) == 0) { + printf( "Usage is: " + "fstest_monitor options programs...\n" + " Options are:\n" + " -h, --help " + "This help message\n" + " -d, --duration arg " + "Stop after arg seconds\n" + "\n" + "Run programs and wait for them." + " If duration is specified,\n" + "kill all programs" + " after that number of seconds have elapsed.\n" + "Example: " + "fstest_monitor \"/bin/ls -l\" /bin/date\n" + ); + return 1; + } + if (strncmp(argv[p], "--duration", 10) == 0 || + strncmp(argv[p], "-d", 2) == 0) { + char *s; + if (p+1 < argc && !isdigit(argv[p][strlen(argv[p])-1])) + ++p; + s = argv[p]; + while (*s && !isdigit(*s)) + ++s; + duration = atoi(s); + ++p; + } + } + + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + for (; p < argc; ++p) { + child_pid = fork(); + if (child_pid) { + /* Parent */ + if (child_pid == (pid_t) -1) { + kill_children(); + result = 1; + break; + } + add_child(child_pid); + } else { + /* Child */ + int cargc; + char **cargv; + + if (parse_command_line(argv[p], &cargc, &cargv)) + return 1; + execve(cargv[0], cargv, env); + return 1; + } + } + if (!result && duration > 0) { + signal(SIGALRM, alarm_handler); + alarm(duration); + } + while (have_children()) { + status = 0; + child_pid = wait(&status); + if (child_pid == (pid_t) -1) { + if (errno == EINTR) + continue; + kill_children(); + return 1; + } + mark_child_gone(child_pid); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + result = 1; + kill_children(); + } + } + + if (alarm_gone_off) + return 0; + + return result; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/fs-tests/utils/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/fs-tests/utils/Makefile 2010-03-03 19:04:31.000000000 -0800 @@ -0,0 +1,19 @@ + +ifeq ($(origin CC),default) +CC = gcc +endif + +CFLAGS := $(CFLAGS) -Wall -g -O2 -I../lib + +LDFLAGS := $(LDFLAGS) + +TARGETS = fstest_monitor free_space + +all: $(TARGETS) + +clean: + rm -f *.o $(TARGETS) + +tests: all + ./fstest_monitor + ./free_space > /dev/null diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/COPYING linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/COPYING --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/COPYING 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/COPYING 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/filljffs2.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/filljffs2.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/filljffs2.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/filljffs2.sh 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,16 @@ +#!/bin/bash + +# Pass following cmd line: +# 1st - file to copy +# 2nd - file to copy to +# 3rd - time to sleep between copies + +while [ $(( 1 )) -gt $(( 0 )) ] +do + cp $1 $2 + rm $2 + df |grep mtd > /dev/console + echo "sleeping $3" + sleep $3 +done + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/JitterTest.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/JitterTest.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/JitterTest.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/JitterTest.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,1044 @@ +/*********************************************************************** + * + * Copyright: Daniel Measurement and Control, Inc. + * 9753 Pine Lake Drive + * Houston, TX 77055 + * + * Created by: Vipin Malik and Gail Murray + * Released under GPL by permission of Daniel Industries. + * + * This software is licensed under the GPL version 2. Plese see the file + * COPYING for details on the license. + * + * NO WARRANTY: Absolutely no claims of warranty or fitness of purpose + * are made in this software. Please use at your own risk. + * + * Filename: JitterTest.c + * + * Description: Program to be used to measure wake jitter. + * See README file for more info. + * + * + * Revision History: + * $Id: JitterTest.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + * $Log: not supported by cvs2svn $ + * Revision 1.13 2005/11/07 11:15:20 gleixner + * [MTD / JFFS2] Clean up trailing white spaces + * + * Revision 1.12 2001/08/10 19:23:11 vipin + * Ready to be released under GPL! Added proper headers etc. + * + * Revision 1.11 2001/07/09 15:35:50 vipin + * Couple of new features:1. The program runs by default as a "regular" + * (SCHED_OTHER) task by default, unless the -p n cmd line parameter is + * specified. It then runs as SCHED_RR at that priority. + * 2. Added ability to send SIGSTOP/SIGCONT to a specified PID. This + * would presumably be the PID of the JFFS2 GC task. SIGSTOP is sent + * before writing to the fs, and a SIGCONT after the write is done. + * 3. The "pad" data now written to the file on the "fs under test" is + * random, not sequential as previously. + * + * Revision 1.10 2001/06/27 19:14:24 vipin + * Now console file to log at can be specified from cmd line. This can enable + * you to run two instances of the program- one logging to the /dev/console + * and another to a regular file (if you want the data) or /dev/null if you don't. + * + * Revision 1.9 2001/06/25 20:21:31 vipin + * This is the latest version, NOT the one last checked in! + * + * Revision 1.7 2001/06/18 22:36:19 vipin + * Fix minor typo that excluded '\n' from msg on console. + * + * Revision 1.6 2001/06/18 21:17:50 vipin + * Added option to specify the amount of data written to outfile each period. + * The regular info is written, but is then padded to the requested size. + * This will enable testing of different sized writes to JFFS fs. + * + * Revision 1.5 2001/06/08 19:36:23 vipin + * All write() are now checked for return err code. + * + * Revision 1.4 2001/06/06 23:10:31 vipin + * Added README file. + * In JitterTest.c: Changed operation of periodic timer to one shot. The timer is now + * reset when the task wakes. This way every "jitter" is from the last time and + * jitters from previous times are not accumulated and screw aroud with our display. + * + * All jitter is now +ve. (as it should be). Also added a "read file" functionality + * to test for jitter in task if we have to read from JFFS fs. + * The program now also prints data to console- where it can be logged, interspersed with + * other "interesting" printk's from the kernel and drivers (flash sector erases etc.) + * + * Revision 1.3 2001/03/01 19:20:39 gmurray + * Add priority scheduling. Shortened name of default output file. + * Changed default interrupt period. Output delta time and jitter + * instead of time of day. + * + * Revision 1.2 2001/02/28 16:20:19 vipin + * Added version control Id and log fields. + * + ***********************************************************************/ +/*************************** Included Files ***************************/ +#include /* fopen, printf, fprintf, fclose */ +#include /* strcpy, strcmp */ +#include /* exit, atol, atoi */ +#include /* setitimer, settimeofday, gettimeofday */ +#include /* signal */ +#include /* sched_setscheduler, sched_get_priority_min,*/ +/* sched_get_priority_max */ +#include /* gettimeofday, sleep */ +#include +#include +#include +#include + + + +/**************************** Enumerations ****************************/ +enum timerActions + { + ONESHOT, + AUTORESETTING + }; + + + +/****************************** Constants *****************************/ +/* Exit error codes */ +#define EXIT_FILE_OPEN_ERR (1) /* error opening output file*/ +#define EXIT_REG_SIGALRM_ERR (2) /* error registering SIGALRM*/ +#define EXIT_REG_SIGINT_ERR (3) /* error registering SIGINT */ +#define EXIT_INV_INT_PERIOD (4) /* error invalid int. period*/ +#define EXIT_MIN_PRIORITY_ERR (5) /* error, minimum priority */ +#define EXIT_MAX_PRIORITY_ERR (6) /* error, maximum priority */ +#define EXIT_INV_SCHED_PRIORITY (7) /* error, invalid priority */ +#define EXIT_SET_SCHEDULER_ERR (8) /* error, set scheduler */ +#define EXIT_PREV_TIME_OF_DAY_ERR (9) /* error, init. prev. */ +/* time of day */ + +#define MAX_FILE_NAME_LEN (32) /* maximum file name length */ + +#define STRINGS_EQUAL ((int) 0) /* strcmp value if equal */ + +#define MIN_INT_PERIOD_MILLISEC ( 5L) /* minimum interrupt period */ +#define MAX_INT_PERIOD_MILLISEC (5000L) /* maximum interrupt period */ +#define DEF_INT_PERIOD_MILLISEC ( 10L) /* default interrupt period */ + +#define READ_FILE_MESSAGE "This is a junk file. Must contain at least 1 byte though!\n" + +/* The user can specify that the program pad out the write file to + a given number of bytes. But a minimum number needs to be written. This + will contain the jitter info. +*/ +#define MIN_WRITE_BYTES 30 +#define DEFAULT_WRITE_BYTES 30 +#define MAX_WRITE_BYTES 4096 + +/* used for gen a printable ascii random # between spc and '~' */ +#define MIN_ASCII 32 /* can be char*/ +#define MAX_ASCII 126.0 /* needs to be float. See man rand() */ + +/*---------------------------------------------------------------------- + * It appears that the preprocessor can't handle multi-line #if + * statements. Thus, the check on the default is divided into two + * #if statements. + *---------------------------------------------------------------------*/ +#if (DEF_INT_PERIOD_MILLISEC < MIN_INT_PERIOD_MILLISEC) +#error *** Invalid default interrupt period. *** +#endif + +#if (DEF_INT_PERIOD_MILLISEC > MAX_INT_PERIOD_MILLISEC) +#error *** Invalid default interrupt period. *** +#endif + + +#define TRUE 1 /* Boolean true value */ +#define FALSE 0 + +/* Time conversion constants. */ +#define MILLISEC_PER_SEC (1000L) /* milliseconds per second */ +#define MICROSEC_PER_MILLISEC (1000L) /* microsecs per millisec */ +#define MICROSEC_PER_SEC (1000000L) /* microsecs per second */ + +#define PRIORITY_POLICY ((int) SCHED_RR) /* If specified iwth "-p" */ + + + +/************************** Module Variables **************************/ +/* version identifier (value supplied by CVS)*/ +static const char Version[] = "$Id: JitterTest.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $"; + +static char OutFileName[MAX_FILE_NAME_LEN+1]; /* output file name */ +static char LogFile[MAX_FILE_NAME_LEN+1] = "/dev/console"; /* default */ +static char ReadFile[MAX_FILE_NAME_LEN+1]; /* This file is read. Should + contain at least 1 byte */ + +static int WriteBytes = DEFAULT_WRITE_BYTES; /* pad out file to these many bytes. */ +static int Fd1; /* fd where the above buffer if o/p */ +static int Cfd; /* fd to console (or file specified) */ +static int Fd2; /* fd for the ReadFile */ +static int DoRead = FALSE; /* should we attempt to ReadFile?*/ +static long InterruptPeriodMilliSec; /* interrupt period, millisec */ +static int MinPriority; /* minimum scheduler priority */ +static int MaxPriority; /* maximum scheduler priority */ +static int RequestedPriority; /* requested priority */ +static struct itimerval ITimer; /* interrupt timer structure */ +static struct timeval PrevTimeVal; /* previous time structure */ +static struct timeval CurrTimeVal; /* current time structure */ +static long LastMaxDiff = 0; /* keeps track of worst jitter encountered */ + +static int GrabKProfile = FALSE; /* To help determine system bottle necks + this parameter can be set. This causes + the /proc/profile file to be read and + stored in unique filenames in current + dir, and indication to be o/p on the + /dev/console also. + */ +static long ProfileTriggerMSecs = 15000l; /* Jitter time in seconds that triggers + a snapshot of the profile to be taken + + */ +static int SignalGCTask = FALSE; /* should be signal SIGSTOP/SIGCONT to gc task?*/ +static int GCTaskPID; + +static int RunAsRTTask = FALSE; /* default action unless priority is + specified on cmd line */ + + +/********************* Local Function Prototypes **********************/ +void HandleCmdLineArgs(int argc, char *argv[]); +void SetFileName(char * pFileName); +void SetInterruptPeriod(char * pASCIIInterruptPeriodMilliSec); +void SetSchedulerPriority(char * pASCIISchedulerPriority); + +void PrintVersionInfo(void); +void PrintHelpInfo(void); + +int Write(int fd, void *buf, size_t bytes, int lineNo); + +void InitITimer(struct itimerval * pITimer, int action); + +/* For catching timer interrupts (SIGALRM). */ +void AlarmHandler(int sigNum); + +/* For catching Ctrl+C SIGINT. */ +void SignalHandler(int sigNum); + + + +/*********************************************************************** + * main function + * return: exit code + ***********************************************************************/ +int main( + int argc, + char *argv[]) +{ + struct sched_param schedParam; + + int mypri; + char tmpBuf[200]; + + + strcpy(OutFileName,"jitter.dat"); + InterruptPeriodMilliSec = MIN_INT_PERIOD_MILLISEC; + + /* Get the minimum and maximum priorities. */ + MinPriority = sched_get_priority_min(PRIORITY_POLICY); + MaxPriority = sched_get_priority_max(PRIORITY_POLICY); + if (MinPriority == -1) { + printf("\n*** Unable to get minimum priority. ***\n"); + exit(EXIT_MIN_PRIORITY_ERR); + } + if (MaxPriority == -1) { + printf("\n*** Unable to get maximum priority. ***\n"); + exit(EXIT_MAX_PRIORITY_ERR); + } + + /* Set requested priority to minimum value as default. */ + RequestedPriority = MinPriority; + + HandleCmdLineArgs(argc, argv); + + if(mlockall(MCL_CURRENT|MCL_FUTURE) < 0){ + printf("Could not lock task into memory. Bye\n"); + perror("Error"); + } + + if(RunAsRTTask){ + + /* Set the priority. */ + schedParam.sched_priority = RequestedPriority; + if (sched_setscheduler( + 0, + PRIORITY_POLICY, + &schedParam) != (int) 0) { + printf("Exiting: Unsuccessful sched_setscheduler.\n"); + close(Fd1); + exit(EXIT_SET_SCHEDULER_ERR); + } + + + /* Double check as I have some doubts that it's really + running at realtime priority! */ + if((mypri = sched_getscheduler(0)) != RequestedPriority) + { + printf("Not running with request priority %i. running with priority %i instead!\n", + RequestedPriority, mypri); + }else + { + printf("Running with %i priority. Good!\n", mypri); + } + + } + + /*------------------------- Initializations --------------------------*/ + if((Fd1 = open(OutFileName, O_RDWR|O_CREAT|O_SYNC)) <= 0) + { + perror("Cannot open outfile for write:"); + exit(1); + } + + /* If a request is made to read from a specified file, then create that + file and fill with junk data so that there is something there to read. + */ + if(DoRead) + { + + if((Fd2 = open(ReadFile, O_RDWR|O_CREAT|O_SYNC|O_TRUNC)) <= 0) + { + perror("cannot open read file:"); + exit(1); + }else + { + + /* Don't really care how much we write here */ + if(write(Fd2, READ_FILE_MESSAGE, strlen(READ_FILE_MESSAGE)) < 0) + { + perror("Problems writing to readfile:"); + exit(1); + } + lseek(Fd2, 0, SEEK_SET); /* position back to byte #0 */ + } + } + + + + /* Also log output to console. This way we can capture it + on a serial console to a log file. + */ + if((Cfd = open(LogFile, O_WRONLY|O_SYNC)) <= 0) + { + perror("cannot open o/p logfile:"); + exit(1); + } + + + /* Set-up handler for periodic interrupt. */ + if (signal(SIGALRM, &AlarmHandler) == SIG_ERR) { + printf("Couldn't register signal handler for SIGALRM.\n"); + sprintf(tmpBuf, + "Couldn't register signal handler for SIGALRM.\n"); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + close(Fd1); + exit(EXIT_REG_SIGALRM_ERR); + } + + /* Set-up handler for Ctrl+C to exit the program. */ + if (signal(SIGINT, &SignalHandler) == SIG_ERR) { + printf("Couldn't register signal handler for SIGINT.\n"); + sprintf(tmpBuf, + "Couldn't register signal handler for SIGINT.\n"); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + close(Fd1); + exit(EXIT_REG_SIGINT_ERR); + } + + printf("Press Ctrl+C to exit the program.\n"); + printf("Output File: %s\n", OutFileName); + printf("Scheduler priority: %d\n", RequestedPriority); + sprintf(tmpBuf, "\nScheduler priority: %d\n", + RequestedPriority); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); + + printf("Interrupt period: %ld milliseconds\n", + InterruptPeriodMilliSec); + sprintf(tmpBuf, "Interrupt period: %ld milliseconds\n", + InterruptPeriodMilliSec); + + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); + + + fflush(0); + + + + /* Initialize the periodic timer. */ + InitITimer(&ITimer, ONESHOT); + + /* Initialize "previous" time. */ + if (gettimeofday(&PrevTimeVal, NULL) != (int) 0) { + printf("Exiting - "); + printf("Unable to initialize previous time of day.\n"); + sprintf(tmpBuf, "Exiting - "); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + sprintf(tmpBuf, + "Unable to initialize previous time of day.\n"); + + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + } + + /* Start the periodic timer. */ + setitimer(ITIMER_REAL, &ITimer, NULL); + + + while(TRUE) { /* Intentional infinite loop. */ + /* Sleep for one second. */ + sleep((unsigned int) 1); + } + + /* Just in case. File should be closed in SignalHandler. */ + close(Fd1); + close(Cfd); + + return 0; +} + + + + +/*********************************************************************** + * SignalHandler + * This is a handler for the SIGINT signal. It is assumed that the + * SIGINT is due to the user pressing Ctrl+C to halt the program. + * output: N/A + ***********************************************************************/ +void SignalHandler( + int sigNum) +{ + + char tmpBuf[200]; + + /* Note sigNum not used. */ + printf("Ctrl+C detected. Worst Jitter time was:%fms.\nJitterTest exiting.\n", + (float)LastMaxDiff/1000.0); + + sprintf(tmpBuf, + "\nCtrl+C detected. Worst Jitter time was:%fms\nJitterTest exiting.\n", + (float)LastMaxDiff/1000.0); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); + + close(Fd1); + close(Cfd); + exit(0); +} + + + + + +/* + A snapshot of the /proc/profile needs to be taken. + This is stored as a new file every time, and the + stats reset by doing a (any) write to the /proc/profile + file. + */ +void doGrabKProfile(int jitterusec, char *fileName) +{ + int fdSnapshot; + int fdProfile; + int readBytes; + char readBuf[4096]; + + if((fdSnapshot = open(fileName, O_WRONLY | O_CREAT)) <= 0) + { + fprintf(stderr, "Could not open file %s.\n", fileName); + perror("Error:"); + return; + } + + if((fdProfile = open("/proc/profile", O_RDWR)) <= 0) + { + fprintf(stderr, "Could not open file /proc/profile. Make sure you booted with profile=2\n"); + close(fdSnapshot); + return; + } + + while((readBytes = read(fdProfile, readBuf, sizeof(readBuf))) > 0) + { + write(fdSnapshot, readBuf, readBytes); + } + + close(fdSnapshot); + + if(write(fdProfile, readBuf, 1) != 1) + { + perror("Could Not clear profile by writing to /proc/profile:"); + } + + close(fdProfile); + + + +}/* end doGrabKProfile()*/ + + +/* + Call this routine to clear the kernel profiling buffer /proc/profile +*/ +void clearProfileBuf(void){ + + + int fdProfile; + char readBuf[10]; + + + if((fdProfile = open("/proc/profile", O_RDWR)) <= 0) + { + fprintf(stderr, "Could not open file /proc/profile. Make sure you booted with profile=2\n"); + return; + } + + + if(write(fdProfile, readBuf, 1) != 1) + { + perror("Could Not clear profile by writing to /proc/profile:"); + } + + close(fdProfile); + + +}/* end clearProfileBuf() */ + + + + + +/*********************************************************************** + * AlarmHandler + * This is a handler for the SIGALRM signal (due to the periodic + * timer interrupt). It prints the time (seconds) to + * the output file. + * output: N/A + ***********************************************************************/ +void AlarmHandler( + int sigNum) /* signal number (not used) */ +{ + + long timeDiffusec; /* diff time in micro seconds */ + long intervalusec; + + + char tmpBuf[MAX_WRITE_BYTES]; + int cntr; + char padChar; + + static int profileFileNo = 0; + char profileFileName[150]; + + static int seedStarter = 0; /* carries over rand info to next time + where time() will be the same as this time + if invoked < 1sec apart. + */ + + if (gettimeofday(&CurrTimeVal, NULL) == (int) 0) { + + /*---------------------------------------------------------------- + * Compute the elapsed time between the current and previous + * time of day values and store the result. + * + * Print the elapsed time to the output file. + *---------------------------------------------------------------*/ + + timeDiffusec = (long)(((((long long)CurrTimeVal.tv_sec) * 1000000L) + CurrTimeVal.tv_usec) - + (((long long)PrevTimeVal.tv_sec * 1000000L) + PrevTimeVal.tv_usec)); + + sprintf(tmpBuf," %f ms ", (float)timeDiffusec/1000.0); + + intervalusec = InterruptPeriodMilliSec * 1000L; + + timeDiffusec = timeDiffusec - intervalusec; + + sprintf(&tmpBuf[strlen(tmpBuf)]," %f ms", (float)timeDiffusec/1000.0); + + + /* should we send a SIGSTOP/SIGCONT to the specified PID? */ + if(SignalGCTask){ + + if(kill(GCTaskPID, SIGSTOP) < 0){ + + perror("error:"); + } + } + + + /* Store some historical #'s */ + if(abs(timeDiffusec) > LastMaxDiff) + { + LastMaxDiff = abs(timeDiffusec); + sprintf(&tmpBuf[strlen(tmpBuf)],"!"); + + if((GrabKProfile == TRUE) && (ProfileTriggerMSecs < (abs(timeDiffusec)/1000))) + { + sprintf(profileFileName, "JitterTest.profilesnap-%i", profileFileNo); + + /* go and grab the kernel performance profile. */ + doGrabKProfile(timeDiffusec, profileFileName); + profileFileNo++; /* unique name next time */ + + /* Say so on the console so that a marker gets put in the console log */ + sprintf(&tmpBuf[strlen(tmpBuf)],"", + profileFileName); + + } + + } + + + + + sprintf(&tmpBuf[strlen(tmpBuf)],"\n"); /* CR for the data going out of the console */ + + Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); + + + /* The "-1" below takes out the '\n' at the end that we appended for the msg printed on + the console.*/ + sprintf(&tmpBuf[strlen(tmpBuf)-1]," PadBytes:"); + + /* Now pad the output file if requested by user. */ + if(WriteBytes > MIN_WRITE_BYTES) + { + + /* start from a new place every time */ + srand(time(NULL) + seedStarter); + + /* already written MIN_WRITE_BYTES by now */ + for(cntr = strlen(tmpBuf); cntr < WriteBytes - 1 ; cntr++) /* "-1" adj for '\n' at end */ + { + /* don't accept any # < 'SPACE' */ + padChar = (char)(MIN_ASCII+(int)((MAX_ASCII-(float)MIN_ASCII)*rand()/(RAND_MAX+1.0))); + + + /* + padChar = (cntr % (126-33)) + 33; + */ + + tmpBuf[cntr] = padChar; + } + + seedStarter = tmpBuf[cntr-1]; /* save for next time */ + + tmpBuf[cntr] = '\n'; /* CR for the data going into the outfile. */ + tmpBuf[cntr+1] = '\0'; /* NULL terminate the string */ + } + + /* write out the entire line to the output file. */ + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + + /* Read a byte from the specified file */ + if(DoRead) + { + + read(Fd2, tmpBuf, 1); + lseek(Fd2, 0, SEEK_SET); /* back to start */ + } + + + /* Start the periodic timer again. */ + setitimer(ITIMER_REAL, &ITimer, NULL); + + + /* Update previous time with current time. */ + PrevTimeVal.tv_sec = CurrTimeVal.tv_sec; + PrevTimeVal.tv_usec = CurrTimeVal.tv_usec; + } + + else { + sprintf(tmpBuf, "gettimeofday error \n"); + Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); + + printf("gettimeofday error \n"); + } + + /* now clear the profiling buffer */ + if(GrabKProfile == TRUE){ + + clearProfileBuf(); + } + + /* should we send a SIGSTOP/SIGCONT to the specified PID? */ + if(SignalGCTask){ + + if(kill(GCTaskPID, SIGCONT) < 0){ + + perror("error:"); + } + } + + + return; +} + + + +/*********************************************************************** + * InitITimer + * This function initializes the 'struct itimerval' structure whose + * address is passed to interrupt every InterruptPeriodMilliSec. + * output: N/A + ***********************************************************************/ +void InitITimer( + struct itimerval * pITimer, /* pointer to interrupt timer struct*/ + int action) /* ONESHOT or autosetting? */ +{ + long seconds; /* seconds portion of int. period */ + long microSeconds; /* microsec. portion of int. period */ + + /*-------------------------------------------------------------------- + * Divide the desired interrupt period into its seconds and + * microseconds components. + *-------------------------------------------------------------------*/ + if (InterruptPeriodMilliSec < MILLISEC_PER_SEC) { + seconds = 0L; + microSeconds = InterruptPeriodMilliSec * MICROSEC_PER_MILLISEC; + } + else { + seconds = InterruptPeriodMilliSec / MILLISEC_PER_SEC; + microSeconds = + (InterruptPeriodMilliSec - (seconds * MILLISEC_PER_SEC)) * + MICROSEC_PER_MILLISEC; + } + + /* Initialize the interrupt period structure. */ + pITimer->it_value.tv_sec = seconds; + pITimer->it_value.tv_usec = microSeconds; + + if(action == ONESHOT) + { + /* This will (should) prevent the timer from restarting itself */ + pITimer->it_interval.tv_sec = 0; + pITimer->it_interval.tv_usec = 0; + }else + { + pITimer->it_interval.tv_sec = seconds; + pITimer->it_interval.tv_usec = microSeconds; + + } + + return; +} + + +/*********************************************************************** + * HandleCmdLineArgs + * This function handles the command line arguments. + * output: stack size + ***********************************************************************/ +void HandleCmdLineArgs( + int argc, /* number of command-line arguments */ + char *argv[]) /* ptrs to command-line arguments */ +{ + int argNum; /* argument number */ + + if (argc > (int) 1) { + + for (argNum = (int) 1; argNum < argc; argNum++) { + + /* The command line contains an argument. */ + + if ((strcmp(argv[argNum],"--version") == STRINGS_EQUAL) || + (strcmp(argv[argNum],"-v") == STRINGS_EQUAL)) { + /* Print version information and exit. */ + PrintVersionInfo(); + exit(0); + } + + else if ((strcmp(argv[argNum],"--help") == STRINGS_EQUAL) || + (strcmp(argv[argNum],"-h") == STRINGS_EQUAL) || + (strcmp(argv[argNum],"-?") == STRINGS_EQUAL)) { + /* Print help information and exit. */ + PrintHelpInfo(); + exit(0); + } + + else if ((strcmp(argv[argNum],"--file") == STRINGS_EQUAL) || + (strcmp(argv[argNum],"-f") == STRINGS_EQUAL)) { + /* Set the name of the output file. */ + ++argNum; + if (argNum < argc) { + SetFileName(argv[argNum]); + } + else { + printf("*** Output file name not specified. ***\n"); + printf("Default output file name will be used.\n"); + } + } + + else if ((strcmp(argv[argNum],"--time") == STRINGS_EQUAL) || + (strcmp(argv[argNum],"-t") == STRINGS_EQUAL)) { + /* Set the interrupt period. */ + ++argNum; + if (argNum < argc) { + SetInterruptPeriod(argv[argNum]); + } + else { + printf("*** Interrupt period not specified. ***\n"); + printf("Default interrupt period will be used.\n"); + } + + } + + else if ((strcmp(argv[argNum],"--priority") == + STRINGS_EQUAL) || + (strcmp(argv[argNum],"-p") == STRINGS_EQUAL)) { + /* Set the scheduler priority. */ + ++argNum; + if (argNum < argc) { + SetSchedulerPriority(argv[argNum]); + } + else { + printf("*** Scheduler priority not specified. ***\n"); + printf("Default scheduler priority will be used.\n"); + } + + } + + else if ((strcmp(argv[argNum],"--readfile") == + STRINGS_EQUAL) || + (strcmp(argv[argNum],"-r") == STRINGS_EQUAL)) { + /* Set the file to read*/ + ++argNum; + + strncpy(ReadFile, argv[argNum], sizeof(ReadFile)); + DoRead = TRUE; + } + + else if ((strcmp(argv[argNum],"--write_bytes") == + STRINGS_EQUAL) || + (strcmp(argv[argNum],"-w") == STRINGS_EQUAL)) { + /* Set the file to read*/ + ++argNum; + + WriteBytes = atoi(argv[argNum]); + + if(WriteBytes < MIN_WRITE_BYTES) + { + printf("Writing less than %i bytes is not allowed. Bye.\n", + MIN_WRITE_BYTES); + exit(0); + } + + + } + + else if ((strcmp(argv[argNum],"--consolefile") == + STRINGS_EQUAL) || + (strcmp(argv[argNum],"-c") == STRINGS_EQUAL)) { + /* Set the file to log console log on. */ + ++argNum; + + strncpy(LogFile, argv[argNum], sizeof(LogFile)); + } + + else if ((strcmp(argv[argNum],"--grab_kprofile") == + STRINGS_EQUAL)) + { + /* We will read the /proc/profile file on configurable timeout */ + GrabKProfile = TRUE; + + ++argNum; + + /* If the jittter is > this #, then the profile is grabbed. */ + ProfileTriggerMSecs = (long) atoi(argv[argNum]); + + if(ProfileTriggerMSecs <= 0){ + + printf("Illegal value for profile trigger threshold.\n"); + exit(0); + } + } + + else if ((strcmp(argv[argNum],"--siggc") == + STRINGS_EQUAL)) + { + /* We will SIGSTOP/SIGCONT the specified pid */ + SignalGCTask = TRUE; + + ++argNum; + + GCTaskPID = atoi(argv[argNum]); + + if(ProfileTriggerMSecs <= 0){ + + printf("Illegal value for JFFS(2) GC task pid.\n"); + exit(0); + } + } + + + else { + /* Unknown argument. Print help information and exit. */ + printf("Invalid option %s\n", argv[argNum]); + printf("Try 'JitterTest --help' for more information.\n"); + exit(0); + } + } + } + + return; +} + + +/*********************************************************************** + * SetFileName + * This function sets the output file name. + * output: N/A + ***********************************************************************/ +void SetFileName( + char * pFileName) /* ptr to desired output file name */ +{ + size_t fileNameLen; /* file name length (bytes) */ + + /* Check file name length. */ + fileNameLen = strlen(pFileName); + if (fileNameLen > (size_t) MAX_FILE_NAME_LEN) { + printf("File name %s exceeds maximum length %d.\n", + pFileName, MAX_FILE_NAME_LEN); + exit(0); + } + + /* File name length is OK so save the file name. */ + strcpy(OutFileName, pFileName); + + return; +} + + +/*********************************************************************** + * SetInterruptPeriod + * This function sets the interrupt period. + * output: N/A + ***********************************************************************/ +void SetInterruptPeriod( + char * /* ptr to desired interrupt period */ + pASCIIInterruptPeriodMilliSec) +{ + long period; /* interrupt period */ + + period = atol(pASCIIInterruptPeriodMilliSec); + if ((period < MIN_INT_PERIOD_MILLISEC) || + (period > MAX_INT_PERIOD_MILLISEC)) { + printf("Invalid interrupt period: %ld ms.\n", period); + exit(EXIT_INV_INT_PERIOD); + } + else { + InterruptPeriodMilliSec = period; + } + return; +} + + +/*********************************************************************** + * SetSchedulerPriority + * This function sets the desired scheduler priority. + * output: N/A + ***********************************************************************/ +void SetSchedulerPriority( + char * pASCIISchedulerPriority) /* ptr to desired scheduler priority*/ +{ + int priority; /* desired scheduler priority value */ + + priority = atoi(pASCIISchedulerPriority); + if ((priority < MinPriority) || + (priority > MaxPriority)) { + printf("Scheduler priority %d outside of range [%d, %d]\n", + priority, MinPriority, MaxPriority); + exit(EXIT_INV_SCHED_PRIORITY); + } + else { + RequestedPriority = priority; + RunAsRTTask = TRUE; /* We shall run as a POSIX real time task */ + } + return; +} + + +/*********************************************************************** + * PrintVersionInfo + * This function prints version information. + * output: N/A + ***********************************************************************/ +void PrintVersionInfo(void) +{ + printf("JitterTest version %s\n", Version); + printf("Copyright (c) 2001, Daniel Industries, Inc.\n"); + return; +} + + +/*********************************************************************** + * PrintHelpInfo + * This function prints help information. + * output: N/A + ***********************************************************************/ +void PrintHelpInfo(void) +{ + printf("Usage: JitterTest [options]\n"); + printf(" *** Requires root privileges. ***\n"); + printf("Option:\n"); + printf(" [-h, --help, -?] Print this message and exit.\n"); + printf(" [-v, --version] "); + printf( "Print the version number of JitterTest and exit.\n"); + printf(" [-f FILE, --file FILE] Set output file name to FILE. Typically you would put this on the fs under test\n"); + printf(" [-c FILE, --consolefile] Set device or file to write the console log to.\n\tTypically you would set this to /dev/console and save it on another computer.\n"); + printf(" [-w BYTES, --write_bytes BYTES Write BYTES to FILE each period.\n"); + printf(" [-r FILE, --readfile FILE] Also read 1 byte every cycle from FILE. FILE will be created and filled with data.\n"); + printf(" [-t , --time ] "); + printf( "Set interrupt period to milliseconds.\n"); + printf(" "); + printf( "Range: [%ld, %ld] milliseconds.\n", + MIN_INT_PERIOD_MILLISEC, MAX_INT_PERIOD_MILLISEC); + printf(" [-p , --priority ] "); + printf( "Set scheduler priority to .\n"); + printf(" "); + printf( "Range: [%d, %d] (higher number = higher priority)\n", + MinPriority, MaxPriority); + printf(" [--grab_kprofile ] Read the /proc/profile if jitter is > THRESHOLD and store in file.\n"); + printf(" [--siggc ] Before writing to fs send SIGSTOP to PID. After write send SIGCONT\n"); + return; + +} + + +/* A common write that checks for write errors and exits. Pass it __LINE__ for lineNo */ +int Write(int fd, void *buf, size_t bytes, int lineNo) +{ + + int err; + + err = write(fd, buf, bytes); + + if(err < bytes) + { + + printf("Write Error at line %i! Wanted to write %i bytes, but wrote only %i bytes.\n", + lineNo, bytes, err); + perror("Write did not complete. Error. Bye:"); /* show error from errno. */ + exit(1); + + } + + return err; + +}/* end Write*/ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/Makefile 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,46 @@ +CC=gcc +# uncomment following for performance +CCFLAGS=-O3 -Wall -m486 -fomit-frame-pointer + +# uncomment following for debugging. Uncomment either this or the one above. Not both. +# CCFLAGS=-Wall -g + + +all: JitterTest plotJittervsFill + +JitterTest: JitterTest.c Makefile + gcc $(CCFLAGS) -lm JitterTest.c -o JitterTest + +plotJittervsFill: plotJittervsFill.c Makefile + gcc $(CCFLAGS) plotJittervsFill.c -o plotJittervsFill + +clean: + rm -rf *~ + rm -rf core + rm -rf *.o + rm -rf JitterTest + + +dep: + makedepend -I./ *.c +# DO NOT DELETE + +JitterTest.o: /usr/include/stdio.h /usr/include/features.h +JitterTest.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +JitterTest.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +JitterTest.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +JitterTest.o: /usr/include/bits/types.h /usr/include/libio.h +JitterTest.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +JitterTest.o: /usr/include/string.h /usr/include/stdlib.h +JitterTest.o: /usr/include/sys/types.h /usr/include/time.h +JitterTest.o: /usr/include/endian.h /usr/include/bits/endian.h +JitterTest.o: /usr/include/sys/select.h /usr/include/bits/select.h +JitterTest.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +JitterTest.o: /usr/include/alloca.h /usr/include/sys/time.h +JitterTest.o: /usr/include/bits/time.h /usr/include/signal.h +JitterTest.o: /usr/include/bits/signum.h /usr/include/bits/siginfo.h +JitterTest.o: /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h +JitterTest.o: /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h +JitterTest.o: /usr/include/sched.h /usr/include/bits/sched.h +JitterTest.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +JitterTest.o: /usr/include/bits/confname.h /usr/include/getopt.h diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/plotJittervsFill.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/plotJittervsFill.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/plotJittervsFill.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/plotJittervsFill.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,312 @@ +/* + *********************************************************************** + * + * Copyright: Daniel Measurement and Control, Inc. + * 9753 Pine Lake Drive + * Houston, TX 77055 + * + * Created by: Vipin Malik + * Released under GPL by permission of Daniel Industries. + * + * This software is licensed under the GPL version 2. Plese see the file + * COPYING for details on the license. + * + * NO WARRANTY: Absolutely no claims of warranty or fitness of purpose + * are made in this software. Please use at your own risk. + * + File: plotJittervsFill.c + By: Vipin Malik + + About: This program reads in a jitter log file as created + by the JitterTest.c program and extracts all the jitters + in the file that are greater than a threshold specified + as a parameter on the cmd line. It also extracts the + amount of disk space at (form the "df" out that should also + be present in the log file) after the jitter extracted. + + It writes the data to the stderr (where you may redirect it). + It is suitable for plotting, as the data is written as + COL1=UsedSpace COL2=Jitter + + $Id: plotJittervsFill.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Log: not supported by cvs2svn $ + Revision 1.6 2005/11/07 11:15:21 gleixner + [MTD / JFFS2] Clean up trailing white spaces + + Revision 1.5 2001/08/10 19:23:11 vipin + Ready to be released under GPL! Added proper headers etc. + + Revision 1.4 2001/07/02 22:25:40 vipin + Fixed couple of minor cosmetic typos. + + Revision 1.3 2001/07/02 14:46:46 vipin + Added a debug option where it o/p's line numbers to debug funky values. + + Revision 1.2 2001/06/26 19:48:57 vipin + Now prints out jitter values found at end of log file, after which + no new "df" disk usage values were encountered. The last "df" disk usage + encountered is printed for these orphaned values. + + Revision 1.1 2001/06/25 19:13:55 vipin + Added new file- plotJittervsFill.c- that mines the data log file + outputed from the fillFlash.sh script file and JitterTest.c file + and produces output suitable to be plotted. + This output plot may be examined to see visually the relationship + of the Jitter vs disk usage of the fs under test. + + */ + +#include +#include +#include +#include +#include + +static char Version_string[] = "$Id: plotJittervsFill.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $"; +static char LogFile[250] = "InputLogFile.log"; + +static int JitterThreshold_ms = 1000; +static int Debug = 0; /* Debug level. Each "-d" on the cmd line increases the level */ + +#define TRUE 1 +#define FALSE 0 + +#define MIN_JITTER_THRESHOLD 1 /* ms minimum jitter threshold */ + +void PrintHelpInfo(void) +{ + printf("Usage: plotJittervsFill [options] -f [--file] -t [--jitter_threshold] \n"); + printf("[options]:\n-v [--version] Print version and exit\n"); + printf("-d Debug. Prints input file line number for each data point picked up.\n"); + printf("-h [--help] [-?] Print this help screen and exit.\n"); +} + + + +/*********************************************************************** + * HandleCmdLineArgs + * This function handles the command line arguments. + * output: stack size + ***********************************************************************/ +void HandleCmdLineArgs( + int argc, /* number of command-line arguments */ + char *argv[]) /* ptrs to command-line arguments */ +{ + int argNum; /* argument number */ + + if (argc > (int) 1) { + + for (argNum = (int) 1; argNum < argc; argNum++) { + + /* The command line contains an argument. */ + + if ((strcmp(argv[argNum],"--version") == 0) || + (strcmp(argv[argNum],"-v") == 0)) { + /* Print version information and exit. */ + printf("%s\n", Version_string); + exit(0); + } + + else if ((strcmp(argv[argNum],"--help") == 0) || + (strcmp(argv[argNum],"-h") == 0) || + (strcmp(argv[argNum],"-?") == 0)) { + /* Print help information and exit. */ + PrintHelpInfo(); + exit(0); + } + + else if ((strcmp(argv[argNum],"--file") == 0) || + (strcmp(argv[argNum],"-f") == 0)) { + /* Set the name of the output file. */ + ++argNum; + if (argNum < argc) { + strncpy(LogFile, argv[argNum], sizeof(LogFile)); + } + else { + printf("*** Input file name not specified. ***\n"); + exit(0); + } + } + + else if ((strcmp(argv[argNum],"--jitter_threshold") == 0) || + (strcmp(argv[argNum],"-t") == 0)) { + /* Set the file to read*/ + ++argNum; + + JitterThreshold_ms = atoi(argv[argNum]); + + if(JitterThreshold_ms < MIN_JITTER_THRESHOLD) + { + printf("A jitter threshold less than %i ms is not allowed. Bye.\n", + MIN_JITTER_THRESHOLD); + exit(0); + } + } + + else if ((strcmp(argv[argNum],"-d") == 0)) + { + /* Increment debug level */ + + Debug++; + } + + else { + /* Unknown argument. Print help information and exit. */ + printf("Invalid option %s\n", argv[argNum]); + printf("Try 'plotJittervsFill --help' for more information.\n"); + exit(0); + } + } + } + + return; +} + + + + + +int main( + int argc, + char *argv[]) +{ + + char lineBuf[1024]; /* how long a single line be? */ + int converted; + int lineNo = 0; + int cnt; + + FILE *fp; + + int junkInt1, junkInt2, junkInt3; + float junkFloat1; + float jitter_ms; + +#define MAX_SAVE_BUFFER 1000 /* How many values will be picked up while searching for + a % disk full line (i.e. before they can be printed out) + */ + int saveJitter[MAX_SAVE_BUFFER]; /* lets us record multiple jitter values that exceed + our threshold till we find a "df" field- which is when + we can o/p all these values. + */ + int dataLineNo[MAX_SAVE_BUFFER]; /* The saved line #'s for the above. Printed if debug specified. */ + + int saveJitterCnt = 0; + int lookFor_df = FALSE; + int dfPercent = -1; /* will be >= 0 if at least one found. The init value is a flag. */ + + char junkStr1[500], junkStr2[500]; + + HandleCmdLineArgs(argc, argv); + + if((fp = fopen(LogFile, "r")) == NULL) + { + printf("Unable to open input log file %s for read.\b", LogFile); + perror("Error:"); + exit(1); + } + + + + while(fgets(lineBuf, sizeof(lineBuf), fp) != NULL) + { + lineNo++; + + + /* Are we looking for a "df" o/p line? (to see how full + the flash is?)*/ + + /* is there a "%" in this line? */ + if((strstr(lineBuf, "%") != NULL) && (lookFor_df)) + { + converted = sscanf(lineBuf, "%s %i %i %i %i\n", + junkStr1, &junkInt1, &junkInt2, &junkInt3, &dfPercent); + if(converted < 5) + { + printf("Line %i contains \"%%\", but expected fileds not found. Skipping.\n", lineNo); + }else + { + /* Now print out the saved jitter values (in col2) with this dfPercent value as the col1. */ + for(cnt = 0; cnt < saveJitterCnt; cnt++) + { + if(Debug) + { + fprintf(stderr, "%i\t%i\t%i\n", (int)dataLineNo[cnt], + dfPercent, (int)saveJitter[cnt]); + }else + { + fprintf(stderr, "%i\t%i\n", dfPercent, (int)saveJitter[cnt]); + } + + + } + + saveJitterCnt = 0; /* all flushed. Reset for next saves. */ + lookFor_df = FALSE; + } + + } + + + /* is there a "ms" in this line?*/ + if(strstr(lineBuf, "ms") == NULL) + { + continue; + } + + /* grab the ms jitter value */ + converted = sscanf(lineBuf, "%f %s %f %s\n", &junkFloat1, junkStr1, &jitter_ms, junkStr2); + if(converted < 4) + { + printf("Line %i contains \"ms\", but expected fileds not found. Converted %i, Skipping.", + lineNo, converted); + printf("1=%i, 2=%s.\n", junkInt1, junkStr1); + continue; /* not our jitter line*/ + } + + /* Is the jitter value > threshold value? */ + if(abs(jitter_ms) > JitterThreshold_ms) + { + /* Found a jitter line that matches our crietrion. + Now set flag to be on the look out for the next + "df" output so that we can see how full the flash is. + */ + + if(saveJitterCnt < MAX_SAVE_BUFFER) + { + saveJitter[saveJitterCnt] = (int)abs(jitter_ms); /* why keep the (ms) jitter in float */ + dataLineNo[saveJitterCnt] = lineNo; + saveJitterCnt++; + lookFor_df = TRUE; + } + else + { + printf("Oops! I've run out of buffer space before I found a %% use line. Dropping itter value. Increase MAX_SAVE_BUFFER and recompile.\n"); + } + + + } + + } + + + /* Now print out any saved jitter values that were not printed out because we did not find + and "df" after these were picked up. Only print if a "df" disk usage was ever found. + */ + if(lookFor_df && (dfPercent >= 0)) + { + /* Now print out the saved jitter values (in col2) with this dfPercent value as the col1. */ + for(cnt = 0; cnt < saveJitterCnt; cnt++) + { + fprintf(stderr, "%i\t%i\n", dfPercent, (int)saveJitter[cnt]); + } + } + + return 0; + + +}/* end main() */ + + + + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/README linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/README --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/jittertest/README 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/jittertest/README 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,197 @@ +$Id: README,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + +This is the README file for the JitterTest (and friends) +program. + +This program is used to measure what the jitter of a +real time task would be under "standard" Linux. + +More particularly, what is the effect of running +a real time task under Linux with background +JFFS file system activity. + +The jitter is measured in milli seconds (ms) from +the expected time of arrival of a signal from a +periodic timer (set by the task) to when the +task actually gets the signal. + +This jitter is then stored in a file specified +(or the default output file "jitter.dat"). + +The data may also be sent out to the console by +writing to /dev/console (See help options. This is +highly desirable specially if you have redirected +your console to the serial port and are storing it +as a minicom log on another computer for later analysis +using some tools provided here). + +This is particularly useful if you have a serial +console and are outputting "interesting" info +from inside some kernel task or driver. +(or something as simple as a "df" program running +periodically and redirecting o/p to the console). + +One "interesting" thing that I have measured +is the effect of FLASH chip erases on the jitter +of a real time task. + +One can do that by putting a printk at the +beginning of the flash erase routine in the MTD +flash chip driver. + +Now you will get jitter data interspersed with +flash sector erase events. Other printk's can also +be placed at suspected jitter causing locations in +the system. + + + +EXECUTING THE PROGRAM "JitterTest" + +You may specify a file to be read by the +program every time it wakes up (every cycle). +This file is created and filled with some junk +data. The purpose of this is to test the jitter +of the program if it were reading from- say +a JFFS (Journaling Flash File System) file system. + +By specifying the complete paths of the read and write +(o/p) files you can test the jitter a POSIX type +real time task will experience under Linux, under +various conditions. + +These can be as follows: + +1. O/P file on ram file system, no i/p file. + + In this case you would presumably generate other +"typical" background activity for your system and +examine the worst case jitter experienced by +a task that is neither reading nor writing to +a file system. + +Other cases could be: + +2. O/P to ram fs, I/P from JFFS (type) fs: + + This is specially useful to test the proper +operation of erase suspend type of operation +in JFFS file systems (with an MTD layer that +supports it). + + In this test you would generate some background +write/erase type activity that would generate +chip erases. Since this program is reading from +the same file system, you contrast the latencies +with those obtained with writes going to the same +fs. + +3. Both read and writes to (or just write to) JFFS +file system: + + Here you would test for latencies experienced by +a program if it were writing (and optionally also +reading) from a JFFS fs. + + + + +Grabing a kernel profile: + +This program can also conditionally grab a kernel profile. +Specify --grab_kprofile on the cmd line as well as +a "threshold" parameter (see help options by -?). + +Any jitter greater than this "threshold" will cause the +program to read the /proc/profile file and dump it in +a local file with increasing file numbers. It will also +output the filename at that time to the console file specified. +This will allow you to corelate later in time the various profiles +with data in your console file and what was going on at that time. + +These profile files may then be later examined by running them through +ksymoops. + +Make sure you specify "profile=2" on the kernel command line +when you boot the kernel if you want to use this functionality. + + + +Signalling the JFFS[2] GC task: + +You can also force this program to send a SIGSTOP/SIGCONT to the +JFFS (or JFFS2) gc task by specifing --siggc on the cmd line. + +This will let you investigate the effect of forcing the gc task to +wake up and do its thing when you are not writing to the fs and to +force it to sleep when you want to write to the fs. + +These are just various tools to investigate the possibility of +achieving minimal read/write latency when using JFFS[2]. + +You need to manually do a "ps aux" and look up the PID of the gc +thread and provide it to the program. + + + + +EXECUTING THE PROGRAM "plotJittervsFill" + +This program is a post processing tool that will extract the jitter +times as printed by the JitterTest program in its console log file +as well as the data printed by the "df" command. + +This "df" data happens to be in the console log because you will +run the shell file fillJffs2.sh on a console when you are doing +your jitter test. + +This shell script copies a specified file to another specified file +every programmable seconds. It also does a "df" and redirects output +to /dev/console where it is mixed with the output from JitterTest. + +All this console data is stored on another computer, as all this data +is being outputted to the serial port as you have redirected the console +to the serial port (that is the only guaranteed way to not loose any +console log or printk data). + +You can then run this saved console log through this program and it +will output a very nice text file with the %fill in one col and +corrosponding jitter values in the second. gnuplot then does a +beautifull plot of this resulting file showing you graphically the +jitters encountered at different fill % of your JFFS[2] fs. + + + +OTHER COMMENTS: + +Use the "-w BYTES" cmd line parameter to simulate your test case. +Not everyone has the same requirements. Someone may want to measure +the jitter of JFFS2 with 500 bytes being written every 500ms. Others +may want to measure the system performance writing 2048 bytes every +5 seconds. + +RUNNING MULTIPLE INSTANCES: + +Things get real interesting when you run multiple instances of this +program *at the same time*. + +You could have one version running as a real time task (by specifing +the priority with the -p cmd line parameter), not interacting with +any fs or at the very least not reading and writing to JFFS[2]. + +At the same time you could have another version running as a regular +task (by not specifing any priority) but reading and writing to JFFS[2]. + +This way you can easily measure the blocking performance of the real time +task while another non-real time task interacts with JFFS[2] in the back ground. + +You get the idea. + + +WATCH OUT! + +Be particularly careful of running this program as a real time task AND +writing to JFFS[2]. Any blocks will cause your whole system to block till +any garbage collect initiated by writes by this task complete. I have measured +these blocks to be of the order of 40-50 seconds on a reasonably powerful +32 bit embedded system. diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/common.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/common.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/common.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/common.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,336 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * The stuff which is common for many tests. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#include "common.h" + +/** + * __initial_check - check that common prerequisites which are required to run + * tests. + * + * @test test name + * @argc count of command-line arguments + * @argv command-line arguments + * + * This function returns %0 if all is fine and test may be run and %-1 if not. + */ +int __initial_check(const char *test, int argc, char * const argv[]) +{ + libubi_t libubi; + struct ubi_dev_info dev_info; + + /* + * All tests require UBI character device name as the first parameter, + * check this. + */ + if (argc < 2) { + __err_msg(test, __FUNCTION__, __LINE__, + "UBI character device node is not specified"); + return -1; + } + + libubi = libubi_open(); + if (libubi == NULL) { + __failed(test, __FUNCTION__, __LINE__, "libubi_open"); + return -1; + } + + if (ubi_get_dev_info(libubi, argv[1], &dev_info)) { + __failed(test, __FUNCTION__, __LINE__, "ubi_get_dev_info"); + goto close; + } + + if (dev_info.avail_lebs < MIN_AVAIL_EBS) { + __err_msg(test, __FUNCTION__, __LINE__, + "insufficient available eraseblocks %d on UBI " + "device, required %d", + dev_info.avail_lebs, MIN_AVAIL_EBS); + goto close; + } + + if (dev_info.vol_count != 0) { + __err_msg(test, __FUNCTION__, __LINE__, + "device %s is not empty", argv[1]); + goto close; + } + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return -1; +} + +/** + * __err_msg - print a message to stderr. + * + * @test test name + * @func function name + * @line line number + * @fmt format string + */ +void __err_msg(const char *test, const char *func, int line, + const char *fmt, ...) +{ + va_list args; + + fprintf(stderr, "[%s] %s():%d: ", test, func, line); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); +} + +/** + * __failed - print function fail message. + * + * @test test name + * @func calling function name + * @line line number + * @failed failed function name + */ +void __failed(const char *test, const char *func, int line, + const char *failed) +{ + fprintf(stderr, "[%s] %s():%d: function %s() failed with error %d (%s)\n", + test, func, line, failed, errno, strerror(errno)); +} + +/** + * __check_volume - check volume information. + * + * @libubi libubi descriptor + * @dev_info UBI device description + * @test test name + * @func function name + * @line line number + * @vol_id ID of existing volume to check + * @req volume creation request to compare with + * + * This function checks if a volume created using @req request has exactly the + * requested characteristics. Returns 0 in case of success and %-1 in case of + * error. + */ +int __check_volume(libubi_t libubi, struct ubi_dev_info *dev_info, + const char *test, const char *func, int line, int vol_id, + const struct ubi_mkvol_request *req) +{ + int ret; + struct ubi_vol_info vol_info; + int leb_size; + long long rsvd_bytes; + + ret = ubi_get_vol_info1(libubi, dev_info->dev_num, vol_id, &vol_info); + if (ret) { + __failed(test, func, line, "ubi_get_vol_info"); + return -1; + } + + if (req->alignment != vol_info.alignment) { + __err_msg(test, func, line, + "bad alignment: requested %d, got %d", + req->alignment, vol_info.alignment); + return -1; + } + if (req->vol_type != vol_info.type) { + __err_msg(test, func, line, "bad type: requested %d, got %d", + req->vol_type, vol_info.type); + return -1; + } + if (strlen(req->name) != strlen(vol_info.name) || + strcmp(req->name, vol_info.name) != 0) { + __err_msg(test, func, line, + "bad name: requested \"%s\", got \"%s\"", + req->name, vol_info.name); + return -1; + } + if (vol_info.corrupted) { + __err_msg(test, func, line, "corrupted new volume"); + return -1; + } + + leb_size = dev_info->leb_size - (dev_info->leb_size % req->alignment); + if (leb_size != vol_info.leb_size) { + __err_msg(test, func, line, + "bad usable LEB size %d, should be %d", + vol_info.leb_size, leb_size); + return -1; + } + + rsvd_bytes = req->bytes; + if (rsvd_bytes % leb_size) + rsvd_bytes += leb_size - (rsvd_bytes % leb_size); + + if (rsvd_bytes != vol_info.rsvd_bytes) { + __err_msg(test, func, line, + "bad reserved bytes %lld, should be %lld", + vol_info.rsvd_bytes, rsvd_bytes); + return -1; + } + + return 0; +} + +/** + * __check_vol_patt - check that volume contains certain data + * + * @libubi libubi descriptor + * @dev_info UBI device description + * @test test name + * @func function name + * @line line number + * @node volume character device node + * @byte data pattern to check + * + * This function returns %0 if the volume contains only @byte bytes, and %-1 if + * not. + */ +int __check_vol_patt(libubi_t libubi, struct ubi_dev_info *dev_info, + const char *test, const char *func, int line, + const char *node, uint8_t byte) +{ + int ret, fd; + long long bytes = 0; + struct ubi_vol_info vol_info; + unsigned char buf[512]; + + fd = open(node, O_RDONLY); + if (fd == -1) { + __failed(test, func, line, "open"); + __err_msg(test, func, line, "cannot open \"%s\"\n", node); + return -1; + } + + ret = ubi_get_vol_info(libubi, node, &vol_info); + if (ret) { + __failed(test, func, line, "ubi_get_vol_info"); + goto close; + } + + while (bytes < vol_info.data_bytes) { + int i; + + memset(buf, ~byte, 512); + ret = read(fd, buf, 512); + if (ret == -1) { + __failed(test, func, line, "read"); + __err_msg(test, func, line, "bytes = %lld, ret = %d", + bytes, ret); + goto close; + } + + if (ret == 0 && bytes + ret < vol_info.data_bytes) { + __err_msg(test, func, line, + "EOF, but read only %lld bytes of %lld", + bytes + ret, vol_info.data_bytes); + goto close; + } + + for (i = 0; i < ret; i++) + if (buf[i] != byte) { + __err_msg(test, func, line, + "byte at %lld is not %#x but %#x", + bytes + i, byte, (int)buf[i]); + goto close; + } + + bytes += ret; + } + + close(fd); + return 0; + +close: + close(fd); + return -1; +} + +/** + * __update_vol_patt - update volume using a certain byte pattern + * + * @libubi libubi descriptor + * @dev_info UBI device description + * @test test name + * @func function name + * @line line number + * @node volume character device node + * @byte data pattern to check + * + * This function returns %0 in case of success, and %-1 if in case of failure. + */ +int __update_vol_patt(libubi_t libubi, const char *test, const char *func, + int line, const char *node, long long bytes, uint8_t byte) +{ + int ret, fd; + long long written = 0; + unsigned char buf[512]; + + fd = open(node, O_RDWR); + if (fd == -1) { + __failed(test, func, line, "open"); + __err_msg(test, func, line, "cannot open \"%s\"\n", node); + return -1; + } + + if (ubi_update_start(libubi, fd, bytes)) { + __failed(test, func, line, "ubi_update_start"); + __err_msg(test, func, line, "bytes = %lld", bytes); + goto close; + } + + memset(buf, byte, 512); + + while (written != bytes) { + ret = write(fd, buf, 512); + if (ret == -1) { + __failed(test, func, line, "write"); + __err_msg(test, func, line, "written = %lld, ret = %d", + written, ret); + goto close; + } + written += ret; + + if (written > bytes) { + __err_msg(test, func, line, "update length %lld bytes, " + "but %lld bytes are already written", + bytes, written); + goto close; + } + } + + close(fd); + return 0; + +close: + close(fd); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/common.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/common.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/common.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/common.h 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,103 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * The stuff which is common for many tests. + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define UBI_VOLUME_PATTERN "/dev/ubi%d_%d" +#define MIN_AVAIL_EBS 5 +#define PAGE_SIZE 4096 + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +#define err_msg(fmt, ...) \ + __err_msg(TESTNAME, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + +#define failed(name) \ + __failed(TESTNAME, __FUNCTION__, __LINE__, name) + +#define initial_check(argc, argv) \ + __initial_check(TESTNAME, argc, argv) + +#define check_volume(vol_id, req) \ + __check_volume(libubi, &dev_info, TESTNAME, __FUNCTION__, \ + __LINE__, vol_id, req) + +#define check_vol_patt(node, byte) \ + __check_vol_patt(libubi, &dev_info, TESTNAME, __FUNCTION__, __LINE__, \ + node, byte) + +#define update_vol_patt(node, bytes, byte) \ + __update_vol_patt(libubi, TESTNAME, __FUNCTION__, __LINE__, \ + node, bytes, byte) + +#define check_failed(ret, error, func, fmt, ...) ({ \ + int __ret; \ + \ + if (!ret) { \ + err_msg("%s() returned success but should have failed", func); \ + err_msg(fmt, ##__VA_ARGS__); \ + __ret = -1; \ + } \ + if (errno != (error)) { \ + err_msg("%s failed with error %d (%s), expected %d (%s)", \ + func, errno, strerror(errno), error, strerror(error)); \ + err_msg(fmt, ##__VA_ARGS__); \ + __ret = -1; \ + } \ + __ret = 0; \ +}) + +/* Alignments to test, @s is eraseblock size */ +#define ALIGNMENTS(s) \ + {3, 5, 27, 666, 512, 1024, 2048, (s)/2-3, (s)/2-2, (s)/2-1, (s)/2+1, \ + (s)/2+2, (s)/2+3, (s)/3-3, (s)/3-2, (s)/3-1, (s)/3+1, (s)/3+2, \ + (s)/3+3, (s)/4-3, (s)/4-2, (s)/4-1, (s)/4+1, (s)/4+2, (s)/4+3, \ + (s)/5-3, (s)/5-2, (s)/5-1, (s)/5+1, (s)/5+2, (s)/5+3, (s)-17, (s)-9, \ + (s)-8, (s)-6, (s)-4, (s)-1, (s)}; + +extern void __err_msg(const char *test, const char *func, int line, + const char *fmt, ...); +void __failed(const char *test, const char *func, int line, + const char *failed); +int __initial_check(const char *test, int argc, char * const argv[]); +int __check_volume(libubi_t libubi, struct ubi_dev_info *dev_info, + const char *test, const char *func, int line, int vol_id, + const struct ubi_mkvol_request *req); +int __check_vol_patt(libubi_t libubi, struct ubi_dev_info *dev_info, + const char *test, const char *func, int line, + const char *node, uint8_t byte); +int __update_vol_patt(libubi_t libubi, const char *test, const char *func, + int line, const char *node, long long bytes, + uint8_t byte); + +#ifdef __cplusplus +} +#endif + +#endif /* !__COMMON_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/integ.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/integ.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/integ.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/integ.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,783 @@ +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "libubi.h" + +struct erase_block_info; +struct volume_info; +struct ubi_device_info; + +struct write_info +{ + struct write_info *next; + struct erase_block_info *erase_block; + int offset_within_block; /* Offset within erase block */ + off64_t offset; /* Offset within volume */ + int size; + int random_seed; +}; + +struct erase_block_info +{ + struct volume_info *volume; + int block_number; + off64_t offset; /* Offset within volume */ + off64_t top_of_data; + int touched; /* Have we done anything at all with this erase block */ + int erased; /* This erased block is currently erased */ + struct write_info *writes; +}; + +struct volume_fd +{ + struct volume_fd *next; + struct volume_info *volume; + int fd; +}; + +struct volume_info +{ + struct volume_info *next; + struct ubi_device_info *ubi_device; + struct volume_fd *fds; + struct erase_block_info *erase_blocks; + const char *device_file_name; + struct ubi_vol_info info; +}; + +struct ubi_device_info +{ + struct volume_info *volumes; + const char *device_file_name; + struct ubi_dev_info info; +}; + +struct open_volume_fd +{ + struct open_volume_fd *next; + struct volume_fd *vol_fd; +}; + +#define MAX_UBI_DEVICES 64 + +static libubi_t libubi; + +static struct ubi_info info; +static struct ubi_device_info ubi_array[MAX_UBI_DEVICES]; + +static uint64_t total_written = 0; +static uint64_t total_space = 0; + +static struct open_volume_fd *open_volumes; +static size_t open_volume_count = 0; + +static const char *ubi_module_load_string; + +static unsigned char *write_buffer = NULL; +static unsigned char *read_buffer = NULL; + +static long long max_ebs_per_vol = 0; /* max number of ebs per vol (zero => no max) */ + +static unsigned long next_seed = 1; + +static unsigned get_next_seed() +{ + next_seed = next_seed * 1103515245 + 12345; + return ((unsigned) (next_seed / 65536) % 32768); +} + +static void error_exit(const char *msg) +{ + int eno = errno; + fprintf(stderr,"UBI Integrity Test Error: %s\n",msg); + if (eno) { + fprintf(stderr, "errno = %d\n", eno); + fprintf(stderr, "strerror = %s\n", strerror(eno)); + } + exit(1); +} + +static void *allocate(size_t n) +{ + void *p = malloc(n); + if (!p) + error_exit("Memory allocation failure"); + memset(p, 0, n); + return p; +} + +static unsigned get_random_number(unsigned n) +{ + uint64_t r, b; + + if (n < 1) + return 0; + r = rand(); + r *= n; + b = RAND_MAX; + b += 1; + r /= b; + return r; +} + +static struct volume_fd *open_volume(struct volume_info *vol) +{ + struct volume_fd *s; + struct open_volume_fd *ofd; + int fd; + + if (vol->fds) { + /* If already open dup it */ + fd = dup(vol->fds->fd); + if (fd == -1) + error_exit("Failed to dup volume device file des"); + } else { + fd = open(vol->device_file_name, O_RDWR | O_LARGEFILE); + if (fd == -1) + error_exit("Failed to open volume device file"); + } + s = allocate(sizeof(*s)); + s->fd = fd; + s->volume = vol; + s->next = vol->fds; + vol->fds = s; + /* Add to open volumes list */ + ofd = allocate(sizeof(*ofd)); + ofd->vol_fd = s; + ofd->next = open_volumes; + open_volumes = ofd; + open_volume_count += 1; + return 0; +} + +static void close_volume(struct volume_fd *vol_fd) +{ + struct volume_fd *vfd, *vfd_last; + struct open_volume_fd *ofd, *ofd_last; + int fd = vol_fd->fd; + + /* Remove from open volumes list */ + ofd_last = NULL; + ofd = open_volumes; + while (ofd) { + if (ofd->vol_fd == vol_fd) { + if (ofd_last) + ofd_last->next = ofd->next; + else + open_volumes = ofd->next; + free(ofd); + open_volume_count -= 1; + break; + } + ofd_last = ofd; + ofd = ofd->next; + } + /* Remove from volume fd list */ + vfd_last = NULL; + vfd = vol_fd->volume->fds; + while (vfd) { + if (vfd == vol_fd) { + if (vfd_last) + vfd_last->next = vfd->next; + else + vol_fd->volume->fds = vfd->next; + free(vfd); + break; + } + vfd_last = vfd; + vfd = vfd->next; + } + /* Close volume device file */ + if (close(fd) == -1) + error_exit("Failed to close volume file descriptor"); +} + +static void set_random_data(unsigned seed, unsigned char *buf, int size) +{ + int i; + unsigned r; + + r = rand(); + srand(seed); + for (i = 0; i < size; ++i) + buf[i] = rand(); + srand(r); +} + +#if 0 +static void print_write_info(struct write_info *w) +{ + printf("Offset: %lld Size:%d Seed:%u\n", w->offset, w->size, w->random_seed); + fflush(stdout); +} +#endif + +static void check_erase_block(struct erase_block_info *erase_block, int fd) +{ + struct write_info *w; + off64_t gap_end; + int leb_size = erase_block->volume->info.leb_size; + ssize_t bytes_read; + + w = erase_block->writes; + gap_end = erase_block->offset + leb_size; + while (w) { + if (w->offset + w->size < gap_end) { + /* There is a gap. Check all 0xff */ + off64_t gap_start = w->offset + w->size; + size_t size = gap_end - gap_start; + if (lseek64(fd, gap_start, SEEK_SET) != gap_start) + error_exit("lseek64 failed"); + memset(read_buffer, 0 , size); + errno = 0; + bytes_read = read(fd, read_buffer, size); + if (bytes_read != size) + error_exit("read failed in gap"); + while (size) + if (read_buffer[--size] != 0xff) { + fprintf(stderr, "block no. = %d\n" , erase_block->block_number); + fprintf(stderr, "offset = %lld\n" , (long long) gap_start); + fprintf(stderr, "size = %ld\n" , (long) bytes_read); + error_exit("verify 0xff failed"); + } + } + if (lseek64(fd, w->offset, SEEK_SET) != w->offset) + error_exit("lseek64 failed"); + memset(read_buffer, 0 , w->size); + errno = 0; + bytes_read = read(fd, read_buffer, w->size); + if (bytes_read != w->size) { + fprintf(stderr, "offset = %lld\n" , (long long) w->offset); + fprintf(stderr, "size = %ld\n" , (long) w->size); + fprintf(stderr, "bytes_read = %ld\n" , (long) bytes_read); + error_exit("read failed"); + } + set_random_data(w->random_seed, write_buffer, w->size); + if (memcmp(read_buffer, write_buffer, w->size)) + error_exit("verify failed"); + gap_end = w->offset; + w = w->next; + } + if (gap_end > erase_block->offset) { + /* Check all 0xff */ + off64_t gap_start = erase_block->offset; + size_t size = gap_end - gap_start; + if (lseek64(fd, gap_start, SEEK_SET) != gap_start) + error_exit("lseek64 failed"); + memset(read_buffer, 0 , size); + errno = 0; + bytes_read = read(fd, read_buffer, size); + if (bytes_read != size) + error_exit("read failed in gap"); + while (size) + if (read_buffer[--size] != 0xff) { + fprintf(stderr, "block no. = %d\n" , erase_block->block_number); + fprintf(stderr, "offset = %lld\n" , (long long) gap_start); + fprintf(stderr, "size = %ld\n" , (long) bytes_read); + error_exit("verify 0xff failed!"); + } + } +} + +static int write_to_erase_block(struct erase_block_info *erase_block, int fd) +{ + int page_size = erase_block->volume->ubi_device->info.min_io_size; + int leb_size = erase_block->volume->info.leb_size; + int next_offset = 0; + int space, size; + off64_t offset; + unsigned seed; + struct write_info *w; + + if (erase_block->writes) + next_offset = erase_block->writes->offset_within_block + erase_block->writes->size; + space = leb_size - next_offset; + if (space <= 0) + return 0; /* No space */ + if (!get_random_number(10)) { + /* 1 time in 10 leave a gap */ + next_offset += get_random_number(space); + next_offset = (next_offset / page_size) * page_size; + space = leb_size - next_offset; + } + if (get_random_number(2)) + size = 1 * page_size; + else if (get_random_number(2)) + size = 2 * page_size; + else if (get_random_number(2)) + size = 3 * page_size; + else if (get_random_number(2)) + size = 4 * page_size; + else { + if (get_random_number(4)) + size = get_random_number(space); + else + size = space; + size = (size / page_size) * page_size; + } + if (size == 0 || size > space) + size = page_size; + if (next_offset + size > leb_size) + error_exit("internal error"); + offset = erase_block->offset + next_offset; + if (offset < erase_block->top_of_data) + error_exit("internal error!"); + if (lseek64(fd, offset, SEEK_SET) != offset) + error_exit("lseek64 failed"); + /* Do write */ + seed = get_next_seed(); + if (!seed) + seed = 1; + set_random_data(seed, write_buffer, size); + if (write(fd, write_buffer, size) != size) + error_exit("write failed"); + erase_block->top_of_data = offset + size; + /* Make write info and add to eb */ + w = allocate(sizeof(*w)); + w->offset_within_block = next_offset; + w->offset = offset; + w->size = size; + w->random_seed = seed; + w->next = erase_block->writes; + erase_block->writes = w; + erase_block->touched = 1; + erase_block->erased = 0; + total_written += size; + return 1; +} + +static void erase_erase_block(struct erase_block_info *erase_block, int fd) +{ + struct write_info *w; + uint32_t eb_no; + int res; + + eb_no = erase_block->block_number; + res = ioctl(fd, UBI_IOCEBER, &eb_no); + if (res) + error_exit("Failed to erase an erase block"); + /* Remove writes from this eb */ + while (erase_block->writes) { + w = erase_block->writes; + erase_block->writes = erase_block->writes->next; + free(w); + } + erase_block->erased = 1; + erase_block->touched = 1; + erase_block->top_of_data = erase_block->offset; +} + +static void operate_on_erase_block(struct erase_block_info *erase_block, int fd) +{ + /* + Possible operations: + read from it and verify + write to it + erase it + */ + int work_done = 1; + static int no_work_done_count = 0; + + if (!get_random_number(10) && no_work_done_count <= 5) { + check_erase_block(erase_block, fd); + work_done = 0; + } else if (get_random_number(100)) { + if (!write_to_erase_block(erase_block, fd)) { + /* The erase block was full */ + if (get_random_number(2) || no_work_done_count > 5) + erase_erase_block(erase_block, fd); + else + work_done = 0; + } + } else + erase_erase_block(erase_block, fd); + if (work_done) + no_work_done_count = 0; + else + no_work_done_count += 1; +} + +static void operate_on_open_volume(struct volume_fd *vol_fd) +{ + /* + Possible operations: + operate on an erase block + close volume + */ + if (get_random_number(100) == 0) + close_volume(vol_fd); + else { + /* Pick an erase block at random */ + int eb_no = get_random_number(vol_fd->volume->info.rsvd_lebs); + operate_on_erase_block(&vol_fd->volume->erase_blocks[eb_no], vol_fd->fd); + } +} + +static void operate_on_volume(struct volume_info *vol) +{ + /* + Possible operations: + open it + resize it (must close fd's first) <- TODO + delete it (must close fd's first) <- TODO + */ + open_volume(vol); +} + +static int ubi_major(const char *device_file_name) +{ + struct stat buf; + static int maj = 0; + + if (maj) + return maj; + if (stat(device_file_name, &buf) == -1) + error_exit("Failed to stat ubi device file"); + maj = major(buf.st_rdev); + return maj; +} + +static void operate_on_ubi_device(struct ubi_device_info *ubi_device) +{ + /* + TODO: + Possible operations: + create a new volume + operate on existing volume + */ + /* + Simplified operation (i.e. only have 1 volume): + If there are no volumes create 1 volumne + Then operate on the volume + */ + if (ubi_device->info.vol_count == 0) { + /* Create the one-and-only volume we will use */ + char dev_name[1024]; + int i, n, maj, fd; + struct volume_info *s; + struct ubi_mkvol_request req; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; /* TODO: What is this? */ + req.bytes = ubi_device->info.leb_size * max_ebs_per_vol; + if (req.bytes == 0 || req.bytes > ubi_device->info.avail_bytes) + req.bytes = ubi_device->info.avail_bytes; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = "integ-test-vol"; + if (ubi_mkvol(libubi, ubi_device->device_file_name, &req)) + error_exit("ubi_mkvol failed"); + s = allocate(sizeof(*s)); + s->ubi_device = ubi_device; + if (ubi_get_vol_info1(libubi, ubi_device->info.dev_num, req.vol_id, &s->info)) + error_exit("ubi_get_vol_info failed"); + n = s->info.rsvd_lebs; + s->erase_blocks = allocate(sizeof(struct erase_block_info) * n); + for (i = 0; i < n; ++i) { + s->erase_blocks[i].volume = s; + s->erase_blocks[i].block_number = i; + s->erase_blocks[i].offset = i * (off64_t) s->info.leb_size; + s->erase_blocks[i].top_of_data = s->erase_blocks[i].offset; + } + /* FIXME: Correctly get device file name */ + sprintf(dev_name, "%s_%d", ubi_device->device_file_name, req.vol_id); + s->device_file_name = strdup(dev_name); + ubi_device->volumes = s; + ubi_device->info.vol_count += 1; + sleep(1); + fd = open(s->device_file_name, O_RDONLY); + if (fd == -1) { + /* FIXME: Correctly make node */ + maj = ubi_major(ubi_device->device_file_name); + sprintf(dev_name, "mknod %s c %d %d", s->device_file_name, maj, req.vol_id + 1); + system(dev_name); + } else if (close(fd) == -1) + error_exit("Failed to close volume device file"); + } + operate_on_volume(ubi_device->volumes); +} + +static void do_an_operation(void) +{ + int too_few = (open_volume_count < info.dev_count * 3); + int too_many = (open_volume_count > info.dev_count * 5); + + if (too_many || (!too_few && get_random_number(1000) > 0)) { + /* Operate on an open volume */ + size_t pos; + struct open_volume_fd *ofd; + pos = get_random_number(open_volume_count); + for (ofd = open_volumes; pos && ofd && ofd->next; --pos) + ofd = ofd->next; + operate_on_open_volume(ofd->vol_fd); + } else if (info.dev_count > 0) { + /* Operate on a ubi device */ + size_t ubi_pos = 0; + if (info.dev_count > 1) + ubi_pos = get_random_number(info.dev_count - 1); + operate_on_ubi_device(&ubi_array[ubi_pos]); + } else + error_exit("Internal error"); +} + +static void get_ubi_devices_info(void) +{ + int i, ubi_pos = 0; + char dev_name[1024]; + size_t buf_size = 1024 * 128; + + if (ubi_get_info(libubi, &info)) + error_exit("ubi_get_info failed"); + if (info.dev_count > MAX_UBI_DEVICES) + error_exit("Too many ubi devices"); + for (i = info.lowest_dev_num; i <= info.highest_dev_num; ++i) { + struct ubi_device_info *s; + s = &ubi_array[ubi_pos++]; + if (ubi_get_dev_info1(libubi, i, &s->info)) + error_exit("ubi_get_dev_info1 failed"); + if (s->info.vol_count) + error_exit("There are existing volumes"); + /* FIXME: Correctly get device file name */ + sprintf(dev_name, "/dev/ubi%d", i); + s->device_file_name = strdup(dev_name); + if (buf_size < s->info.leb_size) + buf_size = s->info.leb_size; + if (max_ebs_per_vol && s->info.leb_size * max_ebs_per_vol < s->info.avail_bytes) + total_space += s->info.leb_size * max_ebs_per_vol; + else + total_space += s->info.avail_bytes; + } + write_buffer = allocate(buf_size); + read_buffer = allocate(buf_size); +} + +static void load_ubi(void) +{ + system("rmmod ubi"); + if (system(ubi_module_load_string) != 0) + error_exit("Failed to load UBI module"); + sleep(1); +} + +static void do_some_operations(void) +{ + unsigned i = 0; + total_written = 0; + printf("Total space: %llu\n", (unsigned long long) total_space); + while (total_written < total_space * 3) { + do_an_operation(); + if (i++ % 10000 == 0) + printf("Total written: %llu\n", (unsigned long long) total_written); + } + printf("Total written: %llu\n", (unsigned long long) total_written); +} + +static void reload_ubi(void) +{ + /* Remove module */ + if (system("rmmod ubi") != 0) + error_exit("Failed to remove UBI module"); + /* Install module */ + if (system(ubi_module_load_string) != 0) + error_exit("Failed to load UBI module"); + sleep(1); +} + +static void check_volume(struct volume_info *vol) +{ + struct erase_block_info *eb = vol->erase_blocks; + int pos; + int fd; + + fd = open(vol->device_file_name, O_RDWR | O_LARGEFILE); + if (fd == -1) + error_exit("Failed to open volume device file"); + for (pos = 0; pos < vol->info.rsvd_lebs; ++pos) + check_erase_block(eb++, fd); + if (close(fd) == -1) + error_exit("Failed to close volume device file"); +} + +static void check_ubi_device(struct ubi_device_info *ubi_device) +{ + struct volume_info *vol; + + vol = ubi_device->volumes; + while (vol) { + check_volume(vol); + vol = vol->next; + } +} + +static void check_ubi(void) +{ + int i; + + for (i = 0; i < info.dev_count; ++i) + check_ubi_device(&ubi_array[i]); +} + +static int is_all_digits(const char *s) +{ + const char *digits = "0123456789"; + if (!s || !*s) + return 0; + for (;*s;++s) + if (!strchr(digits,*s)) + return 0; + return 1; +} + +static int get_short_arg(int *pos,const char *name,long long *result,int argc,char *argv[]) +{ + const char *p = NULL; + int i = *pos; + size_t n = strlen(name); + + if (strlen(argv[i]) > n) + p = argv[i] + n; + else if (++i < argc) + p = argv[i]; + if (!is_all_digits(p)) + return 1; + *result = atoll(p); + *pos = i; + return 0; +} + +static int get_long_arg(int *pos,const char *name,long long *result,int argc,char *argv[]) +{ + const char *p = NULL; + int i = *pos; + size_t n = strlen(name); + + if (strlen(argv[i]) > n) + p = argv[i] + n; + else if (++i < argc) + p = argv[i]; + if (p && *p == '=') { + p += 1; + if (!*p && ++i < argc) + p = argv[i]; + } + if (!is_all_digits(p)) + return 1; + *result = atoll(p); + *pos = i; + return 0; +} + +static int remove_all_volumes(void) +{ + int i; + + for (i = 0; i < info.dev_count; ++i) { + struct ubi_device_info *ubi_device = &ubi_array[i]; + struct volume_info *vol; + vol = ubi_device->volumes; + while (vol) { + int res = ubi_rmvol(libubi, + ubi_device->device_file_name, + vol->info.vol_id); + if (res) + return res; + vol = vol->next; + } + } + return 0; +} + +int main(int argc,char *argv[]) +{ + int i; + long long r, repeat = 1; + int initial_seed = 1, args_ok = 1; + + printf("UBI Integrity Test\n"); + + /* Get arguments */ + ubi_module_load_string = 0; + for (i = 1; i < argc; ++i) { + if (strncmp(argv[i], "-h", 2) == 0) + args_ok = 0; + else if (strncmp(argv[i], "--help", 6) == 0) + args_ok = 0; + else if (strncmp(argv[i], "-n", 2) == 0) { + if (get_short_arg(&i, "-n", &repeat, argc, argv)) + args_ok = 0; + } else if (strncmp(argv[i], "--repeat", 8) == 0) { + if (get_long_arg(&i, "--repeat", &repeat, argc, argv)) + args_ok = 0; + } else if (strncmp(argv[i], "-m", 2) == 0) { + if (get_short_arg(&i,"-m", &max_ebs_per_vol, argc, argv)) + args_ok = 0; + } else if (strncmp(argv[i], "--maxebs", 8) == 0) { + if (get_long_arg(&i, "--maxebs", &max_ebs_per_vol, argc, argv)) + args_ok = 0; + } else if (!ubi_module_load_string) + ubi_module_load_string = argv[i]; + else + args_ok = 0; + } + if (!args_ok || !ubi_module_load_string) { + fprintf(stderr, "Usage is: ubi_integ [] \n"); + fprintf(stderr, " Options: \n"); + fprintf(stderr, " -h, --help Help\n"); + fprintf(stderr, " -n arg, --repeat=arg Repeat test arg times\n"); + fprintf(stderr, " -m arg, --maxebs=arg Max no. of erase blocks\n"); + return 1; + } + + initial_seed = getpid(); + printf("Initial seed = %u\n", (unsigned) initial_seed); + next_seed = initial_seed; + srand(initial_seed); + load_ubi(); + + libubi = libubi_open(); + if (!libubi) + error_exit("Failed to open libubi"); + + get_ubi_devices_info(); + + r = 0; + while (repeat == 0 || r++ < repeat) { + printf("Cycle %lld\n", r); + do_some_operations(); + + /* Close all volumes */ + while (open_volumes) + close_volume(open_volumes->vol_fd); + + check_ubi(); + + libubi_close(libubi); + + reload_ubi(); + + libubi = libubi_open(); + if (!libubi) + error_exit("Failed to open libubi"); + + check_ubi(); + } + + if (remove_all_volumes()) + error_exit("Failed to remove all volumes"); + + libubi_close(libubi); + + printf("UBI Integrity Test completed ok\n"); + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_basic.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_basic.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_basic.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_basic.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,179 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test basic UBI volume I/O capabilities. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "io_basic" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; + +/** + * test_basic - check basic volume read and update capabilities. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_basic(int type) +{ + struct ubi_mkvol_request req; + const char *name = TESTNAME ":test_basic()"; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = type; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, req.vol_id); + + /* Make sure newly created volume contains only 0xFF bytes */ + if (check_vol_patt(vol_node, 0xFF)) + goto remove; + + /* Write 0xA5 bytes to the volume */ + if (update_vol_patt(vol_node, dev_info.avail_bytes, 0xA5)) + goto remove; + if (check_vol_patt(vol_node, 0xA5)) + goto remove; + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +/** + * test_aligned - test volume alignment feature. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_aligned(int type) +{ + int i, ebsz; + struct ubi_mkvol_request req; + const char *name = TESTNAME ":test_aligned()"; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + int alignments[] = ALIGNMENTS(dev_info.leb_size); + + req.vol_type = type; + req.name = name; + + for (i = 0; i < sizeof(alignments)/sizeof(int); i++) { + req.vol_id = UBI_VOL_NUM_AUTO; + + req.alignment = alignments[i]; + req.alignment -= req.alignment % dev_info.min_io_size; + if (req.alignment == 0) + req.alignment = dev_info.min_io_size; + + ebsz = dev_info.leb_size - dev_info.leb_size % req.alignment; + req.bytes = MIN_AVAIL_EBS * ebsz; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, req.vol_id); + + /* Make sure newly created volume contains only 0xFF bytes */ + if (check_vol_patt(vol_node, 0xFF)) + goto remove; + + /* Write 0xA5 bytes to the volume */ + if (update_vol_patt(vol_node, req.bytes, 0xA5)) + goto remove; + if (check_vol_patt(vol_node, 0xA5)) + goto remove; + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (test_basic(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_basic(UBI_STATIC_VOLUME)) + goto close; + if (test_aligned(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_aligned(UBI_STATIC_VOLUME)) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_paral.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_paral.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_paral.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_paral.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,249 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * This test does a lot of I/O to volumes in parallel. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "io_paral" +#include "common.h" + +#define THREADS_NUM 3 +#define ITERATIONS 10 + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; +static int iterations = ITERATIONS; +int total_bytes; + +static long long memory_limit(void) +{ + long long result = 0; + FILE *f; + + f = fopen("/proc/meminfo", "r"); + if (!f) + return 0; + fscanf(f, "%*s %lld", &result); + fclose(f); + return result * 1024 / 4; +} + +/** + * the_thread - the testing thread. + * + * @ptr thread number + */ +static void * the_thread(void *ptr) +{ + int fd, iter = iterations, vol_id = (int)ptr; + unsigned char *wbuf, *rbuf; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + + wbuf = malloc(total_bytes); + rbuf = malloc(total_bytes); + if (!wbuf || !rbuf) { + failed("malloc"); + goto free; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, vol_id); + + while (iter--) { + int i, ret, written = 0, rd = 0; + int bytes = (random() % (total_bytes - 1)) + 1; + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + goto free; + } + + for (i = 0; i < bytes; i++) + wbuf[i] = random() % 255; + memset(rbuf, '\0', bytes); + + do { + ret = ubi_update_start(libubi, fd, bytes); + if (ret && errno != EBUSY) { + failed("ubi_update_start"); + err_msg("vol_id %d", vol_id); + goto close; + } + } while (ret); + + while (written < bytes) { + int to_write = random() % (bytes - written); + + if (to_write == 0) + to_write = 1; + + ret = write(fd, wbuf, to_write); + if (ret != to_write) { + failed("write"); + err_msg("failed to write %d bytes at offset %d " + "of volume %d", to_write, written, + vol_id); + err_msg("update: %d bytes", bytes); + goto close; + } + + written += to_write; + } + + close(fd); + + fd = open(vol_node, O_RDONLY); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + goto free; + } + + /* read data back and check */ + while (rd < bytes) { + int to_read = random() % (bytes - rd); + + if (to_read == 0) + to_read = 1; + + ret = read(fd, rbuf, to_read); + if (ret != to_read) { + failed("read"); + err_msg("failed to read %d bytes at offset %d " + "of volume %d", to_read, rd, vol_id); + goto close; + } + + rd += to_read; + } + + close(fd); + + } + + free(wbuf); + free(rbuf); + return NULL; + +close: + close(fd); +free: + free(wbuf); + free(rbuf); + return NULL; +} + +int main(int argc, char * const argv[]) +{ + int i, ret; + pthread_t threads[THREADS_NUM]; + struct ubi_mkvol_request req; + long long mem_limit; + + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + req.alignment = 1; + mem_limit = memory_limit(); + if (mem_limit && mem_limit < dev_info.avail_bytes) + total_bytes = req.bytes = + (mem_limit / dev_info.leb_size / THREADS_NUM) + * dev_info.leb_size; + else + total_bytes = req.bytes = + ((dev_info.avail_lebs - 3) / THREADS_NUM) + * dev_info.leb_size; + for (i = 0; i < THREADS_NUM; i++) { + char name[100]; + + req.vol_id = i; + sprintf(name, TESTNAME":%d", i); + req.name = name; + req.vol_type = (i & 1) ? UBI_STATIC_VOLUME : UBI_DYNAMIC_VOLUME; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + goto remove; + } + } + + /* Create one volume with static data to make WL work more */ + req.vol_id = THREADS_NUM; + req.name = TESTNAME ":static"; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.bytes = 3*dev_info.leb_size; + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + goto remove; + } + + for (i = 0; i < THREADS_NUM; i++) { + ret = pthread_create(&threads[i], NULL, &the_thread, (void*)i); + if (ret) { + failed("pthread_create"); + goto remove; + } + } + + for (i = 0; i < THREADS_NUM; i++) + pthread_join(threads[i], NULL); + + for (i = 0; i <= THREADS_NUM; i++) { + if (ubi_rmvol(libubi, node, i)) { + failed("ubi_rmvol"); + goto remove; + } + } + + libubi_close(libubi); + return 0; + +remove: + for (i = 0; i <= THREADS_NUM; i++) + ubi_rmvol(libubi, node, i); + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_read.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_read.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_read.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_read.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,388 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test UBI volume read. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "io_basic" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; +static int fd; + +/* Data lengthes to test, @io - minimal I/O unit size, @s - eraseblock size */ +#define LENGTHES(io, s) \ + {1, (io), (io)+1, 2*(io), 3*(io)-1, 3*(io), \ + PAGE_SIZE-1, PAGE_SIZE-(io), 2*PAGE_SIZE, 2*PAGE_SIZE-(io), \ + (s)/2-1, (s)/2, (s)/2+1, (s)-1, (s), (s)+1, 2*(s)-(io), 2*(s), \ + 2*(s)+(io), 3*(s), 3*(s)+(io)}; + +/* + * Offsets to test, @io - minimal I/O unit size, @s - eraseblock size, @sz - + * volume size. + */ +#define OFFSETS(io, s, sz) \ + {0, (io)-1, (io), (io)+1, 2*(io)-1, 2*(io), 3*(io)-1, 3*(io), \ + PAGE_SIZE-1, PAGE_SIZE-(io), 2*PAGE_SIZE, 2*PAGE_SIZE-(io), \ + (s)/2-1, (s)/2, (s)/2+1, (s)-1, (s), (s)+1, 2*(s)-(io), 2*(s), \ + 2*(s)+(io), 3*(s), (sz)-(s)-1, (sz)-(io)-1, (sz)-PAGE_SIZE-1}; + +/** + * test_static - test static volume-specific features. + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_static(void) +{ + struct ubi_mkvol_request req; + const char *name = TESTNAME ":io_basic()"; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + struct ubi_vol_info vol_info; + int fd, ret; + char buf[20]; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = UBI_STATIC_VOLUME; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, req.vol_id); + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + goto remove; + } + + if (ubi_get_vol_info(libubi, vol_node, &vol_info)) { + failed("ubi_get_vol_info"); + goto close; + } + + /* Make sure new static volume contains no data */ + if (vol_info.data_bytes != 0) { + err_msg("data_bytes = %lld, not zero", vol_info.data_bytes); + goto close; + } + + /* Ensure read returns EOF */ + ret = read(fd, buf, 1); + if (ret < 0) { + failed("read"); + goto close; + } + if (ret != 0) { + err_msg("read data from free static volume"); + goto close; + } + + if (ubi_update_start(libubi, fd, 10)) { + failed("ubi_update_start"); + goto close; + } + + ret = write(fd, buf, 10); + if (ret < 0) { + failed("write"); + goto close; + } + if (ret != 10) { + err_msg("written %d bytes", ret); + goto close; + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + failed("seek"); + goto close; + } + ret = read(fd, buf, 20); + if (ret < 0) { + failed("read"); + goto close; + } + if (ret != 10) { + err_msg("read %d bytes", ret); + goto close; + } + + close(fd); + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + return 0; + +close: + close(fd); +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +/* + * A helper function for test_read2(). + */ +static int test_read3(const struct ubi_vol_info *vol_info, int len, off_t off) +{ + int i, len1; + unsigned char ck_buf[len], buf[len]; + off_t new_off; + + if (off + len > vol_info->data_bytes) + len1 = vol_info->data_bytes - off; + else + len1 = len; + + if (lseek(fd, off, SEEK_SET) != off) { + failed("seek"); + err_msg("len = %d", len); + return -1; + } + if (read(fd, buf, len) != len1) { + failed("read"); + err_msg("len = %d", len); + return -1; + } + + new_off = lseek(fd, 0, SEEK_CUR); + if (new_off != off + len1) { + if (new_off == -1) + failed("lseek"); + else + err_msg("read %d bytes from %lld, but resulting " + "offset is %lld", len1, (long long) off, (long long) new_off); + return -1; + } + + for (i = 0; i < len1; i++) + ck_buf[i] = (unsigned char)(off + i); + + if (memcmp(buf, ck_buf, len1)) { + err_msg("incorrect data read from offset %lld", + (long long)off); + err_msg("len = %d", len); + return -1; + } + + return 0; +} + +/* + * A helper function for test_read1(). + */ +static int test_read2(const struct ubi_vol_info *vol_info, int len) +{ + int i; + off_t offsets[] = OFFSETS(dev_info.min_io_size, vol_info->leb_size, + vol_info->data_bytes); + + for (i = 0; i < sizeof(offsets)/sizeof(off_t); i++) { + if (test_read3(vol_info, len, offsets[i])) { + err_msg("offset = %d", offsets[i]); + return -1; + } + } + + return 0; +} + +/* + * A helper function for test_read(). + */ +static int test_read1(struct ubi_vol_info *vol_info) +{ + int i, written = 0; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + int lengthes[] = LENGTHES(dev_info.min_io_size, vol_info->leb_size); + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + vol_info->vol_id); + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + return -1; + } + + /* Write some pattern to the volume */ + if (ubi_update_start(libubi, fd, vol_info->rsvd_bytes)) { + failed("ubi_update_start"); + err_msg("bytes = %lld", vol_info->rsvd_bytes); + goto close; + } + + while (written < vol_info->rsvd_bytes) { + int i, ret; + unsigned char buf[512]; + + for (i = 0; i < 512; i++) + buf[i] = (unsigned char)(written + i); + + ret = write(fd, buf, 512); + if (ret == -1) { + failed("write"); + err_msg("written = %d, ret = %d", written, ret); + goto close; + } + written += ret; + } + + close(fd); + + if (ubi_get_vol_info(libubi, vol_node, vol_info)) { + failed("ubi_get_vol_info"); + return -1; + } + + fd = open(vol_node, O_RDONLY); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + return -1; + } + + for (i = 0; i < sizeof(lengthes)/sizeof(int); i++) { + if (test_read2(vol_info, lengthes[i])) { + err_msg("length = %d", lengthes[i]); + goto close; + } + } + + close(fd); + return 0; + +close: + close(fd); + return -1; +} + +/** + * test_read - test UBI volume reading from different offsets. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_read(int type) +{ + const char *name = TESTNAME ":test_read()"; + int alignments[] = ALIGNMENTS(dev_info.leb_size); + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + struct ubi_mkvol_request req; + int i; + + for (i = 0; i < sizeof(alignments)/sizeof(int); i++) { + int leb_size; + struct ubi_vol_info vol_info; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.vol_type = type; + req.name = name; + + req.alignment = alignments[i]; + req.alignment -= req.alignment % dev_info.min_io_size; + if (req.alignment == 0) + req.alignment = dev_info.min_io_size; + + leb_size = dev_info.leb_size - dev_info.leb_size % req.alignment; + req.bytes = MIN_AVAIL_EBS * leb_size; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + req.vol_id); + + if (ubi_get_vol_info(libubi, vol_node, &vol_info)) { + failed("ubi_get_vol_info"); + goto remove; + } + + if (test_read1(&vol_info)) { + err_msg("alignment = %d", req.alignment); + goto remove; + } + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (test_static()) + goto close; + if (test_read(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_read(UBI_STATIC_VOLUME)) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_update.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_update.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/io_update.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/io_update.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,298 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test UBI volume update and atomic LEB change + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#define TESTNAME "io_update" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; + +#define SEQUENCES(io, s) { \ + {3*(s)-(io)-1, 1}, \ + {512}, \ + {666}, \ + {2048}, \ + {(io), (io), PAGE_SIZE}, \ + {(io)+1, (io)+1, PAGE_SIZE}, \ + {PAGE_SIZE}, \ + {PAGE_SIZE-1}, \ + {PAGE_SIZE+(io)}, \ + {(s)}, \ + {(s)-1}, \ + {(s)+1}, \ + {(io), (s)+1}, \ + {(s)+(io), PAGE_SIZE}, \ + {2*(s), PAGE_SIZE}, \ + {PAGE_SIZE, 2*(s), 1}, \ + {PAGE_SIZE, 2*(s)}, \ + {2*(s)-1, 2*(s)-1}, \ + {3*(s), PAGE_SIZE + 1}, \ + {1, PAGE_SIZE}, \ + {(io), (s)} \ +} + +#define SEQ_SZ 21 + +/* + * test_update1 - helper function for test_update(). + */ +static int test_update1(struct ubi_vol_info *vol_info, int leb_change) +{ + long long total_len = leb_change ? vol_info->leb_size + : vol_info->rsvd_bytes; + int sequences[SEQ_SZ][3] = SEQUENCES(dev_info.min_io_size, + leb_change ? dev_info.min_io_size * 2 + : vol_info->leb_size); + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + unsigned char buf[total_len]; + int fd, i, j; + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + vol_info->vol_id); + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", node); + return -1; + } + + for (i = 0; i < SEQ_SZ; i++) { + int ret, stop = 0, len = 0; + off_t off = 0; + long long test_len; + unsigned char buf1[total_len]; + + /* + * test_len is LEB size (if we test atomic LEB change) or + * volume size (if we test update). For better test coverage, + * use a little smaller LEB change/update length. + */ + test_len = total_len - (rand() % (total_len / 10)); + + if (leb_change) { + if (ubi_leb_change_start(libubi, fd, 0, test_len, + UBI_SHORTTERM)) { + failed("ubi_update_start"); + goto close; + } + } else { + if (ubi_update_start(libubi, fd, test_len)) { + failed("ubi_update_start"); + goto close; + } + } + + for (j = 0; off < test_len; j++) { + int n, rnd_len, l; + + if (!stop) { + if (sequences[i][j] != 0) + l = len = sequences[i][j]; + else + stop = 1; + } + + /* + * Fill some part of the write buffer with random data, + * and the other part with 0xFFs to test how UBI + * stripes 0xFFs multiple of I/O unit size. + */ + if (off + l > test_len) + l = test_len - off; + rnd_len = rand() % (l + 1); + for (n = 0; n < rnd_len; n++) + buf[off + n] = (unsigned char)rand(); + memset(buf + off + rnd_len, 0xFF, l - rnd_len); + + /* + * Deliberately pass len instead of l (len may be + * greater then l if this is the last chunk) because + * UBI have to read only l bytes anyway. + */ + ret = write(fd, buf + off, len); + if (ret < 0) { + failed("write"); + err_msg("failed to write %d bytes at offset " + "%lld", len, (long long)off); + goto close; + } + len = l; + if (ret != len) { + err_msg("failed to write %d bytes at offset " + "%lld, wrote %d", len, (long long)off, ret); + goto close; + } + off += len; + } + + /* Check data */ + if ((ret = lseek(fd, SEEK_SET, 0)) != 0) { + failed("lseek"); + err_msg("cannot seek to 0"); + goto close; + } + + memset(buf1, 0x01, test_len); + + if (vol_info->type == UBI_STATIC_VOLUME) + /* + * Static volume must not let use read more then it + * contains. + */ + ret = read(fd, buf1, test_len + 100); + else + ret = read(fd, buf1, test_len); + if (ret < 0) { + failed("read"); + err_msg("failed to read %d bytes", test_len); + goto close; + } + if (ret != test_len) { + err_msg("failed to read %d bytes, read %d", test_len, ret); + goto close; + } + if (memcmp(buf, buf1, test_len)) { + err_msg("data corruption"); + goto close; + } + } + + close(fd); + return 0; + +close: + close(fd); + return -1; +} + +/** + * test_update - check volume update and atomic LEB change capabilities. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int test_update(int type) +{ + struct ubi_mkvol_request req; + const char *name = TESTNAME ":io_update()"; + int alignments[] = ALIGNMENTS(dev_info.leb_size); + struct ubi_vol_info vol_info; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + int i; + + for (i = 0; i < sizeof(alignments)/sizeof(int); i++) { + int leb_size; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.vol_type = type; + req.name = name; + + req.alignment = alignments[i]; + req.alignment -= req.alignment % dev_info.min_io_size; + if (req.alignment == 0) + req.alignment = dev_info.min_io_size; + + leb_size = dev_info.leb_size - dev_info.leb_size % req.alignment; + req.bytes = MIN_AVAIL_EBS * leb_size; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + req.vol_id); + if (ubi_get_vol_info(libubi, vol_node, &vol_info)) { + failed("ubi_get_vol_info"); + goto remove; + } + + if (test_update1(&vol_info, 0)) { + err_msg("alignment = %d", req.alignment); + goto remove; + } + + if (vol_info.type != UBI_STATIC_VOLUME) { + if (test_update1(&vol_info, 1)) { + err_msg("alignment = %d", req.alignment); + goto remove; + } + } + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (test_update(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_update(UBI_STATIC_VOLUME)) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/Makefile 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,48 @@ +LIBUBI_PATH=../../ubi-utils/new-utils/ +LIBUBI_SRC_PATH=../../ubi-utils/new-utils/src/ +LIBUBI_HEADER_PATH=../../ubi-utils/new-utils/include +UBI_HEADERS_PATH=../../include/ +UBIUTILS_PATH=../../ubi-utils/new-utils/ + +CC := $(CROSS)gcc + +TESTS=io_update volrefcnt integ io_paral io_read io_basic \ + mkvol_basic mkvol_bad mkvol_paral rsvol + +HELPER_NAMES=ubiupdatevol +HELPERS=$(addprefix helpers/, $(HELPER_NAMES)) + +# Because of implicite rules we use make treats .o files as intermediate, thus +# it removes the. If you want to prevent the removal, uncomment the below +#.SECONDARY: $(addsuffix .o, $(TESTS)) $(addsuffix .o, $(HELPERS)) + +CFLAGS += -Wall -I$(LIBUBI_HEADER_PATH) -I $(UBI_HEADERS_PATH) -L. -O2 + +all: ubi-utils libubi $(TESTS) $(HELPERS) + +# Compile ubilib with the udevsettle hack +libubi: $(LIBUBI_SRC_PATH)/libubi.c $(LIBUBI_HEADER_PATH)/libubi.h $(LIBUBI_SRC_PATH)/libubi_int.h + $(CC) $(CFLAGS) -I $(LIBUBI_SRC_PATH) -I../../include -DUDEV_SETTLE_HACK -c $(LIBUBI_SRC_PATH)/libubi.c -o libubi.o + ar cr libubi.a libubi.o + +# The below cancels existing implicite rule to make programs from .c files, +# in order to force make using our rule defined below +%: %.c + +# The below is the rule to get an .o file from a .c file +%.o: %.c + $(CC) $(CFLAGS) $< -c -o $@ + +# And the below is the rule to get final test executable from its .o and common.o +%: %.o common.o + $(CC) $(CFLAGS) $^ -lubi -o $@ + +# *paral tests require libpthread, thus the below rule for them +%paral: %paral.o common.o + $(CC) $(CFLAGS) $^ -lubi -lpthread -o $@ + +ubi-utils: + make -C $(UBIUTILS_PATH) + +clean: + rm -f $(TESTS) $(addsuffix .o, $(TESTS)) libubi.* $(HELPERS) $(addsuffix .o, $(HELPERS)) diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_bad.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_bad.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_bad.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_bad.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,301 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test UBI volume creation and deletion ioctl()s with bad input and in case of + * incorrect usage. + */ + +#include +#include +#include +#include "libubi.h" +#define TESTNAME "mkvol_bad" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; + +/** + * test_mkvol - test that UBI mkvol ioctl rejects bad input parameters. + * + * This function returns %0 if the test passed and %-1 if not. + */ +static int test_mkvol(void) +{ + int ret, i; + struct ubi_mkvol_request req; + const char *name = TESTNAME ":test_mkvol()"; + + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = name; + + /* Bad volume ID */ + req.vol_id = -2; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "vol_id = %d", req.vol_id)) + return -1; + + req.vol_id = dev_info.max_vol_count; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "vol_id = %d", req.vol_id)) + return -1; + + /* Bad alignment */ + req.vol_id = 0; + req.alignment = 0; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "alignment = %d", + req.alignment)) + return -1; + + req.alignment = -1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "alignment = %d", + req.alignment)) + return -1; + + req.alignment = dev_info.leb_size + 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "alignment = %d", + req.alignment)) + return -1; + + if (dev_info.min_io_size > 1) { + req.alignment = dev_info.min_io_size + 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "alignment = %d", + req.alignment)) + return -1; + } + + /* Bad bytes */ + req.alignment = 1; + req.bytes = -1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "bytes = %lld", req.bytes)) + return -1; + + req.bytes = 0; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "bytes = %lld", req.bytes)) + return -1; + + req.bytes = dev_info.avail_bytes + 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, ENOSPC, "ubi_mkvol", "bytes = %lld", req.bytes)) + return -1; + + req.alignment = dev_info.leb_size - dev_info.min_io_size; + req.bytes = (dev_info.leb_size - dev_info.leb_size % req.alignment) * + dev_info.avail_lebs + 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, ENOSPC, "ubi_mkvol", "bytes = %lld", req.bytes)) + return -1; + + /* Bad vol_type */ + req.alignment = 1; + req.bytes = dev_info.leb_size; + req.vol_type = UBI_DYNAMIC_VOLUME + UBI_STATIC_VOLUME; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "vol_type = %d", + req.vol_type)) + return -1; + + req.vol_type = UBI_DYNAMIC_VOLUME; + + /* Too long name */ + { + char name[UBI_VOL_NAME_MAX + 5]; + + memset(name, 'x', UBI_VOL_NAME_MAX + 1); + name[UBI_VOL_NAME_MAX + 1] = '\0'; + + req.name = name; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EINVAL, "ubi_mkvol", "name_len = %d", + UBI_VOL_NAME_MAX + 1)) + return -1; + } + + /* Try to create 2 volumes with the same ID and name */ + req.name = name; + req.vol_id = 0; + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EEXIST, "ubi_mkvol", + "volume with ID 0 created twice")) + return -1; + + req.vol_id = 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EEXIST, "ubi_mkvol", + "volume with name \"%s\" created twice", name)) + return -1; + + if (ubi_rmvol(libubi, node, 0)) { + failed("ubi_rmvol"); + return -1; + } + + /* Try to use too much space */ + req.vol_id = 0; + req.bytes = dev_info.avail_bytes; + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + req.bytes = 1; + req.vol_id = 1; + ret = ubi_mkvol(libubi, node, &req); + if (check_failed(ret, EEXIST, "ubi_mkvol", + "created volume of maximum size %lld, but still " + "can create more volumes", dev_info.avail_bytes)) + return -1; + + if (ubi_rmvol(libubi, node, 0)) { + failed("ubi_rmvol"); + return -1; + } + + /* Try to create too many volumes */ + for (i = 0; i < dev_info.max_vol_count; i++) { + char nm[strlen(name) + 50]; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = 1; + req.vol_type = UBI_STATIC_VOLUME; + + sprintf(nm, "%s:%d", name, i); + req.name = nm; + + if (ubi_mkvol(libubi, node, &req)) { + /* + * Note, because of gluebi we may be unable to create + * dev_info.max_vol_count devices (MTD restrictions). + */ + if (errno == ENFILE) + break; + failed("ubi_mkvol"); + err_msg("vol_id %d", i); + goto remove; + } + } + + for (i = 0; i < dev_info.max_vol_count + 1; i++) + ubi_rmvol(libubi, node, i); + + return 0; + +remove: + for (i = 0; i < dev_info.max_vol_count + 1; i++) + ubi_rmvol(libubi, node, i); + return -1; +} + +/** + * test_rmvol - test that UBI rmvol ioctl rejects bad input parameters. + * + * This function returns %0 if the test passed and %-1 if not. + */ +static int test_rmvol(void) +{ + int ret; + struct ubi_mkvol_request req; + const char *name = TESTNAME ":test_rmvol()"; + + /* Bad vol_id */ + ret = ubi_rmvol(libubi, node, -1); + if (check_failed(ret, EINVAL, "ubi_rmvol", "vol_id = -1")) + return -1; + + ret = ubi_rmvol(libubi, node, dev_info.max_vol_count); + if (check_failed(ret, EINVAL, "ubi_rmvol", "vol_id = %d", + dev_info.max_vol_count)) + return -1; + + /* Try to remove non-existing volume */ + ret = ubi_rmvol(libubi, node, 0); + if (check_failed(ret, ENODEV, "ubi_rmvol", + "removed non-existing volume 0")) + return -1; + + /* Try to remove volume twice */ + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = name; + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + ret = ubi_rmvol(libubi, node, req.vol_id); + if (check_failed(ret, ENODEV, "ubi_rmvol", "volume %d removed twice", + req.vol_id)) + return -1; + + return 0; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (test_mkvol()) + goto close; + + if (test_rmvol()) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_basic.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_basic.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_basic.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_basic.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,250 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test test checks basic volume creation and deletion capabilities. + */ + +#include +#include +#include +#include "libubi.h" +#define TESTNAME "mkvol_basic" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; + +/** + * mkvol_alignment - create volumes with different alignments. + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int mkvol_alignment(void) +{ + struct ubi_mkvol_request req; + int i, vol_id, ebsz; + const char *name = TESTNAME ":mkvol_alignment()"; + int alignments[] = ALIGNMENTS(dev_info.leb_size); + + for (i = 0; i < sizeof(alignments)/sizeof(int); i++) { + req.vol_id = UBI_VOL_NUM_AUTO; + + /* Alignment should actually be multiple of min. I/O size */ + req.alignment = alignments[i]; + req.alignment -= req.alignment % dev_info.min_io_size; + if (req.alignment == 0) + req.alignment = dev_info.min_io_size; + + /* Bear in mind alignment reduces EB size */ + ebsz = dev_info.leb_size - dev_info.leb_size % req.alignment; + req.bytes = dev_info.avail_lebs * ebsz; + + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + err_msg("alignment %d", req.alignment); + return -1; + } + + vol_id = req.vol_id; + if (check_volume(vol_id, &req)) + goto remove; + + if (ubi_rmvol(libubi, node, vol_id)) { + failed("ubi_rmvol"); + return -1; + } + } + + return 0; + +remove: + ubi_rmvol(libubi, node, vol_id); + return -1; +} + +/** + * mkvol_basic - simple test that checks basic volume creation capability. + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int mkvol_basic(void) +{ + struct ubi_mkvol_request req; + struct ubi_vol_info vol_info; + int vol_id, ret; + const char *name = TESTNAME ":mkvol_basic()"; + + /* Create dynamic volume of maximum size */ + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + vol_id = req.vol_id; + if (check_volume(vol_id, &req)) + goto remove; + + if (ubi_rmvol(libubi, node, vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + /* Create static volume of maximum size */ + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = dev_info.avail_bytes; + req.vol_type = UBI_STATIC_VOLUME; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + vol_id = req.vol_id; + if (check_volume(vol_id, &req)) + goto remove; + + if (ubi_rmvol(libubi, node, vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + /* Make sure volume does not exist */ + ret = ubi_get_vol_info1(libubi, dev_info.dev_num, vol_id, &vol_info); + if (ret == 0) { + err_msg("removed volume %d exists", vol_id); + goto remove; + } + + return 0; + +remove: + ubi_rmvol(libubi, node, vol_id); + return -1; +} + +/** + * mkvol_multiple - test multiple volumes creation + * + * Thus function returns %0 if the test passed and %-1 if not. + */ +static int mkvol_multiple(void) +{ + struct ubi_mkvol_request req; + int i, ret, max = dev_info.max_vol_count; + const char *name = TESTNAME ":mkvol_multiple()"; + + /* Create maximum number of volumes */ + for (i = 0; i < max; i++) { + char nm[strlen(name) + 50]; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = 1; + req.vol_type = UBI_STATIC_VOLUME; + + sprintf(nm, "%s:%d", name, i); + req.name = nm; + + if (ubi_mkvol(libubi, node, &req)) { + if (errno == ENFILE) { + max = i; + break; + } + failed("ubi_mkvol"); + err_msg("vol_id %d", i); + goto remove; + } + + if (check_volume(req.vol_id, &req)) { + err_msg("vol_id %d", i); + goto remove; + } + } + + for (i = 0; i < max; i++) { + struct ubi_vol_info vol_info; + + if (ubi_rmvol(libubi, node, i)) { + failed("ubi_rmvol"); + return -1; + } + + /* Make sure volume does not exist */ + ret = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); + if (ret == 0) { + err_msg("removed volume %d exists", i); + goto remove; + } + } + + return 0; + +remove: + for (i = 0; i < dev_info.max_vol_count + 1; i++) + ubi_rmvol(libubi, node, i); + return -1; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (mkvol_basic()) + goto close; + + if (mkvol_alignment()) + goto close; + + if (mkvol_multiple()) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_paral.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_paral.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_paral.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/mkvol_paral.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,110 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * This test creates and deletes volumes in parallel. + */ + +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "mkvol_paral" +#include "common.h" + +#define THREADS_NUM 4 +#define ITERATIONS 500 + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; +static int iterations = ITERATIONS; + +/** + * the_thread - the testing thread. + * + * @ptr thread number + */ +static void * the_thread(void *ptr) +{ + int n = (int)ptr, iter = iterations; + struct ubi_mkvol_request req; + const char *name = TESTNAME ":the_thread()"; + char nm[strlen(name) + 50]; + + req.alignment = 1; + req.bytes = dev_info.avail_bytes/ITERATIONS; + req.vol_type = UBI_DYNAMIC_VOLUME; + sprintf(nm, "%s:%d", name, n); + req.name = nm; + + while (iter--) { + req.vol_id = UBI_VOL_NUM_AUTO; + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return NULL; + } + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return NULL; + } + } + + return NULL; +} + +int main(int argc, char * const argv[]) +{ + int i, ret; + pthread_t threads[THREADS_NUM]; + + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + for (i = 0; i < THREADS_NUM; i++) { + ret = pthread_create(&threads[i], NULL, &the_thread, (void*)i); + if (ret) { + failed("pthread_create"); + goto close; + } + } + + for (i = 0; i < THREADS_NUM; i++) + pthread_join(threads[i], NULL); + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/README.udev linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/README.udev --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/README.udev 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/README.udev 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,25 @@ +There is a problem with udev: when a volume is created, there is a delay +before corresponding /dev/ubiX_Y device node is created by udev, so some +tests fail because of this. The symptom is error messages like +"cannot open /dev/ubi0_0". + +One possible solution of this problem is to pre-create UBI device and volume +nodes. There is even a script which may be used for this in ubi-utils/scripts/. +But this is not enough because udev will still remove and re-create the nodes +and tests will still fail. So you need to stop removing device nodes using +the following udev rule: + + KERNEL=="ubi*_*", ACTION=="remove", OPTIONS+="ignore_device" + +In our Ubuntu distribution we put that to new file: +/etc/udev/rules.d/50-local.rules + +Another possibility is to call udevsettle utility in libubi after the volume +has been created See src/libubi.c - the call is compiled in only if +UDEV_SETTLE_HACK is defined. This is anyway an ugly hack, but works, although +makes the tests slower. Suggestions are welcome. + +So, if you have udevsettel unility in your system, you do not have to do +anyting, and the tests should work, because we compile libubi with +UDEV_SETTLE_HACK. Otherwise, you should remove -D UDEV_SETTLE_HACK +from the makefile and pre-create UBI device nodes. diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/rsvol.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/rsvol.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/rsvol.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/rsvol.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,305 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Tes UBI volume re-size. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "rsvol" +#include "common.h" + +static libubi_t libubi; +static struct ubi_dev_info dev_info; +const char *node; + +/** + * test_basic - check volume re-size capability. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_basic(int type) +{ + struct ubi_mkvol_request req; + const char *name = TESTNAME ":test_basic()"; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = MIN_AVAIL_EBS * dev_info.leb_size; + req.vol_type = type; + req.name = name; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + req.bytes = dev_info.leb_size; + if (ubi_rsvol(libubi, node, req.vol_id, req.bytes)) { + failed("ubi_rsvol"); + goto remove; + } + + if (check_volume(req.vol_id, &req)) + goto remove; + + req.bytes = (MIN_AVAIL_EBS + 1) * dev_info.leb_size; + if (ubi_rsvol(libubi, node, req.vol_id, req.bytes)) { + failed("ubi_rsvol"); + goto remove; + } + + if (check_volume(req.vol_id, &req)) + goto remove; + + req.bytes -= 1; + if (ubi_rsvol(libubi, node, req.vol_id, req.bytes)) { + failed("ubi_rsvol"); + goto remove; + } + + if (check_volume(req.vol_id, &req)) + goto remove; + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +/* + * Helper function for test_rsvol(). + */ +static int test_rsvol1(struct ubi_vol_info *vol_info) +{ + long long bytes; + struct ubi_vol_info vol_info1; + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + unsigned char buf[vol_info->rsvd_bytes]; + int fd, i, ret; + + /* Make the volume smaller and check basic volume I/O */ + bytes = vol_info->rsvd_bytes - vol_info->leb_size; + if (ubi_rsvol(libubi, node, vol_info->vol_id, bytes - 1)) { + failed("ubi_rsvol"); + return -1; + } + + if (ubi_get_vol_info1(libubi, vol_info->dev_num, vol_info->vol_id, + &vol_info1)) { + failed("ubi_get_vol_info"); + return -1; + } + + if (vol_info1.rsvd_bytes != bytes) { + err_msg("rsvd_bytes %lld, must be %lld", + vol_info1.rsvd_bytes, bytes); + return -1; + } + + if (vol_info1.rsvd_lebs != vol_info->rsvd_lebs - 1) { + err_msg("rsvd_lebs %d, must be %d", + vol_info1.rsvd_lebs, vol_info->rsvd_lebs - 1); + return -1; + } + + /* Write data to the volume */ + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + vol_info->vol_id); + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", vol_node); + return -1; + } + + bytes = vol_info->rsvd_bytes - vol_info->leb_size - 1; + if (ubi_update_start(libubi, fd, bytes)) { + failed("ubi_update_start"); + goto close; + } + + for (i = 0; i < bytes; i++) + buf[i] = (unsigned char)i; + + ret = write(fd, buf, bytes); + if (ret != bytes) { + failed("write"); + goto close; + } + + close(fd); + + if (ubi_rsvol(libubi, node, vol_info->vol_id, bytes)) { + failed("ubi_rsvol"); + return -1; + } + + if (ubi_rsvol(libubi, node, vol_info->vol_id, + vol_info->leb_size * dev_info.avail_lebs)) { + failed("ubi_rsvol"); + return -1; + } + + fd = open(vol_node, O_RDWR); + if (fd == -1) { + failed("open"); + err_msg("cannot open \"%s\"\n", vol_node); + return -1; + } + + /* Read data back */ + if (lseek(fd, 0, SEEK_SET) != 0) { + failed("seek"); + goto close; + } + memset(buf, 0, bytes); + ret = read(fd, buf, bytes); + if (ret != bytes) { + failed("read"); + goto close; + } + + for (i = 0; i < bytes; i++) { + if (buf[i] != (unsigned char)i) { + err_msg("bad data"); + goto close; + } + } + + close(fd); + return 0; + +close: + close(fd); + return -1; +} + +/** + * test_rsvol - test UBI volume re-size. + * + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * + * Thus function returns %0 in case of success and %-1 in case of failure. + */ +static int test_rsvol(int type) +{ + const char *name = TESTNAME "test_rsvol:()"; + int alignments[] = ALIGNMENTS(dev_info.leb_size); + char vol_node[strlen(UBI_VOLUME_PATTERN) + 100]; + struct ubi_mkvol_request req; + int i; + + for (i = 0; i < sizeof(alignments)/sizeof(int); i++) { + int leb_size; + struct ubi_vol_info vol_info; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.vol_type = type; + req.name = name; + + req.alignment = alignments[i]; + req.alignment -= req.alignment % dev_info.min_io_size; + if (req.alignment == 0) + req.alignment = dev_info.min_io_size; + + leb_size = dev_info.leb_size - dev_info.leb_size % req.alignment; + req.bytes = MIN_AVAIL_EBS * leb_size; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + return -1; + } + + sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num, + req.vol_id); + + if (ubi_get_vol_info(libubi, vol_node, &vol_info)) { + failed("ubi_get_vol_info"); + goto remove; + } + + if (test_rsvol1(&vol_info)) { + err_msg("alignment = %d", req.alignment); + goto remove; + } + + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + return -1; + } + } + + return 0; + +remove: + ubi_rmvol(libubi, node, req.vol_id); + return -1; +} + +int main(int argc, char * const argv[]) +{ + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto close; + } + + if (test_basic(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_basic(UBI_STATIC_VOLUME)) + goto close; + if (test_rsvol(UBI_DYNAMIC_VOLUME)) + goto close; + if (test_rsvol(UBI_STATIC_VOLUME)) + goto close; + + libubi_close(libubi); + return 0; + +close: + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/runtests.sh linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/runtests.sh --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/runtests.sh 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/runtests.sh 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,39 @@ +#!/bin/sh + +ubidev="$1" +tests="mkvol_basic mkvol_bad mkvol_paral rsvol io_basic io_read io_update +io_paral volrefcnt" + +if test -z "$ubidev"; +then + echo "Usage:" + echo "$0 " + exit 1 +fi + +ubiname=`echo $ubidev | cut -d/ -f3` + +major=`cat /sys/class/ubi/$ubiname/dev | cut -d: -f1` + +for minor in `seq 0 4`; do + if test ! -e ${ubidev}_${minor} ; + then + mknod ${ubidev}_${minor} c $major $(($minor + 1)) + fi +done + +if ! test -c "$ubidev"; +then + echo "Error: $ubidev is not character device" + exit 1 +fi + +for t in `echo $tests`; +do + echo "Running $t $ubidev" + "./$t" "$ubidev" || exit 1 +done + +echo SUCCESS + +exit 0 diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/volrefcnt.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/volrefcnt.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/tests/ubi-tests/volrefcnt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/tests/ubi-tests/volrefcnt.c 2010-03-03 19:04:33.000000000 -0800 @@ -0,0 +1,122 @@ +/* + * Copyright (c) Nokia Corporation, 2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * Test volume reference counting - create a volume, open a sysfs file + * belonging to the volume, delete the volume but do not close the file, make + * sure the file cannot be read, close the file, make sure the volume + * disappeard, make sure its sysfs subtree disappeared. + */ + +#include +#include +#include +#include +#include +#include "libubi.h" +#define TESTNAME "rmvol" +#include "common.h" + +#define SYSFS_FILE "/sys/class/ubi/ubi%d_%d/usable_eb_size" + +int main(int argc, char * const argv[]) +{ + int ret, fd; + char fname[sizeof(SYSFS_FILE) + 20]; + const char *node; + libubi_t libubi; + struct ubi_dev_info dev_info; + struct ubi_mkvol_request req; + char tmp[100]; + + if (initial_check(argc, argv)) + return 1; + + node = argv[1]; + + libubi = libubi_open(); + if (libubi == NULL) { + failed("libubi_open"); + return 1; + } + + if (ubi_get_dev_info(libubi, node, &dev_info)) { + failed("ubi_get_dev_info"); + goto out_libubi; + } + + /* Create a small dynamic volume */ + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = dev_info.min_io_size; + req.bytes = dev_info.leb_size; + req.vol_type = UBI_DYNAMIC_VOLUME; + req.name = "rmvol"; + + if (ubi_mkvol(libubi, node, &req)) { + failed("ubi_mkvol"); + goto out_libubi; + } + + /* Open volume-related sysfs file */ + sprintf(fname, SYSFS_FILE, dev_info.dev_num, req.vol_id); + fd = open(fname, O_RDONLY); + if (fd == -1) { + err_msg("cannot open %s", fname); + failed("open"); + goto out_rmvol; + } + + /* Remove the volume, but do not close the file */ + if (ubi_rmvol(libubi, node, req.vol_id)) { + failed("ubi_rmvol"); + perror("ubi_rmvol"); + goto out_close; + } + + /* Try to read from the file, this should fail */ + ret = read(fd, tmp, 100); + if (ret != -1) { + err_msg("read returned %d, expected -1", ret); + failed("read"); + goto out_close; + } + + /* Close the file and try to open it again, should fail */ + close(fd); + fd = open(fname, O_RDONLY); + if (fd != -1) { + err_msg("opened %s again, open returned %d, expected -1", + fname, fd); + failed("open"); + goto out_libubi; + } + + libubi_close(libubi); + return 0; + +out_rmvol: + ubi_rmvol(libubi, node, req.vol_id); +out_libubi: + libubi_close(libubi); + return 1; + +out_close: + close(fd); + libubi_close(libubi); + return 1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/doc/unubi.roff linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/doc/unubi.roff --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/doc/unubi.roff 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/doc/unubi.roff 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,123 @@ +.TH UNUBI 1 "NOVEMBER 2006" FSP "FSP Flashutils" +.SH NAME +unubi \- extract volumes/eraseblocks from a raw\-UBI image +.SH SYNOPSIS +\fBunubi [\-aevEV] [\-d \fIout\-dir\fB] [\-r \fIvolume\-id\fB] +[\-b \fIblock\-size\fB] \fIimage\-file +.SH DESCRIPTION +.PP +\fBunubi\fR reads an image file containing blocks of UBI headers and data +(such as produced from \fBnand2bin\fR) and rebuilds the volumes within. +The default operation (when no flags are given) is to rebuild all valid +volumes found in the image. \fBunubi\fR can also read straight from the +onboard MTD device (ex. /dev/mtdblock/NAND). +.SH OPTIONS +.IP "\-a, \-\-analyze" +When flagged, analysis files are generated within the output directory. These +may include tables and or graphs detailing statistics gathered from the +eraseblock data. Files are prefixed `analysis_'. + +See \fBANALYSIS\fR. +.IP "\-b, \-\-blocksize \fIblock\-size\fR" +Specify in bytes the \fIimage\-file\fR eraseblock size. Sizes may be +postfixed with `KiB' or `MiB' to indicate mebibytes or kibibytes +respectively. Default is 128KiB. +.IP "\-d, \-\-dir \fIoutput\-dir\fR" +Specify the output directory. If no directory is specified, the default +is `unubi_\fIimage\-file\fR' within the curent working directory. If the +attempt to create the output directory fails, +.B unubi +will try to create it in /tmp before aborting. +.IP "\-e, \-\-eb\-split" +When flagged, images are created for each eraseblock in \fIimage\-file\fR +regardless of its validity. Each image is the complete eraseblock, including +headers and any space to the end of the eraseblock after where the data may +end. + +Invalid images are named `ebEEEE', where EEEE is the physical index of the +eraseblock in the image. Valid images are named `ebEEEE_VVV_NNN_RRR' where +VVV is the known volume ID, NNN is the logical number and RRR is the version +of the eraseblock data. Note that the version number is in hexadecimal. + +Invalid images may also contain this postfix, if the data in the header +could be valid (ie. the header contains a resonable volume ID, but the +header and/or data CRCs are not valid). If this is the case, images are named +`ebEEEE_VVV_NNN_RRR.reason', so as to distinguish known values from +non\-definite ones. + +See \fBREASON SUFFIXES\fR. +.IP "\-r, \-\-rebuild \fIvolume\-id\fR" +Specify a volume to rebuild. Can be used successively to specify +several volumes to be rebuilt. + +Images are named `volumeVVV' where VVV is the volume ID. For each missing +eraseblock, an error message will be printed. +.IP "\-v, \-\-vol\-split" +When flagged, images are created for each valid eraseblock in +\fIimage\-file\fR. Since a vaild eraseblock will have a defined data start and +data length, only this range will make up the image. + +Images are named `volVVV_NNN_RRR_EEEE', where, for the data in the eraseblock, +VVV is the volume ID, NNN is the logical number, RRR is the version and EEEE +is the phyisical index of the eraseblock in the image. +.IP "\-V, \-\-vol\-split!" +Same as above, only all images are the complete eraseblock (including headers, +and raw data, even past the point where the data is supposed to end). +Overrides \-v when both \-v and \-V are flagged. +.SH ANALYSIS +The following files will be generated during the analysis: +.IP "analysis_ec_hdr.data" +A space delimited table with these two columns for each eraseblock: the +eraseblock's index or physical position in the image, and the eraseblock's +erase count. The third column contains the erase count data sorted. +.IP "analysis_vid_hdr.data" +A space delimited table with these four colums for each eraseblock: the +volume ID, the volume logical number, the leb version, and the data size. +In addition there are a normalized column representing the volume ID and +volume logical number, a normalized column representing the leb version, and +a normalized column representing the data_size. These normalized columns are +used to better draw the the gnuplot image. +.IP "analysis_ec_hdr.plot" +A gnuplot script for quickly viewing a sample output from the respective .data +file. +.IP "analysis_vid_hdr.plot" +A gnuplot script for quickly viewing a sample output from the respective .data +file. +.SH REASONS SUFFIXES +When \-\-eb\-split produces possibly invalid, though usable, eraseblocks, the +known reason suffixes are: +.IP ".ec_magic" +The erase counter header did not contain a valid magic field. +.IP ".ec_hdr_crc" +The erase counter header did not contain a vaild header CRC field. +.IP ".vid_magic" +The volume ID header did not contain a valid magic field. +.IP ".vid_hdr_crc" +The volume ID header did not contain a valid header CRC field. +.IP ".data_crc" +The volume ID header did not contain a valid data CRC field. +.SH EXAMPLES +To extract and rebuild all valid volumes from demo.img (note the output +directory will be /home/user/unubi_demo.img): +.sp 1 +.RS +.B /home/user# unubi demo.img +.sp 1 +.RE +To analyze demo.img as well as extract and rebuild volume 7: +.sp 1 +.RS +.B /home/user# unubi \-a \-r 7 demo.img +.sp 1 +.RE +To split demo.img into raw images for each eraseblock into the folder +/var/eraseblocks: +.sp 1 +.RS +.B /home/user# unubi \-e \-d /var/eraseblocks demo.img +.SH AUTHORS +Frank Haverkamp +.sp 0 +Drake Dowsett +.SH CONTACT +Andreas Arnez diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/inc/libubi.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/inc/libubi.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/inc/libubi.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/inc/libubi.h 2010-03-03 19:04:30.000000000 -0800 @@ -0,0 +1,268 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem B. Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_H__ +#define __LIBUBI_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* UBI version libubi is made for */ +#define LIBUBI_UBI_VERSION 1 + +/* UBI library descriptor */ +typedef void * libubi_t; + +/** + * struct ubi_mkvol_request - volume creation request. + * */ +struct ubi_mkvol_request +{ + int vol_id; + int alignment; + long long bytes; + int vol_type; + const char *name; +}; + +/** + * struct ubi_info - general UBI information. + * + * @dev_count count of UBI devices in system + * @lowest_dev_num lowest UBI device number + * @highest_dev_num highest UBI device number + * @version UBI version + */ +struct ubi_info +{ + int dev_count; + int lowest_dev_num; + int highest_dev_num; + int version; +}; + +/** + * struct ubi_dev_info - UBI device information. + * + * @vol_count count of volumes on this UBI device + * @lowest_vol_num lowest volume number + * @highest_vol_num highest volume number + * @total_ebs total number of eraseblocks on this UBI device + * @avail_ebs how many eraseblocks are not used and available for new + * volumes + * @total_bytes @total_ebs * @eb_size + * @avail_bytes @avail_ebs * @eb_size + * @bad_count count of bad eraseblocks + * @eb_size size of UBI eraseblock + * @max_ec current highest erase counter value + * @bad_rsvd how many physical eraseblocks of the underlying flash + * device are reserved for bad eraseblocks handling + * @max_vol_count maximum count of volumes on this UBI device + * @min_io_size minimum input/output size of the UBI device + */ +struct ubi_dev_info +{ + int dev_num; + int vol_count; + int lowest_vol_num; + int highest_vol_num; + int total_ebs; + int avail_ebs; + long long total_bytes; + long long avail_bytes; + int bad_count; + int eb_size; + long long max_ec; + int bad_rsvd; + int max_vol_count; + int min_io_size; +}; + +/** + * struct ubi_vol_info - UBI volume information. + * + * @dev_num UBI device number the volume resides on + * @vol_id ID of this volume + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @alignment alignemnt of this volume + * @data_bytes how many data bytes are stored on this volume (equivalent to + * @rsvd_bytes for dynamic volumes) + * @rsvd_bytes how many bytes are reserved for this volume + * @rsvd_ebs how many eraseblocks are reserved for this volume + * @eb_size logical eraseblock size of this volume (may be less then + * device's logical eraseblock size due to alignment) + * @corrupted the volume is corrupted if this flag is not zero + * @name volume name (null-terminated) + */ +struct ubi_vol_info +{ + int dev_num; + int vol_id; + int type; + int alignment; + long long data_bytes; + long long rsvd_bytes; + int rsvd_ebs; + int eb_size; + int corrupted; + char name[UBI_VOL_NAME_MAX + 1]; +}; + +/** + * libubi_open - open UBI library. + * + * This function initializes and opens the UBI library and returns UBI library + * descriptor in case of success and %NULL in case of failure. + */ +libubi_t libubi_open(void); + +/** + * libubi_close - close UBI library + * + * @desc UBI library descriptor + */ +void libubi_close(libubi_t desc); + +/** + * ubi_get_info - get general UBI information. + * + * @info pointer to the &struct ubi_info object to fill + * @desc UBI library descriptor + * + * This function fills the passed @info object with general UBI information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_info(libubi_t desc, struct ubi_info *info); + +/** + * ubi_mkvol - create an UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device to create a volume at + * @req UBI volume creation request (defined at ) + * + * This function creates a UBI volume as described at @req and returns %0 in + * case of success and %-1 in case of failure. The assigned volume ID is + * returned in @req->vol_id. + */ +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); + +/** + * ubi_rmvol - remove a UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device to remove a volume from + * @vol_id ID of the volume to remove + * + * This function removes volume @vol_id from UBI device @node and returns %0 in + * case of success and %-1 in case of failure. + */ +int ubi_rmvol(libubi_t desc, const char *node, int vol_id); + +/** + * ubi_rsvol - re-size UBI volume. + * + * @desc UBI library descriptor + * @node name of the UBI character device owning the volume which should be + * re-sized + * @vol_id volume ID to re-size + * @bytes new volume size in bytes + * + * This function returns %0 in case of success and %-1 in case of error. + */ +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); + +/** + * ubi_get_dev_info - get UBI device information. + * + * @desc UBI library descriptor + * @node name of the UBI character device to fetch information about + * @info pointer to the &struct ubi_dev_info object to fill + * + * This function fills the passed @info object with UBI device information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_dev_info(libubi_t desc, const char *node, + struct ubi_dev_info *info); + +/** + * ubi_get_dev_info1 - get UBI device information. + * + * @desc UBI library descriptor + * @dev_num UBI device number to fetch information about + * @info pointer to the &struct ubi_dev_info object to fill + * + * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI + * device number, not UBI character device. + */ +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); + +/** + * ubi_get_vol_info - get UBI volume information. + * + * @desc UBI library descriptor + * @node name of the UBI volume character device to fetch information about + * @info pointer to the &struct ubi_vol_info object to fill + * + * This function fills the passed @info object with UBI volume information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_vol_info(libubi_t desc, const char *node, + struct ubi_vol_info *info); + +/** + * ubi_get_vol_info1 - get UBI volume information. + * + * @desc UBI library descriptor + * @dev_num UBI device number + * @vol_id ID of the UBI volume to fetch information about + * @info pointer to the &struct ubi_vol_info object to fill + * + * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI + * volume number, not UBI volume character device. + */ +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, + struct ubi_vol_info *info); + +/** + * ubi_update_start - start UBI volume update. + * + * @desc UBI library descriptor + * @fd volume character devie file descriptor + * @bytes how many bytes will be written to the volume + * + * This function initiates UBI volume update and returns %0 in case of success + * and %-1 in case of error. + */ +int ubi_update_start(libubi_t desc, int fd, long long bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/lib/Makefile.am linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/lib/Makefile.am --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/lib/Makefile.am 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/lib/Makefile.am 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,58 @@ +AUTOMAKE_OPTIONS = foreign +INCLUDES=-I$(top_srcdir)/inc -I$(top_srcdir)/../../kernel/include + +# ----------------------------------------------------------------------------- +# all export libs which shall be generated +lib_LTLIBRARIES = libubi.la \ + libpfiflash.la + +# ----------------------------------------------------------------------------- +# all convinence libs which shall be generated +noinst_LTLIBRARIES = libcrc32.la \ + libubigen.la \ + liberror.la \ + liblist.la \ + libbootenv.la \ + libpfi.la \ + libpeb.la \ + libreader.la \ + libubimirror.la + +# ----------------------------------------------------------------------------- +# exported libs +libpfiflash_la_SOURCES = $(top_srcdir)/src/libpfiflash/pfiflash.c +libpfiflash_la_LDFLAGS = -no-undefined -version-info 1:0:0 +libpfiflash_la_LIBADD = libreader.la \ + libubimirror.la \ + libubi.la + +libubi_la_SOURCES = $(top_srcdir)/src/libubi/libubi.c \ + $(top_srcdir)/src/libubi/libubi_sysfs.c +libubi_la_LDFLAGS = -no-undefined -version-info 1:0:0 + +# ----------------------------------------------------------------------------- +# complex convinence libs, beware for double includes. +libreader_la_SOURCES = $(top_srcdir)/src/libreader/reader.c +libreader_la_LIBADD = libpfi.la \ + liblist.la \ + libpeb.la \ + libbootenv.la + +libubigen_la_SOURCES = $(top_srcdir)/src/libubigen/ubigen.c +libubigen_la_LIBADD = libcrc32.la + +libbootenv_la_SOURCES = $(top_srcdir)/src/libbootenv/bootenv.c \ + $(top_srcdir)/src/libbootenv/hashmap.c +libbootenv_la_LIBADD = libcrc32.la + +libubimirror_la_SOURCES = $(top_srcdir)/src/libubimirror/ubimirror.c +libubimirror_la_LIBADD = libubi.la + + +# ----------------------------------------------------------------------------- +# simple convinence libs +libcrc32_la_SOURCES = $(top_srcdir)/src/libcrc32/crc32.c +liberror_la_SOURCES = $(top_srcdir)/src/liberror/error.c +liblist_la_SOURCES = $(top_srcdir)/src/liblist/list.c +libpeb_la_SOURCES = $(top_srcdir)/src/libpeb/peb.c +libpfi_la_SOURCES = $(top_srcdir)/src/libpfi/pfi.c diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/Makefile 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,88 @@ +# +# Makefile for ubi-utils +# + +OPTFLAGS := -O2 -g -Wall +KERNELHDR := ../include +DESTDIR := /usr/local +SBINDIR=/usr/sbin +MANDIR=/usr/share/man +INCLUDEDIR=/usr/include + +CROSS=mipsel-linux- +CC := $(CROSS)gcc +CFLAGS := -I./inc -I./src -I$(KERNELHDR) $(OPTFLAGS) -Werror \ + -Wwrite-strings -W -std=gnu99 -DPACKAGE_VERSION=\"1.0\" + +PERLPROGS = mkpfi ubicrc32.pl + +NTARGETS = ubiattach ubicrc32 ubidetach ubimkvol ubinfo ubinize \ + ubirmvol ubiupdatevol +TARGETS = pfiflash pddcustomize ubimirror bin2nand nand2bin ubigen \ + mkbootenv unubi pfi2bin $(NTARGETS) + +vpath %.c ./src + +%: %.o + $(CC) $(LDFLAGS) -g -o $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -g -c -o $@ $< -g -Wp,-MD,.$(shell basename $<).dep + +all: $(TARGETS) + mkdir -p ubi-utils-dir + cp $(TARGETS) ubi-utils-dir + make -C new-utils + +IGNORE=${wildcard .*.c.dep} +-include ${IGNORE} + +$(NTARGETS): + make -C new-utils $@ + mv new-utils/$@ $@ + +clean: + rm -rf *.o $(TARGETS) .*.c.dep + rm -fr ubi-utils-dir + make -C new-utils clean + +pddcustomize: pddcustomize.o error.o libubimirror.o bootenv.o hashmap.o \ + libubi.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + +pfiflash: pfiflash.o libpfiflash.o list.o reader.o error.o libubimirror.o \ + bootenv.o hashmap.o pfi.o libubi.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + +ubimirror: ubimirror.o error.o libubimirror.o bootenv.o hashmap.o \ + libubi.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + +nand2bin: nand2bin.o nandecc.o nandcorr.o + $(CC) $(LDFLAGS) -o $@ $^ + +bin2nand: bin2nand.o error.o nandecc.o + $(CC) $(LDFLAGS) -o $@ $^ + +ubigen: ubigen.o libubigen.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + +mkbootenv: mkbootenv.o bootenv.o hashmap.o error.o crc32.o + $(CC) $(LDFLAGS) -o $@ $^ + +unubi: unubi.o crc32.o unubi_analyze.o eb_chain.o + $(CC) $(LDFLAGS) -o $@ $^ + +pfi2bin: pfi2bin.o peb.o error.o list.o crc32.o libubigen.o bootenv.o \ + hashmap.o reader.o pfi.o + $(CC) $(LDFLAGS) -o $@ $^ + +install: ${TARGETS} + mkdir -p ${DESTDIR}/${SBINDIR} + install -m0755 ${TARGETS} ${DESTDIR}/${SBINDIR}/ + (cd perl && install ${PERLPROGS} ${DESTDIR}/${SBINDIR}/) + +uninstall: + for file in ${TARGETS} ${PERLPROGS}; do \ + $(RM) ${DESTDIR}/${SBINDIR}/$$file; \ + done diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libiniparser.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libiniparser.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libiniparser.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libiniparser.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,280 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.h + @author N. Devillard + @date Sep 2007 + @version 3.0 + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ + +/* + $Id: libiniparser.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Revision: 1.1.1.1 $ +*/ + +#ifndef _INIPARSER_H_ +#define _INIPARSER_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include + +/* + * The following #include is necessary on many Unixes but not Linux. + * It is not needed for Windows platforms. + * Uncomment it if needed. + */ +/* #include */ + +#include "dictionary.h" + +/*--------------------------------------------------------------------------- + Macros + ---------------------------------------------------------------------------*/ +/** For backwards compatibility only */ +#define iniparser_getstr(d, k) iniparser_getstring(d, k, NULL) +#define iniparser_setstr iniparser_setstring + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ + +int iniparser_getnsec(dictionary * d); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ + +char * iniparser_getsecname(dictionary * d, int n); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dump_ini(dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getstring(dictionary * d, const char * key, char * def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(dictionary * d, const char * key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(dictionary * d, char * key, double notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(dictionary * d, const char * key, int notfound); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, -1 is returned. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_setstring(dictionary * ini, char * entry, char * val); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, char * entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(dictionary * ini, char * entry) ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d); + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libmtd.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libmtd.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libmtd.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libmtd.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * MTD library. + */ + +#ifndef __LIBMTD_H__ +#define __LIBMTD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * struct mtd_info - information about an MTD device. + * @num: MTD device number + * @major: major number of corresponding character device + * @minor: minor number of corresponding character device + * @type: flash type (constants like %MTD_NANDFLASH defined in mtd-abi.h) + * @type_str: static R/O flash type string + * @size: device size in bytes + * @eb_cnt: count of eraseblocks + * @eb_size: eraseblock size + * @min_io_size: minimum input/output unit size + * @subpage_size: sub-page size (not set by 'mtd_get_info()'!!!) + * @rdonly: non-zero if the device is read-only + * @allows_bb: non-zero if the MTD device may have bad eraseblocks + * @fd: descriptor of the opened MTD character device node + */ +struct mtd_info +{ + int num; + int major; + int minor; + int type; + const char *type_str; + long long size; + int eb_cnt; + int eb_size; + int min_io_size; + int subpage_size; + unsigned int rdonly:1; + unsigned int allows_bb:1; + int fd; +}; + +int mtd_get_info(const char *node, struct mtd_info *mtd); +int mtd_erase(const struct mtd_info *mtd, int eb); +int mtd_is_bad(const struct mtd_info *mtd, int eb); +int mtd_read(const struct mtd_info *mtd, int eb, int offs, void *buf, int len); +int mtd_write(const struct mtd_info *mtd, int eb, int offs, void *buf, int len); + +#ifdef __cplusplus +} +#endif + +#endif /* __LIBMTD_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libscan.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libscan.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libscan.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libscan.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * UBI scanning library. + */ + +#ifndef __LIBSCAN_H__ +#define __LIBSCAN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * If an eraseblock does not contain an erase counter, this value is used + * instead of the erase counter. + */ +#define NO_EC 0xFFFFFFFF + +/* + * If an eraseblock contains a corrupted erase counter, this value is used + * instead of the erase counter. + */ +#define CORRUPT_EC 0xFFFFFFFE + +/* + * If an eraseblock does not contain an erase counter, one of these values is + * used. + * + * @EB_EMPTY: the eraseblock appeared to be empty + * @EB_CORRUPTED: the eraseblock contains corrupted erase counter header + * @EB_ALIEN: the eraseblock contains some non-UBI data + * @EC_MAX: maximum allowed erase counter value + */ +enum +{ + EB_EMPTY = 0xFFFFFFFF, + EB_CORRUPTED = 0xFFFFFFFE, + EB_ALIEN = 0xFFFFFFFD, + EB_BAD = 0xFFFFFFFC, + EC_MAX = UBI_MAX_ERASECOUNTER, +}; + +/** + * struct ubi_scan_info - UBI scanning information. + * @ec: erase counters or eraseblock status for all eraseblocks + * @mean_ec: mean erase counter + * @ok_cnt: count of eraseblock with correct erase counter header + * @empty_cnt: count of supposedly eraseblocks + * @corrupted_cnt: count of eraseblocks with corrupted erase counter header + * @alien_cnt: count of eraseblock containing non-ubi data + * @bad_cnt: count of bad eraseblocks + * @bad_cnt: count of non-bad eraseblocks + * @vid_hdr_offs: volume ID header offset from the found EC headers (%-1 means + * undefined) + * @data_offs: data offset from the found EC headers (%-1 means undefined) + */ +struct ubi_scan_info +{ + uint32_t *ec; + long long mean_ec; + int ok_cnt; + int empty_cnt; + int corrupted_cnt; + int alien_cnt; + int bad_cnt; + int good_cnt; + int vid_hdr_offs; + int data_offs; +}; + +struct mtd_info; + +/** + * ubi_scan - scan an MTD device. + * @mtd: information about the MTD device to scan + * @info: the result of the scanning is returned here + * @verbose: verbose mode: %0 - be silent, %1 - output progress information, + * 2 - debugging output mode + */ +int ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info, int verbose); + +/** + * ubi_scan_free - free scanning information. + * @si: scanning information to free + */ +void ubi_scan_free(struct ubi_scan_info *si); + +#ifdef __cplusplus +} +#endif + +#endif /* __LIBSCAN_H__ */ + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubigen.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubigen.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubigen.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubigen.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,110 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Authors: Frank Haverkamp + * Artem Bityutskiy + */ + +#ifndef __LIBUBIGEN_H__ +#define __LIBUBIGEN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * struct ubigen_info - libubigen information. + * @leb_size: logical eraseblock size + * @peb_size: size of the physical eraseblock + * @min_io_size: minimum input/output unit size + * @vid_hdr_offs: offset of the VID header + * @data_offs: data offset + * @ubi_ver: UBI version + * @vtbl_size: volume table size + * @max_volumes: maximum amount of volumes + */ +struct ubigen_info +{ + int leb_size; + int peb_size; + int min_io_size; + int vid_hdr_offs; + int data_offs; + int ubi_ver; + int vtbl_size; + int max_volumes; +}; + +/** + * struct ubigen_vol_info - information about a volume. + * @id: volume id + * @type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @usable_leb_size: LEB size accessible for volume users + * @name: volume name + * @name_len: volume name length + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @used_ebs: total number of used logical eraseblocks in this volume (relevant + * for static volumes only) + * @bytes: size of the volume contents in bytes (relevant for static volumes + * only) + * @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG) + */ +struct ubigen_vol_info +{ + int id; + int type; + int alignment; + int data_pad; + int usable_leb_size; + const char *name; + int name_len; + int compat; + int used_ebs; + long long bytes; + uint8_t flags; +}; + +void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size, + int subpage_size, int vid_hdr_offs, int ubi_ver); +struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui); +void ubigen_init_ec_hdr(const struct ubigen_info *ui, + struct ubi_ec_hdr *hdr, long long ec); +int ubigen_get_vtbl_size(const struct ubigen_info *ui); +int ubigen_add_volume(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, + struct ubi_vtbl_record *vtbl); +int ubigen_write_volume(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, long long ec, + long long bytes, int in, int out); +int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2, + long long ec1, long long ec2, + struct ubi_vtbl_record *vtbl, int fd); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBIGEN_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubi.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubi.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubi.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/include/libubi.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,382 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_H__ +#define __LIBUBI_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* UBI version libubi is made for */ +#define LIBUBI_UBI_VERSION 1 + +/* UBI library descriptor */ +typedef void * libubi_t; + +/** + * struct ubi_attach_request - MTD device attachement request. + * @dev_num: number to assigne to the newly created UBI device + * (%UBI_DEV_NUM_AUTO should be used to automatically assign the + * number) + * @mtd_num: MTD device number to attach + * @vid_hdr_offset: VID header offset (%0 means default offset and this is what + * most of the users want) + */ +struct ubi_attach_request +{ + int dev_num; + int mtd_num; + int vid_hdr_offset; +}; + +/** + * struct ubi_mkvol_request - volume creation request. + * @vol_id: ID to assign to the new volume (%UBI_VOL_NUM_AUTO should be used to + * automatically assign ID) + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @name: volume name + */ +struct ubi_mkvol_request +{ + int vol_id; + int alignment; + long long bytes; + int vol_type; + const char *name; +}; + +/** + * struct ubi_info - general UBI information. + * @dev_count: count of UBI devices in system + * @lowest_dev_num: lowest UBI device number + * @highest_dev_num: highest UBI device number + * @version: UBI version + * @ctrl_major: major number of the UBI control device + * @ctrl_minor: minor number of the UBI control device + */ +struct ubi_info +{ + int dev_count; + int lowest_dev_num; + int highest_dev_num; + int version; + int ctrl_major; + int ctrl_minor; +}; + +/** + * struct ubi_dev_info - UBI device information. + * @vol_count: count of volumes on this UBI device + * @lowest_vol_num: lowest volume number + * @highest_vol_num: highest volume number + * @major: major number of corresponding character device + * @minor: minor number of corresponding character device + * @total_lebs: total number of logical eraseblocks on this UBI device + * @avail_lebs: how many logical eraseblocks are not used and available for new + * volumes + * @total_bytes: @total_lebs * @leb_size + * @avail_bytes: @avail_lebs * @leb_size + * @bad_count: count of bad physical eraseblocks + * @leb_size: logical eraseblock size + * @max_ec: current highest erase counter value + * @bad_rsvd: how many physical eraseblocks of the underlying flash device are + * reserved for bad eraseblocks handling + * @max_vol_count: maximum possible number of volumes on this UBI device + * @min_io_size: minimum input/output unit size of the UBI device + */ +struct ubi_dev_info +{ + int dev_num; + int vol_count; + int lowest_vol_num; + int highest_vol_num; + int major; + int minor; + int total_lebs; + int avail_lebs; + long long total_bytes; + long long avail_bytes; + int bad_count; + int leb_size; + long long max_ec; + int bad_rsvd; + int max_vol_count; + int min_io_size; +}; + +/** + * struct ubi_vol_info - UBI volume information. + * @dev_num: UBI device number the volume resides on + * @vol_id: ID of this volume + * @major: major number of corresponding volume character device + * @minor: minor number of corresponding volume character device + * @dev_major: major number of corresponding UBI device character device + * @dev_minor: minor number of corresponding UBI device character device + * @type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @alignment: alignemnt of this volume + * @data_bytes: how many data bytes are stored on this volume (equivalent to + * @rsvd_bytes for dynamic volumes) + * @rsvd_bytes: how many bytes are reserved for this volume + * @rsvd_lebs: how many logical eraseblocks are reserved for this volume + * @leb_size: logical eraseblock size of this volume (may be less then + * device's logical eraseblock size due to alignment) + * @corrupted: non-zero if the volume is corrupted + * @name: volume name (null-terminated) + */ +struct ubi_vol_info +{ + int dev_num; + int vol_id; + int major; + int minor; + int dev_major; + int dev_minor; + int type; + int alignment; + long long data_bytes; + long long rsvd_bytes; + int rsvd_lebs; + int leb_size; + int corrupted; + char name[UBI_VOL_NAME_MAX + 1]; +}; + +/** + * libubi_open - open UBI library. + * @required: if non-zero, libubi will print an error messages if this UBI is + * not present in the system + * + * This function initializes and opens the UBI library and returns UBI library + * descriptor in case of success and %NULL in case of failure. + */ +libubi_t libubi_open(int required); + +/** + * libubi_close - close UBI library. + * @desc UBI library descriptor + */ +void libubi_close(libubi_t desc); + +/** + * ubi_get_info - get general UBI information. + * @desc: UBI library descriptor + * @info: pointer to the &struct ubi_info object to fill + * + * This function fills the passed @info object with general UBI information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_info(libubi_t desc, struct ubi_info *info); + +/** + * mtd_num2ubi_dev - find UBI device by attached MTD device. + * @@desc: UBI library descriptor + * @mtd_num: MTD device number + * @dev_num: UBI device number is returned here + * + * This function finds UBI device to which MTD device @mtd_num is attached. + * Returns %0 if the UBI device was found and %-1 if not. + */ +int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num); + +/** + * ubi_attach_mtd - attach MTD device to UBI. + * @desc: UBI library descriptor + * @node: name of the UBI control character device node + * @req: MTD attach request. + * + * This function creates a new UBI device by attaching an MTD device as + * described by @req. Returns %0 in case of success and %-1 in case of failure. + * The newly created UBI device number is returned in @req->dev_num. + */ +int ubi_attach_mtd(libubi_t desc, const char *node, + struct ubi_attach_request *req); + +/** + * ubi_detach_mtd - detach an MTD device. + * @desc: UBI library descriptor + * @node: name of the UBI control character device node + * @mtd_num: MTD device number to detach + * + * This function detaches MTD device number @mtd_num from UBI, which means the + * corresponding UBI device is removed. Returns zero in case of success and %-1 + * in case of failure. + */ +int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num); + +/** + * ubi_remove_dev - remove an UBI device. + * @desc: UBI library descriptor + * @node: name of the UBI control character device node + * @ubi_dev: UBI device number to remove + * + * This function removes UBI device number @ubi_dev and returns zero in case of + * success and %-1 in case of failure. + */ +int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev); + +/** + * ubi_mkvol - create an UBI volume. + * @desc: UBI library descriptor + * @node: name of the UBI character device to create a volume at + * @req: UBI volume creation request + * + * This function creates a UBI volume as described at @req and returns %0 in + * case of success and %-1 in case of failure. The assigned volume ID is + * returned in @req->vol_id. + */ +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); + +/** + * ubi_rmvol - remove a UBI volume. + * @desc: UBI library descriptor + * @node: name of the UBI character device to remove a volume from + * @vol_id: ID of the volume to remove + * + * This function removes volume @vol_id from UBI device @node and returns %0 in + * case of success and %-1 in case of failure. + */ +int ubi_rmvol(libubi_t desc, const char *node, int vol_id); + +/** + * ubi_rsvol - re-size UBI volume. + * @desc: UBI library descriptor + * @node: name of the UBI character device owning the volume which should be + * re-sized + * @vol_id: volume ID to re-size + * @bytes: new volume size in bytes + * + * This function returns %0 in case of success and %-1 in case of error. + */ +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); + +/** + * ubi_node_type - test UBI node type. + * @desc: UBI library descriptor + * @node: the node to test + * + * This function tests whether @node is a UBI device or volume node and returns + * %1 if this is an UBI device node, %2 if this is a volume node, and %-1 if + * this is not an UBI node or if an error occurred (the latter is indicated by + * a non-zero errno). + */ +int ubi_node_type(libubi_t desc, const char *node); + +/** + * ubi_get_dev_info - get UBI device information. + * @desc: UBI library descriptor + * @node: name of the UBI character device to fetch information about + * @info: pointer to the &struct ubi_dev_info object to fill + * + * This function fills the passed @info object with UBI device information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_dev_info(libubi_t desc, const char *node, + struct ubi_dev_info *info); + +/** + * ubi_get_dev_info1 - get UBI device information. + * @desc: UBI library descriptor + * @dev_num: UBI device number to fetch information about + * @info: pointer to the &struct ubi_dev_info object to fill + * + * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI + * device number, not UBI character device. + */ +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); + +/** + * ubi_get_vol_info - get UBI volume information. + * @desc: UBI library descriptor + * @node: name of the UBI volume character device to fetch information about + * @info: pointer to the &struct ubi_vol_info object to fill + * + * This function fills the passed @info object with UBI volume information and + * returns %0 in case of success and %-1 in case of failure. + */ +int ubi_get_vol_info(libubi_t desc, const char *node, + struct ubi_vol_info *info); + +/** + * ubi_get_vol_info1 - get UBI volume information. + * @desc: UBI library descriptor + * @dev_num: UBI device number + * @vol_id: ID of the UBI volume to fetch information about + * @info: pointer to the &struct ubi_vol_info object to fill + * + * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI + * volume number, not UBI volume character device. + */ +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, + struct ubi_vol_info *info); + +/** + * ubi_update_start - start UBI volume update. + * @desc: UBI library descriptor + * @fd: volume character devie file descriptor + * @bytes: how many bytes will be written to the volume + * + * This function initiates UBI volume update and returns %0 in case of success + * and %-1 in case of error. The caller is assumed to write @bytes data to the + * volume @fd afterwards. + */ +int ubi_update_start(libubi_t desc, int fd, long long bytes); + + +/** + * ubi_leb_read_start + * @fd: volume character devie file descriptor + * @leb: structure pointer for volume dump request + * + * This function call "UBI_IOCLEBREAD" ioctl. + * return %1 means the LEB is not mapped, no need to dump + * return %0 LEB read done successful + * return any others error + */ +int ubi_leb_read_start(int fd, struct ubi_leb *leb); + +/** + * ubi_leb_change_start - start atomic LEB change. + * @desc: UBI library descriptor + * @fd: volume character devie file descriptor + * @lnum: LEB number to change + * @bytes: how many bytes of new data will be written to the LEB + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * + * This function initiates atomic LEB change operation and returns %0 in case + * of success and %-1 in case of error. he caller is assumed to write @bytes + * data to the volume @fd afterwards. + */ +int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes, int dtype); + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/LICENSE.libiniparser linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/LICENSE.libiniparser --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/LICENSE.libiniparser 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/LICENSE.libiniparser 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,21 @@ +Copyright (c) 2000-2007 by Nicolas Devillard. +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/Makefile linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/Makefile --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/Makefile 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,84 @@ +# +# Makefile for ubi-utils +# + +OPTFLAGS := -O2 -Wall +KERNELHDR := ../../include +#DESTDIR := /usr/local +DESTDIR := /nfsroot/user/yrtan +SBINDIR=/usr/sbin +MANDIR=/usr/man +INCLUDEDIR=/usr/include +CROSS=mipsel-linux- +CC := $(CROSS)gcc +CFLAGS := -Iinclude -Isrc -I$(KERNELHDR) $(OPTFLAGS) -Werror -Wall + +LIBS = libubi libmtd libubigen libiniparser libscan +UTILS = ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \ + ubidetach ubiformat ubidumpvol ubicrcvol \ + ubinize ubicrcsf ubirefimg +vpath %.c src + +all: $(UTILS) + mkdir -p ./new-utils-dir + cp $(UTILS) ./new-utils-dir + +# The below cancels existing implicite rule to make programs from .c files, +# in order to force make using our rule defined below +%: %.c + +# The below is the rule to get an .o file from a .c file +%.o: %.c + $(CC) $(CFLAGS) $< -c -o $@ + +# And the below is the rule to get final executable from its .o and common.o +%: libubi.a %.o common.o + $(CC) $(CFLAGS) $(filter %.o, $^) -L. -lubi -o $@ + +ubicrcsf: ubicrcsf.o crc32.o + $(CC) $(CFLAGS) -o $@ $^ + +ubicrcvol: ubicrcvol.o common.o crc32.o libubi.a + $(CC) $(CFLAGS) $(filter %.o, $^) -L. -lubi -o $@ + +ubicrc32: ubicrc32.o crc32.o + $(CC) $(CFLAGS) -o $@ $^ + +ubinize: ubinize.o common.o crc32.o libiniparser.a libubigen.a + $(CC) $(CFLAGS) $(filter %.o, $^) -L. -liniparser -lubigen -o $@ + +ubiformat: ubiformat.o common.o crc32.o libmtd.a libscan.a libubi.a libubigen.a + $(CC) $(CFLAGS) $(filter %.o, $^) -L. -lmtd -lscan -lubi -lubigen -o $@ + +libubi.a: libubi.o + $(AR) crv $@ $^ + ranlib $@ + +libmtd.a: libmtd.o + $(AR) crv $@ $^ + ranlib $@ + +libubigen.a: libubigen.o + $(AR) crv $@ $^ + ranlib $@ + +libiniparser.a: libiniparser.o dictionary.o + $(AR) crv $@ $^ + ranlib $@ + +libscan.a: libscan.o crc32.o + $(AR) crv $@ $^ + ranlib $@ + +clean: + rm -rf *.o $(addsuffix .a, $(LIBS)) $(UTILS) .*.c.dep + rm -rf new-utils-dir + +install: ${UTILS} + mkdir -p ${DESTDIR}/${SBINDIR} + install -m0755 ${UTILS} ${DESTDIR}/${SBINDIR}/ + +uninstall: + for file in ${UTILS}; do \ + $(RM) ${DESTDIR}/${SBINDIR}/$$file; \ + done diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/README linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/README --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/README 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/README 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,55 @@ +This directory contains a new UBI toolchain which is intended to replace +the old one. All utilities support "-h" option which prints sufficient +usage information. See the MTD web-site for more information. + +Motivation for new tool-chain. + +I was doing very active UBI development and had to add new features like +dynamic UBI devices and auto-resize feature. Because of the mess in the +the old tools I basically could not figure out how to upgrade them. In +my humble oppinion, they are unmaintainable. The original authors did not +show enthusiasm when I mailed them and asked to clean-up the tool-chain +[1]. Thus, I re-implemented them, but I did borrow things from the old +tool-chain and preserved copyrights and author names. + +I really did try to clean-up the old tool chain, but gave up (see git +history for confirmation). So, + +1. I found the source codes very difficult to navigate and read, especially + those related to pdd, pfi, and bootenv. Try to do this yourself - they + are a puzzle. +2. I foud the concept of PFI needlesly complecated - PFI file is nothing + else but the initial configuration .ini file + the contents of the + UBI volumes packed into one file, but with some changes of the .ini file's + format. The PFI file format is not very nice and it is difficult to parse, + especially because the PFI headers do not tell you data star and end for + each data chunk, and you have to do additional parsing. + + So basically, you have .ini file + images, then you transfer this to pfi, + which does not add any other information. For .ini you have libraries + which may parse them, for pfi - not. Then you have to parse this pfi + which adds unneeded and complex code. This all needs lists, hashmaps, + and so on - for no reason. +3. I found the command line options of the utilities to be inconsistent. + This is OK when you script your single task and do not touch it anymore. + But when you have to use the utilities while developing and testing, + It is difficult to remember their inconsistent options. +4. I found it wrong to add development options to user utilities like + "broken update". End users should not see them. +5. I did not find any consistent style and convention inside which + irritated me. +6. I found it weird to introduce needless "logging infrastructure" instead + of just re-directing stdout and stderr to another file. +7. I found the tool to be rather IBM-setup oriented. For example, the VID + header position was hard-coded. Some utilities were just weird, like + mkbootenv, which changed some ethernet addresses mentioned in a + configuration file. +8. Finally, it was very difficult to realize what is pfi and pdd, what for, + why I need this transiant pfi file when I just want to create an UBI + image. There was zero documentation. + +And so on. + +Feb 19, 2008, Artem Bityutskiy. + +[1]. http://lists.infradead.org/pipermail/linux-mtd/2007-December/020134.html diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2007, 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * This file contains various common stuff used by UBI utilities. + * + * Authors: Artem Bityutskiy + * Adrian Hunter + */ + +#include +#include +#include +#include + +/** + * get_multiplier - convert size specifier to an integer multiplier. + * @str: the size specifier string + * + * This function parses the @str size specifier, which may be one of + * 'KiB', 'MiB', or 'GiB' into an integer multiplier. Returns positive + * size multiplier in case of success and %-1 in case of failure. + */ +static int get_multiplier(const char *str) +{ + if (!str) + return 1; + + /* Remove spaces before the specifier */ + while (*str == ' ' || *str == '\t') + str += 1; + + if (!strcmp(str, "KiB")) + return 1024; + if (!strcmp(str, "MiB")) + return 1024 * 1024; + if (!strcmp(str, "GiB")) + return 1024 * 1024 * 1024; + + /* Handle deprecated stuff */ + if (!strcmp(str, "KB") || !strcmp(str, "Kib") || !strcmp(str, "kib") || + !strcmp(str, "kiB")) { + fprintf(stderr, "Warning: use \"KiB\" instead of \"%s\" to " + "specify Kilobytes - support will be removed\n", str); + return 1024; + } + if (!strcmp(str, "MB") || !strcmp(str, "Mib") || !strcmp(str, "mb")) { + fprintf(stderr, "Warning: use \"MiB\" instead of \"%s\", " + "this support will be removed\n", str); + return 1024*1024; + } + if (!strcmp(str, "GB") || !strcmp(str, "Gib") || !strcmp(str, "gb")) { + fprintf(stderr, "Warning: use \"GiB\" instead of \"%s\", " + "this support will be removed\n", str); + return 1024*1024*1024; + } + + return -1; +} + +/** + * ubiutils_get_bytes - convert a string containing amount of bytes into an + * integer + * @str: string to convert + * + * This function parses @str which may have one of 'KiB', 'MiB', or 'GiB' + * size specifiers. Returns positive amount of bytes in case of success and %-1 + * in case of failure. + */ +long long ubiutils_get_bytes(const char *str) +{ + char *endp; + long long bytes = strtoull(str, &endp, 0); + + if (endp == str || bytes < 0) { + fprintf(stderr, "incorrect amount of bytes: \"%s\"\n", str); + return -1; + } + + if (*endp != '\0') { + int mult = get_multiplier(endp); + + if (mult == -1) { + fprintf(stderr, "bad size specifier: \"%s\" - " + "should be 'KiB', 'MiB' or 'GiB'\n", endp); + return -1; + } + bytes *= mult; + } + + return bytes; +} + +/** + * ubiutils_print_bytes - print bytes. + * @bytes: variable to print + * @bracket: whether brackets have to be put or not + * + * This is a helper function which prints amount of bytes in a human-readable + * form, i.e., it prints the exact amount of bytes following by the approximate + * amount of Kilobytes, Megabytes, or Gigabytes, depending on how big @bytes + * is. + */ +void ubiutils_print_bytes(long long bytes, int bracket) +{ + const char *p; + + if (bracket) + p = " ("; + else + p = ", "; + + printf("%lld bytes", bytes); + + if (bytes > 1024 * 1024 * 1024) + printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024)); + else if (bytes > 1024 * 1024) + printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024)); + else if (bytes > 1024 && bytes != 0) + printf("%s%.1f KiB", p, (double)bytes / 1024); + else + return; + + if (bracket) + printf(")"); +} + +/** + * ubiutils_print_text - print text and fold it. + * @stream: file stream to print to + * @text: text to print + * @width: maximum allowed text width + * + * Print text and fold it so that each line would not have more then @width + * characters. + */ +void ubiutils_print_text(FILE *stream, const char *text, int width) +{ + int pos, bpos = 0; + const char *p; + char line[1024]; + + if (width > 1023) { + fprintf(stream, "%s\n", text); + return; + } + p = text; + pos = 0; + while (p[pos]) { + while (!isspace(p[pos])) { + line[pos] = p[pos]; + if (!p[pos]) + break; + ++pos; + if (pos == width) { + line[pos] = '\0'; + fprintf(stream, "%s\n", line); + p += pos; + pos = 0; + } + } + while (pos < width) { + line[pos] = p[pos]; + if (!p[pos]) { + bpos = pos; + break; + } + if (isspace(p[pos])) + bpos = pos; + ++pos; + } + line[bpos] = '\0'; + fprintf(stream, "%s\n", line); + p += bpos; + pos = 0; + while (p[pos] && isspace(p[pos])) + ++p; + } +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/common.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,84 @@ +/* + * Copyright (c) Artem Bityutskiy, 2007, 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __UBI_UTILS_COMMON_H__ +#define __UBI_UTILS_COMMON_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MIN(a ,b) ((a) < (b) ? (a) : (b)) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +/* Verbose messages */ +#define verbose(verbose, fmt, ...) do { \ + if (verbose) \ + printf(PROGRAM_NAME ": " fmt "\n", ##__VA_ARGS__); \ +} while(0) + +/* Normal messages */ +#define normsg(fmt, ...) do { \ + printf(PROGRAM_NAME ": " fmt "\n", ##__VA_ARGS__); \ +} while(0) +#define normsg_cont(fmt, ...) do { \ + printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \ +} while(0) +#define normsg_cont(fmt, ...) do { \ + printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \ +} while(0) + +/* Error messages */ +#define errmsg(fmt, ...) ({ \ + fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \ + -1; \ +}) + +/* System error messages */ +#define sys_errmsg(fmt, ...) ({ \ + int _err = errno, _i; \ + fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \ + for (_i = 0; _i < sizeof(PROGRAM_NAME) + 1; _i++) \ + fprintf(stderr, " "); \ + fprintf(stderr, "error %d (%s)\n", _err, strerror(_err)); \ + -1; \ +}) + +/* Warnings */ +#define warnmsg(fmt, ...) do { \ + fprintf(stderr, PROGRAM_NAME ": warning!: " fmt "\n", ##__VA_ARGS__); \ +} while(0) + +static inline int is_power_of_2(unsigned long long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + +long long ubiutils_get_bytes(const char *str); +void ubiutils_print_bytes(long long bytes, int bracket); +void ubiutils_print_text(FILE *stream, const char *txt, int len); + +#ifdef __cplusplus +} +#endif + +#endif /* !__UBI_UTILS_COMMON_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,95 @@ +/* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + */ + +#include + +const uint32_t crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/crc32.h 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,19 @@ +#ifndef CRC32_H +#define CRC32_H + +#include + +extern const uint32_t crc32_table[256]; + +/* Return a 32-bit CRC of the contents of the buffer. */ + + static inline uint32_t +crc32(uint32_t val, const void *ss, int len) +{ + const unsigned char *s = ss; + while (--len >= 0) + val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8); + return val; +} + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,405 @@ +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.c + @author N. Devillard + @date Sep 2007 + @version $Revision: 1.1.1.1 $ + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +/* + $Id: dictionary.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Revision: 1.1.1.1 $ +*/ +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ +#include "dictionary.h" + +#include +#include +#include +#include + +/** Maximum value size for integers and doubles. */ +#define MAXVALSZ 1024 + +/** Minimal allocated number of entries in a dictionary */ +#define DICTMINSZ 128 + +/** Invalid key token */ +#define DICT_INVALID_KEY ((char*)-1) + +/*--------------------------------------------------------------------------- + Private functions + ---------------------------------------------------------------------------*/ + +/* Doubles the allocated size associated to a pointer */ +/* 'size' is the current allocated size. */ +static void * mem_double(void * ptr, int size) +{ + void * newptr ; + + newptr = calloc(2*size, 1); + if (newptr==NULL) { + return NULL ; + } + memcpy(newptr, ptr, size); + free(ptr); + return newptr ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char * xstrdup(char * s) +{ + char * t ; + if (!s) + return NULL ; + t = malloc(strlen(s)+1) ; + if (t) { + strcpy(t,s); + } + return t ; +} + +/*--------------------------------------------------------------------------- + Function codes + ---------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(char * key) +{ + int len ; + unsigned hash ; + int i ; + + len = strlen(key); + for (hash=0, i=0 ; i>6) ; + } + hash += (hash <<3); + hash ^= (hash >>11); + hash += (hash <<15); + return hash ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary objet. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(int size) +{ + dictionary * d ; + + /* If no size was specified, allocate space for DICTMINSZ */ + if (sizesize = size ; + d->val = (char **)calloc(size, sizeof(char*)); + d->key = (char **)calloc(size, sizeof(char*)); + d->hash = (unsigned int *)calloc(size, sizeof(unsigned)); + return d ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * d) +{ + int i ; + + if (d==NULL) return ; + for (i=0 ; isize ; i++) { + if (d->key[i]!=NULL) + free(d->key[i]); + if (d->val[i]!=NULL) + free(d->val[i]); + } + free(d->val); + free(d->key); + free(d->hash); + free(d); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * dictionary_get(dictionary * d, char * key, char * def) +{ + unsigned hash ; + int i ; + + hash = dictionary_hash(key); + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + return d->val[i] ; + } + } + } + return def ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * d, char * key, char * val) +{ + int i ; + unsigned hash ; + + if (d==NULL || key==NULL) return -1 ; + + /* Compute hash for this key */ + hash = dictionary_hash(key) ; + /* Find if value is already in dictionary */ + if (d->n>0) { + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (hash==d->hash[i]) { /* Same hash value */ + if (!strcmp(key, d->key[i])) { /* Same key */ + /* Found a value: modify and return */ + if (d->val[i]!=NULL) + free(d->val[i]); + d->val[i] = val ? xstrdup(val) : NULL ; + /* Value has been modified: return */ + return 0 ; + } + } + } + } + /* Add a new value */ + /* See if dictionary needs to grow */ + if (d->n==d->size) { + + /* Reached maximum size: reallocate dictionary */ + d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ; + d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ; + d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ; + if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) { + /* Cannot grow dictionary */ + return -1 ; + } + /* Double size */ + d->size *= 2 ; + } + + /* Insert key in the first empty slot */ + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) { + /* Add key here */ + break ; + } + } + /* Copy key */ + d->key[i] = xstrdup(key); + d->val[i] = val ? xstrdup(val) : NULL ; + d->hash[i] = hash; + d->n ++ ; + return 0 ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, char * key) +{ + unsigned hash ; + int i ; + + if (key == NULL) { + return; + } + + hash = dictionary_hash(key); + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + /* Found key */ + break ; + } + } + } + if (i>=d->size) + /* Key not found */ + return ; + + free(d->key[i]); + d->key[i] = NULL ; + if (d->val[i]!=NULL) { + free(d->val[i]); + d->val[i] = NULL ; + } + d->hash[i] = 0 ; + d->n -- ; + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(dictionary * d, FILE * out) +{ + int i ; + + if (d==NULL || out==NULL) return ; + if (d->n<1) { + fprintf(out, "empty dictionary\n"); + return ; + } + for (i=0 ; isize ; i++) { + if (d->key[i]) { + fprintf(out, "%20s\t[%s]\n", + d->key[i], + d->val[i] ? d->val[i] : "UNDEF"); + } + } + return ; +} + + +/* Test code */ +#ifdef TESTDIC +#define NVALS 20000 +int main(int argc, char *argv[]) +{ + dictionary * d ; + char * val ; + int i ; + char cval[90] ; + + /* Allocate dictionary */ + printf("allocating...\n"); + d = dictionary_new(0); + + /* Set values in dictionary */ + printf("setting %d values...\n", NVALS); + for (i=0 ; in != 0) { + printf("error deleting values\n"); + } + printf("deallocating...\n"); + dictionary_del(d); + return 0 ; +} +#endif +/* vim: set ts=4 et sw=4 tw=75 */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/dictionary.h 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,174 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.h + @author N. Devillard + @date Sep 2007 + @version $Revision: 1.1.1.1 $ + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +/* + $Id: dictionary.h,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Author: yrtan $ + $Date: 2008-05-13 07:15:32 $ + $Revision: 1.1.1.1 $ +*/ + +#ifndef _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + New types + ---------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dictionary object + + This object contains a list of string/string associations. Each + association is identified by a unique string key. Looking up values + in the dictionary is speeded up by the use of a (hopefully collision-free) + hash function. + */ +/*-------------------------------------------------------------------------*/ +typedef struct _dictionary_ { + int n ; /** Number of entries in dictionary */ + int size ; /** Storage size */ + char ** val ; /** List of string values */ + char ** key ; /** List of string keys */ + unsigned * hash ; /** List of hash values for keys */ +} dictionary ; + + +/*--------------------------------------------------------------------------- + Function prototypes + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(char * key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary objet. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(int size); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * vd); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * dictionary_get(dictionary * d, char * key, char * def); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * vd, char * key, char * val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, char * key); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(dictionary * d, FILE * out); + +#endif diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libiniparser.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libiniparser.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libiniparser.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libiniparser.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,646 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.c + @author N. Devillard + @date Sep 2007 + @version 3.0 + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ +/* + $Id: libiniparser.c,v 1.1.1.1 2008-05-13 07:15:32 yrtan Exp $ + $Revision: 1.1.1.1 $ + $Date: 2008-05-13 07:15:32 $ +*/ +/*---------------------------- Includes ------------------------------------*/ +#include +#include + +/*---------------------------- Defines -------------------------------------*/ +#define ASCIILINESZ (1024) +#define INI_INVALID_KEY ((char*)-1) + +/*--------------------------------------------------------------------------- + Private to this module + ---------------------------------------------------------------------------*/ +/** + * This enum stores the status for each parsed line (internal use only). + */ +typedef enum _line_status_ { + LINE_UNPROCESSED, + LINE_ERROR, + LINE_EMPTY, + LINE_COMMENT, + LINE_SECTION, + LINE_VALUE +} line_status ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Convert a string to lowercase. + @param s String to convert. + @return ptr to statically allocated string. + + This function returns a pointer to a statically allocated string + containing a lowercased version of the input string. Do not free + or modify the returned string! Since the returned string is statically + allocated, it will be modified at each function call (not re-entrant). + */ +/*--------------------------------------------------------------------------*/ +static char * strlwc(const char * s) +{ + static char l[ASCIILINESZ+1]; + int i ; + + if (s==NULL) return NULL ; + memset(l, 0, ASCIILINESZ+1); + i=0 ; + while (s[i] && i l) { + if (!isspace((int)*(last-1))) + break ; + last -- ; + } + *last = (char)0; + return (char*)l ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getnsec(dictionary * d) +{ + int i ; + int nsec ; + + if (d==NULL) return -1 ; + nsec=0 ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + nsec ++ ; + } + } + return nsec ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getsecname(dictionary * d, int n) +{ + int i ; + int foundsec ; + + if (d==NULL || n<0) return NULL ; + foundsec=0 ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + foundsec++ ; + if (foundsec>n) + break ; + } + } + if (foundsec<=n) { + return NULL ; + } + return d->key[i] ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(dictionary * d, FILE * f) +{ + int i ; + + if (d==NULL || f==NULL) return ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (d->val[i]!=NULL) { + fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); + } else { + fprintf(f, "[%s]=UNDEF\n", d->key[i]); + } + } + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump_ini(dictionary * d, FILE * f) +{ + int i, j ; + char keym[ASCIILINESZ+1]; + int nsec ; + char * secname ; + int seclen ; + + if (d==NULL || f==NULL) return ; + + nsec = iniparser_getnsec(d); + if (nsec<1) { + /* No section in file: dump all keys as they are */ + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + fprintf(f, "%s = %s\n", d->key[i], d->val[i]); + } + return ; + } + for (i=0 ; isize ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) { + fprintf(f, + "%-30s = %s\n", + d->key[j]+seclen+1, + d->val[j] ? d->val[j] : ""); + } + } + } + fprintf(f, "\n"); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getstring(dictionary * d, const char * key, char * def) +{ + char * lc_key ; + char * sval ; + + if (d==NULL || key==NULL) + return def ; + + lc_key = strlwc(key); + sval = dictionary_get(d, lc_key, def); + return sval ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(dictionary * d, const char * key, int notfound) +{ + char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==INI_INVALID_KEY) return notfound ; + return (int)strtol(str, NULL, 0); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(dictionary * d, char * key, double notfound) +{ + char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==INI_INVALID_KEY) return notfound ; + return atof(str); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(dictionary * d, const char * key, int notfound) +{ + char * c ; + int ret ; + + c = iniparser_getstring(d, key, INI_INVALID_KEY); + if (c==INI_INVALID_KEY) return notfound ; + if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { + ret = 1 ; + } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { + ret = 0 ; + } else { + ret = notfound ; + } + return ret; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry( + dictionary * ini, + char * entry +) +{ + int found=0 ; + if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { + found = 1 ; + } + return found ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, -1 is returned. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, char * entry, char * val) +{ + return dictionary_set(ini, strlwc(entry), val) ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, char * entry) +{ + dictionary_unset(ini, strlwc(entry)); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Load a single line from an INI file + @param input_line Input line, may be concatenated multi-line input + @param section Output space to store section + @param key Output space to store key + @param value Output space to store value + @return line_status value + */ +/*--------------------------------------------------------------------------*/ +static line_status iniparser_line( + char * input_line, + char * section, + char * key, + char * value) +{ + line_status sta ; + char line[ASCIILINESZ+1]; + int len ; + + strcpy(line, strstrip(input_line)); + len = (int)strlen(line); + + sta = LINE_UNPROCESSED ; + if (len<1) { + /* Empty line */ + sta = LINE_EMPTY ; + } else if (line[0]=='#') { + /* Comment line */ + sta = LINE_COMMENT ; + } else if (line[0]=='[' && line[len-1]==']') { + /* Section name */ + sscanf(line, "[%[^]]", section); + strcpy(section, strstrip(section)); + strcpy(section, strlwc(section)); + sta = LINE_SECTION ; + } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 + || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 + || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { + /* Usual key=value, with or without comments */ + strcpy(key, strstrip(key)); + strcpy(key, strlwc(key)); + strcpy(value, strstrip(value)); + /* + * sscanf cannot handle '' or "" as empty values + * this is done here + */ + if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { + value[0]=0 ; + } + sta = LINE_VALUE ; + } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 + || sscanf(line, "%[^=] %[=]", key, value) == 2) { + /* + * Special cases: + * key= + * key=; + * key=# + */ + strcpy(key, strstrip(key)); + strcpy(key, strlwc(key)); + value[0]=0 ; + sta = LINE_VALUE ; + } else { + /* Generate syntax error */ + sta = LINE_ERROR ; + } + return sta ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame) +{ + FILE * in ; + + char line [ASCIILINESZ+1] ; + char section [ASCIILINESZ+1] ; + char key [ASCIILINESZ+1] ; + char tmp [ASCIILINESZ+1] ; + char val [ASCIILINESZ+1] ; + + int last=0 ; + int len ; + int lineno=0 ; + int errs=0; + + dictionary * dict ; + + if ((in=fopen(ininame, "r"))==NULL) { + fprintf(stderr, "iniparser: cannot open %s\n", ininame); + return NULL ; + } + + dict = dictionary_new(0) ; + if (!dict) { + fclose(in); + return NULL ; + } + + memset(line, 0, ASCIILINESZ); + memset(section, 0, ASCIILINESZ); + memset(key, 0, ASCIILINESZ); + memset(val, 0, ASCIILINESZ); + last=0 ; + + while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { + lineno++ ; + len = (int)strlen(line)-1; + /* Safety check against buffer overflows */ + if (line[len]!='\n') { + fprintf(stderr, + "iniparser: input line too long in %s (%d)\n", + ininame, + lineno); + dictionary_del(dict); + fclose(in); + return NULL ; + } + /* Get rid of \n and spaces at end of line */ + while ((len>=0) && + ((line[len]=='\n') || (isspace(line[len])))) { + line[len]=0 ; + len-- ; + } + /* Detect multi-line */ + if (line[len]=='\\') { + /* Multi-line value */ + last=len ; + continue ; + } else { + last=0 ; + } + switch (iniparser_line(line, section, key, val)) { + case LINE_EMPTY: + case LINE_COMMENT: + break ; + + case LINE_SECTION: + errs = dictionary_set(dict, section, NULL); + break ; + + case LINE_VALUE: + sprintf(tmp, "%s:%s", section, key); + errs = dictionary_set(dict, tmp, val) ; + break ; + + case LINE_ERROR: + fprintf(stderr, "iniparser: syntax error in %s (%d):\n", + ininame, + lineno); + fprintf(stderr, "-> %s\n", line); + errs++ ; + break; + + default: + break ; + } + memset(line, 0, ASCIILINESZ); + last=0; + if (errs<0) { + fprintf(stderr, "iniparser: memory allocation failure\n"); + break ; + } + } + if (errs) { + dictionary_del(dict); + dict = NULL ; + } + fclose(in); + return dict ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d) +{ + dictionary_del(d); +} + +/* vim: set ts=4 et sw=4 tw=75 */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libmtd.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libmtd.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libmtd.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libmtd.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * MTD library. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "common.h" + +#define PROGRAM_NAME "libmtd" +#define MTD_DEV_MAJOR 90 + +/** + * mtd_get_info - get information about an MTD device. + * @node: name of the MTD device node + * @mtd: the MTD device information is returned here + * + * This function gets information about MTD device defined by the @node device + * node file and saves this information in the @mtd object. Returns %0 in case + * of success and %-1 in case of failure. + */ +int mtd_get_info(const char *node, struct mtd_info *mtd) +{ + struct stat st; + struct mtd_info_user ui; + int ret; + loff_t offs = 0; + + if (stat(node, &st)) + return sys_errmsg("cannot open \"%s\"", node); + + if (!S_ISCHR(st.st_mode)) { + errno = EINVAL; + return errmsg("\"%s\" is not a character device", node); + } + + mtd->major = major(st.st_rdev); + mtd->minor = minor(st.st_rdev); + + if (mtd->major != MTD_DEV_MAJOR) { + errno = EINVAL; + return errmsg("\"%s\" has major number %d, MTD devices have " + "major %d", node, mtd->major, MTD_DEV_MAJOR); + } + + mtd->num = mtd->minor / 2; + mtd->rdonly = mtd->minor & 1; + + mtd->fd = open(node, O_RDWR); + if (mtd->fd == -1) + return sys_errmsg("cannot open \"%s\"", node); + + if (ioctl(mtd->fd, MEMGETINFO, &ui)) { + sys_errmsg("MEMGETINFO ioctl request failed"); + goto out_close; + } + + ret = ioctl(mtd->fd, MEMGETBADBLOCK, &offs); + if (ret == -1) { + if (errno != EOPNOTSUPP) { + sys_errmsg("MEMGETBADBLOCK ioctl failed"); + goto out_close; + } + errno = 0; + mtd->allows_bb = 0; + } else + mtd->allows_bb = 1; + + mtd->type = ui.type; + mtd->size = ui.size; + mtd->eb_size = ui.erasesize; + mtd->min_io_size = ui.writesize; + + if (mtd->min_io_size <= 0) { + errmsg("mtd%d (%s) has insane min. I/O unit size %d", + mtd->num, node, mtd->min_io_size); + goto out_close; + } + if (mtd->eb_size <= 0 || mtd->eb_size < mtd->min_io_size) { + errmsg("mtd%d (%s) has insane eraseblock size %d", + mtd->num, node, mtd->eb_size); + goto out_close; + } + if (mtd->size <= 0 || mtd->size < mtd->eb_size) { + errmsg("mtd%d (%s) has insane size %lld", + mtd->num, node, mtd->size); + goto out_close; + } + mtd->eb_cnt = mtd->size / mtd->eb_size; + + switch(mtd->type) { + case MTD_ABSENT: + errmsg("mtd%d (%s) is removable and is not present", + mtd->num, node); + goto out_close; + case MTD_RAM: + mtd->type_str = "RAM-based"; + break; + case MTD_ROM: + mtd->type_str = "ROM"; + break; + case MTD_NORFLASH: + mtd->type_str = "NOR"; + break; + case MTD_NANDFLASH: + mtd->type_str = "NAND"; + break; + case MTD_DATAFLASH: + mtd->type_str = "DataFlash"; + break; + case MTD_UBIVOLUME: + mtd->type_str = "UBI-emulated MTD"; + break; + default: + mtd->type_str = "Unknown flash type"; + break; + } + + if (!(ui.flags & MTD_WRITEABLE)) + mtd->rdonly = 1; + + return 0; + +out_close: + close(mtd->fd); + return -1; +} + +/** + * mtd_erase - erase an eraseblock. + * @mtd: MTD device description object + * @eb: eraseblock to erase + * + * This function erases the eraseblock and returns %0 in case of success and + * %-1 in case of failure. + */ +int mtd_erase(const struct mtd_info *mtd, int eb) +{ + struct erase_info_user ei; + + ei.start = eb * mtd->eb_size;; + ei.length = mtd->eb_size; + return ioctl(mtd->fd, MEMERASE, &ei); +} + +/** + * mtd_is_bad - check if eraseblock is bad. + * @mtd: MTD device description object + * @eb: eraseblock to check + * + * This function checks if eraseblock @eb is bad. Returns %0 if not, %1 if yes, + * and %-1 in case of failure. + */ +int mtd_is_bad(const struct mtd_info *mtd, int eb) +{ + int ret; + loff_t seek; + + if (eb < 0 || eb >= mtd->eb_cnt) { + errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", + eb, mtd->num, mtd->eb_cnt); + errno = EINVAL; + return -1; + } + + if (!mtd->allows_bb) + return 0; + + seek = eb * mtd->eb_size; + ret = ioctl(mtd->fd, MEMGETBADBLOCK, &seek); + if (ret == -1) { + sys_errmsg("MEMGETBADBLOCK ioctl failed for " + "eraseblock %d (mtd%d)", eb, mtd->num); + return -1; + } + + return ret; +} + +/** + * mtd_read - read data from an MTD device. + * @mtd: MTD device description object + * @eb: eraseblock to read from + * @offs: offset withing the eraseblock to read from + * @buf: buffer to read data to + * @len: how many bytes to read + * + * This function reads @len bytes of data from eraseblock @eb and offset @offs + * of the MTD device defined by @mtd and stores the read data at buffer @buf. + * Returns %0 in case of success and %-1 in case of failure. + */ +int mtd_read(const struct mtd_info *mtd, int eb, int offs, void *buf, int len) +{ + int ret, rd = 0; + off_t seek; + + if (eb < 0 || eb >= mtd->eb_cnt) { + errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", + eb, mtd->num, mtd->eb_cnt); + errno = EINVAL; + return -1; + } + if (offs < 0 || offs + len > mtd->eb_size) { + errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", + offs, len, mtd->num, mtd->eb_size); + errno = EINVAL; + return -1; + } + + /* Seek to the beginning of the eraseblock */ + seek = eb * mtd->eb_size + offs; + if (lseek(mtd->fd, seek, SEEK_SET) != seek) { + sys_errmsg("cannot seek mtd%d to offset %llu", + mtd->num, (unsigned long long)seek); + return -1; + } + + while (rd < len) { + ret = read(mtd->fd, buf, len); + if (ret < 0) { + sys_errmsg("cannot read %d bytes from mtd%d (eraseblock %d, offset %d)", + len, mtd->num, eb, offs); + return -1; + } + rd += ret; + } + + return 0; +} + +/** + * mtd_write - write data to an MTD device. + * @mtd: MTD device description object + * @eb: eraseblock to write to + * @offs: offset withing the eraseblock to write to + * @buf: buffer to write + * @len: how many bytes to write + * + * This function writes @len bytes of data to eraseblock @eb and offset @offs + * of the MTD device defined by @mtd. Returns %0 in case of success and %-1 in + * case of failure. + */ +int mtd_write(const struct mtd_info *mtd, int eb, int offs, void *buf, int len) +{ + int ret; + off_t seek; + + if (eb < 0 || eb >= mtd->eb_cnt) { + errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", + eb, mtd->num, mtd->eb_cnt); + errno = EINVAL; + return -1; + } + if (offs < 0 || offs + len > mtd->eb_size) { + errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", + offs, len, mtd->num, mtd->eb_size); + errno = EINVAL; + return -1; + } +#if 0 + if (offs % mtd->subpage_size) { + errmsg("write offset %d is not aligned to mtd%d min. I/O size %d", + offs, mtd->num, mtd->subpage_size); + errno = EINVAL; + return -1; + } + if (len % mtd->subpage_size) { + errmsg("write length %d is not aligned to mtd%d min. I/O size %d", + len, mtd->num, mtd->subpage_size); + errno = EINVAL; + return -1; + } +#endif + + /* Seek to the beginning of the eraseblock */ + seek = eb * mtd->eb_size + offs; + if (lseek(mtd->fd, seek, SEEK_SET) != seek) { + sys_errmsg("cannot seek mtd%d to offset %llu", + mtd->num, (unsigned long long)seek); + return -1; + } + + ret = write(mtd->fd, buf, len); + if (ret != len) { + sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)", + len, mtd->num, eb, offs); + return -1; + } + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libscan.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libscan.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libscan.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libscan.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * UBI scanning library. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "common.h" +#include "crc32.h" + +#define PROGRAM_NAME "libscan" + +static int all_ff(const void *buf, int len) +{ + int i; + const uint8_t *p = buf; + + for (i = 0; i < len; i++) + if (p[i] != 0xFF) + return 0; + return 1; +} + +int ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info, int verbose) +{ + int eb, v = (verbose == 2), pr = (verbose == 1); + struct ubi_scan_info *si; + unsigned long long sum = 0; + + si = calloc(1, sizeof(struct ubi_scan_info)); + if (!si) + return sys_errmsg("cannot allocate %zd bytes of memory", + sizeof(struct ubi_scan_info)); + + si->ec = calloc(mtd->eb_cnt, sizeof(uint32_t)); + if (!si->ec) { + sys_errmsg("cannot allocate %zd bytes of memory", + sizeof(struct ubi_scan_info)); + goto out_si; + } + + si->vid_hdr_offs = si->data_offs = -1; + + verbose(v, "start scanning eraseblocks 0-%d", mtd->eb_cnt); + for (eb = 0; eb < mtd->eb_cnt; eb++) { + int ret; + uint32_t crc; + struct ubi_ec_hdr hdr; + unsigned long long ec; + + if (v) { + normsg_cont("scanning eraseblock %d", eb); + fflush(stdout); + } + if (pr) { + printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2lld %% complete ", + eb, (long long)(eb + 1) * 100 / mtd->eb_cnt); + fflush(stdout); + } + + ret = mtd_is_bad(mtd, eb); + if (ret == -1) + goto out_ec; + if (ret) { + si->bad_cnt += 1; + si->ec[eb] = EB_BAD; + if (v) + printf(": bad\n"); + continue; + } + + ret = mtd_read(mtd, eb, 0, &hdr, sizeof(struct ubi_ec_hdr));; + if (ret < 0) + goto out_ec; + + /* Check the EC header */ + if (be32_to_cpu(hdr.magic) != UBI_EC_HDR_MAGIC) { + if (all_ff(&hdr, sizeof(struct ubi_ec_hdr))) { + si->empty_cnt += 1; + si->ec[eb] = EB_EMPTY; + if (v) + printf(": empty\n"); + } else { + si->alien_cnt += 1; + si->ec[eb] = EB_ALIEN; + if (v) + printf(": alien\n"); + } + continue; + } + + crc = crc32(UBI_CRC32_INIT, &hdr, UBI_EC_HDR_SIZE_CRC); + if (be32_to_cpu(hdr.hdr_crc) != crc) { + si->corrupted_cnt += 1; + si->ec[eb] = EB_CORRUPTED; + if (v) + printf(": bad CRC %#08x, should be %#08x\n", + crc, be32_to_cpu(hdr.hdr_crc)); + continue; + } + + ec = be64_to_cpu(hdr.ec); + if (ec > EC_MAX) { + if (pr) + printf("\n"); + errmsg("erase counter in EB %d is %llu, while this " + "program expects them to be less than %u", + eb, ec, EC_MAX); + goto out_ec; + } + + if (si->vid_hdr_offs == -1) { + si->vid_hdr_offs = be32_to_cpu(hdr.vid_hdr_offset); + si->data_offs = be32_to_cpu(hdr.data_offset); + if (si->data_offs % mtd->min_io_size) { + if (pr) + printf("\n"); + if (v) + printf(": corrupted because of the below\n"); + warnmsg("bad data offset %d at eraseblock %d (n" + "of multiple of min. I/O unit size %d)", + si->data_offs, eb, mtd->min_io_size); + warnmsg("treat eraseblock %d as corrupted", eb); + si->corrupted_cnt += 1; + si->ec[eb] = EB_CORRUPTED; + continue; + + } + } else { + if (be32_to_cpu(hdr.vid_hdr_offset) != si->vid_hdr_offs) { + if (pr) + printf("\n"); + if (v) + printf(": corrupted because of the below\n"); + warnmsg("inconsistent VID header offset: was " + "%d, but is %d in eraseblock %d", + si->vid_hdr_offs, + be32_to_cpu(hdr.vid_hdr_offset), eb); + warnmsg("treat eraseblock %d as corrupted", eb); + si->corrupted_cnt += 1; + si->ec[eb] = EB_CORRUPTED; + continue; + } + if (be32_to_cpu(hdr.data_offset) != si->data_offs) { + if (pr) + printf("\n"); + if (v) + printf(": corrupted because of the below\n"); + warnmsg("inconsistent data offset: was %d, but" + " is %d in eraseblock %d", + si->data_offs, + be32_to_cpu(hdr.data_offset), eb); + warnmsg("treat eraseblock %d as corrupted", eb); + si->corrupted_cnt += 1; + si->ec[eb] = EB_CORRUPTED; + continue; + } + } + + si->ok_cnt += 1; + si->ec[eb] = ec; + if (v) + printf(": OK, erase counter %u\n", si->ec[eb]); + } + + if (si->ok_cnt != 0) { + /* Calculate mean erase counter */ + for (eb = 0; eb < mtd->eb_cnt; eb++) { + if (si->ec[eb] > EC_MAX) + continue; + sum += si->ec[eb]; + } + si->mean_ec = sum / si->ok_cnt; + } + + si->good_cnt = mtd->eb_cnt - si->bad_cnt; + verbose(v, "finished, mean EC %lld, %d OK, %d corrupted, %d empty, %d " + "alien, bad %d", si->mean_ec, si->ok_cnt, si->corrupted_cnt, + si->empty_cnt, si->alien_cnt, si->bad_cnt); + + *info = si; + if (pr) + printf("\n"); + return 0; + +out_ec: + free(si->ec); +out_si: + free(si); + *info = NULL; + return -1; +} + +void ubi_scan_free(struct ubi_scan_info *si) +{ + free(si->ec); + free(si); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,1154 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libubi.h" +#include "libubi_int.h" +#include "common.h" + +#define PROGRAM_NAME "libubi" + +/** + * mkpath - compose full path from 2 given components. + * @path: the first component + * @name: the second component + * + * This function returns the resulting path in case of success and %NULL in + * case of failure. + */ +static char *mkpath(const char *path, const char *name) +{ + char *n; + int len1 = strlen(path); + int len2 = strlen(name); + + n = malloc(len1 + len2 + 2); + if (!n) { + sys_errmsg("cannot allocate %d bytes", len1 + len2 + 2); + return NULL; + } + + memcpy(n, path, len1); + if (n[len1 - 1] != '/') + n[len1++] = '/'; + + memcpy(n + len1, name, len2 + 1); + return n; +} + +/** + * read_positive_ll - read a positive 'long long' value from a file. + * @file: the file to read from + * @value: the result is stored here + * + * This function reads file @file and interprets its contents as a positive + * 'long long' integer. If this is not true, it fails with %EINVAL error code. + * Returns %0 in case of success and %-1 in case of failure. + */ +static int read_positive_ll(const char *file, long long *value) +{ + int fd, rd; + char buf[50]; + + fd = open(file, O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, buf, 50); + if (rd == -1) { + sys_errmsg("cannot read \"%s\"", file); + goto out_error; + } + if (rd == 50) { + errmsg("contents of \"%s\" is too long", file); + errno = EINVAL; + goto out_error; + } + + if (sscanf(buf, "%lld\n", value) != 1) { + /* This must be a UBI bug */ + errmsg("cannot read integer from \"%s\"\n", file); + errno = EINVAL; + goto out_error; + } + + if (*value < 0) { + errmsg("negative value %lld in \"%s\"", *value, file); + errno = EINVAL; + goto out_error; + } + + if (close(fd)) + return sys_errmsg("close failed on \"%s\"", file); + + return 0; + +out_error: + close(fd); + return -1; +} + +/** + * read_positive_int - read a positive 'int' value from a file. + * @file: the file to read from + * @value: the result is stored here + * + * This function is the same as 'read_positive_ll()', but it reads an 'int' + * value, not 'long long'. + */ +static int read_positive_int(const char *file, int *value) +{ + long long res; + + if (read_positive_ll(file, &res)) + return -1; + + /* Make sure the value is not too big */ + if (res > INT_MAX) { + errmsg("value %lld read from file \"%s\" is out of range", + res, file); + errno = EINVAL; + return -1; + } + + *value = res; + return 0; +} + +/** + * read_data - read data from a file. + * @file: the file to read from + * @buf: the buffer to read to + * @buf_len: buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. Note, if the file contains more then @buf_len bytes of + * date, this function fails with %EINVAL error code. + */ +static int read_data(const char *file, void *buf, int buf_len) +{ + int fd, rd, tmp, tmp1; + + fd = open(file, O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, buf, buf_len); + if (rd == -1) { + sys_errmsg("cannot read \"%s\"", file); + goto out_error; + } + + /* Make sure all data is read */ + tmp1 = read(fd, &tmp, 1); + if (tmp1 == 1) { + sys_errmsg("cannot read \"%s\"", file); + goto out_error; + } + if (tmp1) { + errmsg("file \"%s\" contains too much data (> %d bytes)", + file, buf_len); + errno = EINVAL; + goto out_error; + } + + if (close(fd)) { + sys_errmsg("close failed on \"%s\"", file); + return -1; + } + + return rd; + +out_error: + close(fd); + return -1; +} + +/** + * read_major - read major and minor numbers from a file. + * @file: name of the file to read from + * @major: major number is returned here + * @minor: minor number is returned here + * + * This function returns % in case of succes, and %-1 in case of failure. + */ +static int read_major(const char *file, int *major, int *minor) +{ + int ret; + char buf[50]; + + ret = read_data(file, buf, 50); + if (ret < 0) + return ret; + + ret = sscanf(buf, "%d:%d\n", major, minor); + if (ret != 2) { + errno = EINVAL; + return errmsg("\"%s\" does not have major:minor format", file); + } + + if (*major < 0 || *minor < 0) { + errno = EINVAL; + return errmsg("bad major:minor %d:%d in \"%s\"", + *major, *minor, file); + } + + return 0; +} + +/** + * dev_read_int - read a positive 'int' value from an UBI device sysfs file. + * @patt: file pattern to read from + * @dev_num: UBI device number + * @value: the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_int(const char *patt, int dev_num, int *value) +{ + char file[strlen(patt) + 50]; + + sprintf(file, patt, dev_num); + return read_positive_int(file, value); +} + +/** + * vol_read_int - read a positive 'int' value from an UBI volume sysfs file. + * @patt: file pattern to read from + * @dev_num: UBI device number + * @vol_id: volume ID + * @value: the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) +{ + char file[strlen(patt) + 100]; + + sprintf(file, patt, dev_num, vol_id); + return read_positive_int(file, value); +} + +/** + * dev_read_ll - read a positive 'long long' value from an UBI device sysfs file. + * @patt: file pattern to read from + * @dev_num: UBI device number + * @value: the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int dev_read_ll(const char *patt, int dev_num, long long *value) +{ + char file[strlen(patt) + 50]; + + sprintf(file, patt, dev_num); + return read_positive_ll(file, value); +} + +/** + * vol_read_ll - read a positive 'long long' value from an UBI volume sysfs file. + * @patt: file pattern to read from + * @dev_num: UBI device number + * @vol_id: volume ID + * @value: the result is stored here + * + * This function returns %0 in case of success and %-1 in case of failure. + */ +static int vol_read_ll(const char *patt, int dev_num, int vol_id, + long long *value) +{ + char file[strlen(patt) + 100]; + + sprintf(file, patt, dev_num, vol_id); + return read_positive_ll(file, value); +} + +/** + * vol_read_data - read data from an UBI volume's sysfs file. + * @patt: file pattern to read from + * @dev_num: UBI device number + * @vol_id: volume ID + * @buf: buffer to read to + * @buf_len: buffer length + * + * This function returns number of read bytes in case of success and %-1 in + * case of failure. + */ +static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, + int buf_len) +{ + char file[strlen(patt) + 100]; + + sprintf(file, patt, dev_num, vol_id); + return read_data(file, buf, buf_len); +} + +/** + * dev_get_major - get major and minor numbers of an UBI device. + * @lib: libubi descriptor + * @dev_num: UBI device number + * @major: major number is returned here + * @minor: minor number is returned here + * + * This function returns zero in case of succes and %-1 in case of failure. + */ +static int dev_get_major(struct libubi *lib, int dev_num, int *major, int *minor) +{ + char file[strlen(lib->dev_dev) + 50]; + + sprintf(file, lib->dev_dev, dev_num); + return read_major(file, major, minor); +} + +/** + * vol_get_major - get major and minor numbers of an UBI volume. + * @lib: libubi descriptor + * @dev_num: UBI device number + * @vol_id: volume ID + * @major: major number is returned here + * @minor: minor number is returned here + * + * This function returns zero in case of succes and %-1 in case of failure. + */ +static int vol_get_major(struct libubi *lib, int dev_num, int vol_id, + int *major, int *minor) +{ + char file[strlen(lib->vol_dev) + 100]; + + sprintf(file, lib->vol_dev, dev_num, vol_id); + return read_major(file, major, minor); +} + +/** + * vol_node2nums - find UBI device number and volume ID by volume device node + * file. + * @lib: UBI library descriptor + * @node: UBI character device node name + * @dev_num: UBI device number is returned here + * @vol_id: volume ID is returned hers + * + * This function returns zero in case of succes and %-1 in case of failure. + */ +static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num, + int *vol_id) +{ + struct stat st; + struct ubi_info info; + int i, fd, major, minor; + char file[strlen(lib->ubi_vol) + 100]; + + if (lstat(node, &st)) + return -1; + + if (!S_ISCHR(st.st_mode)) { + errno = EINVAL; + return errmsg("\"%s\" is not a character device", node); + } + + major = major(st.st_rdev); + minor = minor(st.st_rdev); + + if (minor == 0) { + errno = EINVAL; + return errmsg("\"%s\" is not a volume character device", node); + } + + if (ubi_get_info((libubi_t *)lib, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + int major1, minor1, ret; + + ret = dev_get_major(lib, i, &major1, &minor1); + if (ret) { + if (errno == ENOENT) + continue; + return -1; + } + + if (major1 == major) + break; + } + + if (i > info.highest_dev_num) { + errno = ENODEV; + return -1; + } + + /* Make sure this UBI volume exists */ + sprintf(file, lib->ubi_vol, i, minor - 1); + fd = open(file, O_RDONLY); + if (fd == -1) { + errno = ENODEV; + return -1; + } + + *dev_num = i; + *vol_id = minor - 1; + errno = 0; + return 0; +} + +/** + * dev_node2num - find UBI device number by its character device node. + * @lib: UBI library descriptor + * @node: UBI character device node name + * + * This function returns positive UBI device number in case of success and %-1 + * in case of failure. + */ +static int dev_node2num(struct libubi *lib, const char *node, int *dev_num) +{ + struct stat stat; + struct ubi_info info; + int i, major, minor; + + if (lstat(node, &stat)) + return -1; + + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + return errmsg("\"%s\" is not a character device", node); + } + + major = major(stat.st_rdev); + minor = minor(stat.st_rdev); + + if (minor != 0) { + errno = EINVAL; + return errmsg("\"%s\" is not an UBI character device", node); + } + + if (ubi_get_info((libubi_t *)lib, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + int major1, minor1, ret; + + ret = dev_get_major(lib, i, &major1, &minor1); + if (ret) { + if (errno == ENOENT) + continue; + return -1; + } + + if (major1 == major) { + if (minor1 != 0) { + errmsg("UBI character device minor number is " + "%d, but must be 0", minor1); + errno = EINVAL; + return -1; + } + errno = 0; + *dev_num = i; + return 0; + } + } + + errno = ENODEV; + return -1; +} + +int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num) +{ + struct ubi_info info; + int i, ret, mtd_num1; + struct libubi *lib = desc; + + if (ubi_get_info(desc, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + ret = dev_read_int(lib->dev_mtd_num, i, &mtd_num1); + if (ret) { + if (errno == ENOENT) + continue; + return -1; + } + + if (mtd_num1 == mtd_num) { + errno = 0; + *dev_num = i; + return 0; + } + } + + errno = 0; + return -1; +} + +libubi_t libubi_open(int required) +{ + int fd, version; + struct libubi *lib; + + lib = calloc(1, sizeof(struct libubi)); + if (!lib) + return NULL; + + /* TODO: this must be discovered instead */ + lib->sysfs = strdup("/sys"); + if (!lib->sysfs) + goto out_error; + + lib->sysfs_ctrl = mkpath(lib->sysfs, SYSFS_CTRL); + if (!lib->sysfs_ctrl) + goto out_error; + + lib->ctrl_dev = mkpath(lib->sysfs_ctrl, CTRL_DEV); + if (!lib->ctrl_dev) + goto out_error; + + lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI); + if (!lib->sysfs_ubi) + goto out_error; + + /* Make sure UBI is present */ + fd = open(lib->sysfs_ubi, O_RDONLY); + if (fd == -1) { + if (required) + errmsg("cannot open \"%s\", UBI does not seem to " + "exist in system", lib->sysfs_ubi); + goto out_error; + } + + if (close(fd)) { + sys_errmsg("close failed on \"%s\"", lib->sysfs_ubi); + goto out_error; + } + + lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); + if (!lib->ubi_dev) + goto out_error; + + lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); + if (!lib->ubi_version) + goto out_error; + + lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); + if (!lib->dev_dev) + goto out_error; + + lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); + if (!lib->dev_avail_ebs) + goto out_error; + + lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); + if (!lib->dev_total_ebs) + goto out_error; + + lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); + if (!lib->dev_bad_count) + goto out_error; + + lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); + if (!lib->dev_eb_size) + goto out_error; + + lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); + if (!lib->dev_max_ec) + goto out_error; + + lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); + if (!lib->dev_bad_rsvd) + goto out_error; + + lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); + if (!lib->dev_max_vols) + goto out_error; + + lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); + if (!lib->dev_min_io_size) + goto out_error; + + lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM); + if (!lib->dev_mtd_num) + goto out_error; + + lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); + if (!lib->ubi_vol) + goto out_error; + + lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); + if (!lib->vol_type) + goto out_error; + + lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); + if (!lib->vol_dev) + goto out_error; + + lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); + if (!lib->vol_alignment) + goto out_error; + + lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); + if (!lib->vol_data_bytes) + goto out_error; + + lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); + if (!lib->vol_rsvd_ebs) + goto out_error; + + lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); + if (!lib->vol_eb_size) + goto out_error; + + lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); + if (!lib->vol_corrupted) + goto out_error; + + lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); + if (!lib->vol_name) + goto out_error; + + if (read_positive_int(lib->ubi_version, &version)) + goto out_error; + if (version != LIBUBI_UBI_VERSION) { + errmsg("this library was made for UBI version %d, but UBI " + "version %d is detected\n", LIBUBI_UBI_VERSION, version); + goto out_error; + } + + return lib; + +out_error: + libubi_close((libubi_t)lib); + return NULL; +} + +void libubi_close(libubi_t desc) +{ + struct libubi *lib = (struct libubi *)desc; + + free(lib->vol_name); + free(lib->vol_corrupted); + free(lib->vol_eb_size); + free(lib->vol_rsvd_ebs); + free(lib->vol_data_bytes); + free(lib->vol_alignment); + free(lib->vol_dev); + free(lib->vol_type); + free(lib->ubi_vol); + free(lib->dev_mtd_num); + free(lib->dev_min_io_size); + free(lib->dev_max_vols); + free(lib->dev_bad_rsvd); + free(lib->dev_max_ec); + free(lib->dev_eb_size); + free(lib->dev_bad_count); + free(lib->dev_total_ebs); + free(lib->dev_avail_ebs); + free(lib->dev_dev); + free(lib->ubi_version); + free(lib->ubi_dev); + free(lib->sysfs_ubi); + free(lib->ctrl_dev); + free(lib->sysfs_ctrl); + free(lib->sysfs); + free(lib); +} + +int ubi_attach_mtd(libubi_t desc, const char *node, + struct ubi_attach_request *req) +{ + int fd, ret; + struct ubi_attach_req r; + + memset(&r, sizeof(struct ubi_attach_req), '\0'); + + desc = desc; + r.ubi_num = req->dev_num; + r.mtd_num = req->mtd_num; + r.vid_hdr_offset = req->vid_hdr_offset; + + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + ret = ioctl(fd, UBI_IOCATT, &r); + close(fd); + if (ret == -1) + return -1; + + req->dev_num = r.ubi_num; + +#ifdef UDEV_SETTLE_HACK + if (system("udevsettle") == -1) + return -1; + if (system("udevsettle") == -1) + return -1; +#endif + + return ret; +} + +int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num) +{ + int ret, ubi_dev; + + ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev); + if (ret == -1) { + errno = ENODEV; + return ret; + } + + return ubi_remove_dev(desc, node, ubi_dev); +} + +int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev) +{ + int fd, ret; + + desc = desc; + + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + ret = ioctl(fd, UBI_IOCDET, &ubi_dev); + if (ret == -1) + goto out_close; + +#ifdef UDEV_SETTLE_HACK + if (system("udevsettle") == -1) + return -1; +#endif + +out_close: + close(fd); + return ret; +} + +int ubi_node_type(libubi_t desc, const char *node) +{ + struct stat st; + struct ubi_info info; + int i, fd, major, minor; + struct libubi *lib = (struct libubi *)desc; + char file[strlen(lib->ubi_vol) + 100]; + + if (lstat(node, &st)) + return -1; + + if (!S_ISCHR(st.st_mode)) { + errno = EINVAL; + return -1; + } + + major = major(st.st_rdev); + minor = minor(st.st_rdev); + + if (ubi_get_info((libubi_t *)lib, &info)) + return -1; + + for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { + int major1, minor1, ret; + + ret = dev_get_major(lib, i, &major1, &minor1); + if (ret) { + if (errno == ENOENT) + continue; + return -1; + } + + if (major1 == major) + break; + } + + if (i > info.highest_dev_num) { + /* + * The character device node does not correspond to any + * existing UBI device or volume, but we do not want to return + * any error number in this case, to indicate the fact that it + * could be a UBI device/volume, but it doesn't. + */ + errno = 0; + return -1; + } + + if (minor == 0) + return 1; + + /* This is supposdely an UBI volume device node */ + sprintf(file, lib->ubi_vol, i, minor - 1); + fd = open(file, O_RDONLY); + if (fd == -1) { + errno = 0; + return -1; + } + + return 2; +} + +int ubi_get_info(libubi_t desc, struct ubi_info *info) +{ + DIR *sysfs_ubi; + struct dirent *dirent; + struct libubi *lib = (struct libubi *)desc; + + memset(info, '\0', sizeof(struct ubi_info)); + + if (read_major(lib->ctrl_dev, &info->ctrl_major, &info->ctrl_minor)) { + /* + * Older UBI versions did not have control device, so we do not + * panic here for compatibility reasons. May be few years later + * we could return -1 here, but for now just set major:minor to + * -1. + */ + info->ctrl_major = info->ctrl_minor = -1; + } + + /* + * We have to scan the UBI sysfs directory to identify how many UBI + * devices are present. + */ + sysfs_ubi = opendir(lib->sysfs_ubi); + if (!sysfs_ubi) + return sys_errmsg("cannot open %s", lib->sysfs_ubi); + + info->lowest_dev_num = INT_MAX; + while (1) { + int dev_num, ret; + char tmp_buf[256]; + + errno = 0; + dirent = readdir(sysfs_ubi); + if (!dirent) + break; + + if (strlen(dirent->d_name) > 256) { + errmsg("invalid entry in %s: \"%s\"", + lib->sysfs_ubi, dirent->d_name); + goto out_close; + } + + ret = sscanf(dirent->d_name, UBI_DEV_NAME_PATT"%s", + &dev_num, tmp_buf); + if (ret == 1) { + info->dev_count += 1; + if (dev_num > info->highest_dev_num) + info->highest_dev_num = dev_num; + if (dev_num < info->lowest_dev_num) + info->lowest_dev_num = dev_num; + } + } + + if (!dirent && errno) { + sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); + goto out_close; + } + + if (closedir(sysfs_ubi)) + return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); + + if (info->lowest_dev_num == INT_MAX) + info->lowest_dev_num = 0; + + if (read_positive_int(lib->ubi_version, &info->version)) + return -1; + + return 0; + +out_close: + closedir(sysfs_ubi); + return -1; +} + +int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) +{ + int fd, ret; + struct ubi_mkvol_req r; + size_t n; + + memset(&r, sizeof(struct ubi_mkvol_req), '\0'); + + desc = desc; + r.vol_id = req->vol_id; + r.alignment = req->alignment; + r.bytes = req->bytes; + r.vol_type = req->vol_type; + + n = strlen(req->name); + if (n > UBI_MAX_VOLUME_NAME) + return -1; + + strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); + r.name_len = n; + + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + ret = ioctl(fd, UBI_IOCMKVOL, &r); + if (ret == -1) + goto out_close; + + req->vol_id = r.vol_id; + +#ifdef UDEV_SETTLE_HACK + if (system("udevsettle") == -1) + return -1; +#endif + +out_close: + close(fd); + return ret; +} + +int ubi_rmvol(libubi_t desc, const char *node, int vol_id) +{ + int fd, ret; + + desc = desc; + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); + if (ret == -1) + goto out_close; + +#ifdef UDEV_SETTLE_HACK + if (system("udevsettle") == -1) + return -1; +#endif + +out_close: + close(fd); + return ret; +} + +int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) +{ + int fd, ret; + struct ubi_rsvol_req req; + + desc = desc; + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + + req.bytes = bytes; + req.vol_id = vol_id; + + ret = ioctl(fd, UBI_IOCRSVOL, &req); + close(fd); + return ret; +} + +int ubi_update_start(libubi_t desc, int fd, long long bytes) +{ + desc = desc; + if (ioctl(fd, UBI_IOCVOLUP, &bytes)) + return -1; + return 0; +} + +int ubi_leb_read_start(int fd, struct ubi_leb *leb) +{ + return ioctl(fd, UBI_IOCLEBREAD, leb); +} + +int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes, int dtype) +{ + struct ubi_leb_change_req req; + + desc = desc; + memset(&req, 0, sizeof(struct ubi_leb_change_req)); + req.lnum = lnum; + req.bytes = bytes; + req.dtype = dtype; + + if (ioctl(fd, UBI_IOCEBCH, &req)) + return -1; + return 0; +} + +int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) +{ + DIR *sysfs_ubi; + struct dirent *dirent; + struct libubi *lib = (struct libubi *)desc; + + memset(info, '\0', sizeof(struct ubi_dev_info)); + info->dev_num = dev_num; + + sysfs_ubi = opendir(lib->sysfs_ubi); + if (!sysfs_ubi) + return -1; + + info->lowest_vol_num = INT_MAX; + + while (1) { + int vol_id, ret, devno; + char tmp_buf[256]; + + errno = 0; + dirent = readdir(sysfs_ubi); + if (!dirent) + break; + + if (strlen(dirent->d_name) > 256) { + errmsg("invalid entry in %s: \"%s\"", + lib->sysfs_ubi, dirent->d_name); + goto out_close; + } + + ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT"%s", &devno, &vol_id, tmp_buf); + if (ret == 2 && devno == dev_num) { + info->vol_count += 1; + if (vol_id > info->highest_vol_num) + info->highest_vol_num = vol_id; + if (vol_id < info->lowest_vol_num) + info->lowest_vol_num = vol_id; + } + } + + if (!dirent && errno) { + sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); + goto out_close; + } + + if (closedir(sysfs_ubi)) + return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); + + if (info->lowest_vol_num == INT_MAX) + info->lowest_vol_num = 0; + + if (dev_get_major(lib, dev_num, &info->major, &info->minor)) + return -1; + + if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_lebs)) + return -1; + if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_lebs)) + return -1; + if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) + return -1; + if (dev_read_int(lib->dev_eb_size, dev_num, &info->leb_size)) + return -1; + if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) + return -1; + if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) + return -1; + if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) + return -1; + if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) + return -1; + + info->avail_bytes = info->avail_lebs * info->leb_size; + info->total_bytes = info->total_lebs * info->leb_size; + + return 0; + +out_close: + closedir(sysfs_ubi); + return -1; +} + +int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) +{ + int dev_num; + struct libubi *lib = (struct libubi *)desc; + + if (dev_node2num(lib, node, &dev_num)) + return -1; + + return ubi_get_dev_info1(desc, dev_num, info); +} + +int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, + struct ubi_vol_info *info) +{ + int ret; + struct libubi *lib = (struct libubi *)desc; + char buf[50]; + + memset(info, '\0', sizeof(struct ubi_vol_info)); + info->dev_num = dev_num; + info->vol_id = vol_id; + + if (dev_get_major(lib, dev_num, &info->dev_major, &info->dev_minor)) + return -1; + if (vol_get_major(lib, dev_num, vol_id, &info->major, &info->minor)) + return -1; + + ret = vol_read_data(lib->vol_type, dev_num, vol_id, buf, 50); + if (ret < 0) + return -1; + + if (strncmp(buf, "static\n", ret) == 0) + info->type = UBI_STATIC_VOLUME; + else if (strncmp(buf, "dynamic\n", ret) == 0) + info->type = UBI_DYNAMIC_VOLUME; + else { + errmsg("bad value at \"%s\"", buf); + errno = EINVAL; + return -1; + } + + ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, + &info->alignment); + if (ret) + return -1; + ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, + &info->data_bytes); + if (ret) + return -1; + ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_lebs); + if (ret) + return -1; + ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->leb_size); + if (ret) + return -1; + ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, + &info->corrupted); + if (ret) + return -1; + info->rsvd_bytes = info->leb_size * info->rsvd_lebs; + + ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, + UBI_VOL_NAME_MAX + 2); + if (ret < 0) + return -1; + + info->name[ret - 1] = '\0'; + return 0; +} + +int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) +{ + int vol_id, dev_num; + struct libubi *lib = (struct libubi *)desc; + + if (vol_node2nums(lib, node, &dev_num, &vol_id)) + return -1; + + return ubi_get_vol_info1(desc, dev_num, vol_id, info); +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubigen.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubigen.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubigen.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubigen.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,335 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Generating UBI images. + * + * Authors: Oliver Lohmann + * Artem Bityutskiy + */ + +#include +#include +#include +#include + +#include +#include +#include +#include "crc32.h" +#include "common.h" + +#define PROGRAM_NAME "libubigen" + +/** + * ubigen_info_init - initialize libubigen. + * @ui: libubigen information + * @peb_size: flash physical eraseblock size + * @min_io_size: flash minimum input/output unit size + * @subpage_size: flash sub-page, if present (has to be equivalent to + * @min_io_size if does not exist) + * @vid_hdr_offs: offset of the VID header + * @ubi_ver: UBI version + */ +void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size, + int subpage_size, int vid_hdr_offs, int ubi_ver) +{ + if (!vid_hdr_offs) { + vid_hdr_offs = UBI_EC_HDR_SIZE + subpage_size - 1; + vid_hdr_offs /= subpage_size; + vid_hdr_offs *= subpage_size; + } + + ui->peb_size = peb_size; + ui->min_io_size = min_io_size; + ui->vid_hdr_offs = vid_hdr_offs; + ui->data_offs = vid_hdr_offs + UBI_VID_HDR_SIZE + min_io_size - 1; + ui->data_offs /= min_io_size; + ui->data_offs *= min_io_size; + ui->leb_size = peb_size - ui->data_offs; + ui->ubi_ver = ubi_ver; + + ui->max_volumes = ui->leb_size / UBI_VTBL_RECORD_SIZE; + if (ui->max_volumes > UBI_MAX_VOLUMES) + ui->max_volumes = UBI_MAX_VOLUMES; + ui->vtbl_size = ui->max_volumes * UBI_VTBL_RECORD_SIZE; +} + +/** + * ubigen_create_empty_vtbl - creates empty volume table. + * + * This function creates an empty volume table and returns a pointer to it in + * case of success and %NULL in case of failure. The returned object has to be + * freed with 'free()' call. + */ +struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui) +{ + struct ubi_vtbl_record *vtbl; + int i; + + vtbl = calloc(1, ui->vtbl_size); + if (!vtbl) { + sys_errmsg("cannot allocate %d bytes of memory", ui->vtbl_size); + return NULL; + } + + for (i = 0; i < ui->max_volumes; i++) { + uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i], + UBI_VTBL_RECORD_SIZE_CRC); + vtbl[i].crc = cpu_to_be32(crc); + } + + return vtbl; +} + +/** + * ubigen_add_volume - add a volume to the volume table. + * @ui: libubigen information + * @vi: volume information + * @vtbl: volume table to add to + * + * This function adds volume described by input parameters to the volume table + * @vtbl. + */ +int ubigen_add_volume(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, + struct ubi_vtbl_record *vtbl) +{ + struct ubi_vtbl_record *vtbl_rec = &vtbl[vi->id]; + uint32_t tmp; + + if (vi->id >= ui->max_volumes) + return errmsg("too high volume id %d, max. volumes is %d", + vi->id, ui->max_volumes); + + if (vi->alignment >= ui->leb_size) + return errmsg("too large alignment %d, max is %d (LEB size)", + vi->alignment, ui->leb_size); + + memset(vtbl_rec, '\0', sizeof(struct ubi_vtbl_record)); + tmp = (vi->bytes + ui->leb_size - 1) / ui->leb_size; + vtbl_rec->reserved_pebs = cpu_to_be32(tmp); + vtbl_rec->alignment = cpu_to_be32(vi->alignment); + vtbl_rec->vol_type = vi->type; + tmp = ui->leb_size % vi->alignment; + vtbl_rec->data_pad = cpu_to_be32(tmp); + vtbl_rec->flags = vi->flags; + + memcpy(vtbl_rec->name, vi->name, vi->name_len); + vtbl_rec->name[vi->name_len] = '\0'; + vtbl_rec->name_len = cpu_to_be16(vi->name_len); + + tmp = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); + vtbl_rec->crc = cpu_to_be32(tmp); + return 0; +} + +/** + * ubigen_init_ec_hdr - initialize EC header. + * @ui: libubigen information + * @hdr: the EC header to initialize + * @ec: erase counter value + */ +void ubigen_init_ec_hdr(const struct ubigen_info *ui, + struct ubi_ec_hdr *hdr, long long ec) +{ + uint32_t crc; + + memset(hdr, '\0', sizeof(struct ubi_ec_hdr)); + + hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); + hdr->version = ui->ubi_ver; + hdr->ec = cpu_to_be64(ec); + hdr->vid_hdr_offset = cpu_to_be32(ui->vid_hdr_offs); + + hdr->data_offset = cpu_to_be32(ui->data_offs); + + crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); + hdr->hdr_crc = cpu_to_be32(crc); +} + +/** + * init_vid_hdr - initialize VID header. + * @ui: libubigen information + * @vi: volume information + * @hdr: the VID header to initialize + * @lnum: logical eraseblock number + * @data: the contents of the LEB (static volumes only) + * @data_size: amount of data in this LEB (static volumes only) + * + * Note, @used_ebs, @data and @data_size are ignored in case of dynamic + * volumes. + */ +static void init_vid_hdr(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, + struct ubi_vid_hdr *hdr, int lnum, + const void *data, int data_size) +{ + uint32_t crc; + + memset(hdr, '\0', sizeof(struct ubi_vid_hdr)); + + hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); + hdr->version = ui->ubi_ver; + hdr->vol_type = vi->type; + hdr->vol_id = cpu_to_be32(vi->id); + hdr->lnum = cpu_to_be32(lnum); + hdr->data_pad = cpu_to_be32(vi->data_pad); + hdr->compat = vi->compat; + + if (vi->type == UBI_VID_STATIC) { + hdr->data_size = cpu_to_be32(data_size); + hdr->used_ebs = cpu_to_be32(vi->used_ebs); + crc = crc32(UBI_CRC32_INIT, data, data_size); + hdr->data_crc = cpu_to_be32(crc); + } + + crc = crc32(UBI_CRC32_INIT, hdr, UBI_VID_HDR_SIZE_CRC); + hdr->hdr_crc = cpu_to_be32(crc); +} + +/** + * ubigen_write_volume - write UBI volume. + * @ui: libubigen information + * @vi: volume information + * @ec: erase coutner value to put to EC headers + * @bytes: volume size in bytes + * @in: input file descriptor (has to be properly seeked) + * @out: output file descriptor + * + * This function reads the contents of the volume from the input file @in and + * writes the UBI volume to the output file @out. Returns zero on success and + * %-1 on failure. + */ +int ubigen_write_volume(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, long long ec, + long long bytes, int in, int out) +{ + int len = vi->usable_leb_size, rd, lnum = 0; + char inbuf[ui->leb_size+sizeof(unsigned int)], outbuf[ui->peb_size]; + + if (vi->id >= ui->max_volumes) + return errmsg("too high volume id %d, max. volumes is %d", + vi->id, ui->max_volumes); + + if (vi->alignment >= ui->leb_size) + return errmsg("too large alignment %d, max is %d (LEB size)", + vi->alignment, ui->leb_size); + + memset(outbuf, 0xFF, ui->data_offs); + ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec); + + while (bytes) { + int l; + struct ubi_vid_hdr *vid_hdr; + + if (bytes < len) + len = bytes; + bytes -= len; + + l = len; + do { + rd = read(in, inbuf + len - l, sizeof(unsigned int)); + if (rd != sizeof(unsigned int)) + return sys_errmsg("cannot read leb lnum from the input file"); + + rd = read(in, inbuf + len - l + sizeof(unsigned int), l); + if (rd != l) + return sys_errmsg("cannot read %d bytes from the input file", l); + + l -= rd; + } while (l); + + vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); + lnum = ((unsigned int *)inbuf)[0]; + init_vid_hdr(ui, vi, vid_hdr, lnum, inbuf+sizeof(unsigned int), len); + + memcpy(outbuf + ui->data_offs, inbuf+sizeof(unsigned int), len); + memset(outbuf + ui->data_offs + len, 0xFF, + ui->peb_size - ui->data_offs - len); + + if (write(out, outbuf, ui->peb_size) != ui->peb_size) + return sys_errmsg("cannot write %d bytes to the output file", ui->peb_size); + +// lnum += 1; + } + + return 0; +} + +/** + * ubigen_write_layout_vol - write UBI layout volume + * @ui: libubigen information + * @peb1: physical eraseblock number to write the first volume table copy + * @peb2: physical eraseblock number to write the second volume table copy + * @ec1: erase counter value for @peb1 + * @ec2: erase counter value for @peb1 + * @vtbl: volume table + * @fd: output file descriptor seeked to the proper position + * + * This function creates the UBI layout volume which contains 2 copies of the + * volume table. Returns zero in case of success and %-1 in case of failure. + */ +int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2, + long long ec1, long long ec2, + struct ubi_vtbl_record *vtbl, int fd) +{ + int ret; + struct ubigen_vol_info vi; + char outbuf[ui->peb_size]; + struct ubi_vid_hdr *vid_hdr; + off_t seek; + + vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS; + vi.id = UBI_LAYOUT_VOLUME_ID; + vi.alignment = UBI_LAYOUT_VOLUME_ALIGN; + vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN; + vi.usable_leb_size = ui->leb_size - vi.data_pad; + vi.data_pad = ui->leb_size - vi.usable_leb_size; + vi.type = UBI_LAYOUT_VOLUME_TYPE; + vi.name = UBI_LAYOUT_VOLUME_NAME; + vi.name_len = strlen(UBI_LAYOUT_VOLUME_NAME); + vi.compat = UBI_LAYOUT_VOLUME_COMPAT; + + memset(outbuf, 0xFF, ui->data_offs); + vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); + memcpy(outbuf + ui->data_offs, vtbl, ui->vtbl_size); + memset(outbuf + ui->data_offs + ui->vtbl_size, 0xFF, + ui->peb_size - ui->data_offs - ui->vtbl_size); + + seek = peb1 * ui->peb_size; + if (lseek(fd, seek, SEEK_SET) != seek) + return sys_errmsg("cannot seek output file"); + ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec1); + init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0); + ret = write(fd, outbuf, ui->peb_size); + if (ret != ui->peb_size) + return sys_errmsg("cannot write %d bytes", ui->peb_size); + + seek = peb2 * ui->peb_size; + if (lseek(fd, seek, SEEK_SET) != seek) + return sys_errmsg("cannot seek output file"); + ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec2); + init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0); + ret = write(fd, outbuf, ui->peb_size); + if (ret != ui->peb_size) + return sys_errmsg("cannot write %d bytes", ui->peb_size); + + return 0; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi_int.h linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi_int.h --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi_int.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/libubi_int.h 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,133 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Artem Bityutskiy + * + * UBI (Unsorted Block Images) library. + */ + +#ifndef __LIBUBI_INT_H__ +#define __LIBUBI_INT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The below are pre-define UBI file and directory names. + * + * Note, older kernels put 'ubiX_Y' directories straight to '/sys/class/ubi/'. + * New kernels puts 'ubiX_Y' directories to '/sys/class/ubi/ubiX/', which is + * saner. And for compatibility reasons it also puts symlinks to 'ubiX_Y' + * directories to '/sys/class/ubi/'. For now libubi assumes old layout. + */ + +#define SYSFS_UBI "class/ubi" +#define SYSFS_CTRL "class/misc/ubi_ctrl/" + +#define CTRL_DEV "dev" + +#define UBI_VER "version" +#define UBI_DEV_NAME_PATT "ubi%d" + +#define DEV_DEV "dev" +#define DEV_AVAIL_EBS "avail_eraseblocks" +#define DEV_TOTAL_EBS "total_eraseblocks" +#define DEV_BAD_COUNT "bad_peb_count" +#define DEV_EB_SIZE "eraseblock_size" +#define DEV_MAX_EC "max_ec" +#define DEV_MAX_RSVD "reserved_for_bad" +#define DEV_MAX_VOLS "max_vol_count" +#define DEV_MIN_IO_SIZE "min_io_size" +#define DEV_MTD_NUM "mtd_num" + +#define UBI_VOL_NAME_PATT "ubi%d_%d" +#define VOL_TYPE "type" +#define VOL_DEV "dev" +#define VOL_ALIGNMENT "alignment" +#define VOL_DATA_BYTES "data_bytes" +#define VOL_RSVD_EBS "reserved_ebs" +#define VOL_EB_SIZE "usable_eb_size" +#define VOL_CORRUPTED "corrupted" +#define VOL_NAME "name" + +/** + * libubi - UBI library description data structure. + * @sysfs: sysfs file system path + * @sysfs_ctrl: UBI control device directory in sysfs + * @ctrl_dev: UBI control device major/minor numbers sysfs file + * @sysfs_ubi: UBI directory in sysfs + * @ubi_dev: UBI device sysfs directory pattern + * @ubi_version: UBI version file sysfs path + * @dev_dev: UBI device major/minor numbers file pattern + * @dev_avail_ebs: count of available eraseblocks sysfs path pattern + * @dev_total_ebs: total eraseblocks count sysfs path pattern + * @dev_bad_count: count of bad eraseblocks sysfs path pattern + * @dev_eb_size: size of UBI device's eraseblocks sysfs path pattern + * @dev_max_ec: maximum erase counter sysfs path pattern + * @dev_bad_rsvd: count of physical eraseblock reserved for bad eraseblocks + * handling + * @dev_max_vols: maximum volumes number count sysfs path pattern + * @dev_min_io_size: minimum I/O unit size sysfs path pattern + * @ubi_vol: UBI volume sysfs directory pattern + * @vol_type: volume type sysfs path pattern + * @vol_dev: volume major/minor numbers file pattern + * @vol_alignment: volume alignment sysfs path pattern + * @vol_data_bytes: volume data size sysfs path pattern + * @vol_rsvd_ebs: volume reserved size sysfs path pattern + * @vol_eb_size: volume eraseblock size sysfs path pattern + * @vol_corrupted: volume corruption flag sysfs path pattern + * @vol_name: volume name sysfs path pattern + */ +struct libubi +{ + char *sysfs; + char *sysfs_ctrl; + char *ctrl_dev; + char *sysfs_ubi; + char *ubi_dev; + char *ubi_version; + char *dev_dev; + char *dev_avail_ebs; + char *dev_total_ebs; + char *dev_bad_count; + char *dev_eb_size; + char *dev_max_ec; + char *dev_bad_rsvd; + char *dev_max_vols; + char *dev_min_io_size; + char *dev_mtd_num; + char *ubi_vol; + char *vol_type; + char *vol_dev; + char *vol_alignment; + char *vol_data_bytes; + char *vol_rsvd_ebs; + char *vol_eb_size; + char *vol_corrupted; + char *vol_name; + char *vol_max_count; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !__LIBUBI_INT_H__ */ diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiattach.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiattach.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiattach.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiattach.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to attach MTD devices to UBI. + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubiattach" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int mtdn; + int vidoffs; + const char *node; +}; + +static struct args args = { + .devn = UBI_DEV_NUM_AUTO, + .mtdn = -1, + .vidoffs = 0, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to attach MTD device to UBI."; + +static const char *optionsstr = +"-d, --devn= the number to assign to the newly created UBI device\n" +" (the number is assigned automatically if this is not\n" +" specified\n" +"-m, --mtdn= MTD device number to attach\n" +"-O, --vid-hdr-offset VID header offset (do not specify this unless you\n" +" really know what you do and the optimal defaults will\n" +" be used)\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-m ] [-d ]\n" +"\t\t[--mtdn=] [--devn ]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI and\n" +" and create UBI device number 3 (ubi3)"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "m:d:O:hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'm': + args.mtdn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.mtdn < 0) + return errmsg("bad MTD device number: \"%s\"", optarg); + + break; + + case 'O': + args.vidoffs = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vidoffs <= 0) + return errmsg("bad VID header offset: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc) + return errmsg("UBI control device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI control device specified (use -h for help)"); + + if (args.mtdn == -1) + return errmsg("MTD device number was not specified (use -h for help)"); + + args.node = argv[optind]; + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_info ubi_info; + struct ubi_dev_info dev_info; + struct ubi_attach_request req; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(1); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + /* + * Make sure the kernel is fresh enough and this feature is supported. + */ + err = ubi_get_info(libubi, &ubi_info); + if (err) { + sys_errmsg("cannot get UBI information"); + goto out_libubi; + } + + if (ubi_info.ctrl_major == -1) { + errmsg("MTD attach/detach feature is not supported by your kernel"); + goto out_libubi; + } + + req.dev_num = args.devn; + req.mtd_num = args.mtdn; + req.vid_hdr_offset = args.vidoffs; + + err = ubi_attach_mtd(libubi, args.node, &req); + if (err) { + sys_errmsg("cannot attach mtd%d", args.mtdn); + goto out_libubi; + } + + /* Print some information about the new UBI device */ + err = ubi_get_dev_info1(libubi, req.dev_num, &dev_info); + if (err) { + sys_errmsg("cannot get information about newly created UBI device"); + goto out_libubi; + } + + printf("UBI device number %d, total %d LEBs (", dev_info.dev_num, dev_info.total_lebs); + ubiutils_print_bytes(dev_info.total_bytes, 0); + printf("), available %d LEBs (", dev_info.avail_lebs); + ubiutils_print_bytes(dev_info.avail_bytes, 0); + printf("), LEB size "); + ubiutils_print_bytes(dev_info.leb_size, 1); + printf("\n"); + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrc32.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrc32.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrc32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrc32.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,124 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Calculate CRC32 with UBI start value (0xFFFFFFFF) for a given binary image. + * + * Author: Oliver Lohmann + */ + +#include +#include +#include +#include +#include +#include + +#include "crc32.h" +#include "common.h" + +#define BUFSIZE 4096 + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubicrc32" + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)"; + +static const char *optionsstr = +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-h] [--help]"; + +static const struct option long_options[] = { + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err = 0; + uint32_t crc = UBI_CRC32_INIT; + char buf[BUFSIZE]; + FILE *fp; + + if (argc > 1) { + fp = fopen(argv[1], "r"); + if (!fp) + return sys_errmsg("cannot open \"%s\"", argv[1]); + } else + fp = stdin; + + err = parse_opt(argc, argv); + if (err) + return err; + + while (!feof(fp)) { + size_t read; + + read = fread(buf, 1, BUFSIZE, fp); + if (ferror(fp)) { + sys_errmsg("cannot read input file"); + err = -1; + goto out_close; + } + crc = crc32(crc, buf, read); + } + + printf("0x%08x\n", crc); + +out_close: + if (fp != stdin) + fclose(fp); + return err; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcsf.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcsf.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcsf.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcsf.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to generate input file CRC + * + * Authors: Yurong Tan (Nancy) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "common.h" +#include "crc32.h" + +#define PROGRAM_VERSION "1.1" +#define PROGRAM_NAME "ubicrcsf" +#define UBI_LEB_SIZE 258048 +#define BUF_SIZE (UBI_LEB_SIZE + sizeof(unsigned int)) + +/* + * usage: $ubicrcsf ubifs.img + */ +int main(int argc, char * const argv[]) +{ + int err, ifd, tmp, i; + int crc_sum = 0; + struct stat st; + char *buf=NULL; + + buf = malloc(BUF_SIZE); + if(buf==NULL){ + printf("no mem\n"); + goto out_free; + } + + err = stat(argv[1], &st); + if (err < 0) { + printf("stat failed on \"%s\"", argv[1]); + goto out_free; + } + + ifd = open(argv[1], O_RDONLY); + if (ifd == -1) { + printf("cannot open \"%s\"", argv[1]); + goto out_close; + } + + tmp = st.st_size/BUF_SIZE; + + for( i=0; i< tmp; i++ ){ + err = read(ifd, buf, BUF_SIZE); + if (err != BUF_SIZE) { + printf("read error\n"); + goto out_close; + } + crc_sum = crc32(crc_sum, &buf[sizeof(unsigned int)], UBI_LEB_SIZE); + } + + printf("CRC sum: %d\n",crc_sum); + free(buf); + close(ifd); + return 0; +out_close: + close(ifd); +out_free: + free(buf); + return -1; +} + + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcvol.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcvol.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcvol.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubicrcvol.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,221 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to update UBI volumes. + * + * Authors: Frank Haverkamp + * Joshua W. Boyer + * Artem Bityutskiy + * Yurong Tan (Nancy) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "common.h" +#include "crc32.h" + +#define PROGRAM_VERSION "1.1" +#define PROGRAM_NAME "ubicrcfatvol" + +struct args { + const char *node; + long long size; + int devn; + char dev_name[256]; +}; + +static struct args args = { + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to read UBI volumes data and generate CRC."; + +static const char *optionsstr = +"-h, --help print help message\n" +"-V, --version print program version\n\n" +"-s, --read size\n" +; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-s] [-h] [-V] [--help]\n" +"\t\t\t[--version] \n\n" + "Example 1: " PROGRAM_NAME " /dev/ubi0_1 \n"; + +struct option long_options[] = { + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + /* Deprecated -d and -B options */ + { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, + { NULL, 0, NULL, 0} +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "n:sh?Vd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 's': + args.size = ubiutils_get_bytes(optarg); + if (args.size <= 0) + return errmsg("bad read size: \"%s\"", optarg); + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) + return errmsg("UBI device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("specify UBI device name and image file name as first 2 " + "parameters (use -h for help)"); + } + + args.node = argv[optind]; + + return 0; +} + +static int crc_volume(libubi_t libubi, struct ubi_vol_info *vol_info) +{ + int fd; + struct ubi_leb leb; + int i, tmp; + int crc_sum = 0; + + leb.buf = malloc(vol_info->leb_size); + if (!leb.buf) + return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); + + fd = open(args.node, O_RDONLY); + if (fd == -1) { + sys_errmsg("cannot open UBI volume \"%s\"", args.node); + goto out_free; + } + + for(i=0; i < vol_info->rsvd_lebs ; i++){ + leb.lnum = i; + tmp = ubi_leb_read_start(fd, &leb); + if(tmp == 1) + continue; + else if(tmp == 0){ + crc_sum = crc32(crc_sum, leb.buf, vol_info->leb_size); + }else{ + printf("LEB %d read error\n", i); + goto out_close; + } + } + + close(fd); + free(leb.buf); + printf("CRC sum: %d\n",crc_sum); + return 0; + goto out_close; +out_close: + close(fd); +out_free: + free(leb.buf); + return -1; +} + + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_vol_info vol_info; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(1); + if (libubi == NULL) { + sys_errmsg("cannot open libubi"); + goto out_libubi; + } + + err = ubi_node_type(libubi, args.node); + if (err == 1) { + errmsg("\"%s\" is an UBI device node, not an UBI volume node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI volume node", args.node); + goto out_libubi; + } + + err = ubi_get_vol_info(libubi, args.node, &vol_info); + if (err) { + sys_errmsg("cannot get information about UBI volume \"%s\"", + args.node); + goto out_libubi; + } + + err = crc_volume(libubi, &vol_info); + if (err) + goto out_libubi; + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; + +} + + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidetach.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidetach.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidetach.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidetach.c 2010-03-03 19:04:29.000000000 -0800 @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to delete UBI devices (detach MTD devices from UBI). + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubidetach" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int mtdn; + const char *node; +}; + +static struct args args = { + .devn = UBI_DEV_NUM_AUTO, + .mtdn = -1, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION +" - a tool to remove UBI devices (detach MTD devices from UBI)"; + +static const char *optionsstr = +"-d, --devn= UBI device number to delete\n" +"-m, --mtdn= or altrnatively, MTD device number to detach -\n" +" this will delete corresponding UBI device\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-d ] [-m ]\n" +"\t\t[--devn ] [--mtdn=]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - detach MTD device 0 (mtd0)"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "m:d:hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'm': + args.mtdn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.mtdn < 0) + return errmsg("bad MTD device number: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc) + return errmsg("UBI control device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI control device specified (use -h for help)"); + + if (args.mtdn == -1 && args.devn == -1) + return errmsg("neither MTD nor UBI devices were specified (use -h for help)"); + + if (args.mtdn != -1 && args.devn != -1) + return errmsg("specify either MTD or UBI device (use -h for help)"); + + args.node = argv[optind]; + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_info ubi_info; + + err = parse_opt(argc, argv); + if (err) + return -1; + + libubi = libubi_open(1); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + /* + * Make sure the kernel is fresh enough and this feature is supported. + */ + err = ubi_get_info(libubi, &ubi_info); + if (err) { + sys_errmsg("cannot get UBI information"); + goto out_libubi; + } + + if (ubi_info.ctrl_major == -1) { + errmsg("MTD detach/detach feature is not supported by your kernel"); + goto out_libubi; + } + + if (args.devn != -1) { + err = ubi_remove_dev(libubi, args.node, args.devn); + if (err) { + sys_errmsg("cannot remove ubi%d", args.devn); + goto out_libubi; + } + } else { + err = ubi_detach_mtd(libubi, args.node, args.mtdn); + if (err) { + sys_errmsg("cannot detach mtd%d", args.mtdn); + goto out_libubi; + } + } + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} + diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidumpvol.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidumpvol.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidumpvol.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubidumpvol.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,264 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to update UBI volumes. + * + * Authors: Frank Haverkamp + * Joshua W. Boyer + * Artem Bityutskiy + * Yurong Tan (Nancy) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.1" +#define PROGRAM_NAME "ubidumpvol" + +struct args { + int truncate; + const char *node; + const char *img; + /* For deprecated -d and -B options handling */ + int devn; + char dev_name[256]; + int broken_update; +}; + +static struct args args = { + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to write data to UBI volumes."; + +static const char *optionsstr = +"-n, --vol_id= ID of UBI volume to update\n" +"-t, --truncate truncate volume (wipe it out)\n" +"-h, --help print help message\n" +"-V, --version print program version\n\n" +"The following are compatibility options which are deprecated, do not use them\n" +"-d, --devn= UBI device number - may be used instead of the UBI\n" +" device node name in which case the utility assumes\n" +" that the device node is \"/dev/ubi\"\n" +"-B, --broken-update broken update, this is for testing"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-t] [-h] [-V] [--truncate] [--help]\n" +"\t\t\t[--version] \n\n" + "Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - dump UBI volume /dev/ubi0_1 to file \"fs.img\" \n"; + +struct option long_options[] = { + { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + /* Deprecated -d and -B options */ + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "broken-update", .has_arg = 1, .flag = NULL, .val = 'B' }, + { NULL, 0, NULL, 0} +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "n:th?Vd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 't': + args.truncate = 1; + break; + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'd': + { + char *endp; + + /* Handle deprecated -d option */ + warnmsg("-d is depricated and will be removed, do not use it"); + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: " "\"%s\"", optarg); + break; + } + + case 'B': + /* Handle deprecated -B option */ + warnmsg("-B is depricated and will be removed, do not use it"); + args.broken_update = 1; + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) + return errmsg("UBI device name was not specified (use -h for help)"); + else if (optind != argc - 2) + return errmsg("specify UBI device name and image file name as first 2 " + "parameters (use -h for help)"); + } + + args.node = argv[optind]; + args.img = argv[optind + 1]; + + return 0; +} + +static int dump_volume(libubi_t libubi, struct ubi_vol_info *vol_info) +{ + int err, fd, ifd; + struct ubi_leb leb; + int i, tmp; + + leb.buf = malloc(vol_info->leb_size); + if (!leb.buf) + return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); + + fd = open(args.node, O_RDONLY); + if (fd == -1) { + sys_errmsg("cannot open UBI volume \"%s\"", args.node); + goto out_free; + } + + ifd = open(args.img, O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (ifd == -1) { + sys_errmsg("cannot open \"%s\"", args.img); + goto out_close1; + } + + for(i=0; i < vol_info->rsvd_lebs; i++){ + leb.lnum = i; + tmp = ubi_leb_read_start(fd, &leb); + if(tmp == 1) + continue; + else if(tmp == 0){ + // write lnum + err = write(ifd, (char *)&leb.lnum, sizeof(leb.lnum)); + if (err != sizeof(leb.lnum)){ + perror("Image file write error\n"); + goto out_close; + } + // write LEB data + err = write(ifd, leb.buf, vol_info->leb_size); + if (err != vol_info->leb_size){ + perror("Image file write error\n"); + goto out_close; + } + }else{ + printf("LEB %d read error\n", i); + goto out_close; + } + } + + close(ifd); + close(fd); + free(leb.buf); + printf("Dump Volume succeed\n"); + return 0; + goto out_close; +out_close: + close(ifd); +out_close1: + close(fd); +out_free: + free(leb.buf); + return -1; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_vol_info vol_info; + + err = parse_opt(argc, argv); + if (err) + return -1; + + if (!args.img && !args.truncate) + return errmsg("incorrect arguments, use -h for help"); + + libubi = libubi_open(1); + if (libubi == NULL) { + sys_errmsg("cannot open libubi"); + goto out_libubi; + } + + err = ubi_node_type(libubi, args.node); + if (err == 1) { + errmsg("\"%s\" is an UBI device node, not an UBI volume node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI volume node", args.node); + goto out_libubi; + } + + err = ubi_get_vol_info(libubi, args.node, &vol_info); + if (err) { + sys_errmsg("cannot get information about UBI volume \"%s\"", + args.node); + goto out_libubi; + } + + err = dump_volume(libubi, &vol_info); + if (err) + goto out_libubi; + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiformat.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiformat.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiformat.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubiformat.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,712 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to format MTD devices into UBI and flash UBI images. + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "crc32.h" +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubiformat" + +/* The variables below are set by command line arguments */ +struct args { + unsigned int yes:1; + unsigned int quiet:1; + unsigned int verbose:1; + unsigned int override_ec:1; + unsigned int novtbl:1; + int subpage_size; + int vid_hdr_offs; + int ubi_ver; + long long ec; + const char *image; + const char *node; +}; + +static struct args args = +{ + .ubi_ver = 1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to format MTD devices and flash UBI images"; + +static const char *optionsstr = +"-s, --sub-page-size= minimum input/output unit used for UBI\n" +" headers, e.g. sub-page size in case of NAND\n" +" flash (equivalent to the minimum input/output\n" +" unit size by default)\n" +"-O, --vid-hdr-offset= offset if the VID header from start of the\n" +" physical eraseblock (default is the next\n" +" minimum I/O unit or sub-page after the EC\n" +" header)\n" +"-n, --no-volume-table only erase all eraseblock and preserve erase\n" +" counters, do not write empty volume table\n" +"-f, --flash-image= flash image file\n" +"-e, --erase-counter= use as the erase counter value for all\n" +" eraseblocks\n" +"-y, --yes assume the answer is \"yes\" for all question\n" +" this program would otherwise ask\n" +"-q, --quiet suppress progress percentage information\n" +"-v, --verbose be verbose\n" +"-x, --ubi-ver= UBI version number to put to EC headers\n" +" (default is 1)\n" +"-h, -?, --help print help message\n" +"-V, --version print program version\n"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-h] [-V] [-y] [-q] [-v]\n" +"\t\t\t[-x ] [-E ] [-s ] [-O ] [-n]\n" +"\t\t\t[--help] [--version] [--yes] [--verbose] [--quiet]\n" +"\t\t\t[--ec=] [--vid-hdr-offset=]\n" +"\t\t\t[--ubi-ver=] [--no-volume-table]\n\n" + +"Example 1: " PROGRAM_NAME " /dev/mtd0 -y - format MTD device number 0 and do\n" +" not ask questions.\n" +"Example 2: " PROGRAM_NAME " /dev/mtd0 -q -e 0 - format MTD device number 0,\n" +" be quiet and force erase counter value 0."; + +static const struct option long_options[] = { + { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, + { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, + { .name = "no-volume-table", .has_arg = 0, .flag = NULL, .val = 'n' }, + { .name = "flash-image", .has_arg = 0, .flag = NULL, .val = 'f' }, + { .name = "yes", .has_arg = 0, .flag = NULL, .val = 'y' }, + { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, + { .name = "quiet", .has_arg = 0, .flag = NULL, .val = 'q' }, + { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, + { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "nh?Vyqve:x:s:O:f:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 's': + args.subpage_size = ubiutils_get_bytes(optarg); + if (args.subpage_size <= 0) + return errmsg("bad sub-page size: \"%s\"", optarg); + if (!is_power_of_2(args.subpage_size)) + return errmsg("sub-page size should be power of 2"); + break; + + case 'O': + args.vid_hdr_offs = strtoul(optarg, &endp, 0); + if (args.vid_hdr_offs <= 0 || *endp != '\0' || endp == optarg) + return errmsg("bad VID header offset: \"%s\"", optarg); + break; + + case 'e': + args.ec = strtoull(optarg, &endp, 0); + if (args.ec <= 0 || *endp != '\0' || endp == optarg) + return errmsg("bad erase counter value: \"%s\"", optarg); + if (args.ec >= EC_MAX) + return errmsg("too high erase %llu, counter, max is %u", args.ec, EC_MAX); + args.override_ec = 1; + break; + + case 'f': + args.image = optarg; + break; + + case 'n': + args.novtbl = 1; + break; + + case 'y': + args.yes = 1; + break; + + case 'q': + args.quiet = 1; + break; + + case 'x': + args.ubi_ver = strtoul(optarg, &endp, 0); + if (args.ubi_ver < 0 || *endp != '\0' || endp == optarg) + return errmsg("bad UBI version: \"%s\"", optarg); + break; + + case 'v': + args.verbose = 1; + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (args.quiet && args.verbose) + return errmsg("using \"-q\" and \"-v\" at the same time does not make sense"); + + if (optind == argc) + return errmsg("MTD device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one MTD device specified (use -h for help)"); + + if (args.image && args.novtbl) + return errmsg("-n cannot be used together with -f"); + + args.node = argv[optind]; + return 0; +} + +static int want_exit(void) +{ + char buf[4]; + + while (1) { + normsg_cont("continue? (yes/no) "); + scanf("%3s", buf); + if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1)) + return 0; + if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1)) + return 1; + } +} + +static int answer_is_yes(void) +{ + char buf[4]; + + while (1) { + scanf("%3s", buf); + if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1)) + return 1; + if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1)) + return 0; + } +} + +static void print_bad_eraseblocks(const struct mtd_info *mtd, + const struct ubi_scan_info *si) +{ + int first = 1, eb; + + if (si->bad_cnt == 0) + return; + + normsg_cont("bad eraseblocks: "); + for (eb = 0; eb < mtd->eb_cnt; eb++) { + if (si->ec[eb] != EB_BAD) + continue; + if (first) { + printf("%d", eb); + first = 0; + } else + printf(", %d", eb); + } + printf("\n"); +} + +static int change_ec(struct ubi_ec_hdr *hdr, long long ec) +{ + uint32_t crc; + + /* Check the EC header */ + if (be32_to_cpu(hdr->magic) != UBI_EC_HDR_MAGIC) + return errmsg("mad UBI magic %#08x, should be %#08x", + be32_to_cpu(hdr->magic), UBI_EC_HDR_MAGIC); + + crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); + if (be32_to_cpu(hdr->hdr_crc) != crc) + return errmsg("bad CRC %#08x, should be %#08x\n", + crc, be32_to_cpu(hdr->hdr_crc)); + + hdr->ec = cpu_to_be64(ec); + crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); + hdr->hdr_crc = cpu_to_be32(crc); + + return 0; +} + +static int drop_ffs(const struct mtd_info *mtd, const void *buf, int len) +{ + int i; + + for (i = len - 1; i >= 0; i--) + if (((const uint8_t *)buf)[i] != 0xFF) + break; + + /* The resulting length must be aligned to the minimum flash I/O size */ + len = i + 1; + len = (len + mtd->min_io_size - 1) / mtd->min_io_size; + len *= mtd->min_io_size; + return len; +} + +static int flash_image(const struct mtd_info *mtd, const struct ubigen_info *ui, + struct ubi_scan_info *si) +{ + int fd, img_ebs, eb, written_ebs = 0, divisor; + struct stat st; + + if (stat(args.image, &st)) + return sys_errmsg("cannot open \"%s\"", args.image); + + img_ebs = st.st_size / mtd->eb_size; + if (img_ebs > si->good_cnt) + return sys_errmsg("file \"%s\" is too large (%lld bytes)", + args.image, (long long)st.st_size); + + if (st.st_size % mtd->eb_size) + return sys_errmsg("file \"%s\" (size %lld bytes) is not multiple of eraseblock size (%d bytes)", + args.image, (long long)st.st_size, mtd->eb_size); + + fd = open(args.image, O_RDONLY); + if (fd == -1) + return sys_errmsg("cannot open \"%s\"", args.image); + + verbose(args.verbose, "will write %d eraseblocks", img_ebs); + divisor = img_ebs; + for (eb = 0; eb < mtd->eb_cnt; eb++) { + int err, new_len; + char buf[mtd->eb_size]; + long long ec; + + if (!args.quiet && !args.verbose) { + printf("\r" PROGRAM_NAME ": flashing eraseblock %d -- %2lld %% complete ", + eb, (long long)(eb + 1) * 100 / divisor); + fflush(stdout); + } + + if (si->ec[eb] == EB_BAD) { + divisor += 1; + continue; + } + + if (args.verbose) { + normsg_cont("eraseblock %d: erase", eb); + fflush(stdout); + } + + err = mtd_erase(mtd, eb); + if (err) { + sys_errmsg("failed to erase eraseblock %d", eb); + goto out_close; + } + + if (read(fd, buf, mtd->eb_size) != mtd->eb_size) { + sys_errmsg("failed to read eraseblock %d from \"%s\"", + written_ebs, args.image); + goto out_close; + } + + + if (si->ec[eb] <= EC_MAX) + ec = si->ec[eb] + 1; + else if (!args.override_ec) + ec = si->mean_ec; + else + ec = args.ec; + + if (args.verbose) { + printf(", change EC to %lld", ec); + fflush(stdout); + } + + err = change_ec((struct ubi_ec_hdr *)buf, ec); + if (err) { + errmsg("bad EC header at eraseblock %d of \"%s\"", + written_ebs, args.image); + goto out_close; + } + + if (args.verbose) { + printf(", write data\n"); + fflush(stdout); + } + + new_len = drop_ffs(mtd, buf, mtd->eb_size); + + err = mtd_write(mtd, eb, 0, buf, new_len); + if (err) { + sys_errmsg("cannot write eraseblock %d", eb); + goto out_close; + } + if (++written_ebs >= img_ebs) + break; + } + + if (!args.quiet && !args.verbose) + printf("\n"); + close(fd); + return eb + 1; + +out_close: + close(fd); + return -1; +} + +static int format(const struct mtd_info *mtd, const struct ubigen_info *ui, + const struct ubi_scan_info *si, int start_eb, int novtbl) +{ + int eb, err, write_size; + struct ubi_ec_hdr *hdr; + struct ubi_vtbl_record *vtbl; + int eb1 = -1, eb2 = -1; + long long ec1 = -1, ec2 = -1; + + write_size = UBI_EC_HDR_SIZE + mtd->subpage_size - 1; + write_size /= mtd->subpage_size; + write_size *= mtd->subpage_size; + hdr = malloc(write_size); + if (!hdr) + return sys_errmsg("cannot allocate %d bytes of memory", write_size); + + memset(hdr, 0xFF, write_size); + + for (eb = start_eb; eb < mtd->eb_cnt; eb++) { + long long ec; + + if (!args.quiet && !args.verbose) { + printf("\r" PROGRAM_NAME ": formatting eraseblock %d -- %2lld %% complete ", + eb, (long long)(eb + 1 - start_eb) * 100 / (mtd->eb_cnt - start_eb)); + fflush(stdout); + } + + if (si->ec[eb] == EB_BAD) + continue; + + if (si->ec[eb] <= EC_MAX) + ec = si->ec[eb] + 1; + else if (!args.override_ec) + ec = si->mean_ec; + else + ec = args.ec; + ubigen_init_ec_hdr(ui, hdr, ec); + + if (args.verbose) { + normsg_cont("eraseblock %d: erase", eb); + fflush(stdout); + } + + err = mtd_erase(mtd, eb); + if (err) { + sys_errmsg("failed to erase eraseblock %d", eb); + goto out_free; + } + + if ((eb1 == -1 || eb2 == -1) && !novtbl) { + if (eb1 == -1) { + eb1 = eb; + ec1 = ec; + } else if (eb2 == -1) { + eb2 = eb; + ec2 = ec; + } + if (args.verbose) + printf(", do not write EC, leave for vtbl\n"); + continue; + } + + if (args.verbose) { + printf(", write EC %lld\n", ec); + fflush(stdout); + } + + err = mtd_write(mtd, eb, 0, hdr, write_size); + if (err) { + sys_errmsg("cannot write EC header (%d bytes buffer) to eraseblock %d", + write_size, eb); + if (args.subpage_size != mtd->min_io_size) + normsg("may be %d is incorrect?", args.subpage_size); + goto out_free; + } + } + + if (!args.quiet && !args.verbose) + printf("\n"); + + if (!novtbl) { + if (eb1 == -1 || eb2 == -1) { + errmsg("no eraseblocks for volume table"); + goto out_free; + } + + verbose(args.verbose, "write volume table to eraseblocks %d and %d", eb1, eb2); + vtbl = ubigen_create_empty_vtbl(ui); + if (!vtbl) + goto out_free; + + err = ubigen_write_layout_vol(ui, eb1, eb2, ec1, ec2, vtbl, mtd->fd); + free(vtbl); + if (err) { + errmsg("cannot write layout volume"); + goto out_free; + } + } + + free(hdr); + return 0; + +out_free: + free(hdr); + return -1; +} + +int main(int argc, char * const argv[]) +{ + int err, verbose; + struct mtd_info mtd; + libubi_t libubi; + struct ubigen_info ui; + struct ubi_scan_info *si; + + err = parse_opt(argc, argv); + if (err) + return -1; + + err = mtd_get_info(args.node, &mtd); + if (err) + return errmsg("cannot get information about \"%s\"", args.node); + + if (args.subpage_size == 0) + args.subpage_size = mtd.min_io_size; + else { + if (args.subpage_size > mtd.min_io_size) { + errmsg("sub-page cannot be larger than min. I/O unit"); + goto out_close; + } + + if (mtd.min_io_size % args.subpage_size) { + errmsg("min. I/O unit size should be multiple of sub-page size"); + goto out_close; + } + } + + /* Validate VID header offset if it was specified */ + if (args.vid_hdr_offs != 0) { + if (args.vid_hdr_offs % 8) { + errmsg("VID header offset has to be multiple of min. I/O unit size"); + goto out_close; + } + if (args.vid_hdr_offs + UBI_VID_HDR_SIZE > mtd.eb_size) { + errmsg("bad VID header offset"); + goto out_close; + } + } + + /* + * Because of MTD interface limitations 'mtd_get_info()' cannot get + * sub-page so we force the user to pass it via the command line. Let's + * hope the user passed us something sane. + */ + mtd.subpage_size = args.subpage_size; + + if (mtd.rdonly) { + errmsg("mtd%d (%s) is a read-only device", mtd.num, args.node); + goto out_close; + } + + /* Make sure this MTD device is not attached to UBI */ + libubi = libubi_open(0); + if (libubi) { + int ubi_dev_num; + + err = mtd_num2ubi_dev(libubi, mtd.num, &ubi_dev_num); + libubi_close(libubi); + if (!err) { + errmsg("please, first detach mtd%d (%s) from ubi%d", + mtd.num, args.node, ubi_dev_num); + goto out_close; + } + } + + if (!args.quiet) { + normsg_cont("mtd%d (%s), size ", mtd.num, mtd.type_str); + ubiutils_print_bytes(mtd.size, 1); + printf(", %d eraseblocks of ", mtd.eb_size); + ubiutils_print_bytes(mtd.eb_size, 1); + printf(", min. I/O size %d bytes\n", mtd.min_io_size); + } + + if (args.quiet) + verbose = 0; + else if (args.verbose) + verbose = 2; + else + verbose = 1; + err = ubi_scan(&mtd, &si, verbose); + if (err) { + errmsg("failed to scan mtd%d (%s)", mtd.num, args.node); + goto out_close; + } + + if (si->good_cnt == 0) { + errmsg("all %d eraseblocks are bad", si->bad_cnt); + goto out_free; + } + + if (si->good_cnt < 2 && (!args.novtbl || args.image)) { + errmsg("too few non-bad eraseblocks (%d) on mtd%d", si->good_cnt, mtd.num); + goto out_free; + } + + if (!args.quiet) { + if (si->ok_cnt) + normsg("%d eraseblocks have valid erase counter, mean value is %lld", + si->ok_cnt, si->mean_ec); + if (si->empty_cnt) + normsg("%d eraseblocks are supposedly empty", si->empty_cnt); + if (si->corrupted_cnt) + normsg("%d corrupted erase counters", si->corrupted_cnt); + print_bad_eraseblocks(&mtd, si); + } + + if (si->alien_cnt) { + if (!args.yes || !args.quiet) + warnmsg("%d of %d eraseblocks contain non-ubifs data", + si->alien_cnt, si->good_cnt); + if (!args.yes && want_exit()) { + if (args.yes && !args.quiet) + printf("yes\n"); + goto out_free; + } + } + + if (!args.override_ec && si->empty_cnt < si->good_cnt) { + int percent = ((double)si->ok_cnt)/si->good_cnt * 100; + + /* + * Make sure the majority of eraseblocks have valid + * erase counters. + */ + if (percent < 50) { + if (!args.yes || !args.quiet) + warnmsg("only %d of %d eraseblocks have valid erase counter", + si->ok_cnt, si->good_cnt); + normsg("erase counter 0 will be used for all eraseblocks"); + normsg("note, arbitrary erase counter value may be specified using -e option"); + if (!args.yes && want_exit()) { + if (args.yes && !args.quiet) + printf("yes\n"); + goto out_free; + } + args.ec = 0; + args.override_ec = 1; + } else if (percent < 95) { + if (!args.yes || !args.quiet) + warnmsg("only %d of %d eraseblocks have valid erase counter", + si->ok_cnt, si->good_cnt); + normsg("mean erase counter %lld will be used for the rest of eraseblock", + si->mean_ec); + if (!args.yes && want_exit()) { + if (args.yes && !args.quiet) + printf("yes\n"); + goto out_free; + } + args.ec = si->mean_ec; + args.override_ec = 1; + } + } + + if (!args.quiet && args.override_ec) + normsg("use erase counter %lld for all eraseblocks", args.ec); + + ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, args.subpage_size, + args.vid_hdr_offs, args.ubi_ver); + + if (si->vid_hdr_offs != -1 && ui.vid_hdr_offs != si->vid_hdr_offs) { + /* + * Hmm, what we read from flash and what we calculated using + * min. I/O unit size and sub-page size differs. + */ + if (!args.yes || !args.quiet) { + warnmsg("VID header and data offsets on flash are %d and %d, " + "which is different to calculated offsets %d and %d", + si->vid_hdr_offs, si->data_offs, ui.vid_hdr_offs, + ui.data_offs); + normsg_cont("use old offsets %d and %d? (yes/no) ", + si->vid_hdr_offs, si->data_offs); + } + if (args.yes || answer_is_yes()) { + if (args.yes && !args.quiet) + printf("yes\n"); + ui.vid_hdr_offs = si->vid_hdr_offs; + ui.data_offs = si->data_offs; + } + } + + if (args.image) { + err = flash_image(&mtd, &ui, si); + if (err < 0) + goto out_free; + + err = format(&mtd, &ui, si, err, 1); + if (err) + goto out_free; + } else { + err = format(&mtd, &ui, si, 0, args.novtbl); + if (err) + goto out_free; + } + + ubi_scan_free(si); + close(mtd.fd); + return 0; + +out_free: + ubi_scan_free(si); +out_close: + close(mtd.fd); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubimkvol.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubimkvol.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubimkvol.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubimkvol.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,310 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to create UBI volumes. + * + * Authors: Artem Bityutskiy + * Frank Haverkamp + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubimkvol" + +/* The variables below are set by command line arguments */ +struct args { + int vol_id; + int vol_type; + long long bytes; + int lebs; + int alignment; + const char *name; + int nlen; + const char *node; + int maxavs; + /* For deprecated -d option handling */ + int devn; + char dev_name[256]; +}; + +static struct args args = { + .vol_type = UBI_DYNAMIC_VOLUME, + .bytes = -1, + .lebs = -1, + .alignment = 1, + .vol_id = UBI_VOL_NUM_AUTO, + .devn = -1, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to create UBI volumes."; + +static const char *optionsstr = +"-a, --alignment= volume alignment (default is 1)\n" +"-n, --vol_id= UBI volume ID, if not specified, the volume ID\n" +" will be assigned automatically\n" +"-N, --name= volume name\n" +"-s, --size= volume size volume size in bytes, kilobytes (KiB)\n" +" or megabytes (MiB)\n" +"-S, --lebs= alternative way to give volume size in logical\n" +" eraseblocks\n" +"-m, --maxavsize set volume size to maximum available size\n" +"-t, --type= volume type (dynamic, static), default is dynamic\n" +"-h, -?, --help print help message\n" +"-V, --version print program version\n\n" +"The following is a compatibility option which is deprecated, do not use it\n" +"-d, --devn= UBI device number - may be used instead of the UBI\n" +" device node name in which case the utility assumes\n" +" that the device node is \"/dev/ubi\""; + + +static const char *usage = +"Usage: " PROGRAM_NAME " [-h] [-a ] [-n ] [-N ]\n" +"\t\t\t[-s ] [-S ] [-t ] [-V] [-m]\n" +"\t\t\t[--alignment=][--vol_id=] [--name=]\n" +"\t\t\t[--size=] [--lebs=] [--type=] [--help]\n" +"\t\t\t[--version] [--maxavsize]\n\n" +"Example: " PROGRAM_NAME "/dev/ubi0 -s 20MiB -N config_data - create a 20 Megabytes volume\n" +" named \"config_data\" on UBI device /dev/ubi0."; + +static const struct option long_options[] = { + { .name = "alignment", .has_arg = 1, .flag = NULL, .val = 'a' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, + { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, + { .name = "lebs", .has_arg = 1, .flag = NULL, .val = 'S' }, + { .name = "type", .has_arg = 1, .flag = NULL, .val = 't' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { .name = "maxavsize", .has_arg = 0, .flag = NULL, .val = 'm' }, + /* Deprecated -d option */ + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { NULL, 0, NULL, 0}, +}; + +static int param_sanity_check(void) +{ + int len; + + if (args.bytes == -1 && !args.maxavs && args.lebs == -1) + return errmsg("volume size was not specified (use -h for help)"); + + if ((args.bytes != -1 && (args.maxavs || args.lebs != -1)) || + (args.lebs != -1 && (args.maxavs || args.bytes != -1)) || + (args.maxavs && (args.bytes != -1 || args.lebs != -1))) + return errmsg("size specified with more then one option"); + + if (args.name == NULL) + return errmsg("volume name was not specified (use -h for help)"); + + len = strlen(args.name); + if (len > UBI_MAX_VOLUME_NAME) + return errmsg("too long name (%d symbols), max is %d", len, UBI_MAX_VOLUME_NAME); + + return 0; +} + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "a:n:N:s:S:t:h?Vmd:", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 't': + if (!strcmp(optarg, "dynamic")) + args.vol_type = UBI_DYNAMIC_VOLUME; + else if (!strcmp(optarg, "static")) + args.vol_type = UBI_STATIC_VOLUME; + else + return errmsg("bad volume type: \"%s\"", optarg); + break; + + case 's': + args.bytes = ubiutils_get_bytes(optarg); + if (args.bytes <= 0) + return errmsg("bad volume size: \"%s\"", optarg); + break; + + case 'S': + args.lebs = strtoull(optarg, &endp, 0); + if (endp == optarg || args.lebs <= 0 || *endp != '\0') + return errmsg("bad LEB count: \"%s\"", optarg); + break; + + case 'a': + args.alignment = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.alignment <= 0) + return errmsg("bad volume alignment: \"%s\"", optarg); + break; + + case 'n': + args.vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vol_id < 0) + return errmsg("bad volume ID: " "\"%s\"", optarg); + break; + + case 'd': + /* Handle deprecated -d option */ + warnmsg("-d is depricated and will be removed, do not use it"); + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: " "\"%s\"", optarg); + break; + + case 'N': + args.name = optarg; + args.nlen = strlen(args.name); + break; + + case 'h': + case '?': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case 'm': + args.maxavs = 1; + break; + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + /* Handle deprecated -d option */ + if (args.devn != -1) { + sprintf(args.dev_name, "/dev/ubi%d", args.devn); + args.node = args.dev_name; + } else { + if (optind == argc) + return errmsg("UBI device name was not specified (use -h for help)"); + else if (optind != argc - 1) + return errmsg("more then one UBI device specified (use -h for help)"); + + args.node = argv[optind]; + } + + if (param_sanity_check()) + return -1; + + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + struct ubi_dev_info dev_info; + struct ubi_vol_info vol_info; + struct ubi_mkvol_request req; + + err = parse_opt(argc, argv); + if (err) + return err; + + libubi = libubi_open(1); + if (!libubi) + return sys_errmsg("cannot open libubi"); + + err = ubi_node_type(libubi, args.node); + if (err == 2) { + errmsg("\"%s\" is an UBI volume node, not an UBI device node", + args.node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI device node", args.node); + goto out_libubi; + } + + err = ubi_get_dev_info(libubi, args.node, &dev_info); + if (err) { + sys_errmsg("cannot get information about UBI device \"%s\"", + args.node); + goto out_libubi; + } + + if (args.maxavs) { + args.bytes = dev_info.avail_bytes; + printf("Set volume size to %lld\n", args.bytes); + } + + if (args.lebs != -1) { + args.bytes = dev_info.leb_size; + args.bytes -= dev_info.leb_size % args.alignment; + args.bytes *= args.lebs; + } + + req.vol_id = args.vol_id; + req.alignment = args.alignment; + req.bytes = args.bytes; + req.vol_type = args.vol_type; + req.name = args.name; + + err = ubi_mkvol(libubi, args.node, &req); + if (err < 0) { + sys_errmsg("cannot UBI create volume"); + goto out_libubi; + } + + args.vol_id = req.vol_id; + + /* Print information about the created device */ + err = ubi_get_vol_info1(libubi, dev_info.dev_num, args.vol_id, &vol_info); + if (err) { + sys_errmsg("cannot get information about newly created UBI volume"); + goto out_libubi; + } + + printf("Volume ID %d, size %d LEBs (", vol_info.vol_id, vol_info.rsvd_lebs); + ubiutils_print_bytes(vol_info.rsvd_bytes, 0); + printf("), LEB size "); + ubiutils_print_bytes(vol_info.leb_size, 1); + printf(", %s, name \"%s\", alignment %d\n", + req.vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static", + vol_info.name, vol_info.alignment); + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinfo.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinfo.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinfo.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinfo.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2007, 2008 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to get UBI information. + * + * Author: Artem Bityutskiy + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubinfo" + +/* The variables below are set by command line arguments */ +struct args { + int devn; + int vol_id; + int all; + const char *node; +}; + +static struct args args = { + .vol_id = -1, + .devn = -1, + .all = 0, + .node = NULL, +}; + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION + " - a tool to print UBI information."; + +static const char *optionsstr = +"-d, --devn= UBI device number to get information about\n" +"-n, --vol_id= ID of UBI volume to print information about\n" +"-a, --all print information about all devices and volumes,\n" +" or about all volumes if the UBI device was\n" +" specified\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage 1: " PROGRAM_NAME " [-d ] [-n ] [-a] [-h] [-V] [--vol_id=]\n" +"\t\t[--devn ] [--all] [--help] [--version]\n" +"Usage 2: " PROGRAM_NAME " [-a] [-h] [-V] [--all] [--help] [--version]\n" +"Usage 3: " PROGRAM_NAME " [-h] [-V] [--help] [--version]\n\n" +"Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n" +"Example 2: " PROGRAM_NAME " -d 1 - print information about UBI device number 1\n" +"Example 3: " PROGRAM_NAME " /dev/ubi0 -a - print information about all volumes of UBI\n" +" device /dev/ubi0\n" +"Example 4: " PROGRAM_NAME " /dev/ubi1_0 - print information about UBI volume /dev/ubi1_0\n" +"Example 5: " PROGRAM_NAME " -a - print all information\n"; + +static const struct option long_options[] = { + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "all", .has_arg = 0, .flag = NULL, .val = 'a' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0}, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "an:d:hV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'a': + args.all = 1; + break; + + case 'n': + args.vol_id = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.vol_id < 0) + return errmsg("bad volume ID: " "\"%s\"", optarg); + break; + + case 'd': + args.devn = strtoul(optarg, &endp, 0); + if (*endp != '\0' || endp == optarg || args.devn < 0) + return errmsg("bad UBI device number: \"%s\"", optarg); + + break; + + case 'h': + fprintf(stderr, "%s\n\n", doc); + fprintf(stderr, "%s\n\n", usage); + fprintf(stderr, "%s\n", optionsstr); + exit(EXIT_SUCCESS); + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(EXIT_SUCCESS); + + case ':': + return errmsg("parameter is missing"); + + default: + fprintf(stderr, "Use -h for help\n"); + return -1; + } + } + + if (optind == argc - 1) + args.node = argv[optind]; + else if (optind < argc) + return errmsg("more then one UBI devices specified (use -h for help)"); + + return 0; +} + +static int translate_dev(libubi_t libubi, const char *node) +{ + int err; + + err = ubi_node_type(libubi, node); + if (err == -1) { + if (errno) + return errmsg("unrecognized device node \"%s\"", node); + return errmsg("\"%s\" does not correspond to any UBI device or volume", node); + } + + if (err == 1) { + struct ubi_dev_info dev_info; + + err = ubi_get_dev_info(libubi, node, &dev_info); + if (err) + return sys_errmsg("cannot get information about UBI device \"%s\"", node); + + args.devn = dev_info.dev_num; + } else { + struct ubi_vol_info vol_info; + + err = ubi_get_vol_info(libubi, node, &vol_info); + if (err) + return sys_errmsg("cannot get information about UBI volume \"%s\"", node); + + if (args.vol_id != -1) + return errmsg("both volume character device node (\"%s\") and " + "volume ID (%d) are specify, use only one of them" + "(use -h for help)", node, args.vol_id); + + args.devn = vol_info.dev_num; + args.vol_id = vol_info.vol_id; + } + + return 0; +} + +static int print_vol_info(libubi_t libubi, int dev_num, int vol_id) +{ + int err; + struct ubi_vol_info vol_info; + + err = ubi_get_vol_info1(libubi, dev_num, vol_id, &vol_info); + if (err) + return sys_errmsg("cannot get information about UBI volume %d on ubi%d", + vol_id, dev_num); + + printf("Volume ID: %d (on ubi%d)\n", vol_info.vol_id, vol_info.dev_num); + printf("Type: %s\n", + vol_info.type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"); + printf("Alignment: %d\n", vol_info.alignment); + + printf("Size: %d LEBs (", vol_info.rsvd_lebs); + ubiutils_print_bytes(vol_info.rsvd_bytes, 0); + printf(")\n"); + + if (vol_info.type == UBI_STATIC_VOLUME) { + printf("Data bytes: "); + ubiutils_print_bytes(vol_info.data_bytes, 1); + } + printf("State: %s\n", vol_info.corrupted ? "corrupted" : "OK"); + printf("Name: %s\n", vol_info.name); + printf("Character device major/minor: %d:%d\n", + vol_info.major, vol_info.minor); + + return 0; +} + +static int print_dev_info(libubi_t libubi, int dev_num, int all) +{ + int i, err, first = 1; + struct ubi_dev_info dev_info; + struct ubi_vol_info vol_info; + + err = ubi_get_dev_info1(libubi, dev_num, &dev_info); + if (err) + return sys_errmsg("cannot get information about UBI device %d", dev_num); + + printf("ubi%d:\n", dev_info.dev_num); + printf("Volumes count: %d\n", dev_info.vol_count); + printf("Logical eraseblock size: %d\n", dev_info.leb_size); + + printf("Total amount of logical eraseblocks: %d (", dev_info.total_lebs); + ubiutils_print_bytes(dev_info.total_bytes, 0); + printf(")\n"); + + printf("Amount of available logical eraseblocks: %d (", dev_info.avail_lebs); + ubiutils_print_bytes(dev_info.avail_bytes, 0); + printf(")\n"); + + printf("Maximum count of volumes %d\n", dev_info.max_vol_count); + printf("Count of bad physical eraseblocks: %d\n", dev_info.bad_count); + printf("Count of reserved physical eraseblocks: %d\n", dev_info.bad_rsvd); + printf("Current maximum erase counter value: %lld\n", dev_info.max_ec); + printf("Minimum input/output unit size: %d bytes\n", dev_info.min_io_size); + printf("Character device major/minor: %d:%d\n", + dev_info.major, dev_info.minor); + + if (dev_info.vol_count == 0) + return 0; + + printf("Present volumes: "); + for (i = dev_info.lowest_vol_num; + i <= dev_info.highest_vol_num; i++) { + err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe volume %d on ubi%d", + i, dev_info.dev_num); + } + + if (!first) + printf(", %d", i); + else { + printf("%d", i); + first = 0; + } + } + printf("\n"); + + if (!all) + return 0; + + first = 1; + printf("\n"); + + for (i = dev_info.lowest_vol_num; + i <= dev_info.highest_vol_num; i++) { + if(!first) + printf("-----------------------------------\n"); + err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe volume %d on ubi%d", + i, dev_info.dev_num); + } + first = 0; + + err = print_vol_info(libubi, dev_info.dev_num, i); + if (err) + return err; + } + + return 0; +} + +static int print_general_info(libubi_t libubi, int all) +{ + int i, err, first = 1; + struct ubi_info ubi_info; + struct ubi_dev_info dev_info; + + err = ubi_get_info(libubi, &ubi_info); + if (err) + return sys_errmsg("cannot get UBI information"); + + printf("UBI version: %d\n", ubi_info.version); + printf("Count of UBI devices: %d\n", ubi_info.dev_count); + if (ubi_info.ctrl_major != -1) + printf("UBI control device major/minor: %d:%d\n", + ubi_info.ctrl_major, ubi_info.ctrl_minor); + else + printf("UBI control device is not supported by this kernel\n"); + + if (ubi_info.dev_count == 0) + return 0; + + printf("Present UBI devices: "); + for (i = ubi_info.lowest_dev_num; + i <= ubi_info.highest_dev_num; i++) { + err = ubi_get_dev_info1(libubi, i, &dev_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe UBI device %d", i); + } + + if (!first) + printf(", ubi%d", i); + else { + printf("ubi%d", i); + first = 0; + } + } + printf("\n"); + + if (!all) + return 0; + + first = 1; + printf("\n"); + + for (i = ubi_info.lowest_dev_num; + i <= ubi_info.highest_dev_num; i++) { + if(!first) + printf("\n===================================\n\n"); + err = ubi_get_dev_info1(libubi, i, &dev_info); + if (err == -1) { + if (errno == ENOENT) + continue; + + return sys_errmsg("libubi failed to probe UBI device %d", i); + } + first = 0; + + err = print_dev_info(libubi, i, all); + if (err) + return err; + } + return 0; +} + +int main(int argc, char * const argv[]) +{ + int err; + libubi_t libubi; + + err = parse_opt(argc, argv); + if (err) + return -1; + + if (!args.node && args.devn != -1) + return errmsg("specify either device number or node file (use -h for help)"); + + libubi = libubi_open(1); + if (libubi == NULL) + return sys_errmsg("cannot open libubi"); + + if (args.node) { + /* + * A character device was specified, translate this into UBI + * device number and volume ID. + */ + err = translate_dev(libubi, args.node); + if (err) + goto out_libubi; + } + + if (args.vol_id != -1 && args.devn == -1) { + errmsg("volume ID is specified, but UBI device number is not " + "(use -h for help)\n"); + goto out_libubi; + } + + if (args.devn != -1 && args.vol_id != -1) { + print_vol_info(libubi, args.devn, args.vol_id); + goto out; + } + + if (args.devn == -1 && args.vol_id == -1) + err = print_general_info(libubi, args.all); + else if (args.devn != -1 && args.vol_id == -1) + err = print_dev_info(libubi, args.devn, args.all); + + if (err) + goto out_libubi; + +out: + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff -aurN /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinize.c linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinize.c --- /home/stdev/development/source/02os/linux-2.6.24.3/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinize.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.24.3-20100304/drivers/mtd/mtd-utils/ubi-utils/new-utils/src/ubinize.c 2010-03-03 19:04:28.000000000 -0800 @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2008 Nokia Corporation + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Generate UBI images. + * + * Authors: Artem Bityutskiy + * Oliver Lohmann + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubinize" + +static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION +" - a tool to generate UBI images. An UBI image may contain one or more UBI " +"volumes which have to be defined in the input configuration ini-file. The " +"ini file defines all the UBI volumes - their characteristics and the and the " +"contents, but it does not define the characteristics of the flash the UBI " +"image is generated for. Instead, the flash characteristics are defined via " +"the command-line options. Note, if not sure about some of the command-line " +"parameters, do not specify them and let the utility to use default values."; + +static const char *optionsstr = +"-o, --output= output file name\n" +"-p, --peb-size= size of the physical eraseblock of the flash\n" +" this UBI image is created for in bytes,\n" +" kilobytes (KiB), or megabytes (MiB)\n" +" (mandatory parameter)\n" +"-m, --min-io-size= minimum input/output unit size of the flash\n" +" in bytes\n" +"-s, --sub-page-size= minimum input/output unit used for UBI\n" +" headers, e.g. sub-page size in case of NAND\n" +" flash (equivalent to the minimum input/output\n" +" unit size by default)\n" +"-O, --vid-hdr-offset= offset if the VID header from start of the\n" +" physical eraseblock (default is the next\n" +" minimum I/O unit or sub-page after the EC\n" +" header)\n" +"-e, --erase-counter= the erase counter value to put to EC headers\n" +" (default is 0)\n" +"-x, --ubi-ver= UBI version number to put to EC headers\n" +" (default is 1)\n" +"-v, --verbose be verbose\n" +"-h, --help print help message\n" +"-V, --version print program version"; + +static const char *usage = +"Usage: " PROGRAM_NAME " [-o filename] [-h] [-V] [--output=] [--help]\n" +"\t\t[--version] ini-file\n" +"Example: " PROGRAM_NAME " -o ubi.img cfg.ini - create UBI image 'ubi.img' as\n" +" described by configuration file 'cfg.ini'"; + +static const char *ini_doc = "INI-file format.\n" +"The input configuration ini-file describes all the volumes which have to\n" +"be included to the output UBI image. Each volume is described in its own\n" +"section which may be named arbitrarily. The section consists on\n" +"\"key=value\" pairs, for example:\n\n" +"[jffs2-volume]\n" +"mode=ubi\n" +"image=../jffs2.img\n" +"vol_id=1\n" +"vol_size=30MiB\n" +"vol_type=dynamic\n" +"vol_name=jffs2_volume\n" +"vol_flags=autoresize\n" +"vol_alignment=1\n\n" +"This example configuration file tells the utility to create an UBI image\n" +"with one volume with ID 1, volume size 30MiB, the volume is dynamic, has\n" +"name \"jffs2_volume\", \"autoresize\" volume flag, and alignment 1. The\n" +"\"image=../jffs2.img\" line tells the utility to take the contents of the\n" +"volume from the \"../jffs2.img\" file. The size of the image file has to be\n" +"less or equivalent to the volume size (30MiB). The \"mode=ubi\" line is\n" +"mandatory and just tells that the section describes an UBI volume - other\n" +"section modes may be added in the future.\n" +"Notes:\n" +" * size in vol_size might be specified kilobytes (KiB), megabytes (MiB),\n" +" gigabytes (GiB) or bytes (no modifier);\n" +" * if \"vol_size\" key is absent, the volume size is assumed to be\n" +" equivalent to the size of the image file (defined by \"image\" key);\n" +" * if the \"image\" is absent, the volume is assumed to be empty;\n" +" * volume alignment must not be greater than the logical eraseblock size;\n" +" * one ini file may contain arbitrary number of sections, the utility will\n" +" put all the volumes which are described by these section to the output\n" +" UBI image file."; + +struct option long_options[] = { + { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, + { .name = "peb-size", .has_arg = 1, .flag = NULL, .val = 'p' }, + { .name = "min-io-size", .has_arg = 1, .flag = NULL, .val = 'm' }, + { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, + { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, + { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, + { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, + { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0} +}; + +struct args { + const char *f_in; + const char *f_out; + int out_fd; + int peb_size; + int min_io_size; + int subpage_size; + int vid_hdr_offs; + int ec; + int ubi_ver; + int verbose; + dictionary *dict; +}; + +static struct args args = { + .peb_size = -1, + .min_io_size = -1, + .subpage_size = -1, + .ubi_ver = 1, +}; + +static int parse_opt(int argc, char * const argv[]) +{ + while (1) { + int key; + char *endp; + + key = getopt_long(argc, argv, "o:p:m:s:O:e:x:vhV", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'o': + args.out_fd = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, + S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH); + if (args.out_fd == -1) + return sys_errmsg("cannot open file \"%s\"", optarg); + args.f_out = optarg; + break; + + case 'p': + args.peb_size = ubiutils_get_bytes(optarg); + if (args.peb_size <= 0) + return errmsg("bad physical eraseblock size: \"%s\"", optarg); + break; + + case 'm': + args.min_io_size = ubiutils_get_bytes(optarg); + if (args.min_io_size <= 0) + return errmsg("bad min. I/O unit size: \"%s\"", optarg); + if (!is_power_