diff -ru linux-2.6/arch/mips/boot/Makefile /plain/src/qi/linux-2.6.27.git.svn/arch/mips/boot/Makefile --- linux-2.6/arch/mips/boot/Makefile 2009-08-18 00:01:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/boot/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -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 -ru linux-2.6/arch/mips/Kconfig /plain/src/qi/linux-2.6.27.git.svn/arch/mips/Kconfig --- linux-2.6/arch/mips/Kconfig 2009-08-18 00:01:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -19,6 +19,90 @@ 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 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 JZ4760_F4760 + bool "Ingenic JZ4760 FPGA board" + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SOC_JZ4760 + select JZ_FPGA + config MACH_ALCHEMY bool "Alchemy processor based machines" @@ -610,6 +694,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_JZ4760 + 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 GENERIC_LOCKBREAK bool default y @@ -1740,6 +1870,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 # @@ -2013,6 +2151,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" config ARCH_SUSPEND_POSSIBLE diff -ru linux-2.6/arch/mips/kernel/cpu-probe.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/cpu-probe.c --- linux-2.6/arch/mips/kernel/cpu-probe.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/cpu-probe.c 2009-08-12 10:39:09.000000000 +0200 @@ -153,6 +153,7 @@ case CPU_25KF: case CPU_PR4450: case CPU_BCM3302: + case CPU_JZRISC: cpu_wait = r4k_wait; break; @@ -813,6 +814,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]; /* @@ -894,6 +911,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(); } @@ -933,6 +951,9 @@ case PRID_COMP_NXP: cpu_probe_nxp(c); break; + case PRID_COMP_INGENIC: + cpu_probe_ingenic(c); + break; default: c->cputype = CPU_UNKNOWN; } diff -ru linux-2.6/arch/mips/kernel/signal.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/signal.c --- linux-2.6/arch/mips/kernel/signal.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/signal.c 2009-08-12 10:39:09.000000000 +0200 @@ -351,6 +351,7 @@ if (!access_ok(VERIFY_READ, act, sizeof(*act))) return -EFAULT; err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); + err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); if (err) @@ -366,6 +367,7 @@ return -EFAULT; err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); + err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); @@ -565,6 +567,10 @@ regs->regs[31] = (unsigned long) frame->rs_code; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; + /* Add for bionic. I'm not sure whether it works. */ + if (ka->sa.sa_flags & SA_RESTORER) + regs->regs[31] = (unsigned long)ka->sa.sa_restorer; + DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", current->comm, current->pid, frame, regs->cp0_epc, regs->regs[31]); diff -ru linux-2.6/arch/mips/kernel/unaligned.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/unaligned.c --- linux-2.6/arch/mips/kernel/unaligned.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/kernel/unaligned.c 2009-08-12 10:39:09.000000000 +0200 @@ -497,6 +497,11 @@ send_sig(SIGILL, current, 1); } +#if defined(CONFIG_JZ_TCSM) +#undef user_mode +#define user_mode(regs) ((((regs)->cp0_status & KU_MASK) == KU_USER) || (regs->cp0_badvaddr < 0x80000000)) +#endif + asmlinkage void do_ade(struct pt_regs *regs) { extern int do_dsemulret(struct pt_regs *); diff -ru linux-2.6/arch/mips/Makefile /plain/src/qi/linux-2.6.27.git.svn/arch/mips/Makefile --- linux-2.6/arch/mips/Makefile 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -167,6 +167,46 @@ # # +# 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 JZ4760 series +# + +core-$(CONFIG_SOC_JZ4760) += arch/mips/jz4760/ +cflags-$(CONFIG_SOC_JZ4760) += -Iinclude/asm-mips/mach-jz4760 +load-$(CONFIG_SOC_JZ4760) += 0xffffffff80010000 + +# # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. # core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/ @@ -673,6 +713,12 @@ all: $(all-y) +uImage: $(vmlinux-32) + +@$(call makeboot,$@) + +zImage: $(vmlinux-32) + +@$(call makeboot,$@) + vmlinux.bin: $(vmlinux-32) +@$(call makeboot,$@) @@ -697,6 +743,7 @@ archclean: @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/boot/compressed @$(MAKE) $(clean)=arch/mips/lasat define archhelp @@ -703,6 +746,9 @@ 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 -ru linux-2.6/arch/mips/mm/cache.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/cache.c --- linux-2.6/arch/mips/mm/cache.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/cache.c 2009-08-12 10:39:09.000000000 +0200 @@ -51,6 +51,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 -ru linux-2.6/arch/mips/mm/c-r4k.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/c-r4k.c --- linux-2.6/arch/mips/mm/c-r4k.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/c-r4k.c 2009-08-12 10:39:09.000000000 +0200 @@ -895,6 +895,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 -ru linux-2.6/arch/mips/mm/tlbex.c /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/tlbex.c --- linux-2.6/arch/mips/mm/tlbex.c 2009-08-17 23:58:00.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/arch/mips/mm/tlbex.c 2009-08-12 10:39:09.000000000 +0200 @@ -379,6 +379,11 @@ tlbw(p); break; + case CPU_JZRISC: + tlbw(p); + uasm_i_nop(p); + break; + default: panic("No TLB refill handler yet (CPU type: %d)", current_cpu_data.cputype); diff -ru linux-2.6/drivers/i2c/busses/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/busses/Kconfig --- linux-2.6/drivers/i2c/busses/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/busses/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -7,6 +7,14 @@ comment "PC SMBus host controller drivers" depends on PCI +config I2C_JZ47XX + tristate "JZ47XX I2C Interface support" + depends on JZSOC + 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 -ru linux-2.6/drivers/i2c/busses/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/busses/Makefile --- linux-2.6/drivers/i2c/busses/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/busses/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -3,6 +3,7 @@ # # PC SMBus host controller 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 -ru linux-2.6/drivers/i2c/i2c-dev.c /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/i2c-dev.c --- linux-2.6/drivers/i2c/i2c-dev.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/i2c/i2c-dev.c 2009-08-12 10:39:09.000000000 +0200 @@ -37,6 +37,8 @@ #include #include +extern unsigned short sub_addr; +extern int addr_val; static struct i2c_driver i2cdev_driver; /* @@ -424,6 +426,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 -ru linux-2.6/drivers/input/keyboard/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/input/keyboard/Kconfig --- linux-2.6/drivers/input/keyboard/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/input/keyboard/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -280,6 +280,39 @@ To compile this driver as a module, choose M here: the module will be called aaed2000_kbd. +config KEYBOARD_JZ_GPIO + tristate "JZ keypad driver based on GPIO Buttons" + depends on JZSOC + help + This driver implements support for buttons connected + to GPIO pins of various CPUs (and some other chips). + + Say Y here if your device has buttons connected + directly to such GPIO pins. Your board-specific + setup logic must also provide a platform device, + with configuration data saying which GPIOs are used. + + To compile this driver as a module, choose M here: the + module will be called jz_gpio_keypad. + +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 KEYBOARD_JZ_5x5 + 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_5x5. + config KEYBOARD_GPIO tristate "GPIO Buttons" depends on GENERIC_GPIO diff -ru linux-2.6/drivers/input/keyboard/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/input/keyboard/Makefile --- linux-2.6/drivers/input/keyboard/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/input/keyboard/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -20,6 +20,9 @@ obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o +obj-$(CONFIG_KEYBOARD_JZ_GPIO) += jz_gpio_keypad.o +obj-$(CONFIG_KEYBOARD_JZ_5x5) += jz_keypad_5x5.o +obj-$(CONFIG_KEYBOARD_JZ) += jz_keypad.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o diff -ru linux-2.6/drivers/input/touchscreen/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/input/touchscreen/Kconfig --- linux-2.6/drivers/input/touchscreen/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/input/touchscreen/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -115,6 +115,24 @@ To compile this driver as a module, choose M here: the module will be called inexio. +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_MK712 tristate "ICS MicroClock MK712 touchscreen" help @@ -181,6 +199,12 @@ To compile this driver as a module, choose M here: the module will be called migor_ts. +config TOUCHSCREEN_SYNAPTICS_I2C_RMI + tristate "Synaptics i2c touchscreen" + depends on I2C + help + This enables support for Synaptics RMI over I2C based touchscreens. + config TOUCHSCREEN_TOUCHRIGHT tristate "Touchright serial touchscreen" select SERIO diff -ru linux-2.6/drivers/input/touchscreen/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/input/touchscreen/Makefile --- linux-2.6/drivers/input/touchscreen/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/input/touchscreen/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -14,6 +14,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o +obj-$(CONFIG_TOUCHSCREEN_JZ) += jz_ts.o obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o @@ -22,6 +23,7 @@ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI) += synaptics_i2c_rmi.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff -ru linux-2.6/drivers/misc/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/misc/Kconfig --- linux-2.6/drivers/misc/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/misc/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -13,6 +13,40 @@ if MISC_DEVICES +config JZ_TCSM + bool "JZ TCSM for multimedia" + default y + +config JZ_CIM + bool "JZ CIM for Camera driver" + default y + +choice + depends on JZ_CIM + prompt "Camera Sensor" + default OV3640 + +config OV3640 + bool "OmniVision OV3640 sensor support (3.1 MegaPixel)" +config OV2640 + bool "OmniVision OV2640 sensor support (2.0 MegaPixel)" +config OV9650 + bool "OmniVision OV9650 sensor support (1.3 MegaPixel)" +endchoice + +config ANDROID_PMEM + bool "Android pmem allocator" + default y + +config TIMED_OUTPUT + bool "Timed output class driver" + default y + +config TIMED_GPIO + bool "Android timed gpio driver" + depends on GENERIC_GPIO && TIMED_OUTPUT + default y + config ATMEL_PWM tristate "Atmel AT32/AT91 PWM support" depends on AVR32 || ARCH_AT91 @@ -55,6 +89,10 @@ TC can be used for other purposes, such as PWM generation and interval timing. +config BINDER_IPC + tristate "Binder IPC Driver" + default y + config IBM_ASM tristate "Device driver for IBM RSA service processor" depends on X86 && PCI && INPUT && EXPERIMENTAL @@ -424,6 +462,13 @@ driver (SCSI/ATA) which supports enclosures or a SCSI enclosure device (SES) to use these services. +config KERNEL_DEBUGGER_CORE + bool "Kernel Debugger Core" + default n + ---help--- + Generic kernel debugging command processor used by low level + (interrupt context) platform-specific debuggers. + config SGI_XP tristate "Support communication between SGI SSIs" depends on NET @@ -475,4 +520,75 @@ This option enables addition debugging code for the SGI GRU driver. If you are unsure, say N. +config LOW_MEMORY_KILLER + tristate "Low Memory Killer" + ---help--- + Register processes to be killed when memory is low + +config LOGGER + bool "High-speed in-kernel logging driver" + default y + +config UID_STAT + bool "UID based statistics tracking exported to /proc/uid_stat" + default n + +config ANDROID_RAM_CONSOLE + bool "RAM buffer console" + default n + +config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE + bool "Enable verbose console messages" + default y + depends on ANDROID_RAM_CONSOLE + +menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION + bool "Enable error correction" + default n + depends on ANDROID_RAM_CONSOLE + depends on !ANDROID_RAM_CONSOLE_EARLY_INIT + select REED_SOLOMON + select REED_SOLOMON_ENC8 + select REED_SOLOMON_DEC8 + +if ANDROID_RAM_CONSOLE_ERROR_CORRECTION + +config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE + int "Data data size" + default 128 + help + Must be a power of 2. + +config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE + int "ECC size" + default 16 + +config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE + int "Symbol size" + default 8 +config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL + hex "Polynomial" + default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4) + default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5) + default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6) + default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7) + default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8) + +endif #ANDROID_RAM_CONSOLE_ERROR_CORRECTION + +config ANDROID_RAM_CONSOLE_EARLY_INIT + bool "Start ram console early" + default n + depends on ANDROID_RAM_CONSOLE + +config ANDROID_RAM_CONSOLE_EARLY_ADDR + hex "RAM console virtual address" + default 0 + depends on ANDROID_RAM_CONSOLE_EARLY_INIT + +config ANDROID_RAM_CONSOLE_EARLY_SIZE + hex "RAM console buffer size" + default 0 + depends on ANDROID_RAM_CONSOLE_EARLY_INIT + endif # MISC_DEVICES diff -ru linux-2.6/drivers/misc/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/misc/Makefile --- linux-2.6/drivers/misc/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/misc/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -10,9 +10,13 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o +obj-$(CONFIG_ANDROID_PMEM) += pmem.o +obj-$(CONFIG_TIMED_OUTPUT) += timed_output.o +obj-$(CONFIG_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o +obj-$(CONFIG_BINDER_IPC) += binder.o obj-$(CONFIG_HP_WMI) += hp-wmi.o obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o obj-$(CONFIG_LKDTM) += lkdtm.o @@ -26,7 +30,14 @@ obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o +obj-$(CONFIG_KERNEL_DEBUGGER_CORE) += kernel_debugger.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_HP_ILO) += hpilo.o +obj-$(CONFIG_LOGGER) += logger.o +obj-$(CONFIG_UID_STAT) += uid_stat.o +obj-$(CONFIG_LOW_MEMORY_KILLER) += lowmemorykiller.o +obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o +obj-$(CONFIG_JZ_TCSM) += jz_tcsm.o +obj-$(CONFIG_JZ_CIM) += jz_sensor.o jz_cim.o diff -ru linux-2.6/drivers/mmc/card/block.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/card/block.c --- linux-2.6/drivers/mmc/card/block.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/card/block.c 2009-08-12 10:39:09.000000000 +0200 @@ -228,7 +228,11 @@ brq.mrq.cmd = &brq.cmd; brq.mrq.data = &brq.data; +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + brq.cmd.arg = req->sector + 8192; +#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; @@ -594,6 +598,9 @@ if (md) { mmc_blk_set_blksize(md, card); +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME + md->queue.check_status = 1; +#endif mmc_queue_resume(&md->queue); } return 0; diff -ru linux-2.6/drivers/mmc/core/mmc.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/core/mmc.c --- linux-2.6/drivers/mmc/core/mmc.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/core/mmc.c 2009-08-12 10:39:09.000000000 +0200 @@ -140,8 +140,12 @@ e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 csd->capacity = (1 + m) << (e + 2); - + csd->capacity -= 8192; +#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); diff -ru linux-2.6/drivers/mmc/core/sd.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/core/sd.c --- linux-2.6/drivers/mmc/core/sd.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/core/sd.c 2009-08-12 10:39:09.000000000 +0200 @@ -109,8 +109,12 @@ e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 csd->capacity = (1 + m) << (e + 2); - + csd->capacity -= 8192; +#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); @@ -137,7 +141,12 @@ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); m = UNSTUFF_BITS(resp, 48, 22); +#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0 + csd->capacity = (1 + m) << 10; + csd->capacity -= 8192; +#else csd->capacity = (1 + m) << 10; +#endif csd->read_blkbits = 9; csd->read_partial = 0; @@ -336,7 +345,9 @@ int err; u32 cid[4]; unsigned int max_dtr; - +#ifdef CONFIG_MMC_PARANOID_SD_INIT + int retries; +#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -448,11 +459,29 @@ err = mmc_decode_scr(card); if (err < 0) goto free_card; - /* * Fetch switch information from card. */ +#ifdef CONFIG_MMC_PARANOID_SD_INIT + for (retries = 1; retries <= 3; retries++) { + err = mmc_read_switch(card); + if (!err) { + if (retries > 1) { + printk(KERN_WARNING + "%s: recovered\n", + mmc_hostname(host)); + } + break; + } else { + printk(KERN_WARNING + "%s: read switch failed (attempt %d)\n", + mmc_hostname(host), retries); + } + } +#else err = mmc_read_switch(card); +#endif + if (err) goto free_card; } @@ -535,18 +564,37 @@ */ static void mmc_sd_detect(struct mmc_host *host) { - int err; + int err = 0; +#ifdef CONFIG_MMC_PARANOID_SD_INIT + int retries = 5; +#endif BUG_ON(!host); BUG_ON(!host->card); - + mmc_claim_host(host); /* * Just check if our card has been removed. */ +#ifdef CONFIG_MMC_PARANOID_SD_INIT + while(retries) { + err = mmc_send_status(host->card, NULL); + printk("%s(%s): err = %d\n", __func__, mmc_hostname(host), err); + if (err) { + retries--; + udelay(5); + continue; + } + break; + } + if (!retries) { + printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n", + __func__, mmc_hostname(host), err); + } +#else err = mmc_send_status(host->card, NULL); - +#endif mmc_release_host(host); if (err) { @@ -584,12 +632,31 @@ static void mmc_sd_resume(struct mmc_host *host) { int err; +#ifdef CONFIG_MMC_PARANOID_SD_INIT + int retries; +#endif BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); +#ifdef CONFIG_MMC_PARANOID_SD_INIT + retries = 5; + while (retries) { + err = mmc_sd_init_card(host, host->ocr, host->card); + + if (err) { + printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n", + mmc_hostname(host), err, retries); + mdelay(5); + retries--; + continue; + } + break; + } +#else err = mmc_sd_init_card(host, host->ocr, host->card); +#endif mmc_release_host(host); if (err) { @@ -622,6 +689,9 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) { int err; +#ifdef CONFIG_MMC_PARANOID_SD_INIT + int retries; +#endif BUG_ON(!host); WARN_ON(!host->claimed); @@ -670,9 +740,27 @@ /* * Detect and init the card. */ +#ifdef CONFIG_MMC_PARANOID_SD_INIT + retries = 5; + while (retries) { + err = mmc_sd_init_card(host, host->ocr, NULL); + if (err) { + retries--; + continue; + } + break; + } + + if (!retries) { + printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n", + mmc_hostname(host), err); + goto err; + } +#else err = mmc_sd_init_card(host, host->ocr, NULL); if (err) goto err; +#endif mmc_release_host(host); diff -ru linux-2.6/drivers/mmc/host/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/host/Kconfig --- linux-2.6/drivers/mmc/host/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/host/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -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 -ru linux-2.6/drivers/mmc/host/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/host/Makefile --- linux-2.6/drivers/mmc/host/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mmc/host/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -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 -ru linux-2.6/drivers/mtd/mtd_blkdevs.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtd_blkdevs.c --- linux-2.6/drivers/mtd/mtd_blkdevs.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtd_blkdevs.c 2009-08-12 10:39:09.000000000 +0200 @@ -39,8 +39,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; @@ -275,7 +275,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 -ru linux-2.6/drivers/mtd/mtdblock.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdblock.c --- linux-2.6/drivers/mtd/mtdblock.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdblock.c 2009-08-12 10:39:09.000000000 +0200 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -359,12 +360,26 @@ 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 -ru linux-2.6/drivers/mtd/mtdchar.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdchar.c --- linux-2.6/drivers/mtd/mtdchar.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdchar.c 2009-08-12 10:39:09.000000000 +0200 @@ -145,8 +145,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); @@ -165,7 +164,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; @@ -259,7 +258,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; @@ -592,6 +591,72 @@ 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 einfo; @@ -643,9 +708,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; @@ -656,9 +721,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; @@ -773,6 +838,7 @@ } default: + printk("line : %d\n", __LINE__); ret = -ENOTTY; } diff -ru linux-2.6/drivers/mtd/mtdcore.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdcore.c --- linux-2.6/drivers/mtd/mtdcore.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdcore.c 2009-08-12 10:39:09.000000000 +0200 @@ -297,10 +298,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) { @@ -344,7 +345,7 @@ if (!this) return 0; - return sprintf(buf, "mtd%d: %8.8x %8.8x \"%s\"\n", i, this->size, + return sprintf(buf, "mtd%d: %09llx %8.8x \"%s\"\n", i, this->size, this->erasesize, this->name); } diff -ru linux-2.6/drivers/mtd/mtdpart.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdpart.c --- linux-2.6/drivers/mtd/mtdpart.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/mtdpart.c 2009-08-12 10:39:09.000000000 +0200 @@ -26,7 +26,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; @@ -44,8 +44,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; @@ -65,8 +65,8 @@ return res; } -static int part_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) +static int part_point(struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, void **virt, resource_size_t *phys) { struct mtd_part *part = PART(mtd); if (from >= mtd->size) @@ -77,14 +77,14 @@ len, retlen, virt, phys); } -static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void part_unpoint(struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len) { struct mtd_part *part = PART(mtd); part->master->unpoint(part->master, 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); @@ -105,8 +105,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, @@ -114,14 +114,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, @@ -129,14 +129,14 @@ } static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len) + 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)) @@ -149,8 +149,8 @@ len, retlen, buf); } -static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int part_panic_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)) @@ -163,7 +163,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); @@ -178,23 +178,23 @@ 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)) @@ -235,7 +235,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) @@ -243,7 +243,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) @@ -269,7 +269,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) @@ -278,7 +278,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; @@ -317,7 +317,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master, const struct mtd_partition *part, int partno, - u_int32_t cur_offset) + u_int64_t cur_offset) { struct mtd_part *slave; @@ -345,6 +345,7 @@ slave->mtd.read = part_read; slave->mtd.write = part_write; + slave->mtd.priv = master->priv; //add by Nancy if (master->panic_write) slave->mtd.panic_write = part_panic_write; @@ -395,18 +396,20 @@ 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; - printk(KERN_NOTICE "Moving partition %d: " - "0x%08x -> 0x%08x\n", partno, - cur_offset, slave->offset); + //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%09llx -> 0x%09llx\n", partno, + cur_offset, slave->offset); } } + if (slave->mtd.size == MTDPART_SIZ_FULL) slave->mtd.size = master->size - slave->offset; - printk(KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, + printk (KERN_NOTICE "0x%09llx-0x%09llx : \"%s\"\n", slave->offset, slave->offset + slave->mtd.size, slave->mtd.name); /* let's do some sanity checks */ @@ -420,9 +423,10 @@ } if (slave->offset + slave->mtd.size > master->size) { slave->mtd.size = master->size - slave->offset; - printk(KERN_WARNING"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", part->name, master->name, slave->mtd.size); } + if (master->numeraseregions > 1) { /* Deal with variable erase size stuff */ int i, max = master->numeraseregions; @@ -449,7 +453,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 */ @@ -458,7 +462,7 @@ part->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(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", part->name); @@ -466,7 +470,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, @@ -501,7 +505,7 @@ int nbparts) { struct mtd_part *slave; - u_int32_t cur_offset = 0; + u_int64_t cur_offset = 0; int i, j, ret; printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); diff -ru linux-2.6/drivers/mtd/nand/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/Kconfig --- linux-2.6/drivers/mtd/nand/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -406,4 +406,121 @@ Enables support for NAND Flash chips wired onto Freescale PowerPC processor localbus with User-Programmable Machine support. +config MTD_NAND_JZ4740 + tristate "Support NAND Flash device on Jz4740 board" + depends on SOC_JZ4740 + help + Support NAND Flash device on Jz4740 board + +config MTD_NAND_JZ4750 + tristate "Support NAND Flash device on Jz4750 board" + depends on SOC_JZ4750 || SOC_JZ4750D + help + Support NAND Flash device on Jz4750 board + +config MTD_NAND_CS2 + depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 + bool 'Use NAND on CS2_N of JZSOC' + default n + +config MTD_NAND_CS3 + depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 + bool 'Use NAND on CS3_N of JZSOC' + default n + +config MTD_NAND_CS4 + depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 + bool 'Use NAND on CS4_N of JZSOC' + default n + +config MTD_NAND_MULTI_PLANE + depends on MTD_NAND_JZ4730 || MTD_NAND_JZ4740 || MTD_NAND_JZ4750 + bool 'Use multiple planes if the NAND supports' + default y + help + It is just supported on jz4740 now. + +if MTD_NAND_JZ4740 || MTD_NAND_JZ4730 || MTD_NAND_JZ4750 +choice + prompt "ECC type" + default CONFIG_MTD_SW_HM_ECC + +config MTD_HW_HM_ECC + depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4730 + bool 'Select hardware HM ECC' + +config MTD_SW_HM_ECC + bool 'Select software HM ECC' + +config MTD_HW_RS_ECC + depends on MTD_NAND_JZ4740 + bool 'Select hardware RS ECC' + +config MTD_HW_BCH_ECC + depends on MTD_NAND_JZ4750 + bool 'Select hardware BCH ECC' +endchoice + +choice + prompt "4 bit or 8 bit BCH ecc" + depends on MTD_HW_BCH_ECC + default CONFIG_MTD_HW_BCH_4BIT + +config MTD_HW_BCH_4BIT + bool '4 bit' + +config MTD_HW_BCH_8BIT + bool '8 bit' + +endchoice + +config MTD_NAND_DMA + depends on MTD_HW_BCH_ECC + bool 'Use DMA mode' + help + This enables using DMA for reading and writing NAND flash, if not selected, + then CPU mode is used. + +config MTD_NAND_DMABUF + depends on MTD_NAND_DMA + bool 'use DMA buffer in NAND driver' + help + It's better to say NO. If saying yes, DMA buffers will be allocated for + NAND reading and writing in NAND driver instead of upper layer. It's + slower. Just usable on CS1_N now. By saying NO, upper buffers will be + used as DMA buffer. It's faster, but kmalloc instead of vmalloc is required. +endif + +config MTD_MTDBLOCK_WRITE_VERIFY_ENABLE + bool "MTDBLOCK write verify enable" + default n + help + This will enable the write verification, which will read back data to check + after doing a write opetaion. + + It will be used by the JZ mtdblock driver (mtdblock-jz.c). + +config MTD_OOB_COPIES + int "how many copies of the fs info in the oob area" + default 3 + range 0 128 + depends on MTD + help + This defines the copies of the fs info in the oob area inside a block. + Value ranges from 0 to (pages_per_block - 1). + + It will be used by the JZ mtdblock driver (mtdblock-jz.c). + +config MTD_BADBLOCK_FLAG_PAGE + int "which page inside a block will store the badblock mark" + default 0 + range 0 127 + depends on MTD + help + This defines which page of a block will store the badblock mark. + Value ranges from 0 to (pages_per_block - 1). + + Old SLC NANDs store the badblock mark in the first page of a block, but + most modern MLC NANDs store it in the last page of a block. + endif # MTD_NAND diff -ru linux-2.6/drivers/mtd/nand/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/Makefile --- linux-2.6/drivers/mtd/nand/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -34,5 +34,7 @@ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o +obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o +obj-$(CONFIG_MTD_NAND_JZ4750) += jz4750_nand.o nand-objs := nand_base.o nand_bbt.o diff -ru linux-2.6/drivers/mtd/nand/nand_base.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_base.c --- linux-2.6/drivers/mtd/nand/nand_base.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_base.c 2009-08-12 10:39:09.000000000 +0200 @@ -52,6 +52,16 @@ #include #endif +#include + +u8 nand_nce; /* indicates which chip select on JZSOC is used for + current nand chip */ +int global_page; /* page index of large page used for nand with multiple planes */ + +struct mtd_info *jz_mtd1 = NULL; /* for 1 plane operation */ +char all_use_planes = 1; /* indicates whether multiple planes operation is used + by all partitions if multiple planes is supported by NAND */ + /* Define default oob placement schemes for large and small page devices */ static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, @@ -72,6 +82,20 @@ }; static struct nand_ecclayout nand_oob_64 = { +#if defined(CONFIG_MTD_HW_RS_ECC) || defined(CONFIG_MTD_HW_BCH_ECC) +/* Reed-Solomon ECC or BCH ECC */ + .eccbytes = 36, + .eccpos = { + 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { + {.offset = 2, + . length = 26}} +#else +/* HW&SW Hamming ECC */ .eccbytes = 24, .eccpos = { 40, 41, 42, 43, 44, 45, 46, 47, @@ -80,12 +104,85 @@ .oobfree = { {.offset = 2, .length = 38}} +#endif +}; + +static struct nand_ecclayout nand_oob_128 = { +#if defined(CONFIG_MTD_HW_RS_ECC) +/* Reed-Solomon ECC */ + .eccbytes = 72, + .eccpos = { + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}, + .oobfree = { + {.offset = 2, + . length = 54}} + +#elif defined(CONFIG_MTD_HW_BCH_ECC) +#if !defined(CONFIG_MTD_HW_BCH_8BIT) +/* 4-bit BCH ECC */ + .eccbytes = 56, + .eccpos = { + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}, + .oobfree = { + {.offset = 2, + . length = 70}} + +#else +/* 8-bit BCH ECC */ + .eccbytes = 104, + .eccpos = { + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}, + .oobfree = { + {.offset = 2, + . length = 22}} + +#endif +#else +/* HW&SW Hamming ECC */ + .eccbytes = 48, + .eccpos = { + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}, + .oobfree = { + {.offset = 2, + .length = 78}} +#endif }; static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state); -static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +static int nand_do_write_oob(struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops); /* @@ -95,6 +192,35 @@ DEFINE_LED_TRIGGER(nand_led_trigger); /** + * ffs_ll - find first bit set in a 64bit word. + * @word: The word to search + */ +static inline int ffs_ll(u64 word) +{ + u32 low = word & 0xffffffff; + u32 high = word >> 32; + int i; + + for(i = 0; i < 32; i++) { + if (low & 0x1) + break; + low >>= 1; + } + if (i == 32) { + for(i = 0; i < 32; i++) { + if (high & 0x1) + break; + high >>= 1; + } + i += 32; + } + if (i == 64) + return 0; + else + return (i+1); +} + +/** * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure * @@ -169,6 +295,20 @@ chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); break; case 0: + nand_nce = NAND_NCE1; + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + break; + case 1: + nand_nce = NAND_NCE2; + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + break; + case 2: + nand_nce = NAND_NCE3; + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + break; + case 3: + nand_nce = NAND_NCE4; + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); break; default: @@ -298,13 +438,19 @@ * * Check, if the block is bad. */ -static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) +static int nand_block_bad(struct mtd_info *mtd, loff_mtd_t ofs, int getchip) { - int page, chipnr, res = 0; + int page, page1 = 0, chipnr, res = 0; struct nand_chip *chip = mtd->priv; u16 bad; - page = (int)(ofs >> chip->page_shift) & chip->pagemask; + if (chip->planenum > 1) { + page = ((int)(ofs >> chip->page_shift) * chip->planenum + CONFIG_MTD_BADBLOCK_FLAG_PAGE); + page1 = page + mtd->erasesize / mtd->writesize; + page &= chip->pagemask; + page1 &= chip->pagemask; + } else + page = ((int)(ofs >> chip->page_shift) + CONFIG_MTD_BADBLOCK_FLAG_PAGE) & chip->pagemask; if (getchip) { chipnr = (int)(ofs >> chip->chip_shift); @@ -343,7 +489,7 @@ * This is the default implementation, which can be overridden by * a hardware specific driver. */ -static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) +static int nand_default_block_markbad(struct mtd_info *mtd, loff_mtd_t ofs) { struct nand_chip *chip = mtd->priv; uint8_t buf[2] = { 0, 0 }; @@ -363,6 +509,7 @@ */ nand_get_device(chip, mtd, FL_WRITING); ofs += mtd->oobsize; + ofs += (CONFIG_MTD_BADBLOCK_FLAG_PAGE << chip->page_shift); chip->ops.len = chip->ops.ooblen = 2; chip->ops.datbuf = NULL; chip->ops.oobbuf = buf; @@ -402,7 +549,7 @@ * Check, if the block is bad. Either by reading the bad block table or * calling of the scan function. */ -static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, +static int nand_block_checkbad(struct mtd_info *mtd, loff_mtd_t ofs, int getchip, int allowbbt) { struct nand_chip *chip = mtd->priv; @@ -554,7 +701,10 @@ /* Emulate NAND_CMD_READOOB */ if (command == NAND_CMD_READOOB) { - column += mtd->writesize; + if (chip->planenum > 1) + column += (mtd->writesize / chip->planenum); + else + column += mtd->writesize; command = NAND_CMD_READ0; } @@ -600,6 +750,8 @@ case NAND_CMD_RNDIN: case NAND_CMD_STATUS: case NAND_CMD_DEPLETE1: + case 0x81: /* for two-plane page program */ + case 0x11: /* for two-plane page program */ return; /* @@ -878,7 +1029,8 @@ return 0; } -/** +#ifndef CONFIG_MTD_HW_RS_ECC +/* HW&SW Hamming ECC *//** * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function * @mtd: mtd info structure * @chip: nand chip info structure @@ -922,6 +1074,63 @@ return 0; } +#else /* CONFIG_MTD_HW_RS_ECC */ + +/** + * nand_read_page_hwecc_rs - [REPLACABLE] hardware rs ecc based page read function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data + * + * Not for syndrome calculating ecc controllers which need a special oob layout + */ +static int nand_read_page_hwecc_rs(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_calc = chip->buffers->ecccalc; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; + uint32_t page; + uint8_t flag = 0; + + page = (buf[3]<<24) + (buf[2]<<16) + (buf[1]<<8) + buf[0]; + + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + for (i = 0; i < chip->ecc.total; i++) { + ecc_code[i] = chip->oob_poi[eccpos[i]]; + if (ecc_code[i] != 0xff) flag = 1; + } + + eccsteps = chip->ecc.steps; + p = buf; + + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0x00, -1); + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + if (flag) { + chip->ecc.hwctl(mtd, NAND_ECC_READ); + chip->read_buf(mtd, p, eccsize); + stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + } + else { + chip->ecc.hwctl(mtd, NAND_ECC_READ); + chip->read_buf(mtd, p, eccsize); + } + } + return 0; +} + +#endif /* CONFIG_MTD_HW_RS_ECC */ + /** * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read * @mtd: mtd info structure @@ -984,7 +1193,7 @@ * @len: size of oob to transfer */ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, - struct mtd_oob_ops *ops, size_t len) + struct mtd_oob_ops *ops, size_mtd_t len) { switch(ops->mode) { @@ -996,7 +1205,7 @@ case MTD_OOB_AUTO: { struct nand_oobfree *free = chip->ecc.layout->oobfree; uint32_t boffs = 0, roffs = ops->ooboffs; - size_t bytes = 0; + size_mtd_t bytes = 0; for(; free->length && len; free++, len -= bytes) { /* Read request not from offset 0 ? */ @@ -1006,11 +1215,11 @@ continue; } boffs = free->offset + roffs; - bytes = min_t(size_t, len, + bytes = min_t(size_mtd_t, len, (free->length - roffs)); roffs = 0; } else { - bytes = min_t(size_t, len, free->length); + bytes = min_t(size_mtd_t, len, free->length); boffs = free->offset; } memcpy(oob, chip->oob_poi + boffs, bytes); @@ -1033,7 +1242,7 @@ * * Internal function. Called with chip held. */ -static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, +static int nand_do_read_ops(struct mtd_info *mtd, loff_mtd_t from, struct mtd_oob_ops *ops) { int chipnr, page, realpage, col, bytes, aligned; @@ -1067,10 +1276,18 @@ if (realpage != chip->pagebuf || oob) { bufpoi = aligned ? buf : chip->buffers->databuf; + global_page = page; +#if defined(CONFIG_MTD_HW_RS_ECC) || defined(CONFIG_MTD_NAND_DMA) + bufpoi[0] = (uint8_t)page; + bufpoi[1] = (uint8_t)(page >> 8); + bufpoi[2] = (uint8_t)(page >> 16); + bufpoi[3] = (uint8_t)(page >> 24); +#else if (likely(sndcmd)) { chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); sndcmd = 0; } +#endif /* Now read the page into the buffer */ if (unlikely(ops->mode == MTD_OOB_RAW)) @@ -1149,7 +1366,7 @@ sndcmd = 1; } - ops->retlen = ops->len - (size_t) readlen; + ops->retlen = ops->len - (size_mtd_t) readlen; if (oob) ops->oobretlen = ops->ooblen - oobreadlen; @@ -1172,8 +1389,8 @@ * * Get hold of the chip and call nand_do_read */ -static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, uint8_t *buf) +static int nand_read(struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, uint8_t *buf) { struct nand_chip *chip = mtd->priv; int ret; @@ -1346,7 +1563,7 @@ * * NAND read out-of-band data from the spare area */ -static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, +static int nand_do_read_oob(struct mtd_info *mtd, loff_mtd_t from, struct mtd_oob_ops *ops) { int page, realpage, chipnr, sndcmd = 1; @@ -1439,7 +1656,7 @@ * * NAND read data and/or out-of-band data */ -static int nand_read_oob(struct mtd_info *mtd, loff_t from, +static int nand_read_oob(struct mtd_info *mtd, loff_mtd_t from, struct mtd_oob_ops *ops) { struct nand_chip *chip = mtd->priv; @@ -1602,12 +1819,17 @@ { int status; - chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); - - if (unlikely(raw)) - chip->ecc.write_page_raw(mtd, chip, buf); - else + global_page = page; + if (chip->planenum > 1) chip->ecc.write_page(mtd, chip, buf); + else { + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); + + if (unlikely(raw)) + chip->ecc.write_page_raw(mtd, chip, buf); + else + chip->ecc.write_page(mtd, chip, buf); + } /* * Cached progamming disabled for now, Not sure if its worth the @@ -1617,7 +1839,15 @@ if (!cached || !(chip->options & NAND_CACHEPRG)) { - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); +/* +* __nand_cmd(CMD_PAGEPROG) and __nand_sync() have been done by DMA for jz4750 and +* later chip, status should still be read by "status = chip->waitfunc(mtd, chip)" +*/ +#if defined(CONFIG_SOC_JZ4730) || defined(CONFIG_SOC_JZ4740) || \ + (!defined(CONFIG_SOC_JZ4730) && !defined(CONFIG_SOC_JZ4740) \ + && !defined(CONFIG_MTD_NAND_DMA)) + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); +#endif status = chip->waitfunc(mtd, chip); /* * See if operation failed and additional status checks are @@ -1653,7 +1883,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, struct mtd_oob_ops *ops) { - size_t len = ops->ooblen; + size_mtd_t len = ops->ooblen; switch(ops->mode) { @@ -1665,7 +1895,7 @@ case MTD_OOB_AUTO: { struct nand_oobfree *free = chip->ecc.layout->oobfree; uint32_t boffs = 0, woffs = ops->ooboffs; - size_t bytes = 0; + size_mtd_t bytes = 0; for(; free->length && len; free++, len -= bytes) { /* Write request not from offset 0 ? */ @@ -1675,11 +1905,11 @@ continue; } boffs = free->offset + woffs; - bytes = min_t(size_t, len, + bytes = min_t(size_mtd_t, len, (free->length - woffs)); woffs = 0; } else { - bytes = min_t(size_t, len, free->length); + bytes = min_t(size_mtd_t, len, free->length); boffs = free->offset; } memcpy(chip->oob_poi + boffs, oob, bytes); @@ -1703,7 +1933,7 @@ * * NAND write with ECC */ -static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, +static int nand_do_write_ops(struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops) { int chipnr, realpage, page, blockmask, column; @@ -1806,8 +2036,8 @@ * * NAND write with ECC */ -static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const uint8_t *buf) +static int nand_write(struct mtd_info *mtd, loff_mtd_t to, size_mtd_t len, + size_mtd_t *retlen, const uint8_t *buf) { struct nand_chip *chip = mtd->priv; int ret; @@ -1841,7 +2071,7 @@ * * NAND write out-of-band */ -static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +static int nand_do_write_oob(struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops) { int chipnr, page, status, len; @@ -1919,7 +2149,7 @@ * @to: offset to write to * @ops: oob operation description structure */ -static int nand_write_oob(struct mtd_info *mtd, loff_t to, +static int nand_write_oob(struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops) { struct nand_chip *chip = mtd->priv; @@ -2083,7 +2313,7 @@ /* * heck if we have a bad block, we do not erase bad blocks ! */ - if (nand_block_checkbad(mtd, ((loff_t) page) << + if (nand_block_checkbad(mtd, ((loff_mtd_t) page) << chip->page_shift, 0, allowbbt)) { printk(KERN_WARNING "nand_erase: attempt to erase a " "bad block at page 0x%08x\n", page); @@ -2205,7 +2435,7 @@ * @mtd: MTD device structure * @offs: offset relative to mtd start */ -static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) +static int nand_block_isbad(struct mtd_info *mtd, loff_mtd_t offs) { /* Check for invalid offset */ if (offs > mtd->size) @@ -2219,7 +2449,7 @@ * @mtd: MTD device structure * @ofs: offset relative to mtd start */ -static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) +static int nand_block_markbad(struct mtd_info *mtd, loff_mtd_t ofs) { struct nand_chip *chip = mtd->priv; int ret; @@ -2379,7 +2609,21 @@ extid >>= 2; /* Get buswidth information */ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + /* The 5th id byte */ +#if defined(CONFIG_MTD_NAND_MULTI_PLANE) + extid = chip->read_byte(mtd); + chip->realplanenum = 1 << ((extid & 0x0c) >> 2); +#else + chip->realplanenum = 1; +#endif + if (chip->realplanenum > 1) { /* use muti planes mode */ + chip->planenum = 2; + mtd->writesize *= 2; /* two pages as one page */ + mtd->oobsize *= 2; + mtd->erasesize *= 2; /* two blocks as one block */ + } else + chip->planenum = 1; } else { /* * Old devices have chip data hardcoded in the device id table @@ -2417,7 +2661,7 @@ chip->bbt_erase_shift = chip->phys_erase_shift = ffs(mtd->erasesize) - 1; - chip->chip_shift = ffs(chip->chipsize) - 1; + chip->chip_shift = ffs_ll(chip->chipsize) - 1; /* Set the bad block position */ chip->badblockpos = mtd->writesize > 512 ? @@ -2449,8 +2693,8 @@ chip->cmdfunc = nand_command_lp; printk(KERN_INFO "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, - nand_manuf_ids[maf_idx].name, type->name); + " 0x%02x, Chip ID: 0x%02x (%s %s) planenum:%d\n", *maf_id, dev_id, + nand_manuf_ids[maf_idx].name, type->name, chip->realplanenum); return type; } @@ -2517,7 +2761,7 @@ */ int nand_scan_tail(struct mtd_info *mtd) { - int i; + int i, res; struct nand_chip *chip = mtd->priv; if (!(chip->options & NAND_OWN_BUFFERS)) @@ -2542,6 +2786,16 @@ case 64: chip->ecc.layout = &nand_oob_64; break; + case 128: + if (chip->planenum > 1) + chip->ecc.layout = &nand_oob_64; + else + chip->ecc.layout = &nand_oob_128; + break; + case 256: + if (chip->planenum > 1) + chip->ecc.layout = &nand_oob_128; + break; default: printk(KERN_WARNING "No oob scheme defined for " "oobsize %d\n", mtd->oobsize); @@ -2565,7 +2819,11 @@ case NAND_ECC_HW: /* Use standard hwecc read page function ? */ if (!chip->ecc.read_page) +#ifndef CONFIG_MTD_HW_RS_ECC chip->ecc.read_page = nand_read_page_hwecc; +#else + chip->ecc.read_page = nand_read_page_hwecc_rs; +#endif if (!chip->ecc.write_page) chip->ecc.write_page = nand_write_page_hwecc; if (!chip->ecc.read_oob) @@ -2575,11 +2833,7 @@ case NAND_ECC_HW_SYNDROME: if ((!chip->ecc.calculate || !chip->ecc.correct || - !chip->ecc.hwctl) && - (!chip->ecc.read_page || - chip->ecc.read_page == nand_read_page_hwecc || - !chip->ecc.write_page || - chip->ecc.write_page == nand_write_page_hwecc)) { + !chip->ecc.hwctl)) { printk(KERN_WARNING "No ECC functions supplied, " "Hardware ECC not possible\n"); BUG(); @@ -2600,7 +2854,7 @@ "%d byte page size, fallback to SW ECC\n", chip->ecc.size, mtd->writesize); chip->ecc.mode = NAND_ECC_SOFT; - + case NAND_ECC_SOFT: chip->ecc.calculate = nand_calculate_ecc; chip->ecc.correct = nand_correct_data; @@ -2703,8 +2957,58 @@ if (chip->options & NAND_SKIP_BBTSCAN) return 0; - /* Build bad block table */ - return chip->scan_bbt(mtd); + /* Create jz_mtd1 for one plane operation if the NAND support multiple + planes operation, because some partitions will only use one plane. */ + if ((chip->planenum == 2) && !all_use_planes) { + int i, len, numblocks; + struct nand_chip *this = (struct nand_chip *) (&jz_mtd1[1]); + + memcpy(jz_mtd1, mtd, sizeof(*mtd)); + jz_mtd1->priv = this; + memcpy(this, chip, sizeof(*chip)); + + this->planenum = 1; + jz_mtd1->writesize >>= 1; + jz_mtd1->oobsize >>= 1; + jz_mtd1->erasesize >>= 1; + this->page_shift = chip->page_shift - 1; + this->pagemask = (this->chipsize >> this->page_shift) - 1; + this->bbt_erase_shift = this->phys_erase_shift = + chip->phys_erase_shift - 1; + this->ecc.steps >>= 1; + this->ecc.total = this->ecc.steps * this->ecc.bytes; + this->subpagesize = jz_mtd1->writesize; + + this->erase_cmd = single_erase_cmd; +#if defined(CONFIG_MTD_HW_RS_ECC) + this->ecc.read_page = nand_read_page_hwecc_rs; + this->ecc.write_page = nand_write_page_hwecc; +#endif + this->ecc.read_oob = nand_read_oob_std; + this->ecc.write_oob = nand_write_oob_std; + this->write_buf = nand_write_buf; + this->read_buf = nand_read_buf; + + /* Firstly, build bad block table as one plane */ + res = this->scan_bbt(jz_mtd1); + + /* Secondly, build bad block table as 2 plane based on bbt of jz_mtd1 */ + numblocks = chip->chipsize >> (chip->bbt_erase_shift - 1); /* = (real numblocks * 2) */ + len = mtd->size >> (chip->bbt_erase_shift + 2); + chip->bbt = kzalloc(len, GFP_KERNEL); + +#define isbad_2plane(block) (((this->bbt[(block) >> 3] >> ((block) & 0x06)) \ + | (this->bbt[((block)+2) >> 3] >> (((block)+2) & 0x06))) & 0x03) + + for (i = 0; i < numblocks; i += 2) { + if (isbad_2plane(2*i)) + chip->bbt[i >> 3] |= 0x03 << (i & 0x6); + } + } else { + res = chip->scan_bbt(mtd); + } + + return res; } /* module_text_address() isn't exported, and it's mostly a pointless diff -ru linux-2.6/drivers/mtd/nand/nand_bbt.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_bbt.c --- linux-2.6/drivers/mtd/nand/nand_bbt.c 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_bbt.c 2009-08-12 10:39:09.000000000 +0200 @@ -145,15 +145,15 @@ { int res, i, j, act = 0; struct nand_chip *this = mtd->priv; - size_t retlen, len, totlen; - loff_t from; + size_mtd_t retlen, len, totlen; + loff_mtd_t from; uint8_t msk = (uint8_t) ((1 << bits) - 1); totlen = (num * bits) >> 3; - from = ((loff_t) page) << this->page_shift; + from = ((loff_mtd_t) page) << this->page_shift; while (totlen) { - len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); + len = min(totlen, (size_mtd_t) (1 << this->bbt_erase_shift)); res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { @@ -233,8 +233,8 @@ /* * Scan read raw data from flash */ -static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, - size_t len) +static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_mtd_t offs, + size_mtd_t len) { struct mtd_oob_ops ops; @@ -251,7 +251,7 @@ /* * Scan write data with oob to flash */ -static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, +static int scan_write_bbt(struct mtd_info *mtd, loff_mtd_t offs, size_mtd_t len, uint8_t *buf, uint8_t *oob) { struct mtd_oob_ops ops; @@ -306,7 +306,7 @@ * Scan a given block full */ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, - loff_t offs, uint8_t *buf, size_t readlen, + loff_mtd_t offs, uint8_t *buf, size_mtd_t readlen, int scanlen, int len) { int ret, j; @@ -326,7 +326,7 @@ * Scan a given block partially */ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, - loff_t offs, uint8_t *buf, int len) + loff_mtd_t offs, uint8_t *buf, int len) { struct mtd_oob_ops ops; int j, ret; @@ -372,8 +372,8 @@ struct nand_chip *this = mtd->priv; int i, numblocks, len, scanlen; int startblock; - loff_t from; - size_t readlen; + loff_mtd_t from; + size_mtd_t readlen; printk(KERN_INFO "Scanning device for bad blocks\n"); @@ -401,7 +401,7 @@ * below as it makes shifting and masking less painful */ numblocks = mtd->size >> (this->bbt_erase_shift - 1); startblock = 0; - from = 0; + from = (CONFIG_MTD_BADBLOCK_FLAG_PAGE << this->page_shift); //from = 0; } else { if (chip >= this->numchips) { printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", @@ -411,7 +411,7 @@ numblocks = this->chipsize >> (this->bbt_erase_shift - 1); startblock = chip * numblocks; numblocks += startblock; - from = startblock << (this->bbt_erase_shift - 1); + from = (startblock << (this->bbt_erase_shift - 1)) + (CONFIG_MTD_BADBLOCK_FLAG_PAGE << this->page_shift); //from = startblock << (this->bbt_erase_shift - 1); } for (i = startblock; i < numblocks;) { @@ -428,8 +428,8 @@ if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", - i >> 1, (unsigned int)from); + printk(KERN_WARNING "Bad eraseblock %d at 0x%09llx\n", + i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++; } @@ -495,7 +495,7 @@ for (block = 0; block < td->maxblocks; block++) { int actblock = startblock + dir * block; - loff_t offs = actblock << this->bbt_erase_shift; + loff_mtd_t offs = actblock << this->bbt_erase_shift; /* Read first page */ scan_read_raw(mtd, buf, offs, mtd->writesize); @@ -565,8 +565,8 @@ int nrchips, bbtoffs, pageoffs, ooboffs; uint8_t msk[4]; uint8_t rcode = td->reserved_block_code; - size_t retlen, len = 0; - loff_t to; + size_mtd_t retlen, len = 0; + loff_mtd_t to; struct mtd_oob_ops ops; ops.ooblen = mtd->oobsize; @@ -653,12 +653,12 @@ bbtoffs = chip * (numblocks >> 2); - to = ((loff_t) page) << this->page_shift; + to = ((loff_mtd_t) page) << this->page_shift; /* Must we save the block contents ? */ if (td->options & NAND_BBT_SAVECONTENT) { /* Make it block aligned */ - to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); + to &= ~((loff_mtd_t) ((1 << this->bbt_erase_shift) - 1)); len = 1 << this->bbt_erase_shift; res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { @@ -683,12 +683,12 @@ pageoffs = page - (int)(to >> this->page_shift); offs = pageoffs << this->page_shift; /* Preset the bbt area with 0xff */ - memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); + memset(&buf[offs], 0xff, (size_mtd_t) (numblocks >> sft)); ooboffs = len + (pageoffs * mtd->oobsize); } else { /* Calc length */ - len = (size_t) (numblocks >> sft); + len = (size_mtd_t) (numblocks >> sft); /* Make it page aligned ! */ len = (len + (mtd->writesize - 1)) & ~(mtd->writesize - 1); @@ -1015,7 +1015,7 @@ * * The function updates the bad block table(s) */ -int nand_update_bbt(struct mtd_info *mtd, loff_t offs) +int nand_update_bbt(struct mtd_info *mtd, loff_mtd_t offs) { struct nand_chip *this = mtd->priv; int len, res = 0, writeops = 0; @@ -1191,7 +1191,7 @@ * @allowbbt: allow access to bad block table region * */ -int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) +int nand_isbad_bbt(struct mtd_info *mtd, loff_mtd_t offs, int allowbbt) { struct nand_chip *this = mtd->priv; int block; diff -ru linux-2.6/drivers/mtd/nand/nand_ids.c /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_ids.c --- linux-2.6/drivers/mtd/nand/nand_ids.c 2009-08-17 23:57:37.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/mtd/nand/nand_ids.c 2009-08-12 10:39:09.000000000 +0200 @@ -109,6 +109,10 @@ {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, + /* 32 Gigabit */ + {"NAND 4GiB 3,3V 8-bit", 0xD7, 0, 4096, 0, LP_OPTIONS}, + {"NAND 4GiB 3,3V 8-bit", 0xD5, 0, 4096, 0, LP_OPTIONS}, + /* * Renesas AND 1 Gigabit. Those chips do not support extended id and * have a strange page/block layout ! The chosen minimum erasesize is diff -ru linux-2.6/drivers/net/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/net/Kconfig --- linux-2.6/drivers/net/Kconfig 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/net/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -207,6 +207,33 @@ or internal device. It is safe to say Y or M here even if your ethernet card lack MII. +config JZ_ETH + tristate "JZ4730/JZ5730 On-Chip Ethernet support" + depends on NET_ETHERNET && (SOC_JZ4730 || SOC_JZ5730 || JZ_FPGA) + help + Say Y for support of JZ4730/JZ5730 On-Chip Ethernet interface. + + To compile this driver as a module, choose M here: the module + will be called jz_eth. + +config JZCS8900 + tristate "JZ CS8900A Ethernet support" + depends on NET_ETHERNET && (SOC_JZ4740 || SOC_JZ4750) + help + Say Y for support of JZ CS8900A Ethernet interface. + + To compile this driver as a module, choose M here: the module + will be called jzcs8900a. + +config JZ4760_ETH + tristate "JZ4760 On-Chip Ethernet support" + depends on NET_ETHERNET && (SOC_JZ4760 || SOC_JZ4810 || JZ_FPGA) + help + Say Y for support of JZ4760 On-Chip Ethernet interface. + + To compile this driver as a module, choose M here: the module + will be called jz4760_eth. + config MACB tristate "Atmel MACB support" depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 diff -ru linux-2.6/drivers/net/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/net/Makefile --- linux-2.6/drivers/net/Makefile 2009-08-17 23:58:01.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/net/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -90,6 +90,9 @@ obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_PHYLIB) += phy/ +obj-$(CONFIG_JZ_ETH) += jz_eth.o +obj-$(CONFIG_JZCS8900) += jzcs8900a.o +obj-$(CONFIG_JZ4760_ETH) += jz4760_eth.o obj-$(CONFIG_SUNDANCE) += sundance.o obj-$(CONFIG_HAMACHI) += hamachi.o obj-$(CONFIG_NET) += Space.o loopback.o diff -ru linux-2.6/drivers/power/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/power/Kconfig --- linux-2.6/drivers/power/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/power/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -62,4 +62,9 @@ help Say Y to enable support for the battery in Palm T|X. +config BATTERY_JZ + tristate "JZ battery" + help + Say Y to enable support for the battery in JZ SOC. + endif # POWER_SUPPLY diff -ru linux-2.6/drivers/power/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/power/Makefile --- linux-2.6/drivers/power/Makefile 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/power/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -22,3 +22,4 @@ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o obj-$(CONFIG_BATTERY_PALMTX) += palmtx_battery.o +obj-$(CONFIG_BATTERY_JZ) += jz_battery.o diff -ru linux-2.6/drivers/power/power_supply_sysfs.c /plain/src/qi/linux-2.6.27.git.svn/drivers/power/power_supply_sysfs.c --- linux-2.6/drivers/power/power_supply_sysfs.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/power/power_supply_sysfs.c 2009-08-12 10:39:09.000000000 +0200 @@ -107,7 +107,8 @@ POWER_SUPPLY_ATTR(energy_now), POWER_SUPPLY_ATTR(energy_avg), POWER_SUPPLY_ATTR(capacity), - POWER_SUPPLY_ATTR(temp), + POWER_SUPPLY_ATTR(batt_temp), + POWER_SUPPLY_ATTR(batt_vol), POWER_SUPPLY_ATTR(temp_ambient), POWER_SUPPLY_ATTR(time_to_empty_now), POWER_SUPPLY_ATTR(time_to_empty_avg), diff -ru linux-2.6/drivers/rtc/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/rtc/Kconfig --- linux-2.6/drivers/rtc/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/rtc/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -105,6 +105,16 @@ driver does not expose RTC_UIE ioctls. Those requests generate once-per-second update interrupts, used for synchronization. +config RTC_INTF_ALARM + bool "Android alarm driver" + depends on RTC_CLASS + default y + help + Provides non-wakeup and rtc backed wakeup alarms based on rtc or + elapsed realtime, and a non-wakeup alarm on the monotonic clock. + Also provides an ioctl to set the wall time which must be used + for elapsed realtime to work. + config RTC_DRV_TEST tristate "Test driver/device" help @@ -468,6 +478,16 @@ To compile this driver as a module, choose M here: the module will be called rtc-sa1100. +config RTC_DRV_JZ4750 + tristate "JZ4750/JZ4750D" + depends on SOC_JZ4750 || SOC_JZ4750D + help + If you say Y here you will get access to the real time clock + built into your JZ4750 or JZ4750D CPU. + + To compile this driver as a module, choose M here: the + module will be called rtc-jz4750. + config RTC_DRV_SH tristate "SuperH On-Chip RTC" depends on RTC_CLASS && SUPERH diff -ru linux-2.6/drivers/rtc/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/rtc/Makefile --- linux-2.6/drivers/rtc/Makefile 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/rtc/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -11,6 +11,7 @@ obj-$(CONFIG_RTC_CLASS) += rtc-core.o rtc-core-y := class.o interface.o +rtc-core-$(CONFIG_RTC_INTF_ALARM) += alarm.o rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o @@ -59,3 +60,4 @@ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o +obj-$(CONFIG_RTC_DRV_JZ4750) += rtc-jz4750.o diff -ru linux-2.6/drivers/serial/8250.c /plain/src/qi/linux-2.6.27.git.svn/drivers/serial/8250.c --- linux-2.6/drivers/serial/8250.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/serial/8250.c 2009-08-12 10:39:09.000000000 +0200 @@ -178,7 +178,7 @@ [PORT_16550A] = { .name = "16550A", .fifo_size = 16, - .tx_loadsz = 16, + .tx_loadsz = 8, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO, }, @@ -397,6 +397,10 @@ break; case UPIO_MEM: +#if defined(CONFIG_JZSOC) + if (offset == (UART_FCR << up->port.regshift)) + value |= 0x10; /* set FCR.UUE */ +#endif writeb(value, up->port.membase + offset); break; @@ -2057,6 +2061,83 @@ serial_unlink_irq_chain(up); } +#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730) +static unsigned short quot1[3] = {0}; /* quot[0]:baud_div, quot[1]:umr, quot[2]:uacr */ +static unsigned short * serial8250_get_divisor(struct uart_port *port, unsigned int baud) +{ + int err, sum, i, j; + int a[12], b[12]; + unsigned short div, umr, uacr; + unsigned short umr_best, div_best, uacr_best; + long long t0, t1, t2, t3; + + sum = 0; + umr_best = div_best = uacr_best = 0; + div = 1; + + if ((port->uartclk % (16 * baud)) == 0) { + quot1[0] = port->uartclk / (16 * baud); + quot1[1] = 16; + quot1[2] = 0; + return quot1; + } + + while (1) { + umr = port->uartclk / (baud * div); + if (umr > 32) { + div++; + continue; + } + if (umr < 4) { + break; + } + for (i = 0; i < 12; i++) { + a[i] = umr; + b[i] = 0; + sum = 0; + for (j = 0; j <= i; j++) { + sum += a[j]; + } + + /* the precision could be 1/2^(36) due to the value of t0 */ + t0 = 0x1000000000LL; + t1 = (i + 1) * t0; + t2 = (sum * div) * t0; + t3 = div * t0; + do_div(t1, baud); + do_div(t2, port->uartclk); + do_div(t3, (2 * port->uartclk)); + err = t1 - t2 - t3; + + if (err > 0) { + a[i] += 1; + b[i] = 1; + } + } + + uacr = 0; + for (i = 0; i < 12; i++) { + if (b[i] == 1) { + uacr |= 1 << i; + } + } + + /* the best value of umr should be near 16, and the value of uacr should better be smaller */ + if (abs(umr - 16) < abs(umr_best - 16) || (abs(umr - 16) == abs(umr_best - 16) && uacr_best > uacr)) { + div_best = div; + umr_best = umr; + uacr_best = uacr; + } + div++; + } + + quot1[0] = div_best; + quot1[1] = umr_best; + quot1[2] = uacr_best; + + return quot1; +} +#else static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) { unsigned int quot; @@ -2076,6 +2157,7 @@ return quot; } +#endif static void serial8250_set_termios(struct uart_port *port, struct ktermios *termios, @@ -2085,6 +2167,9 @@ unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; +#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730) + unsigned short *quot1; +#endif switch (termios->c_cflag & CSIZE) { case CS5: @@ -2117,7 +2202,12 @@ * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); +#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730) + quot1 = serial8250_get_divisor(port, baud); + quot = quot1[0]; /* not usefull, just let gcc happy */ +#else quot = serial8250_get_divisor(port, baud); +#endif /* * Oxford Semi 952 rev B workaround @@ -2195,6 +2285,10 @@ if (up->capabilities & UART_CAP_UUE) up->ier |= UART_IER_UUE | UART_IER_RTOIE; +#ifdef CONFIG_JZSOC + up->ier |= UART_IER_RTOIE; /* Set this flag, or very slow */ +#endif + serial_out(up, UART_IER, up->ier); if (up->capabilities & UART_CAP_EFR) { @@ -2229,7 +2323,15 @@ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ } +#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730) +#define UART_UMR 9 +#define UART_UACR 10 + serial_dl_write(up, quot1[0]); + serial_outp(up, UART_UMR, quot1[1]); + serial_outp(up, UART_UACR, quot1[2]); +#else serial_dl_write(up, quot); +#endif /* * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR diff -ru linux-2.6/drivers/usb/core/hub.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/core/hub.c --- linux-2.6/drivers/usb/core/hub.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/core/hub.c 2009-08-12 10:39:09.000000000 +0200 @@ -1749,6 +1749,25 @@ { int i, status; +#ifdef CONFIG_SOC_JZ4730 + /* + * On Jz4730, we assume that the first USB port was used as device. + * If not, please comment next lines. + */ + if (port1 == 1) { + return 0; + } +#endif + +#if defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + /* + * On Jz4740 and Jz4750, the second USB port was used as device. + */ + if (port1 == 2) { + return 0; + } +#endif + /* Block EHCI CF initialization during the port reset. * Some companion controllers don't like it when they mix. */ @@ -2666,11 +2685,35 @@ le16_to_cpu(hub->descriptor->wHubCharacteristics); struct usb_device *udev; int status, i; +#ifdef CONFIG_JZSOC + static char jzhub = 1; /* the hub first to be initialized is jzsoc on-chip hub */ +#endif dev_dbg (hub_dev, "port %d, status %04x, change %04x, %s\n", port1, portstatus, portchange, portspeed (portstatus)); +#ifdef CONFIG_SOC_JZ4730 + /* + * On Jz4730, we assume that the first USB port was used as device. + * If not, please comment next lines. + */ + if ((port1 == 1) && (jzhub)) { + jzhub = 0; + return; + } +#endif + +#if defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D) + /* + * On Jz4740 and Jz4750, the second USB port was used as device. + */ + if ((port1 == 2) && (jzhub)) { + jzhub = 0; + return; + } +#endif + if (hub->has_indicators) { set_port_led(hub, port1, HUB_LED_AUTO); hub->indicator[port1-1] = INDICATOR_AUTO; diff -ru linux-2.6/drivers/usb/gadget/composite.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/composite.c --- linux-2.6/drivers/usb/gadget/composite.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/composite.c 2009-08-12 10:39:09.000000000 +0200 @@ -492,7 +492,8 @@ while (*sp) { s = *sp++; - if (s->language != language) + + if (language && s->language != language) continue; value = usb_gadget_get_string(s, id, buf); if (value > 0) @@ -612,8 +613,8 @@ * housekeeping for the gadget function we're implementing. Most of * the work is in config and function specific setup. */ -static int -composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) + +int composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_request *req = cdev->req; @@ -984,7 +985,7 @@ .speed = USB_SPEED_HIGH, .bind = composite_bind, - .unbind = __exit_p(composite_unbind), + .unbind = composite_unbind, .setup = composite_setup, .disconnect = composite_disconnect, diff -ru linux-2.6/drivers/usb/gadget/file_storage.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/file_storage.c --- linux-2.6/drivers/usb/gadget/file_storage.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/file_storage.c 2009-08-12 10:39:09.000000000 +0200 @@ -274,6 +274,18 @@ /*-------------------------------------------------------------------------*/ +#if defined(CONFIG_UDC_USE_LB_CACHE) +#define GHOST +#endif + +#ifdef GHOST +extern unsigned long udc_read(unsigned int offset, unsigned int len, unsigned char *); +extern unsigned long udc_write(unsigned int offset, unsigned int len, unsigned char *); +extern int NAND_LB_Init(void); +extern int NAND_LB_FLASHCACHE(void); +extern int NAND_MTD_FLASHCACHE(void); +extern int FlushDataState; +#endif #define LDBG(lun,fmt,args...) \ dev_dbg(&(lun)->dev , fmt , ## args) @@ -345,8 +357,8 @@ } mod_data = { // Default values .transport_parm = "BBB", .protocol_parm = "SCSI", - .removable = 0, - .can_stall = 1, + .removable = 1, + .can_stall = 0, .vendor = DRIVER_VENDOR_ID, .product = DRIVER_PRODUCT_ID, .release = 0xffff, // Use controller chip type @@ -806,6 +818,7 @@ #define STRING_SERIAL 3 #define STRING_CONFIG 4 #define STRING_INTERFACE 5 +#define STRING_MS_OS 0xee /* There is only one configuration. */ #define CONFIG_VALUE 1 @@ -993,6 +1006,7 @@ {STRING_SERIAL, serial}, {STRING_CONFIG, "Self-powered"}, {STRING_INTERFACE, "Mass Storage"}, + {STRING_MS_OS, "Microsoft"}, {} }; @@ -1614,9 +1628,13 @@ /* Perform the read */ file_offset_tmp = file_offset; +#ifdef GHOST + nread = udc_read(file_offset_tmp, amount, bh->buf); +#else nread = vfs_read(curlun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); +#endif VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); @@ -1795,9 +1813,13 @@ /* Perform the write */ file_offset_tmp = file_offset; +#ifdef GHOST + nwritten = udc_write(file_offset_tmp, amount, bh->buf); +#else nwritten = vfs_write(curlun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); +#endif VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nwritten); @@ -1972,9 +1994,13 @@ /* Perform the read */ file_offset_tmp = file_offset; +#ifdef GHOST + nread = udc_read(file_offset_tmp, amount, bh->buf); +#else nread = vfs_read(curlun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); +#endif VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); @@ -2009,7 +2035,7 @@ { u8 *buf = (u8 *) bh->buf; - static char vendor_id[] = "Linux "; + static char vendor_id[] = "Ingenic "; static char product_id[] = "File-Stor Gadget"; if (!fsg->curlun) { // Unsupported LUNs are okay @@ -2876,6 +2902,15 @@ reply = check_command(fsg, 6, DATA_DIR_NONE, 0, 1, "TEST UNIT READY"); +#ifdef GHOST + if( FlushDataState >= 1) + FlushDataState++; + if(FlushDataState > 6) + { + NAND_LB_FLASHCACHE(); + FlushDataState = 0; + } +#endif break; /* Although optional, this command is used by MS-Windows. We @@ -3425,6 +3460,13 @@ /* The main loop */ while (fsg->state != FSG_STATE_TERMINATED) { +#ifdef GHOST + if ((fsg->atomic_bitflags & SUSPENDED)) + { + NAND_LB_FLASHCACHE(); + NAND_MTD_FLASHCACHE(); + } +#endif if (exception_in_progress(fsg) || signal_pending(current)) { handle_exception(fsg); continue; @@ -3547,6 +3589,10 @@ LDBG(curlun, "open backing file: %s\n", filename); rc = 0; +#ifdef GHOST + NAND_LB_Init(); +#endif + out: filp_close(filp, current->files); return rc; diff -ru linux-2.6/drivers/usb/gadget/gadget_chips.h /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/gadget_chips.h --- linux-2.6/drivers/usb/gadget/gadget_chips.h 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/gadget_chips.h 2009-08-12 10:39:09.000000000 +0200 @@ -15,6 +15,24 @@ #ifndef __GADGET_CHIPS_H #define __GADGET_CHIPS_H +#ifdef CONFIG_USB_GADGET_JZ4750 +#define gadget_is_jz4750(g) !strcmp("ingenic_hsusb", (g)->name) /* same driver */ +#else +#define gadget_is_jz4750(g) 0 +#endif + +#ifdef CONFIG_USB_GADGET_JZ4740 +#define gadget_is_jz4740(g) !strcmp("ingenic_hsusb", (g)->name) +#else +#define gadget_is_jz4740(g) 0 +#endif + +#ifdef CONFIG_USB_GADGET_JZ4730 +#define gadget_is_jz4730(g) !strcmp("jz4730_udc", (g)->name) +#else +#define gadget_is_jz4730(g) 0 +#endif + #ifdef CONFIG_USB_GADGET_NET2280 #define gadget_is_net2280(g) !strcmp("net2280", (g)->name) #else @@ -216,6 +234,13 @@ return 0x20; else if (gadget_is_m66592(gadget)) return 0x21; + else if (gadget_is_jz4730(gadget)) + return 0x22; + else if (gadget_is_jz4740(gadget)) + return 0x23; + else if (gadget_is_jz4750(gadget)) + return 0x24; + return -ENOENT; } diff -ru linux-2.6/drivers/usb/gadget/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/Kconfig --- linux-2.6/drivers/usb/gadget/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -94,6 +94,47 @@ Many controller drivers are platform-specific; these often need board-specific hooks. +config USB_GADGET_JZ4740 + boolean "JZ4740 UDC" + depends on SOC_JZ4740 + select USB_GADGET_DUALSPEED + help + Select this to support the Ingenic JZ4740 processor + high speed USB device controller. + +config USB_JZ4740 + tristate + depends on USB_GADGET_JZ4740 + default USB_GADGET + select USB_GADGET_SELECTED + +config USB_GADGET_JZ4750 + boolean "JZ4750 UDC" + depends on SOC_JZ4750 || SOC_JZ4750D + select USB_GADGET_DUALSPEED + help + Select this to support the Ingenic JZ4750 processor + high speed USB device controller. + +config USB_JZ4750 + tristate + depends on USB_GADGET_JZ4750 + default USB_GADGET + select USB_GADGET_SELECTED + +config USB_GADGET_JZ4730 + boolean "JZ4730 UDC" + depends on SOC_JZ4730 + help + Select this to support the Ingenic JZ4730 processor + full speed USB device controller. + +config USB_JZ4730 + tristate + depends on USB_GADGET_JZ4730 + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_AMD5536UDC boolean "AMD5536 UDC" depends on PCI @@ -399,6 +440,18 @@ endchoice +config USB_JZ_UDC_HOTPLUG + boolean "Ingenic USB Device Controller Hotplug Support" + depends on USB_GADGET_JZ4750 + +config UDC_USE_LB_CACHE + bool "NAND LB Cache Support" + depends on (USB_FILE_STORAGE || USB_ANDROID) && (SOC_JZ4740 || SOC_JZ4750 || SOC_JZ4750D) + default y + help + say "y" to enable lb cache and UDC work in faster speed. + say "n" to disable lb cache and UDC work in normal speed. + config USB_GADGET_DUALSPEED bool depends on USB_GADGET @@ -406,7 +459,6 @@ help Means that gadget drivers should include extra descriptors and code to handle dual-speed controllers. - # # USB Gadget Drivers # @@ -596,6 +648,16 @@ For more information, see Documentation/usb/gadget_printer.txt which includes sample code for accessing the device file. +config USB_ANDROID + tristate "Android Gadget" + select USB_JZ_UDC_HOTPLUG + + help + The Android gadget provides mass storage and adb transport. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_android". + config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" depends on NET diff -ru linux-2.6/drivers/usb/gadget/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/Makefile --- linux-2.6/drivers/usb/gadget/Makefile 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/gadget/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -18,6 +18,11 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o +obj-$(CONFIG_USB_JZ4740) += jz4740_udc.o +obj-$(CONFIG_USB_JZ4730) += jz4730_udc.o +obj-$(CONFIG_USB_JZ4750) += jz4740_udc.o + +obj-$(CONFIG_USB_JZ_UDC_HOTPLUG)+= udc_hotplug_core.o # # USB gadget drivers @@ -35,6 +40,7 @@ epautoconf.o g_cdc-objs := cdc2.o u_ether.o f_ecm.o \ u_serial.o f_acm.o $(C_UTILS) +g_android-objs := android.o f_adb.o f_mass_storage.o $(C_UTILS) ifeq ($(CONFIG_USB_ETH_RNDIS),y) g_ether-objs += f_rndis.o rndis.o @@ -48,4 +54,5 @@ obj-$(CONFIG_USB_G_PRINTER) += g_printer.o obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o +obj-$(CONFIG_USB_ANDROID) += g_android.o diff -ru linux-2.6/drivers/usb/host/ohci-hcd.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/host/ohci-hcd.c --- linux-2.6/drivers/usb/host/ohci-hcd.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/host/ohci-hcd.c 2009-08-12 10:39:09.000000000 +0200 @@ -995,6 +995,11 @@ #define PCI_DRIVER ohci_pci_driver #endif +#ifdef CONFIG_JZSOC +#include "ohci-jz.c" +#define PLATFORM_DRIVER ohci_hcd_jz_driver +#endif + #if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_SA1111) #include "ohci-sa1111.c" #define SA1111_DRIVER ohci_hcd_sa1111_driver diff -ru linux-2.6/drivers/usb/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/Kconfig --- linux-2.6/drivers/usb/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -42,6 +42,7 @@ default y if PPC_MPC52xx # MIPS: default y if SOC_AU1X00 + default y if JZSOC # SH: default y if CPU_SUBTYPE_SH7720 default y if CPU_SUBTYPE_SH7721 diff -ru linux-2.6/drivers/usb/musb/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/Kconfig --- linux-2.6/drivers/usb/musb/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -8,7 +8,10 @@ # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller config USB_MUSB_HDRC - depends on (USB || USB_GADGET) && HAVE_CLK + depends on (USB || USB_GADGET) + +#&& HAVE_CLK Disabled by River + depends on !SUPERH select TWL4030_USB if MACH_OMAP_3430SDP tristate 'Inventra Highspeed Dual Role Controller (TI, ...)' @@ -144,12 +147,17 @@ parameter. config USB_INVENTRA_DMA - bool + bool 'Use INVENTRA DMA' depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY - default ARCH_OMAP2430 || ARCH_OMAP34XX + default ARCH_OMAP2430 || ARCH_OMAP34XX || SOC_JZ4760 help Enable DMA transfers using Mentor's engine. +config USB_MUSB_HSDMA_IRQ_SHARED + bool 'INVENTRA DMA IRQ shared with USB IRQ' + depends on USB_MUSB_HDRC && USB_INVENTRA_DMA && !MUSB_PIO_ONLY + default SOC_JZ4760 + config USB_TI_CPPI_DMA bool depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY diff -ru linux-2.6/drivers/usb/musb/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/Makefile --- linux-2.6/drivers/usb/musb/Makefile 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -22,6 +22,10 @@ musb_hdrc-objs += omap2430.o endif +ifeq ($(CONFIG_SOC_JZ4760),y) + musb_hdrc-objs += jz4760.o +endif + ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o endif diff -ru linux-2.6/drivers/usb/musb/musb_core.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_core.c --- linux-2.6/drivers/usb/musb/musb_core.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_core.c 2009-08-12 10:39:09.000000000 +0200 @@ -107,13 +107,10 @@ #include "musb_core.h" - #ifdef CONFIG_ARCH_DAVINCI #include "davinci.h" #endif - - unsigned debug; module_param(debug, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); @@ -148,6 +145,34 @@ /*-------------------------------------------------------------------------*/ +static inline void musb_dump_packet(int epnum, const u8 *packet, u16 len) +{ + u16 i; + +#ifdef MUSB_DUMP_EP_NUM + if (epnum != MUSB_DUMP_EP_NUM) + return; +#endif + + printk(KERN_ERR "\nMUSB Packet Dump: Length: %d bytes.\n", len); + printk(KERN_ERR "==============================================\n"); + + for (i = 0; i < len; i++) { + printk("0x%02x ", packet[i]); + if ((i+ 1) % 10 == 0) + printk("\n"); + } + + printk("\n"); + printk(KERN_ERR "==============================================\n"); +} + +#define MUSB_DUMP_TX_PACKET(epnum, packet, len) \ +// musb_dump_packet(epnum, packet, len) + +#define MUSB_DUMP_RX_PACKET(epnum, packet, len) \ +// musb_dump_packet(epnum, packet, len) + #ifndef CONFIG_USB_TUSB6010 /* * Load an endpoint's FIFO @@ -187,6 +212,8 @@ /* byte aligned */ writesb(fifo, src, len); } + + MUSB_DUMP_TX_PACKET(hw_ep->num, src, len); } /* @@ -225,6 +252,8 @@ /* byte aligned */ readsb(fifo, dst, len); } + + MUSB_DUMP_RX_PACKET(hw_ep->epnum, dst, len); } #endif /* normal PIO */ @@ -477,6 +506,20 @@ #ifdef CONFIG_USB_MUSB_HDRC_HCD /* see manual for the order of the tests */ + +#ifdef CONFIG_SOC_JZ4760 + /* + * Modified by River + * Note: There is a strange Session request IRQ asserted in the MUSB IP core of JZ4760 when MUSB is operating in DEVICE mode. + * We just ignore it. + */ + + if ((int_usb & MUSB_INTR_SESSREQ) && !(devctl & MUSB_DEVCTL_HM)) { + DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); + + handled = IRQ_HANDLED; + } +#else if (int_usb & MUSB_INTR_SESSREQ) { DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); @@ -495,6 +538,7 @@ handled = IRQ_HANDLED; } +#endif if (int_usb & MUSB_INTR_VBUSERROR) { int ignore = 0; @@ -766,6 +810,7 @@ #ifdef CONFIG_USB_MUSB_HDRC_HCD case OTG_STATE_A_HOST: case OTG_STATE_A_SUSPEND: + usb_hcd_resume_root_hub(musb_to_hcd(musb)); /* River - from Linux-2.6.29-rc6 usb-musb-resume-suspend-root-hub-on-disconnect.patch */ musb_root_disconnect(musb); if (musb->a_wait_bcon != 0) musb_platform_try_idle(musb, jiffies @@ -959,10 +1004,13 @@ spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); musb_generic_disable(musb); + +#ifdef CONFIG_HAVE_CLK if (musb->clock) { clk_put(musb->clock); musb->clock = NULL; } +#endif spin_unlock_irqrestore(&musb->lock, flags); /* FIXME power down */ @@ -1259,7 +1307,7 @@ hw_ep = musb->endpoints + epnum; /* read from core using indexed model */ - reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); + reg = musb_readb(mbase, 0x10 + MUSB_FIFOSIZE); /* Do not use hw_ep->regs before it's initialized. - Fixed by River. */ if (!reg) { /* 0's returned when no more endpoints */ break; @@ -1402,6 +1450,9 @@ /* configure ep0 */ musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; + + /* Added by River */ + musb->endpoints[0].is_shared_fifo = 1; /* discover endpoint configuration */ musb->nr_endpoints = 1; @@ -1477,8 +1528,48 @@ /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_SOC_JZ4760) /* Added by River */ + +/* Modified by River - For DMA IRQ Sharing */ +#if defined(CONFIG_USB_MUSB_HSDMA_IRQ_SHARED) +static irqreturn_t generic_interrupt(int irq, void *__hci) +{ + unsigned long flags; + struct musb *musb = __hci; + + irqreturn_t rv, rv_dma, rv_usb; + + rv = rv_dma = rv_usb = IRQ_NONE; + + spin_lock_irqsave(&musb->lock, flags); + + /* Process DMA IRQ. */ + if (dma_controller_fetch_intr(musb->dma_controller)) + rv_dma = dma_controller_irq(irq, (void *)musb); + + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + rv_usb = musb_interrupt(musb); + + spin_unlock_irqrestore(&musb->lock, flags); + + /* REVISIT we sometimes get spurious IRQs on g_ep0 + * not clear why... + */ + + rv = (rv_dma == IRQ_HANDLED || rv_usb == IRQ_HANDLED) ? IRQ_HANDLED : IRQ_NONE; + if (rv != IRQ_HANDLED) + DBG(5, "spurious?\n"); + + return IRQ_HANDLED; +} + +#else /* !CONFIG_USB_MUSB_HSDMA_IRQ_SHARED */ +/* Original IRQ Handler */ static irqreturn_t generic_interrupt(int irq, void *__hci) { unsigned long flags; @@ -1504,6 +1595,7 @@ return IRQ_HANDLED; } +#endif /* Defined CONFIG_USB_MUSB_HSDMA_IRQ_SHARED - End added */ #else #define generic_interrupt NULL @@ -1525,11 +1617,14 @@ devctl = musb_readb(musb->mregs, MUSB_DEVCTL); power = musb_readb(musb->mregs, MUSB_POWER); + + D("DEVCTL: 0x%x, POWER: 0x%x.\n", devctl, power); + D("musb->int_usb: 0x%x, musb->int_tx: 0x%x, musb->int_rx: 0x%x.\n", musb->int_usb, musb->int_tx, musb->int_rx); DBG(4, "** IRQ %s usb%04x tx%04x rx%04x\n", (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", musb->int_usb, musb->int_tx, musb->int_rx); - + /* the core can interrupt us for multiple reasons; docs have * a generic interrupt flowchart to follow */ @@ -1652,6 +1747,30 @@ #ifdef CONFIG_SYSFS static ssize_t +musb_devctl_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long flags; + int ret = -EINVAL; + + + spin_lock_irqsave(&musb->lock, flags); + ret = sprintf(buf, "0x%x\n", musb_readb(musb->mregs, MUSB_DEVCTL)); + spin_unlock_irqrestore(&musb->lock, flags); + + return ret; +} + +static ssize_t +musb_devctl_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t n) +{ + return n; +} +static DEVICE_ATTR(devctl, 0644, musb_devctl_show, musb_devctl_store); + + +static ssize_t musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct musb *musb = dev_to_musb(dev); @@ -1826,6 +1945,7 @@ */ #ifdef CONFIG_SYSFS + device_remove_file(musb->controller, &dev_attr_devctl); device_remove_file(musb->controller, &dev_attr_mode); device_remove_file(musb->controller, &dev_attr_vbus); #ifdef CONFIG_USB_MUSB_OTG @@ -1838,9 +1958,12 @@ #endif if (musb->nIrq >= 0) { - disable_irq_wake(musb->nIrq); + if (musb->b_irq_wake) /* Fixed by River. - Don't call disable_irq_wake() when set_irq_wake() fails. */ + disable_irq_wake(musb->nIrq); + free_irq(musb->nIrq, musb); } + if (is_dma_capable() && musb->dma_controller) { struct dma_controller *c = musb->dma_controller; @@ -1852,10 +1975,12 @@ musb_platform_exit(musb); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); +#ifdef CONFIG_HAVE_CLK /* Added by River */ if (musb->clock) { clk_disable(musb->clock); clk_put(musb->clock); } +#endif #ifdef CONFIG_USB_MUSB_OTG put_device(musb->xceiv.dev); @@ -1922,9 +2047,13 @@ spin_lock_init(&musb->lock); musb->board_mode = plat->mode; musb->board_set_power = plat->set_power; + +#ifdef CONFIG_HAVE_CLK /* Added by River */ musb->set_clock = plat->set_clock; +#endif musb->min_power = plat->min_power; +#ifdef CONFIG_HAVE_CLK /* Added by River */ /* Clock usage is chip-specific ... functional clock (DaVinci, * OMAP2430), or PHY ref (some TUSB6010 boards). All this core * code does is make sure a clock handle is available; platform @@ -1938,6 +2067,7 @@ goto fail; } } +#endif /* assume vbus is off */ @@ -1990,8 +2120,10 @@ } musb->nIrq = nIrq; /* FIXME this handles wakeup irqs wrong */ - if (enable_irq_wake(nIrq) == 0) + if (enable_irq_wake(nIrq) == 0) { /* Fixe by River. */ device_init_wakeup(dev, 1); + musb->b_irq_wake = 1; + } pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", musb_driver_name, @@ -2057,13 +2189,18 @@ return 0; fail: + +#ifdef CONFIG_HAVE_CLK if (musb->clock) clk_put(musb->clock); +#endif + device_init_wakeup(dev, 0); musb_free(musb); return status; #ifdef CONFIG_SYSFS + status = device_create_file(dev, &dev_attr_devctl); status = device_create_file(dev, &dev_attr_mode); status = device_create_file(dev, &dev_attr_vbus); #ifdef CONFIG_USB_GADGET_MUSB_HDRC @@ -2144,8 +2281,10 @@ unsigned long flags; struct musb *musb = dev_to_musb(&pdev->dev); +#ifdef CONFIG_HAVE_CLK if (!musb->clock) return 0; +#endif spin_lock_irqsave(&musb->lock, flags); @@ -2159,10 +2298,13 @@ */ } +#ifdef CONFIG_HAVE_CLK if (musb->set_clock) musb->set_clock(musb->clock, 0); else clk_disable(musb->clock); +#endif + spin_unlock_irqrestore(&musb->lock, flags); return 0; } @@ -2172,15 +2314,18 @@ unsigned long flags; struct musb *musb = dev_to_musb(&pdev->dev); +#ifdef CONFIG_HAVE_CLK if (!musb->clock) return 0; - +#endif spin_lock_irqsave(&musb->lock, flags); +#ifdef CONFIG_HAVE_CLK if (musb->set_clock) musb->set_clock(musb->clock, 1); else clk_enable(musb->clock); +#endif /* for static cmos like DaVinci, register values were preserved * unless for some reason the whole soc powered down and we're diff -ru linux-2.6/drivers/usb/musb/musb_core.h /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_core.h --- linux-2.6/drivers/usb/musb/musb_core.h 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_core.h 2009-08-12 10:39:09.000000000 +0200 @@ -52,7 +52,6 @@ struct musb_hw_ep; struct musb_ep; - #include "musb_debug.h" #include "musb_dma.h" @@ -63,7 +62,8 @@ #include "../core/hcd.h" #include "musb_host.h" - +#define D(fmt, args...) \ +// printk(KERN_ERR "%s(): LINE: %d "fmt, __func__, __LINE__, ##args) #ifdef CONFIG_USB_MUSB_OTG @@ -306,7 +306,10 @@ struct musb { /* device lock */ spinlock_t lock; + +#ifdef CONFIG_HAVE_CLK /* Added by River */ struct clk *clock; +#endif irqreturn_t (*isr)(int, void *); struct work_struct irq_work; @@ -359,7 +362,8 @@ struct otg_transceiver xceiv; int nIrq; - + u8 b_irq_wake; /* Added by River. */ + struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; #define control_ep endpoints @@ -371,8 +375,9 @@ u8 board_mode; /* enum musb_mode */ int (*board_set_power)(int state); +#ifdef CONFIG_HAVE_CLK /* Added by River */ int (*set_clock)(struct clk *clk, int is_active); - +#endif u8 min_power; /* vbus for periph, in mA/2 */ bool is_host; diff -ru linux-2.6/drivers/usb/musb/musb_dma.h /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_dma.h --- linux-2.6/drivers/usb/musb/musb_dma.h 2009-08-17 23:57:37.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_dma.h 2009-08-12 10:39:09.000000000 +0200 @@ -148,6 +148,13 @@ * Controllers manage dma channels. */ struct dma_controller { + +/* Added by River - For DMA IRQ Sharing */ +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED + u8 int_hsdma; /* MUSB_HSDMA_INTR */ +#endif +/* End added */ + int (*start)(struct dma_controller *); int (*stop)(struct dma_controller *); struct dma_channel *(*channel_alloc)(struct dma_controller *, @@ -163,10 +170,18 @@ /* called after channel_program(), may indicate a fault */ extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit); - extern struct dma_controller *__init dma_controller_create(struct musb *, void __iomem *); extern void dma_controller_destroy(struct dma_controller *); +/* Added by River - For DMA IRQ Sharing */ +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED +extern u8 dma_controller_fetch_intr(struct dma_controller *c); + +irqreturn_t dma_controller_irq(int irq, void *private_data); + +#endif /* End added */ + #endif /* __MUSB_DMA_H__ */ + diff -ru linux-2.6/drivers/usb/musb/musb_gadget_ep0.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_gadget_ep0.c --- linux-2.6/drivers/usb/musb/musb_gadget_ep0.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_gadget_ep0.c 2009-08-12 10:39:09.000000000 +0200 @@ -405,7 +405,8 @@ csr |= MUSB_RXCSR_P_SENDSTALL | MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_CLRDATATOG - | MUSB_TXCSR_P_WZC_BITS; +// | MUSB_TXCSR_P_WZC_BITS; + | MUSB_RXCSR_P_WZC_BITS; /* Corrected by River. */ musb_writew(regs, MUSB_RXCSR, csr); } diff -ru linux-2.6/drivers/usb/musb/musb_host.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_host.c --- linux-2.6/drivers/usb/musb/musb_host.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_host.c 2009-08-12 10:39:09.000000000 +0200 @@ -40,10 +40,16 @@ #include #include #include +#include #include "musb_core.h" #include "musb_host.h" +/* Added by River. */ +/* The MUSBHDRC core RTL V1.8 in JZ4760 has no data toogle control. */ +#ifndef CONFIG_SOC_JZ4760 +#define HAVE_DATA_TOGGLE_CONTROL 1 +#endif /* MUSB HOST status 22-mar-2006 * @@ -296,9 +302,10 @@ spin_lock(&musb->lock); } +/* Modified by River. */ +#ifdef HAVE_DATA_TOGGLE_CONTROL /* for bulk/interrupt endpoints only */ -static inline void -musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) +static inline void musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) { struct usb_device *udev = urb->dev; u16 csr; @@ -326,6 +333,12 @@ ? 1 : 0); } } +#else /* !HAVE_DATA_TOGGLE_CONTROL */ +static inline void musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) +{ + return; +} +#endif /* caller owns controller lock, irqs are blocked */ static struct musb_qh * @@ -563,7 +576,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) { u16 csr; - + /* NOTE: we know the "rx" fifo reinit never triggers for ep0. * That always uses tx_reinit since ep0 repurposes TX register * offsets; the initial SETUP packet is also a kind of OUT. @@ -586,8 +599,12 @@ if (csr & MUSB_RXCSR_RXPKTRDY) WARNING("rx%d, packet/%d ready?\n", ep->epnum, musb_readw(ep->regs, MUSB_RXCOUNT)); - +/* Modified by River. */ +#ifdef HAVE_DATA_TOGGLE_CONTROL musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); +#else + musb_h_flush_rxfifo(ep, 0); +#endif } /* target addr and (for multipoint) hub addr/port */ @@ -688,13 +705,15 @@ | MUSB_TXCSR_TXPKTRDY ); csr |= MUSB_TXCSR_MODE; - +/* Modified by River. */ +#ifdef HAVE_DATA_TOGGLE_CONTROL if (usb_gettoggle(urb->dev, qh->epnum, 1)) csr |= MUSB_TXCSR_H_WR_DATATOGGLE | MUSB_TXCSR_H_DATATOGGLE; else csr |= MUSB_TXCSR_CLRDATATOG; +#endif /* twice in case of double packet buffering */ musb_writew(epio, MUSB_TXCSR, csr); @@ -867,13 +886,18 @@ if (hw_ep->rx_reinit) { musb_rx_reinit(musb, qh, hw_ep); - +/* Modified by River. */ +#ifdef HAVE_DATA_TOGGLE_CONTROL /* init new state: toggle and NYET, maybe DMA later */ - if (usb_gettoggle(urb->dev, qh->epnum, 0)) + if (usb_gettoggle(urb->dev, qh->epnum, 0)) { csr = MUSB_RXCSR_H_WR_DATATOGGLE | MUSB_RXCSR_H_DATATOGGLE; - else + }else{ csr = 0; + } +#else + csr = 0; +#endif if (qh->type == USB_ENDPOINT_XFER_INT) csr |= MUSB_RXCSR_DISNYET; diff -ru linux-2.6/drivers/usb/musb/musbhsdma.c /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musbhsdma.c --- linux-2.6/drivers/usb/musb/musbhsdma.c 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musbhsdma.c 2009-08-12 10:39:09.000000000 +0200 @@ -294,7 +294,11 @@ return 0; } +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED +irqreturn_t dma_controller_irq(int irq, void *private_data) +#else static irqreturn_t dma_controller_irq(int irq, void *private_data) +#endif /* Defined CONFIG_USB_MUSB_HSDMA_IRQ_SHARED */ { struct musb_dma_controller *controller = (struct musb_dma_controller *)private_data; @@ -311,7 +315,14 @@ spin_lock_irqsave(&musb->lock, flags); + /* Added By River - For DMA IRQ Sharing */ +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED + int_hsdma = controller->Controller.int_hsdma; +#else int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); +#endif + /* End added */ + if (!int_hsdma) goto done; @@ -419,15 +430,32 @@ controller->Controller.channel_release = dma_channel_release; controller->Controller.channel_program = dma_channel_program; controller->Controller.channel_abort = dma_channel_abort; - + + /* Modified By River - For DMA IRQ Sharing */ +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED + irq = 0; /* Skip free_irq() when the controller will be removed. */ +#else if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, musb->controller->bus_id, &controller->Controller)) { dev_err(dev, "request_irq %d failed!\n", irq); dma_controller_destroy(&controller->Controller); return NULL; } - +#endif + /* End modified */ controller->irq = irq; return &controller->Controller; } + +/* Added by river - For DMA IRQ Sharing */ +#ifdef CONFIG_USB_MUSB_HSDMA_IRQ_SHARED +u8 dma_controller_fetch_intr(struct dma_controller *c) +{ + struct musb_dma_controller *mc = (struct musb_dma_controller *)c; /* See the defination... */ + + c->int_hsdma = musb_readb(mc->pCoreBase, MUSB_HSDMA_INTR); + + return c->int_hsdma; +} +#endif diff -ru linux-2.6/drivers/usb/musb/musb_io.h /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_io.h --- linux-2.6/drivers/usb/musb/musb_io.h 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/usb/musb/musb_io.h 2009-08-12 10:39:09.000000000 +0200 @@ -37,7 +37,7 @@ #include -#ifndef CONFIG_ARM +#if !defined(CONFIG_ARM) && !defined(CONFIG_MIPS) static inline void readsl(const void __iomem *addr, void *buf, int len) { insl((unsigned long)addr, buf, len); } static inline void readsw(const void __iomem *addr, void *buf, int len) diff -ru linux-2.6/drivers/video/Kconfig /plain/src/qi/linux-2.6.27.git.svn/drivers/video/Kconfig --- linux-2.6/drivers/video/Kconfig 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/video/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -234,6 +234,454 @@ comment "Frame buffer hardware drivers" depends on FB +/************************************************************/ + +config JZSOC_BOOT_LOGO + tristate "JZSOC boot up LOGO support" + depends on FB && JZSOC + ---help--- + If you select this function, you need put a logo file at ramdisk root directory, + whose name should be "/logo.rle" or "/logo.rgb565". + +choice + prompt "Boot LOGO File Format Select" + depends on JZSOC_BOOT_LOGO + +config FB_565RLE_LOGO + bool "Boot logo is 565REL file" + +config FB_565RGB_LOGO + bool "Boot logo a 565RGB file" + +endchoice + + +config FB_ANDROID_JZ4755SOC + tristate "JZ4755SOC ANDROID LCD controller support" + depends on FB && JZSOC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + JZSOC ANDROID LCD Controller driver support. + +config IPU_ANDROID_JZ4755 + bool "Jz4755 android ipu support" + depends on FB_ANDROID_JZ4755SOC && SOC_JZ4750D + ---help--- + Use JZ4755 Android IPU, if need, please select this. +config FB_JZ4755_ANDROID_LCD + tristate "JZ4755 Android LCD Controller support" + depends on FB_ANDROID_JZ4755SOC && SOC_JZ4750D + ---help--- + JZ4755 Android LCD Controller driver. + JZ4755 Android LCD Controller support OSD function(refer jz4755_lcdc_spec.pdf). + JZ4755 Android LCD OSD implement 2 framebuffer layers: foreground0 and foreground1. +# JZ4755 LCD driver support 2 foregrounds default. + +choice + prompt "Android LCD Type Select" + depends on FB_JZ4755_ANDROID_LCD + default FB_JZ4755_ANDROID_TFT_LCD + +config FB_JZ4755_ANDROID_TFT + bool "JZ4755 Android LCD Controller TFT LCD support" + +endchoice + +choice + depends on FB_JZ4755_ANDROID_LCD && FB_JZ4755_ANDROID_TFT + prompt "JZ4755 Android LCD TFT Panels Support" + default JZ4755_ANDROID_LCD_AUO_A043FL01V2 + ---help--- + Please select the lcd panel in you board + +config JZ4755_ANDROID_LCD_AUO_A043FL01V2 + bool "AUO A043FL01V2 TFT panel (480x272)(24bits)" + +config JZ4755_ANDROID_LCD_TOPPOLY_TD043MGEB1 + bool "TOPPOLY_TD043MGEB1 TFT panel(800x480)(24bit mode)" + +endchoice + + +config FB_ANDROID_JZSOC + tristate "JZSOC ANDROID LCD controller support" + depends on FB && JZSOC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + JZSOC ANDROID LCD Controller driver support. + +config IPU_ANDROID_JZ4750 + bool "Jz4750 android ipu support" + depends on FB_ANDROID_JZSOC && SOC_JZ4750 + ---help--- + Use JZ4750 Android IPU, if need, please select this. +config FB_JZ4750_ANDROID_LCD + tristate "JZ4750 Android LCD Controller support" + depends on FB_ANDROID_JZSOC && SOC_JZ4750 + ---help--- + JZ4750 Android LCD Controller driver. + JZ4750 Android LCD Controller support OSD function(refer jz4750_lcdc_spec.pdf). + JZ4750 Android LCD OSD implement 2 framebuffer layers: foreground0 and foreground1. +# JZ4750 LCD driver support 2 foregrounds default. + +choice + prompt "Android LCD Type Select" + depends on FB_JZ4750_ANDROID_LCD + default FB_JZ4750_ANDROID_TFT_LCD + +config FB_JZ4750_ANDROID_TFT + bool "JZ4750 Android LCD Controller TFT LCD support" + +endchoice + +choice + depends on FB_JZ4750_ANDROID_LCD && FB_JZ4750_ANDROID_TFT + prompt "JZ4750 Android LCD TFT Panels Support" + default JZ4750_ANDROID_LCD_AUO_A043FL01V2 + ---help--- + Please select the lcd panel in you board + +config JZ4750_ANDROID_LCD_AUO_A043FL01V2 + bool "AUO A043FL01V2 TFT panel (480x272)(24bits)" + +config JZ4750_ANDROID_LCD_TOPPOLY_TD043MGEB1 + bool "TOPPOLY_TD043MGEB1 TFT panel(800x480)(24bit mode)" + +endchoice + +/************************************************************/ +config FB_JZSOC + tristate "JZSOC LCD controller support" + depends on FB && JZSOC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + JZSOC LCD Controller and Smart LCD Controller driver support. + +config FB_JZ4740_SLCD + tristate "JZ4740 Smart LCD controller support" + depends on FB_JZSOC && SOC_JZ4740 + default n + ---help--- + This is the frame buffer device driver for the JZ4740 Smart LCD controller. + If select this, please set to . + +choice + depends on FB_JZ4740_SLCD + prompt "SLCD Panel" + default JZ_SLCD_LGDP4551_8BUS + +config JZ_SLCD_LGDP4551 + bool "LG LGDP4551 Smart LCD panel" + ---help--- + Driver for Smart LCD LGDP4551, 8-bit sytem interface, 16BPP. + +config JZ_SLCD_SPFD5420A + bool "SPFD5420A Smart LCD panel" + ---help--- + Driver for Smart LCD SPFD5420A 18-bit sytem interface, 18BPP. + +config JZ_SLCD_TRULY + bool "TRULY Smart LCD panel (MAX Pixels 400x240)" + ---help--- + +endchoice + +config FB_JZLCD_4730_4740 + tristate "JZ4730 JZ4740 LCD controller support" + depends on FB_JZSOC && (SOC_JZ4730 || SOC_JZ4740) + help + This is the frame buffer device driver for the JZ4730 and JZ4740 LCD controller. +config JZLCD_FRAMEBUFFER_MAX + int "Default FrameBuffer num" + depends on FB_JZLCD_4730_4740 + default "1" + ---help--- + JZ LCD driver support multi-framebuffers for video applications. +config JZLCD_FRAMEBUFFER_ROTATE_SUPPORT + bool "JZLCD FrameBuffer Rotate Support(For TEST)" + depends on FB_JZLCD_4730_4740 + default n + ---help--- + JZ LCD driver framebuffer rotate support. Rotate angle can be 0,90,180,270. + Note, this fearture is implemented by software, and will cost a lot of cpu capcity. + That is to say, if you select this function, you system will become slowly. + Rotate cost cpu about: + ratate angle 0'C: 0% cpu + ratate angle 90'C: 40% cpu + ratate angle 180'C: 20% cpu + ratate angle 270'C: 40% cpu + +config JZLCD_FRAMEBUFFER_DEFAULT_ROTATE_ANGLE + int "FrameBuffer default rotate angle" + depends on JZLCD_FRAMEBUFFER_ROTATE_SUPPORT + default 0 + ---help--- + JZ LCD driver framebuffer angle value can be: + 0: 0'C + 1: 90'C + 2: 180'C + 3: 270'C +config JZLCD_FRAMEBUFFER_BPP + int "FrameBuffer bit per pixel" + depends on JZLCD_FRAMEBUFFER_ROTATE_SUPPORT + default 32 + ---help--- + JZ LCD driver framebuffer support 8bpp, 16bpp, 32bpp +choice + depends on FB_JZLCD_4730_4740 + prompt "LCD Panel" + default JZLCD_SAMSUNG_LTP400WQF01 + +config JZLCD_SHARP_LQ035Q7 + bool "SHARP LQ035Q7 TFT panel (240x320)" + +config JZLCD_SAMSUNG_LTS350Q1 + bool "SAMSUNG LTS350Q1 TFT panel (240x320)" + +config JZLCD_SAMSUNG_LTV350QVF04 + bool "SAMSUNG LTV350QV_F04 TFT panel (320x240)" + +config JZLCD_SAMSUNG_LTP400WQF01 + bool "SAMSUNG LTP400WQF01 TFT panel (480x272)(16bits)" + +config JZLCD_SAMSUNG_LTP400WQF02 + bool "SAMSUNG LTP400WQF02 TFT panel (480x272)(18bits)" + +config JZLCD_AUO_A030FL01_V1 + bool "AUO A030FL01_V1 TFT panel (480x272)" + +config JZLCD_TRULY_TFTG320240DTSW + bool "TRULY TFTG320240DTSW TFT panel (320x240)" + +config JZLCD_TRULY_TFTG320240DTSW_SERIAL + bool "TRULY TFTG320240DTSW TFT panel (320x240)(8bit-serial mode)" + +config JZLCD_TRULY_TFTG240320UTSW_63W_E + bool "TRULY TFTG240320UTSW-63W-E TFT panel (240x320,2.5in)" + +config JZLCD_FOXCONN_PT035TN01 + bool "FOXCONN PT035TN01 TFT panel (320x240)" + +config JZLCD_INNOLUX_PT035TN01_SERIAL + bool "INNOLUX PT035TN01 TFT panel (320x240,3.5in)(8bit-serial mode)" + +config JZLCD_TOSHIBA_LTM084P363 + bool "Toshiba LTM084P363 TFT panel (800x600)" + +config JZLCD_HYNIX_HT10X21 + bool "Hynix HT10X21_300 TFT panel (1024x768)" + +config JZLCD_INNOLUX_AT080TN42 + bool "INNOLUX AT080TN42 TFT panel (800x600)" + +config JZLCD_CSTN_800x600 + bool "800x600 colorDSTN panel" + +config JZLCD_CSTN_320x240 + bool "320x240 colorSTN panel" + +config JZLCD_MSTN_480x320 + bool "480x320 monoSTN panel" + +config JZLCD_MSTN_320x240 + bool "320x240 monoSTN panel" + +config JZLCD_MSTN_240x128 + bool "240x128 monoSTN panel" + +config JZLCD_MSTN_INVERSE + bool "Use an inverse color display." + depends on (JZLCD_MSTN_480x320 || JZLCD_MSTN_240x128) + +endchoice + + +config FB_JZ4750_TVE + bool "Jz4750 TV Encode support" + depends on FB_JZSOC && (SOC_JZ4750 || SOC_JZ4750D) + ---help--- + Use JZ4750 TV Encoder controller to display on TV. + +config IPU_JZ4750 + bool "Jz4750 ipu support" + depends on FB_JZSOC && (SOC_JZ4750 || SOC_JZ4750D) + ---help--- + Use JZ4750 IPU, if need, please select this. + +config FB_JZ4750_LCD + tristate "JZ4750 LCD Controller support" + depends on FB_JZSOC && (SOC_JZ4750 || SOC_JZ4750D) + ---help--- + JZ4750 LCD Controller driver. + JZ4750 LCD Controller support OSD function(refer jz4750_lcdc_spec.pdf). + JZ4750 LCD OSD implement 2 framebuffer layers: foreground0 and foreground1. +# JZ4750 LCD driver support only foreground0 default. + +choice + depends on FB_JZ4750_LCD + prompt "JZ4750 LCD OSD Mode select" + default JZ4750_LCD_USE_FG1_ONLY + +config JZ4750_LCD_USE_FG0_ONLY + bool "Only use foreground 0" + +config JZ4750_LCD_USE_FG1_ONLY + bool "Only use foreground 1" + +config JZ4750_LCD_USE_2LAYER_FG + bool "Use two-layer foregrounds." +endchoice + + +choice + prompt "LCD Type Select" + depends on FB_JZ4750_LCD + default FB_JZ4750_TFT_LCD + +config FB_JZ4750_TFT + bool "JZ4750 LCD Controller TFT LCD support" + +config FB_JZ4750_SLCD + bool "JZ4750 LCD Controller Smart LCD support" +endchoice + +choice + depends on FB_JZ4750_LCD && FB_JZ4750_TFT + prompt "JZ4750 LCD TFT Panels Support" + default JZ4750_LCD_SAMSUNG_LTP400WQF02 + ---help--- + Please select the lcd panel in you board + +config JZ4750_LCD_SAMSUNG_LTP400WQF01 + bool "SAMSUNG LTP400WQF01 TFT panel (480x272)(16bits)" + +config JZ4750_LCD_SAMSUNG_LTP400WQF02 + bool "SAMSUNG LTP400WQF02 TFT panel (480x272)(18bits)" + +config JZ4750_LCD_AUO_A043FL01V2 + bool "AUO A043FL01V2 TFT panel (480x272)(24bits)" + +config JZ4750_LCD_FOXCONN_PT035TN01 + bool "FOXCONN PT035TN01 TFT panel (320x240,3.5in)(18bit-parallel mode)" + +config JZ4750_LCD_INNOLUX_PT035TN01_SERIAL + bool "INNOLUX PT035TN01 TFT panel (320x240,3.5in)(8bit-serial mode)" + +config JZ4750_LCD_TOPPOLY_TD025THEA7_RGB_DELTA + bool "TOPPOLY_TD025THEA7 TFT panel(320x240)(serial RGB delta mode)" + +config JZ4750_LCD_TRULY_TFTG320240DTSW_18BIT + bool "TRULY_TFTG320240DTSW TFT panel (320x240) (Parallel 18bit mode)" + +config JZ4750D_VGA_DISPLAY + depends on SOC_JZ4750D + bool "Jz4750D VGA Display, Jz4750 don't support" +endchoice + +choice + depends on FB_JZ4750_LCD && FB_JZ4750_SLCD + prompt "JZ4750 Smart LCD Panels Support" + default JZ4750_SLCD_KGM701A3_TFT_SPFD5420A + ---help--- + Please select the lcd panel in you board +config JZ4750_LCD_TRULY_TFT_GG1P0319LTSW_W + bool "TRULY_TFT_GG1P0319LTSW_W (240x320) (Smart LCD 16bit)" + +config JZ4750_SLCD_KGM701A3_TFT_SPFD5420A + bool "KGM701A3_TFT_SPFD5420A (400x240) (Smart LCD 18bit)" + +endchoice + +config FB_JZ4760_LCD + tristate "JZ4760 LCD Controller support" + depends on FB_JZSOC && SOC_JZ4760 + ---help--- + JZ4760 LCD Controller driver. + JZ4760 LCD Controller support OSD function(refer jz4760_lcdc_spec.pdf). + JZ4760 LCD OSD implement 2 framebuffer layers: foreground0 and foreground1. +# JZ4760 LCD driver support only foreground0 default. + +choice + depends on FB_JZ4760_LCD + prompt "JZ4760 LCD OSD Mode select" + default JZ4760_LCD_USE_FG1_ONLY + +config JZ4760_LCD_USE_FG0_ONLY + bool "Only use foreground 0" + +config JZ4760_LCD_USE_FG1_ONLY + bool "Only use foreground 1" + +config JZ4760_LCD_USE_2LAYER_FG + bool "Use two-layer foregrounds." +endchoice + + +choice + prompt "LCD Type Select" + depends on FB_JZ4760_LCD + default FB_JZ4760_TFT_LCD + +config FB_JZ4760_TFT + bool "JZ4760 LCD Controller TFT LCD support" + +config FB_JZ4760_SLCD + bool "JZ4760 LCD Controller Smart LCD support" +endchoice + +choice + depends on FB_JZ4760_LCD && FB_JZ4760_TFT + prompt "JZ4760 LCD TFT Panels Support" + default JZ4760_LCD_SAMSUNG_LTP400WQF02 + ---help--- + Please select the lcd panel in you board + +config JZ4760_LCD_SAMSUNG_LTP400WQF01 + bool "SAMSUNG LTP400WQF01 TFT panel (480x272)(16bits)" + +config JZ4760_LCD_SAMSUNG_LTP400WQF02 + bool "SAMSUNG LTP400WQF02 TFT panel (480x272)(18bits)" + +config JZ4760_LCD_AUO_A043FL01V2 + bool "AUO A043FL01V2 TFT panel (480x272)(24bits)" + +config JZ4760_LCD_FOXCONN_PT035TN01 + bool "FOXCONN PT035TN01 TFT panel (320x240,3.5in)(18bit-parallel mode)" + +config JZ4760_LCD_INNOLUX_PT035TN01_SERIAL + bool "INNOLUX PT035TN01 TFT panel (320x240,3.5in)(8bit-serial mode)" + +config JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA + bool "TOPPOLY_TD025THEA7 TFT panel(320x240)(serial RGB delta mode)" + +config JZ4760_LCD_TRULY_TFTG320240DTSW_18BIT + bool "TRULY_TFTG320240DTSW TFT panel (320x240) (Parallel 18bit mode)" + +config JZ4760_VGA_DISPLAY + bool "Jz4760 VGA Display, Jz4760 don't support" +endchoice + +choice + depends on FB_JZ4760_LCD && FB_JZ4760_SLCD + prompt "JZ4760 Smart LCD Panels Support" + default JZ4760_SLCD_KGM701A3_TFT_SPFD5420A + ---help--- + Please select the lcd panel in you board +config JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W + bool "TRULY_TFT_GG1P0319LTSW_W (240x320) (Smart LCD 16bit)" + +config JZ4760_SLCD_KGM701A3_TFT_SPFD5420A + bool "KGM701A3_TFT_SPFD5420A (400x240) (Smart LCD 18bit)" + +endchoice + + config FB_CIRRUS tristate "Cirrus Logic support" depends on FB && (ZORRO || PCI) diff -ru linux-2.6/drivers/video/Makefile /plain/src/qi/linux-2.6.27.git.svn/drivers/video/Makefile --- linux-2.6/drivers/video/Makefile 2009-08-17 23:58:02.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/drivers/video/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -28,6 +28,17 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o # Hardware specific drivers go first +obj-$(CONFIG_JZSOC_BOOT_LOGO) += logo.o +obj-$(CONFIG_FB_JZLCD_4730_4740) += jzlcd.o +obj-$(CONFIG_FB_JZ4740_SLCD) += jz4740_slcd.o +obj-$(CONFIG_FB_JZ4750_TFT) += jz4750_lcd.o +obj-$(CONFIG_FB_JZ4750_SLCD) += jz4750_slcd.o +obj-$(CONFIG_FB_JZ4760_TFT) += jz4760_lcd.o +obj-$(CONFIG_FB_JZ4760_SLCD) += jz4760_slcd.o +obj-$(CONFIG_FB_JZ4750_TVE) += jz4750_tve.o +obj-$(CONFIG_FB_JZ4750_ANDROID_TFT) += jz4750_android_lcd.o +obj-$(CONFIG_FB_JZ4755_ANDROID_TFT) += jz4755_android_lcd.o + obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o obj-$(CONFIG_FB_AM200EPD) += am200epd.o obj-$(CONFIG_FB_ARC) += arcfb.o diff -ru linux-2.6/include/asm-mips/bootinfo.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/bootinfo.h --- linux-2.6/include/asm-mips/bootinfo.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/bootinfo.h 2009-08-12 10:39:09.000000000 +0200 @@ -57,6 +57,15 @@ #define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */ #define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */ +/* + * Valid machtype for group INGENIC + */ +#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */ +#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */ +#define MACH_INGENIC_JZ4750 2 /* JZ4750 SOC */ +#define MACH_INGENIC_JZ4750D 3 /* JZ4750D SOC */ +#define MACH_INGENIC_JZ4760 4 /* JZ4760 SOC */ + #define CL_SIZE COMMAND_LINE_SIZE extern char *system_type; diff -ru linux-2.6/include/asm-mips/cpu.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/cpu.h --- linux-2.6/include/asm-mips/cpu.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/cpu.h 2009-08-12 10:39:09.000000000 +0200 @@ -33,8 +33,11 @@ #define PRID_COMP_TOSHIBA 0x070000 #define PRID_COMP_LSI 0x080000 #define PRID_COMP_LEXRA 0x0b0000 - - +#if defined(CONFIG_JZ_FPGA) && defined(CONFIG_SOC_JZ4760) +#define PRID_COMP_INGENIC 0xd80000 +#else +#define PRID_COMP_INGENIC 0xd00000 +#endif /* * Assigned values for the product ID register. In order to detect a * certain CPU type exactly eventually additional registers may need to @@ -114,6 +117,12 @@ #define PRID_IMP_BCM3302 0x9000 /* + * These are the PRID's for when 23:16 == PRID_COMP_INGENIC + */ + +#define PRID_IMP_JZRISC 0x0200 + +/* * Definitions for 7:0 on legacy processors */ @@ -204,6 +213,11 @@ */ CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, + /* + * Ingenic class processors + */ + CPU_JZRISC, CPU_XBURST, + CPU_LAST }; diff -ru linux-2.6/include/asm-mips/mach-generic/irq.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/mach-generic/irq.h --- linux-2.6/include/asm-mips/mach-generic/irq.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/mach-generic/irq.h 2009-08-12 10:39:09.000000000 +0200 @@ -9,7 +9,7 @@ #define __ASM_MACH_GENERIC_IRQ_H #ifndef NR_IRQS -#define NR_IRQS 128 +#define NR_IRQS 256 #endif #ifdef CONFIG_I8259 diff -ru linux-2.6/include/asm-mips/ptrace.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/ptrace.h --- linux-2.6/include/asm-mips/ptrace.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/ptrace.h 2009-08-12 10:39:09.000000000 +0200 @@ -79,7 +79,12 @@ /* * Does the process account for user or for system time? */ + +#if defined(CONFIG_JZ_TCSM) +#define user_mode(regs) ((((regs)->cp0_status & KU_MASK) == KU_USER) || (((regs)->cp0_status & 0x08000000) == 0x08000000)) +# else #define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER) +#endif #define instruction_pointer(regs) ((regs)->cp0_epc) #define profile_pc(regs) instruction_pointer(regs) diff -ru linux-2.6/include/asm-mips/r4kcache.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/r4kcache.h --- linux-2.6/include/asm-mips/r4kcache.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/r4kcache.h 2009-08-12 10:39:09.000000000 +0200 @@ -17,6 +17,58 @@ #include #include +#ifdef CONFIG_JZRISC + +#define K0_TO_K1() \ +do { \ + unsigned long __k0_addr; \ + \ + __asm__ __volatile__( \ + "la %0, 1f\n\t" \ + "or %0, %0, %1\n\t" \ + "jr %0\n\t" \ + "nop\n\t" \ + "1: nop\n" \ + : "=&r"(__k0_addr) \ + : "r" (0x20000000) ); \ +} while(0) + +#define K1_TO_K0() \ +do { \ + unsigned long __k0_addr; \ + __asm__ __volatile__( \ + "nop;nop;nop;nop;nop;nop;nop\n\t" \ + "la %0, 1f\n\t" \ + "jr %0\n\t" \ + "nop\n\t" \ + "1: nop\n" \ + : "=&r" (__k0_addr)); \ +} while (0) + +#define INVALIDATE_BTB() \ +do { \ + unsigned long tmp; \ + __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" \ + : "=&r" (tmp)); \ +} while (0) + +#define SYNC_WB() __asm__ __volatile__ ("sync") + +#else /* CONFIG_JZRISC */ + +#define K0_TO_K1() do { } while (0) +#define K1_TO_K0() do { } while (0) +#define INVALIDATE_BTB() do { } while (0) +#define SYNC_WB() do { } while (0) + +#endif /* CONFIG_JZRISC */ + /* * This macro return a properly sign-extended address suitable as base address * for indexed cache operations. Two issues here: @@ -144,6 +196,7 @@ { __iflush_prologue cache_op(Index_Invalidate_I, addr); + INVALIDATE_BTB(); __iflush_epilogue } @@ -151,6 +204,7 @@ { __dflush_prologue cache_op(Index_Writeback_Inv_D, addr); + SYNC_WB(); __dflush_epilogue } @@ -163,6 +217,7 @@ { __iflush_prologue cache_op(Hit_Invalidate_I, addr); + INVALIDATE_BTB(); __iflush_epilogue } @@ -170,6 +225,7 @@ { __dflush_prologue cache_op(Hit_Writeback_Inv_D, addr); + SYNC_WB(); __dflush_epilogue } @@ -177,6 +233,7 @@ { __dflush_prologue cache_op(Hit_Invalidate_D, addr); + SYNC_WB(); __dflush_epilogue } @@ -209,6 +266,7 @@ static inline void protected_flush_icache_line(unsigned long addr) { protected_cache_op(Hit_Invalidate_I, addr); + INVALIDATE_BTB(); } /* @@ -220,6 +278,7 @@ static inline void protected_writeback_dcache_line(unsigned long addr) { protected_cache_op(Hit_Writeback_Inv_D, addr); + SYNC_WB(); } static inline void protected_writeback_scache_line(unsigned long addr) @@ -396,20 +455,132 @@ __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16) +#ifndef CONFIG_JZRISC __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32) __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32) +#endif __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32) __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16) +#ifndef CONFIG_JZRISC __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32) +#endif __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16) __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32) __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64) __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128) +#ifdef CONFIG_JZRISC + +static inline void blast_dcache32(void) +{ + unsigned long start = INDEX_BASE; + unsigned long end = start + current_cpu_data.dcache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); + + SYNC_WB(); +} + +static inline void blast_dcache32_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + do { + cache32_unroll32(start,Hit_Writeback_Inv_D); + start += 0x400; + } while (start < end); + + SYNC_WB(); +} + +static inline void blast_dcache32_page_indexed(unsigned long page) +{ + unsigned long indexmask = current_cpu_data.dcache.waysize - 1; + unsigned long start = INDEX_BASE + (page & indexmask); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); + + SYNC_WB(); +} + +static inline void blast_icache32(void) +{ + unsigned long start = INDEX_BASE; + unsigned long end = start + current_cpu_data.icache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + K0_TO_K1(); + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); + + INVALIDATE_BTB(); + + K1_TO_K0(); +} + +static inline void blast_icache32_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + K0_TO_K1(); + + do { + cache32_unroll32(start,Hit_Invalidate_I); + start += 0x400; + } while (start < end); + + INVALIDATE_BTB(); + + K1_TO_K0(); +} + +static inline void blast_icache32_page_indexed(unsigned long page) +{ + unsigned long indexmask = current_cpu_data.icache.waysize - 1; + unsigned long start = INDEX_BASE + (page & indexmask); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + K0_TO_K1(); + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); + + INVALIDATE_BTB(); + + K1_TO_K0(); +} + +#endif /* CONFIG_JZRISC */ + /* build blast_xxx_range, protected_blast_xxx_range */ #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ @@ -431,13 +602,73 @@ __##pfx##flush_epilogue \ } +#ifndef CONFIG_JZRISC __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) +#endif __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) +#ifndef CONFIG_JZRISC __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) +#endif __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) /* blast_inv_dcache_range */ __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, ) +#ifdef CONFIG_JZRISC + +static inline void protected_blast_dcache_range(unsigned long start, + unsigned long end) +{ + unsigned long lsize = cpu_dcache_line_size(); + unsigned long addr = start & ~(lsize - 1); + unsigned long aend = (end - 1) & ~(lsize - 1); + + while (1) { + protected_cache_op(Hit_Writeback_Inv_D, addr); + if (addr == aend) + break; + addr += lsize; + } + SYNC_WB(); +} + +static inline void protected_blast_icache_range(unsigned long start, + unsigned long end) +{ + unsigned long lsize = cpu_icache_line_size(); + unsigned long addr = start & ~(lsize - 1); + unsigned long aend = (end - 1) & ~(lsize - 1); + + K0_TO_K1(); + + while (1) { + protected_cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } + INVALIDATE_BTB(); + + K1_TO_K0(); +} + +static inline void blast_dcache_range(unsigned long start, + unsigned long end) +{ + unsigned long lsize = cpu_dcache_line_size(); + unsigned long addr = start & ~(lsize - 1); + unsigned long aend = (end - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + if (addr == aend) + break; + addr += lsize; + } + SYNC_WB(); +} + +#endif /* CONFIG_JZRISC */ + #endif /* _ASM_R4KCACHE_H */ diff -ru linux-2.6/include/asm-mips/signal.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/signal.h --- linux-2.6/include/asm-mips/signal.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/signal.h 2009-08-12 10:39:09.000000000 +0200 @@ -11,6 +11,11 @@ #include +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ + #define _NSIG 128 #define _NSIG_BPW (sizeof(unsigned long) * 8) #define _NSIG_WORDS (_NSIG / _NSIG_BPW) @@ -21,6 +26,14 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ @@ -55,6 +68,9 @@ #define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */ #define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */ +/* Define these two used by Android's bionic */ +#define SIGUNUSED SIGSYS +#define SIGSTKFLT SIGEMT /* These should not be considered constants from userland. */ #define SIGRTMIN 32 @@ -111,16 +127,38 @@ #include +#ifdef __KERNEL__ + struct sigaction { unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; + __sigrestore_t sa_restorer; }; struct k_sigaction { struct sigaction sa; }; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + unsigned long sa_flags; + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long pad[3]; /* padding for sa_mask */ + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif + /* IRIX compatible stack_t */ typedef struct sigaltstack { void __user *ss_sp; diff -ru linux-2.6/include/asm-mips/suspend.h /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/suspend.h --- linux-2.6/include/asm-mips/suspend.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/asm-mips/suspend.h 2009-08-12 10:39:09.000000000 +0200 @@ -1,6 +1,11 @@ #ifndef __ASM_SUSPEND_H #define __ASM_SUSPEND_H -/* Somewhen... Maybe :-) */ +/* Jz suspend interfaces */ + +#if defined(CONFIG_PM) && defined(CONFIG_JZSOC) +extern int jz_pm_init(void); +static inline int arch_prepare_suspend(void) { return 0; } +#endif #endif /* __ASM_SUSPEND_H */ diff -ru linux-2.6/include/linux/miscdevice.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/miscdevice.h --- linux-2.6/include/linux/miscdevice.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/miscdevice.h 2009-08-12 10:39:09.000000000 +0200 @@ -30,6 +30,8 @@ #define TUN_MINOR 200 #define HPET_MINOR 228 #define KVM_MINOR 232 +#define TCSM_MINOR 233 /* JZ TCSM for multimedia */ +#define CIM_MINOR 234 /* JZ CIM for multimedia */ struct device; diff -ru linux-2.6/include/linux/mmc/host.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/mmc/host.h --- linux-2.6/include/linux/mmc/host.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/mmc/host.h 2009-08-12 10:39:09.000000000 +0200 @@ -41,6 +41,7 @@ #define MMC_BUS_WIDTH_1 0 #define MMC_BUS_WIDTH_4 2 +#define MMC_BUS_WIDTH_8 4 unsigned char timing; /* timing specification used */ @@ -159,6 +160,15 @@ struct dentry *debugfs_root; +#ifdef CONFIG_MMC_EMBEDDED_SDIO + struct { + struct sdio_cis *cis; + struct sdio_cccr *cccr; + struct sdio_embedded_func *funcs; + int num_funcs; + } embedded_sdio_data; +#endif + unsigned long private[0] ____cacheline_aligned; }; @@ -167,6 +177,14 @@ extern void mmc_remove_host(struct mmc_host *); extern void mmc_free_host(struct mmc_host *); +#ifdef CONFIG_MMC_EMBEDDED_SDIO +extern void mmc_set_embedded_sdio_data(struct mmc_host *host, + struct sdio_cis *cis, + struct sdio_cccr *cccr, + struct sdio_embedded_func *funcs, + int num_funcs); +#endif + static inline void *mmc_priv(struct mmc_host *host) { return (void *)host->private; diff -ru linux-2.6/include/linux/mtd/mtd.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/mtd.h --- linux-2.6/include/linux/mtd/mtd.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/mtd.h 2009-08-12 10:39:09.000000000 +0200 @@ -30,9 +30,9 @@ specific to any particular block. */ struct erase_info { struct mtd_info *mtd; - u_int32_t addr; - u_int32_t len; - u_int32_t fail_addr; + u_int64_t addr; + u_int64_t len; + u_int64_t fail_addr; u_long time; u_long retries; u_int dev; @@ -44,7 +44,7 @@ }; struct mtd_erase_region_info { - u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ + u_int64_t offset; /* At which this region starts, from the beginning of the MTD */ u_int32_t erasesize; /* For this region */ u_int32_t numblocks; /* Number of blocks of erasesize in this region */ unsigned long *lockmap; /* If keeping bitmap of locks */ @@ -87,10 +87,10 @@ */ struct mtd_oob_ops { mtd_oob_mode_t mode; - size_t len; - size_t retlen; - size_t ooblen; - size_t oobretlen; + size_mtd_t len; + size_mtd_t retlen; + size_mtd_t ooblen; + size_mtd_t oobretlen; uint32_t ooboffs; uint8_t *datbuf; uint8_t *oobbuf; @@ -99,7 +99,7 @@ struct mtd_info { u_char type; u_int32_t flags; - u_int32_t size; // Total size of the MTD + u_int64_t size; // Total size of the MTD /* "Major" erase size for the device. Naïve users may take this * to be the only erase size available, or may use the more detailed @@ -142,15 +142,15 @@ /* This stuff for eXecute-In-Place */ /* phys is optional and may be set to NULL */ - int (*point) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); + int (*point) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t *retlen, void **virt, resource_size_t *phys); /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ - void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + void (*unpoint) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len); - int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + int (*read) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, size_mtd_t *retlen, u_char *buf); + int (*write) (struct mtd_info *mtd, loff_mtd_t to, size_mtd_t len, size_mtd_t *retlen, const u_char *buf); /* In blackbox flight recorder like scenarios we want to make successful writes in interrupt context. panic_write() is only intended to be @@ -159,11 +159,11 @@ longer, this function can break locks and delay to ensure the write succeeds (but not sleep). */ - int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + int (*panic_write) (struct mtd_info *mtd, loff_mtd_t to, size_mtd_t len, size_mtd_t *retlen, const u_char *buf); - int (*read_oob) (struct mtd_info *mtd, loff_t from, + int (*read_oob) (struct mtd_info *mtd, loff_mtd_t from, struct mtd_oob_ops *ops); - int (*write_oob) (struct mtd_info *mtd, loff_t to, + int (*write_oob) (struct mtd_info *mtd, loff_mtd_t to, struct mtd_oob_ops *ops); /* @@ -171,33 +171,33 @@ * flash devices. The user data is one time programmable but the * factory data is read only. */ - int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); - int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); - int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); + int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_mtd_t len); + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, size_mtd_t *retlen, u_char *buf); + int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_mtd_t len); + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, size_mtd_t *retlen, u_char *buf); + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, size_mtd_t *retlen, u_char *buf); + int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len); /* kvec-based read/write methods. NB: The 'count' parameter is the number of _vectors_, each of which contains an (ofs, len) tuple. */ - int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); + int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_mtd_t to, size_mtd_t *retlen); /* Sync */ void (*sync) (struct mtd_info *mtd); /* Chip-supported device locking */ - int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); - int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); + int (*lock) (struct mtd_info *mtd, loff_mtd_t ofs, size_mtd_t len); + int (*unlock) (struct mtd_info *mtd, loff_mtd_t ofs, size_mtd_t len); /* Power Management functions */ int (*suspend) (struct mtd_info *mtd); void (*resume) (struct mtd_info *mtd); /* Bad block management functions */ - int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); - int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); + int (*block_isbad) (struct mtd_info *mtd, loff_mtd_t ofs); + int (*block_markbad) (struct mtd_info *mtd, loff_mtd_t ofs); struct notifier_block reboot_notifier; /* default mode before reboot */ @@ -242,10 +242,10 @@ extern int unregister_mtd_user (struct mtd_notifier *old); 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); int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, - unsigned long count, loff_t from, size_t *retlen); + unsigned long count, loff_mtd_t from, size_mtd_t *retlen); #ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); diff -ru linux-2.6/include/linux/mtd/nand.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/nand.h --- linux-2.6/include/linux/mtd/nand.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/nand.h 2009-08-12 10:39:09.000000000 +0200 @@ -37,14 +37,14 @@ extern void nand_wait_ready(struct mtd_info *mtd); /* The maximum number of NAND chips in an array */ -#define NAND_MAX_CHIPS 8 +#define NAND_MAX_CHIPS 4 /* This constant declares the max. oobsize / page, which * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 64 -#define NAND_MAX_PAGESIZE 2048 +#define NAND_MAX_OOBSIZE 256 +#define NAND_MAX_PAGESIZE 8192 /* * Constants for hardware specific CLE/ALE/NCE function @@ -54,6 +54,10 @@ */ /* Select the chip by setting nCE to low */ #define NAND_NCE 0x01 +#define NAND_NCE1 0x08 +#define NAND_NCE2 0x10 +#define NAND_NCE3 0x20 +#define NAND_NCE4 0x40 /* Select the command latch by setting CLE to high */ #define NAND_CLE 0x02 /* Select the address latch by setting ALE to high */ @@ -377,8 +381,8 @@ void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); void (*select_chip)(struct mtd_info *mtd, int chip); - int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); - int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); + int (*block_bad)(struct mtd_info *mtd, loff_mtd_t ofs, int getchip); + int (*block_markbad)(struct mtd_info *mtd, loff_mtd_t ofs); void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl); int (*dev_ready)(struct mtd_info *mtd); @@ -398,12 +402,14 @@ int bbt_erase_shift; int chip_shift; int numchips; - unsigned long chipsize; + u64 chipsize; int pagemask; int pagebuf; int subpagesize; uint8_t cellinfo; int badblockpos; + int realplanenum; /* number of planes the NAND has */ + int planenum; /* number of planes operating synchronously */ nand_state_t state; @@ -455,7 +461,7 @@ char *name; int id; unsigned long pagesize; - unsigned long chipsize; + u64 chipsize; unsigned long erasesize; unsigned long options; }; @@ -543,13 +549,13 @@ #define NAND_BBT_SCAN_MAXBLOCKS 4 extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); +extern int nand_update_bbt(struct mtd_info *mtd, loff_mtd_t offs); extern int nand_default_bbt(struct mtd_info *mtd); -extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); +extern int nand_isbad_bbt(struct mtd_info *mtd, loff_mtd_t offs, int allowbbt); extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt); -extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, uint8_t * buf); +extern int nand_do_read(struct mtd_info *mtd, loff_mtd_t from, size_mtd_t len, + size_mtd_t * retlen, uint8_t * buf); /* * Constants for oob configuration diff -ru linux-2.6/include/linux/mtd/partitions.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/partitions.h --- linux-2.6/include/linux/mtd/partitions.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/mtd/partitions.h 2009-08-12 10:39:09.000000000 +0200 @@ -36,8 +36,9 @@ struct mtd_partition { char *name; /* identifier string */ - u_int32_t size; /* partition size */ - u_int32_t offset; /* offset within the master MTD space */ + u_int64_t size; /* partition size */ + u_int64_t offset; /* offset within the master MTD space */ + char use_planes; /* flag to specify whether multiple planes of NAND is used in the partition */ u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ struct mtd_info **mtdp; /* pointer to store the MTD object */ diff -ru linux-2.6/include/linux/power_supply.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/power_supply.h --- linux-2.6/include/linux/power_supply.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/power_supply.h 2009-08-12 10:39:09.000000000 +0200 @@ -86,7 +86,8 @@ POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_ENERGY_AVG, POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ - POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TEMP, /* for android, but not supported */ + POWER_SUPPLY_PROP_VOL, /* for android, but not supported */ POWER_SUPPLY_PROP_TEMP_AMBIENT, POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, diff -ru linux-2.6/include/linux/suspend.h /plain/src/qi/linux-2.6.27.git.svn/include/linux/suspend.h --- linux-2.6/include/linux/suspend.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/linux/suspend.h 2009-08-12 10:39:09.000000000 +0200 @@ -1,9 +1,11 @@ #ifndef _LINUX_SUSPEND_H #define _LINUX_SUSPEND_H -#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) +#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32)\ + || defined(CONFIG_PPC64) || defined(CONFIG_MIPS) #include #endif + #include #include #include @@ -245,6 +247,9 @@ void save_processor_state(void); void restore_processor_state(void); +//void save_processor_state(void){} +//void restore_processor_state(void){} + /* kernel/power/main.c */ extern int register_pm_notifier(struct notifier_block *nb); extern int unregister_pm_notifier(struct notifier_block *nb); diff -ru linux-2.6/include/mtd/mtd-abi.h /plain/src/qi/linux-2.6.27.git.svn/include/mtd/mtd-abi.h --- linux-2.6/include/mtd/mtd-abi.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/mtd/mtd-abi.h 2009-08-12 10:39:09.000000000 +0200 @@ -1,13 +1,23 @@ /* + * $Id: mtd-abi.h,v 1.1.1.1 2008-03-28 04:29:21 jlwei 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 { - uint32_t start; - uint32_t length; + uint64_t start; + uint64_t length; }; struct mtd_oob_buf { @@ -16,6 +26,14 @@ 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 @@ -50,7 +68,7 @@ struct mtd_info_user { uint8_t type; uint32_t flags; - uint32_t size; // Total size of the MTD + 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) @@ -61,7 +79,7 @@ }; struct region_info_user { - uint32_t offset; /* At which this region starts, + 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 */ @@ -84,8 +102,8 @@ #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_t) -#define MEMSETBADBLOCK _IOW('M', 12, loff_t) +#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) @@ -93,6 +111,7 @@ #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) #define MTDREFRESH _IO('M', 23) /* @@ -102,7 +121,8 @@ uint32_t useecc; uint32_t eccbytes; uint32_t oobfree[8][2]; - uint32_t eccpos[32]; + uint32_t eccpos[104]; /* more fields(13*8) are required for + * 8-bit BCH ECC and 4KB pagesize nand, by Regen */ }; struct nand_oobfree { @@ -117,7 +137,7 @@ */ struct nand_ecclayout { uint32_t eccbytes; - uint32_t eccpos[64]; + uint32_t eccpos[128]; uint32_t oobavail; struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; }; diff -ru linux-2.6/include/sound/pcm.h /plain/src/qi/linux-2.6.27.git.svn/include/sound/pcm.h --- linux-2.6/include/sound/pcm.h 2009-08-17 23:58:03.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/include/sound/pcm.h 2009-08-12 10:39:09.000000000 +0200 @@ -107,23 +107,23 @@ #define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */ #define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */ #define SNDRV_PCM_RATE_11025 (1<<2) /* 11025Hz */ -#define SNDRV_PCM_RATE_16000 (1<<3) /* 16000Hz */ -#define SNDRV_PCM_RATE_22050 (1<<4) /* 22050Hz */ -#define SNDRV_PCM_RATE_32000 (1<<5) /* 32000Hz */ -#define SNDRV_PCM_RATE_44100 (1<<6) /* 44100Hz */ -#define SNDRV_PCM_RATE_48000 (1<<7) /* 48000Hz */ -#define SNDRV_PCM_RATE_64000 (1<<8) /* 64000Hz */ -#define SNDRV_PCM_RATE_88200 (1<<9) /* 88200Hz */ -#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ -#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ -#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */ +#define SNDRV_PCM_RATE_12000 (1<<3) /* 12000Hz */ +#define SNDRV_PCM_RATE_16000 (1<<4) /* 16000Hz */ +#define SNDRV_PCM_RATE_22050 (1<<5) /* 22050Hz */ +#define SNDRV_PCM_RATE_24000 (1<<6) /* 24000Hz */ +#define SNDRV_PCM_RATE_32000 (1<<7) /* 32000Hz */ +#define SNDRV_PCM_RATE_44100 (1<<8) /* 44100Hz */ +#define SNDRV_PCM_RATE_48000 (1<<9) /* 48000Hz */ +#define SNDRV_PCM_RATE_64000 (1<<10) /* 64000Hz */ +#define SNDRV_PCM_RATE_88200 (1<<11) /* 88200Hz */ +#define SNDRV_PCM_RATE_96000 (1<<12) /* 96000Hz */ +#define SNDRV_PCM_RATE_176400 (1<<13) /* 176400Hz */ +#define SNDRV_PCM_RATE_192000 (1<<14) /* 192000Hz */ #define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ #define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ -#define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\ - SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\ - SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100) +#define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|SNDRV_PCM_RATE_12000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_24000|SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100) #define SNDRV_PCM_RATE_8000_48000 (SNDRV_PCM_RATE_8000_44100|SNDRV_PCM_RATE_48000) #define SNDRV_PCM_RATE_8000_96000 (SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_64000|\ SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000) diff -ru linux-2.6/sound/core/pcm_lib.c /plain/src/qi/linux-2.6.27.git.svn/sound/core/pcm_lib.c --- linux-2.6/sound/core/pcm_lib.c 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/core/pcm_lib.c 2009-08-12 10:39:09.000000000 +0200 @@ -1875,6 +1875,7 @@ return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } +#if 0 snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size) { struct snd_pcm_runtime *runtime; @@ -1892,6 +1893,99 @@ return -EINVAL; return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); } +#else +snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size) +{ + struct snd_pcm_runtime *runtime; + int nonblock; + + snd_pcm_sframes_t tmp_frames; + snd_pcm_sframes_t final_frames; + int channels; + + snd_assert(substream != NULL, return -ENXIO); + runtime = substream->runtime; + snd_assert(runtime != NULL, return -ENXIO); + snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + + nonblock = !!(substream->f_flags & O_NONBLOCK); + if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) + return -EINVAL; + + /* + * mono capture process for no mono codec + * function codec such as ipcood and dlv + */ + + tmp_frames = snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); + + channels = runtime->channels; + + if (channels == 1) { + short *tmpbuf = kcalloc(tmp_frames, sizeof(short), GFP_KERNEL); + short *src, *dst, *end; + + memcpy(tmpbuf, buf, frames_to_bytes(runtime, tmp_frames)); + + src = (short *)buf; + dst = (short *)tmpbuf; + end = dst + tmp_frames - 1; + + src++; + dst++; + dst++; + final_frames = 1; + while (dst <= end) { + *src = *dst; + final_frames++; + src++; + dst++; + dst++; + } + tmp_frames = final_frames; + kfree(tmpbuf); + +#if 0 + /* when i have time, i will try the code, no kcalloc */ + snd_assert(runtime->dma_area, return -EFAULT); + if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) + return -EFAULT; + + unsigned int up_bytes = frames_to_bytes(runtime, frames); + + int while_cnt = 4; + int while_all = up_bytes - 2; + + while (while_cnt <= while_all) { + //printk("[%d = %d]\n",(while_cnt/2),while_cnt); + buf[(while_cnt/2)] = buf[while_cnt]; + //printk("[%d = %d]\n",((while_cnt/2)+1),(while_cnt+1)); + buf[((while_cnt/2)+1)] = buf[(while_cnt+1)]; + while_cnt += 4; +#if 0 + buf[2] = buf[4]; + buf[3] = buf[5]; + + buf[4] = buf[8]; + buf[5] = buf[9]; + + buf[6] = buf[12]; + buf[7] = buf[13]; + + buf[8] = buf[16]; + buf[9] = buf[17]; +#endif + } + /* when i have time, i will try the code, no kcalloc */ +#endif + + } + + return tmp_frames; +} +#endif EXPORT_SYMBOL(snd_pcm_lib_read); diff -ru linux-2.6/sound/core/pcm_native.c /plain/src/qi/linux-2.6.27.git.svn/sound/core/pcm_native.c --- linux-2.6/sound/core/pcm_native.c 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/core/pcm_native.c 2009-08-12 10:39:09.000000000 +0200 @@ -1756,12 +1756,13 @@ return snd_interval_refine(hw_param_interval(params, rule->var), &t); } -#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 14 #error "Change this table" #endif -static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, - 48000, 64000, 88200, 96000, 176400, 192000 }; +static unsigned int rates[] = { 5512, 8000, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, + 176400, 192000 }; const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { .count = ARRAY_SIZE(rates), @@ -1772,9 +1773,17 @@ struct snd_pcm_hw_rule *rule) { struct snd_pcm_hardware *hw = rule->private; +#if 0 return snd_interval_list(hw_param_interval(params, rule->var), snd_pcm_known_rates.count, snd_pcm_known_rates.list, hw->rates); +#else + //printk("hw->rates=0x%08x\n",hw->rates);//0x3b6 + hw->rates = 0x3fe;//12KHz and 24KHz bits are all zero,you need set 1 + return snd_interval_list(hw_param_interval(params, rule->var), + snd_pcm_known_rates.count, + snd_pcm_known_rates.list, hw->rates); +#endif } static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params, diff -ru linux-2.6/sound/soc/codecs/Kconfig /plain/src/qi/linux-2.6.27.git.svn/sound/soc/codecs/Kconfig --- linux-2.6/sound/soc/codecs/Kconfig 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/soc/codecs/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -50,3 +50,15 @@ config SND_SOC_TLV320AIC3X tristate depends on I2C + +config SND_SOC_ICODEC + tristate "Jz4740 internal codec" + depends on SND_SOC && SND_JZ4740_SOC_PAVO && SND_JZ4740_SOC_I2S + help + Say Y if you want to use internal codec on Ingenic Jz4740 PAVO board. + +config SND_SOC_DLV + tristate "Jz4750 internal codec" + depends on SND_SOC && SND_JZ4750_SOC_APUS && SND_JZ4750_SOC_I2S + help + Say Y if you want to use internal codec on Ingenic Jz4750 APUS board. \ No newline at end of file diff -ru linux-2.6/sound/soc/codecs/Makefile /plain/src/qi/linux-2.6.27.git.svn/sound/soc/codecs/Makefile --- linux-2.6/sound/soc/codecs/Makefile 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/soc/codecs/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -10,6 +10,8 @@ snd-soc-wm9713-objs := wm9713.o snd-soc-cs4270-objs := cs4270.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o +snd-soc-jzcodec-objs := jzcodec.o +snd-soc-jzdlv-objs := jzdlv.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o @@ -23,3 +25,5 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o +obj-$(CONFIG_SND_SOC_ICODEC) += snd-soc-jzcodec.o +obj-$(CONFIG_SND_SOC_DLV) += snd-soc-jzdlv.o \ No newline at end of file diff -ru linux-2.6/sound/soc/Kconfig /plain/src/qi/linux-2.6.27.git.svn/sound/soc/Kconfig --- linux-2.6/sound/soc/Kconfig 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/soc/Kconfig 2009-08-12 10:39:09.000000000 +0200 @@ -31,6 +31,8 @@ source "sound/soc/fsl/Kconfig" source "sound/soc/davinci/Kconfig" source "sound/soc/omap/Kconfig" +source "sound/soc/jz4740/Kconfig" +source "sound/soc/jz4750/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff -ru linux-2.6/sound/soc/Makefile /plain/src/qi/linux-2.6.27.git.svn/sound/soc/Makefile --- linux-2.6/sound/soc/Makefile 2009-08-17 23:58:04.000000000 +0200 +++ /plain/src/qi/linux-2.6.27.git.svn/sound/soc/Makefile 2009-08-12 10:39:09.000000000 +0200 @@ -2,4 +2,4 @@ obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ -obj-$(CONFIG_SND_SOC) += omap/ au1x/ +obj-$(CONFIG_SND_SOC) += omap/ au1x/ jz4740/ jz4750/