aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 20:46:21 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 20:46:21 -0400
commit70ac4385a13f78bc478f26d317511893741b05bd (patch)
treedafc7f3018295fc4ee00339889e4f35d5b9d7743
parentd59bf96cdde5b874a57bfd1425faa45da915d0b7 (diff)
parent077e98945db7e54a9865b5f29a1f02f531eca414 (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts: include/linux/nfs_fs.h Fixed up conflict with kernel header updates.
-rw-r--r--Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen61
-rw-r--r--Documentation/arm/Sharp-LH/LCDPanels59
-rw-r--r--Documentation/filesystems/inotify.txt130
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/head.S4
-rw-r--r--arch/arm/configs/lpd7a400_defconfig135
-rw-r--r--arch/arm/configs/lpd7a404_defconfig430
-rw-r--r--arch/arm/configs/pnx4008_defconfig2072
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/irq.c4
-rw-r--r--arch/arm/kernel/time.c24
-rw-r--r--arch/arm/mach-lh7a40x/Kconfig5
-rw-r--r--arch/arm/mach-lh7a40x/Makefile19
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c200
-rw-r--r--arch/arm/mach-lh7a40x/clcd.c241
-rw-r--r--arch/arm/mach-lh7a40x/clocks.c199
-rw-r--r--arch/arm/mach-lh7a40x/common.h1
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a404.c17
-rw-r--r--arch/arm/mach-lh7a40x/lcd-panel.h346
-rw-r--r--arch/arm/mach-lh7a40x/ssp-cpld.c343
-rw-r--r--arch/arm/mach-lh7a40x/time.c4
-rw-r--r--arch/arm/mach-pnx4008/Makefile12
-rw-r--r--arch/arm/mach-pnx4008/Makefile.boot4
-rw-r--r--arch/arm/mach-pnx4008/clock.c1010
-rw-r--r--arch/arm/mach-pnx4008/clock.h43
-rw-r--r--arch/arm/mach-pnx4008/core.c207
-rw-r--r--arch/arm/mach-pnx4008/dma.c1109
-rw-r--r--arch/arm/mach-pnx4008/gpio.c330
-rw-r--r--arch/arm/mach-pnx4008/irq.c121
-rw-r--r--arch/arm/mach-pnx4008/pm.c184
-rw-r--r--arch/arm/mach-pnx4008/serial.c69
-rw-r--r--arch/arm/mach-pnx4008/sleep.S196
-rw-r--r--arch/arm/mach-pnx4008/time.c141
-rw-r--r--arch/arm/mach-pxa/lubbock.c84
-rw-r--r--arch/arm/mach-s3c2410/Kconfig26
-rw-r--r--arch/arm/mach-s3c2410/Makefile10
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/common-smdk.c65
-rw-r--r--arch/arm/mach-s3c2410/cpu.c77
-rw-r--r--arch/arm/mach-s3c2410/cpu.h7
-rw-r--r--arch/arm/mach-s3c2410/devs.c78
-rw-r--r--arch/arm/mach-s3c2410/devs.h8
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-osiris.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2410/pm.c4
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c85
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-irq.c77
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c234
-rw-r--r--arch/arm/mach-s3c2410/s3c2442-clock.c171
-rw-r--r--arch/arm/mach-s3c2410/s3c2442.c52
-rw-r--r--arch/arm/mach-s3c2410/s3c2442.h17
-rw-r--r--arch/arm/mach-s3c2410/s3c244x-irq.c142
-rw-r--r--arch/arm/mach-s3c2410/s3c244x.c182
-rw-r--r--arch/arm/mach-s3c2410/s3c244x.h25
-rw-r--r--arch/arm/mach-s3c2410/sleep.S2
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/um/kernel/physmem.c2
-rw-r--r--block/as-iosched.c5
-rw-r--r--block/cfq-iosched.c8
-rw-r--r--block/deadline-iosched.c5
-rw-r--r--drivers/char/rio/daemon.h12
-rw-r--r--drivers/char/rio/func.h25
-rw-r--r--drivers/char/rio/host.h16
-rw-r--r--drivers/char/rio/port.h16
-rw-r--r--drivers/char/rio/rio.h4
-rw-r--r--drivers/char/rio/rio_linux.c31
-rw-r--r--drivers/char/rio/rio_linux.h20
-rw-r--r--drivers/char/rio/rioboot.c54
-rw-r--r--drivers/char/rio/riocmd.c36
-rw-r--r--drivers/char/rio/rioctrl.c182
-rw-r--r--drivers/char/rio/rioinit.c28
-rw-r--r--drivers/char/rio/riointr.c42
-rw-r--r--drivers/char/rio/rioparam.c28
-rw-r--r--drivers/char/rio/rioroute.c22
-rw-r--r--drivers/char/rio/riotable.c24
-rw-r--r--drivers/char/rio/riotty.c2
-rw-r--r--drivers/char/rio/unixrup.h2
-rw-r--r--drivers/mmc/sdhci.c2
-rw-r--r--drivers/mtd/Kconfig4
-rw-r--r--drivers/mtd/chips/Kconfig1
-rw-r--r--drivers/mtd/chips/Makefile7
-rw-r--r--drivers/mtd/chips/amd_flash.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c474
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c22
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c22
-rw-r--r--drivers/mtd/chips/cfi_probe.c8
-rw-r--r--drivers/mtd/chips/gen_probe.c45
-rw-r--r--drivers/mtd/chips/map_ram.c2
-rw-r--r--drivers/mtd/chips/map_rom.c4
-rw-r--r--drivers/mtd/chips/sharp.c1
-rw-r--r--drivers/mtd/devices/Kconfig6
-rw-r--r--drivers/mtd/devices/Makefile7
-rw-r--r--drivers/mtd/devices/block2mtd.c27
-rw-r--r--drivers/mtd/devices/doc2000.c129
-rw-r--r--drivers/mtd/devices/doc2001.c60
-rw-r--r--drivers/mtd/devices/doc2001plus.c60
-rw-r--r--drivers/mtd/devices/docprobe.c26
-rw-r--r--drivers/mtd/devices/lart.c1
-rw-r--r--drivers/mtd/devices/m25p80.c1
-rw-r--r--drivers/mtd/devices/ms02-nv.c2
-rw-r--r--drivers/mtd/devices/mtdram.c1
-rw-r--r--drivers/mtd/devices/phram.c16
-rw-r--r--drivers/mtd/devices/slram.c3
-rw-r--r--drivers/mtd/inftlcore.c192
-rw-r--r--drivers/mtd/inftlmount.c60
-rw-r--r--drivers/mtd/maps/Kconfig11
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c4
-rw-r--r--drivers/mtd/maps/dbox2-flash.c2
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c2
-rw-r--r--drivers/mtd/maps/nettel.c4
-rw-r--r--drivers/mtd/maps/pcmciamtd.c1
-rw-r--r--drivers/mtd/maps/physmap.c255
-rw-r--r--drivers/mtd/mtdblock.c16
-rw-r--r--drivers/mtd/mtdblock_ro.c4
-rw-r--r--drivers/mtd/mtdchar.c327
-rw-r--r--drivers/mtd/mtdconcat.c335
-rw-r--r--drivers/mtd/mtdcore.c33
-rw-r--r--drivers/mtd/mtdpart.c171
-rw-r--r--drivers/mtd/nand/Kconfig57
-rw-r--r--drivers/mtd/nand/Makefile4
-rw-r--r--drivers/mtd/nand/ams-delta.c237
-rw-r--r--drivers/mtd/nand/au1550nd.c321
-rw-r--r--drivers/mtd/nand/autcpu12.c125
-rw-r--r--drivers/mtd/nand/cs553x_nand.c353
-rw-r--r--drivers/mtd/nand/diskonchip.c530
-rw-r--r--drivers/mtd/nand/edb7312.c97
-rw-r--r--drivers/mtd/nand/h1910.c98
-rw-r--r--drivers/mtd/nand/nand_base.c3249
-rw-r--r--drivers/mtd/nand/nand_bbt.c502
-rw-r--r--drivers/mtd/nand/nand_ecc.c227
-rw-r--r--drivers/mtd/nand/nand_ids.c177
-rw-r--r--drivers/mtd/nand/nandsim.c95
-rw-r--r--drivers/mtd/nand/ndfc.c311
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c256
-rw-r--r--drivers/mtd/nand/rtc_from4.c351
-rw-r--r--drivers/mtd/nand/s3c2410.c252
-rw-r--r--drivers/mtd/nand/sharpsl.c146
-rw-r--r--drivers/mtd/nand/spia.c101
-rw-r--r--drivers/mtd/nand/toto.c121
-rw-r--r--drivers/mtd/nand/ts7250.c206
-rw-r--r--drivers/mtd/nftlcore.c221
-rw-r--r--drivers/mtd/nftlmount.c91
-rw-r--r--drivers/mtd/onenand/Kconfig14
-rw-r--r--drivers/mtd/onenand/onenand_base.c718
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c9
-rw-r--r--drivers/mtd/redboot.c18
-rw-r--r--drivers/mtd/rfd_ftl.c48
-rw-r--r--drivers/net/smc91x.h44
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/s390/crypto/z90crypt.h185
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/serial_lh7a40x.c13
-rw-r--r--drivers/video/Kconfig63
-rw-r--r--fs/Kconfig62
-rw-r--r--fs/Makefile1
-rw-r--r--fs/eventpoll.c6
-rw-r--r--fs/exec.c6
-rw-r--r--fs/ext3/dir.c2
-rw-r--r--fs/inotify.c991
-rw-r--r--fs/inotify_user.c719
-rw-r--r--fs/jffs/intrep.c15
-rw-r--r--fs/jffs2/Makefile3
-rw-r--r--fs/jffs2/README.Locking21
-rw-r--r--fs/jffs2/acl.c485
-rw-r--r--fs/jffs2/acl.h45
-rw-r--r--fs/jffs2/build.c2
-rw-r--r--fs/jffs2/compr.c2
-rw-r--r--fs/jffs2/compr.h4
-rw-r--r--fs/jffs2/debug.c14
-rw-r--r--fs/jffs2/debug.h6
-rw-r--r--fs/jffs2/dir.c121
-rw-r--r--fs/jffs2/erase.c56
-rw-r--r--fs/jffs2/file.c35
-rw-r--r--fs/jffs2/fs.c63
-rw-r--r--fs/jffs2/gc.c131
-rw-r--r--fs/jffs2/histo.h3
-rw-r--r--fs/jffs2/jffs2_fs_i.h (renamed from include/linux/jffs2_fs_i.h)5
-rw-r--r--fs/jffs2/jffs2_fs_sb.h (renamed from include/linux/jffs2_fs_sb.h)13
-rw-r--r--fs/jffs2/malloc.c127
-rw-r--r--fs/jffs2/nodelist.c183
-rw-r--r--fs/jffs2/nodelist.h190
-rw-r--r--fs/jffs2/nodemgmt.c196
-rw-r--r--fs/jffs2/os-linux.h23
-rw-r--r--fs/jffs2/readinode.c137
-rw-r--r--fs/jffs2/scan.c442
-rw-r--r--fs/jffs2/security.c82
-rw-r--r--fs/jffs2/summary.c484
-rw-r--r--fs/jffs2/summary.h64
-rw-r--r--fs/jffs2/super.c20
-rw-r--r--fs/jffs2/symlink.c7
-rw-r--r--fs/jffs2/wbuf.c968
-rw-r--r--fs/jffs2/write.c147
-rw-r--r--fs/jffs2/xattr.c1238
-rw-r--r--fs/jffs2/xattr.h116
-rw-r--r--fs/jffs2/xattr_trusted.c52
-rw-r--r--fs/jffs2/xattr_user.c52
-rw-r--r--fs/namei.c2
-rw-r--r--fs/open.c4
-rw-r--r--fs/proc/base.c5
-rw-r--r--fs/xattr.c4
-rw-r--r--include/acpi/platform/aclinux.h1
-rw-r--r--include/acpi/processor.h1
-rw-r--r--include/asm-alpha/bitops.h1
-rw-r--r--include/asm-alpha/cache.h1
-rw-r--r--include/asm-alpha/cacheflush.h1
-rw-r--r--include/asm-alpha/core_cia.h1
-rw-r--r--include/asm-alpha/core_t2.h1
-rw-r--r--include/asm-alpha/dma-mapping.h1
-rw-r--r--include/asm-alpha/dma.h1
-rw-r--r--include/asm-alpha/floppy.h1
-rw-r--r--include/asm-alpha/hardirq.h1
-rw-r--r--include/asm-alpha/hw_irq.h1
-rw-r--r--include/asm-alpha/ide.h1
-rw-r--r--include/asm-alpha/io.h1
-rw-r--r--include/asm-alpha/irq.h1
-rw-r--r--include/asm-alpha/kmap_types.h1
-rw-r--r--include/asm-alpha/machvec.h1
-rw-r--r--include/asm-alpha/mmu_context.h1
-rw-r--r--include/asm-alpha/mmzone.h1
-rw-r--r--include/asm-alpha/page.h1
-rw-r--r--include/asm-alpha/param.h1
-rw-r--r--include/asm-alpha/pgalloc.h1
-rw-r--r--include/asm-alpha/pgtable.h1
-rw-r--r--include/asm-alpha/serial.h1
-rw-r--r--include/asm-alpha/smp.h1
-rw-r--r--include/asm-alpha/spinlock.h1
-rw-r--r--include/asm-alpha/system.h1
-rw-r--r--include/asm-alpha/tlbflush.h1
-rw-r--r--include/asm-alpha/unistd.h7
-rw-r--r--include/asm-arm/apm.h1
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h1
-rw-r--r--include/asm-arm/arch-cl7500/acornfb.h1
-rw-r--r--include/asm-arm/arch-clps711x/hardware.h1
-rw-r--r--include/asm-arm/arch-clps711x/memory.h1
-rw-r--r--include/asm-arm/arch-clps711x/uncompress.h1
-rw-r--r--include/asm-arm/arch-ebsa285/hardware.h1
-rw-r--r--include/asm-arm/arch-ebsa285/memory.h1
-rw-r--r--include/asm-arm/arch-ebsa285/vmalloc.h1
-rw-r--r--include/asm-arm/arch-integrator/smp.h1
-rw-r--r--include/asm-arm/arch-iop3xx/memory.h1
-rw-r--r--include/asm-arm/arch-iop3xx/timex.h1
-rw-r--r--include/asm-arm/arch-iop3xx/uncompress.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/dma.h1
-rw-r--r--include/asm-arm/arch-lh7a40x/clocks.h20
-rw-r--r--include/asm-arm/arch-lh7a40x/constants.h9
-rw-r--r--include/asm-arm/arch-lh7a40x/dma.h79
-rw-r--r--include/asm-arm/arch-lh7a40x/entry-macro.S70
-rw-r--r--include/asm-arm/arch-lh7a40x/hardware.h4
-rw-r--r--include/asm-arm/arch-lh7a40x/irqs.h8
-rw-r--r--include/asm-arm/arch-lh7a40x/registers.h65
-rw-r--r--include/asm-arm/arch-lh7a40x/ssp.h71
-rw-r--r--include/asm-arm/arch-lh7a40x/uncompress.h2
-rw-r--r--include/asm-arm/arch-omap/board.h1
-rw-r--r--include/asm-arm/arch-omap/hardware.h1
-rw-r--r--include/asm-arm/arch-omap/system.h1
-rw-r--r--include/asm-arm/arch-omap/uncompress.h1
-rw-r--r--include/asm-arm/arch-pnx4008/clock.h61
-rw-r--r--include/asm-arm/arch-pnx4008/debug-macro.S27
-rw-r--r--include/asm-arm/arch-pnx4008/dma.h162
-rw-r--r--include/asm-arm/arch-pnx4008/entry-macro.S121
-rw-r--r--include/asm-arm/arch-pnx4008/gpio.h139
-rw-r--r--include/asm-arm/arch-pnx4008/hardware.h32
-rw-r--r--include/asm-arm/arch-pnx4008/io.h21
-rw-r--r--include/asm-arm/arch-pnx4008/irq.h42
-rw-r--r--include/asm-arm/arch-pnx4008/irqs.h215
-rw-r--r--include/asm-arm/arch-pnx4008/memory.h24
-rw-r--r--include/asm-arm/arch-pnx4008/param.h21
-rw-r--r--include/asm-arm/arch-pnx4008/platform.h69
-rw-r--r--include/asm-arm/arch-pnx4008/pm.h62
-rw-r--r--include/asm-arm/arch-pnx4008/system.h38
-rw-r--r--include/asm-arm/arch-pnx4008/timex.h73
-rw-r--r--include/asm-arm/arch-pnx4008/uncompress.h46
-rw-r--r--include/asm-arm/arch-pnx4008/vmalloc.h20
-rw-r--r--include/asm-arm/arch-pxa/idp.h1
-rw-r--r--include/asm-arm/arch-pxa/irqs.h1
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h1
-rw-r--r--include/asm-arm/arch-pxa/timex.h1
-rw-r--r--include/asm-arm/arch-realview/smp.h1
-rw-r--r--include/asm-arm/arch-s3c2410/dma.h1
-rw-r--r--include/asm-arm/arch-s3c2410/map.h11
-rw-r--r--include/asm-arm/arch-s3c2410/regs-clock.h6
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h5
-rw-r--r--include/asm-arm/arch-s3c2410/uncompress.h6
-rw-r--r--include/asm-arm/arch-sa1100/assabet.h1
-rw-r--r--include/asm-arm/arch-sa1100/cerf.h1
-rw-r--r--include/asm-arm/arch-sa1100/collie.h1
-rw-r--r--include/asm-arm/arch-sa1100/dma.h1
-rw-r--r--include/asm-arm/arch-sa1100/hardware.h1
-rw-r--r--include/asm-arm/arch-sa1100/ide.h1
-rw-r--r--include/asm-arm/arch-sa1100/irqs.h1
-rw-r--r--include/asm-arm/arch-sa1100/memory.h1
-rw-r--r--include/asm-arm/arch-sa1100/system.h1
-rw-r--r--include/asm-arm/atomic.h1
-rw-r--r--include/asm-arm/bug.h1
-rw-r--r--include/asm-arm/cacheflush.h1
-rw-r--r--include/asm-arm/cpu.h1
-rw-r--r--include/asm-arm/dma-mapping.h1
-rw-r--r--include/asm-arm/dma.h1
-rw-r--r--include/asm-arm/elf.h1
-rw-r--r--include/asm-arm/fpstate.h1
-rw-r--r--include/asm-arm/glue.h1
-rw-r--r--include/asm-arm/hardirq.h1
-rw-r--r--include/asm-arm/hardware/dec21285.h1
-rw-r--r--include/asm-arm/hardware/iomd.h1
-rw-r--r--include/asm-arm/leds.h1
-rw-r--r--include/asm-arm/mach/serial_at91rm9200.h1
-rw-r--r--include/asm-arm/mach/serial_sa1100.h1
-rw-r--r--include/asm-arm/mach/time.h1
-rw-r--r--include/asm-arm/memory.h1
-rw-r--r--include/asm-arm/page.h1
-rw-r--r--include/asm-arm/pci.h1
-rw-r--r--include/asm-arm/proc-fns.h1
-rw-r--r--include/asm-arm/ptrace.h1
-rw-r--r--include/asm-arm/smp.h1
-rw-r--r--include/asm-arm/system.h1
-rw-r--r--include/asm-arm/tlbflush.h1
-rw-r--r--include/asm-arm/unistd.h10
-rw-r--r--include/asm-arm26/atomic.h1
-rw-r--r--include/asm-arm26/bug.h1
-rw-r--r--include/asm-arm26/dma.h1
-rw-r--r--include/asm-arm26/hardirq.h1
-rw-r--r--include/asm-arm26/hardware.h1
-rw-r--r--include/asm-arm26/io.h1
-rw-r--r--include/asm-arm26/leds.h1
-rw-r--r--include/asm-arm26/mach-types.h1
-rw-r--r--include/asm-arm26/page.h1
-rw-r--r--include/asm-arm26/pgtable.h1
-rw-r--r--include/asm-arm26/serial.h1
-rw-r--r--include/asm-arm26/smp.h1
-rw-r--r--include/asm-arm26/sysirq.h1
-rw-r--r--include/asm-arm26/system.h1
-rw-r--r--include/asm-arm26/unistd.h10
-rw-r--r--include/asm-cris/arch-v10/io.h1
-rw-r--r--include/asm-cris/arch-v10/page.h1
-rw-r--r--include/asm-cris/arch-v10/system.h1
-rw-r--r--include/asm-cris/arch-v32/io.h1
-rw-r--r--include/asm-cris/arch-v32/irq.h1
-rw-r--r--include/asm-cris/arch-v32/page.h1
-rw-r--r--include/asm-cris/arch-v32/processor.h1
-rw-r--r--include/asm-cris/arch-v32/system.h1
-rw-r--r--include/asm-cris/eshlibld.h1
-rw-r--r--include/asm-cris/etraxgpio.h1
-rw-r--r--include/asm-cris/fasttimer.h1
-rw-r--r--include/asm-cris/page.h1
-rw-r--r--include/asm-cris/pci.h1
-rw-r--r--include/asm-cris/pgtable.h1
-rw-r--r--include/asm-cris/processor.h1
-rw-r--r--include/asm-cris/rtc.h1
-rw-r--r--include/asm-cris/tlbflush.h1
-rw-r--r--include/asm-cris/unistd.h9
-rw-r--r--include/asm-frv/atomic.h1
-rw-r--r--include/asm-frv/bitops.h1
-rw-r--r--include/asm-frv/bug.h1
-rw-r--r--include/asm-frv/cache.h1
-rw-r--r--include/asm-frv/dma.h1
-rw-r--r--include/asm-frv/elf.h1
-rw-r--r--include/asm-frv/fpu.h1
-rw-r--r--include/asm-frv/hardirq.h1
-rw-r--r--include/asm-frv/highmem.h1
-rw-r--r--include/asm-frv/ide.h1
-rw-r--r--include/asm-frv/io.h1
-rw-r--r--include/asm-frv/irq.h1
-rw-r--r--include/asm-frv/mmu_context.h1
-rw-r--r--include/asm-frv/page.h1
-rw-r--r--include/asm-frv/pci.h1
-rw-r--r--include/asm-frv/pgalloc.h1
-rw-r--r--include/asm-frv/pgtable.h1
-rw-r--r--include/asm-frv/processor.h1
-rw-r--r--include/asm-frv/segment.h1
-rw-r--r--include/asm-frv/serial.h1
-rw-r--r--include/asm-frv/smp.h1
-rw-r--r--include/asm-frv/system.h1
-rw-r--r--include/asm-frv/tlbflush.h1
-rw-r--r--include/asm-frv/types.h1
-rw-r--r--include/asm-frv/unaligned.h1
-rw-r--r--include/asm-frv/unistd.h7
-rw-r--r--include/asm-frv/virtconvert.h1
-rw-r--r--include/asm-generic/bug.h1
-rw-r--r--include/asm-generic/dma-mapping.h1
-rw-r--r--include/asm-generic/fcntl.h1
-rw-r--r--include/asm-generic/local.h1
-rw-r--r--include/asm-generic/signal.h7
-rw-r--r--include/asm-generic/tlb.h1
-rw-r--r--include/asm-h8300/bitops.h1
-rw-r--r--include/asm-h8300/dma.h1
-rw-r--r--include/asm-h8300/elf.h1
-rw-r--r--include/asm-h8300/hardirq.h1
-rw-r--r--include/asm-h8300/io.h1
-rw-r--r--include/asm-h8300/keyboard.h1
-rw-r--r--include/asm-h8300/mmu_context.h1
-rw-r--r--include/asm-h8300/page.h1
-rw-r--r--include/asm-h8300/page_offset.h1
-rw-r--r--include/asm-h8300/param.h1
-rw-r--r--include/asm-h8300/pgtable.h1
-rw-r--r--include/asm-h8300/processor.h1
-rw-r--r--include/asm-h8300/semaphore-helper.h1
-rw-r--r--include/asm-h8300/shm.h1
-rw-r--r--include/asm-h8300/system.h1
-rw-r--r--include/asm-h8300/unaligned.h1
-rw-r--r--include/asm-h8300/unistd.h7
-rw-r--r--include/asm-h8300/virtconvert.h1
-rw-r--r--include/asm-i386/apic.h1
-rw-r--r--include/asm-i386/atomic.h1
-rw-r--r--include/asm-i386/bitops.h1
-rw-r--r--include/asm-i386/bug.h1
-rw-r--r--include/asm-i386/bugs.h1
-rw-r--r--include/asm-i386/byteorder.h1
-rw-r--r--include/asm-i386/cache.h1
-rw-r--r--include/asm-i386/dma.h1
-rw-r--r--include/asm-i386/fixmap.h1
-rw-r--r--include/asm-i386/hardirq.h1
-rw-r--r--include/asm-i386/highmem.h1
-rw-r--r--include/asm-i386/hpet.h1
-rw-r--r--include/asm-i386/hw_irq.h1
-rw-r--r--include/asm-i386/ide.h1
-rw-r--r--include/asm-i386/io.h1
-rw-r--r--include/asm-i386/io_apic.h1
-rw-r--r--include/asm-i386/irq.h1
-rw-r--r--include/asm-i386/kmap_types.h1
-rw-r--r--include/asm-i386/mach-summit/mach_apic.h1
-rw-r--r--include/asm-i386/mmu_context.h1
-rw-r--r--include/asm-i386/mtrr.h1
-rw-r--r--include/asm-i386/page.h5
-rw-r--r--include/asm-i386/param.h1
-rw-r--r--include/asm-i386/pci.h1
-rw-r--r--include/asm-i386/pgalloc.h1
-rw-r--r--include/asm-i386/pgtable.h1
-rw-r--r--include/asm-i386/processor.h1
-rw-r--r--include/asm-i386/serial.h1
-rw-r--r--include/asm-i386/smp.h1
-rw-r--r--include/asm-i386/spinlock.h1
-rw-r--r--include/asm-i386/string.h1
-rw-r--r--include/asm-i386/system.h1
-rw-r--r--include/asm-i386/thread_info.h1
-rw-r--r--include/asm-i386/timex.h1
-rw-r--r--include/asm-i386/tlbflush.h1
-rw-r--r--include/asm-i386/types.h1
-rw-r--r--include/asm-i386/uaccess.h1
-rw-r--r--include/asm-i386/unistd.h7
-rw-r--r--include/asm-ia64/asmmacro.h1
-rw-r--r--include/asm-ia64/cache.h1
-rw-r--r--include/asm-ia64/delay.h1
-rw-r--r--include/asm-ia64/dma-mapping.h1
-rw-r--r--include/asm-ia64/dma.h1
-rw-r--r--include/asm-ia64/elf.h1
-rw-r--r--include/asm-ia64/hardirq.h1
-rw-r--r--include/asm-ia64/ia32.h1
-rw-r--r--include/asm-ia64/ide.h1
-rw-r--r--include/asm-ia64/intrinsics.h1
-rw-r--r--include/asm-ia64/kmap_types.h1
-rw-r--r--include/asm-ia64/machvec.h1
-rw-r--r--include/asm-ia64/meminit.h1
-rw-r--r--include/asm-ia64/nodedata.h1
-rw-r--r--include/asm-ia64/numa.h1
-rw-r--r--include/asm-ia64/page.h1
-rw-r--r--include/asm-ia64/param.h1
-rw-r--r--include/asm-ia64/percpu.h1
-rw-r--r--include/asm-ia64/pgalloc.h1
-rw-r--r--include/asm-ia64/pgtable.h1
-rw-r--r--include/asm-ia64/processor.h1
-rw-r--r--include/asm-ia64/ptrace.h1
-rw-r--r--include/asm-ia64/smp.h1
-rw-r--r--include/asm-ia64/sn/simulator.h1
-rw-r--r--include/asm-ia64/sn/sn_cpuid.h1
-rw-r--r--include/asm-ia64/sn/sn_sal.h1
-rw-r--r--include/asm-ia64/sn/xpc.h1
-rw-r--r--include/asm-ia64/string.h1
-rw-r--r--include/asm-ia64/system.h1
-rw-r--r--include/asm-ia64/tlb.h1
-rw-r--r--include/asm-ia64/tlbflush.h1
-rw-r--r--include/asm-ia64/unistd.h1
-rw-r--r--include/asm-m32r/assembler.h1
-rw-r--r--include/asm-m32r/atomic.h1
-rw-r--r--include/asm-m32r/bitops.h1
-rw-r--r--include/asm-m32r/cacheflush.h1
-rw-r--r--include/asm-m32r/hardirq.h1
-rw-r--r--include/asm-m32r/ide.h1
-rw-r--r--include/asm-m32r/irq.h1
-rw-r--r--include/asm-m32r/kmap_types.h1
-rw-r--r--include/asm-m32r/m32104ut/m32104ut_pld.h1
-rw-r--r--include/asm-m32r/m32700ut/m32700ut_lan.h1
-rw-r--r--include/asm-m32r/m32700ut/m32700ut_lcd.h1
-rw-r--r--include/asm-m32r/m32700ut/m32700ut_pld.h1
-rw-r--r--include/asm-m32r/m32r.h1
-rw-r--r--include/asm-m32r/mmu.h1
-rw-r--r--include/asm-m32r/mmu_context.h2
-rw-r--r--include/asm-m32r/opsput/opsput_lan.h1
-rw-r--r--include/asm-m32r/opsput/opsput_lcd.h1
-rw-r--r--include/asm-m32r/opsput/opsput_pld.h1
-rw-r--r--include/asm-m32r/page.h1
-rw-r--r--include/asm-m32r/pgalloc.h1
-rw-r--r--include/asm-m32r/pgtable-2level.h1
-rw-r--r--include/asm-m32r/pgtable.h1
-rw-r--r--include/asm-m32r/processor.h1
-rw-r--r--include/asm-m32r/ptrace.h1
-rw-r--r--include/asm-m32r/rtc.h1
-rw-r--r--include/asm-m32r/semaphore.h1
-rw-r--r--include/asm-m32r/serial.h1
-rw-r--r--include/asm-m32r/sigcontext.h1
-rw-r--r--include/asm-m32r/smp.h1
-rw-r--r--include/asm-m32r/spinlock.h1
-rw-r--r--include/asm-m32r/system.h1
-rw-r--r--include/asm-m32r/timex.h1
-rw-r--r--include/asm-m32r/tlbflush.h1
-rw-r--r--include/asm-m32r/uaccess.h1
-rw-r--r--include/asm-m32r/unistd.h5
-rw-r--r--include/asm-m68k/atomic.h1
-rw-r--r--include/asm-m68k/bug.h1
-rw-r--r--include/asm-m68k/dma-mapping.h1
-rw-r--r--include/asm-m68k/dma.h1
-rw-r--r--include/asm-m68k/dvma.h1
-rw-r--r--include/asm-m68k/elf.h1
-rw-r--r--include/asm-m68k/entry.h1
-rw-r--r--include/asm-m68k/fpu.h1
-rw-r--r--include/asm-m68k/hardirq.h1
-rw-r--r--include/asm-m68k/ide.h1
-rw-r--r--include/asm-m68k/io.h1
-rw-r--r--include/asm-m68k/irq.h1
-rw-r--r--include/asm-m68k/mc146818rtc.h1
-rw-r--r--include/asm-m68k/mmu_context.h1
-rw-r--r--include/asm-m68k/motorola_pgtable.h1
-rw-r--r--include/asm-m68k/openprom.h1
-rw-r--r--include/asm-m68k/page.h1
-rw-r--r--include/asm-m68k/page_offset.h1
-rw-r--r--include/asm-m68k/pgalloc.h1
-rw-r--r--include/asm-m68k/pgtable.h1
-rw-r--r--include/asm-m68k/processor.h1
-rw-r--r--include/asm-m68k/semaphore-helper.h1
-rw-r--r--include/asm-m68k/serial.h1
-rw-r--r--include/asm-m68k/setup.h1
-rw-r--r--include/asm-m68k/shm.h1
-rw-r--r--include/asm-m68k/system.h1
-rw-r--r--include/asm-m68k/tlbflush.h1
-rw-r--r--include/asm-m68k/unistd.h7
-rw-r--r--include/asm-m68k/virtconvert.h1
-rw-r--r--include/asm-m68knommu/bitops.h1
-rw-r--r--include/asm-m68knommu/coldfire.h1
-rw-r--r--include/asm-m68knommu/commproc.h1
-rw-r--r--include/asm-m68knommu/dma-mapping.h1
-rw-r--r--include/asm-m68knommu/dma.h1
-rw-r--r--include/asm-m68knommu/elf.h1
-rw-r--r--include/asm-m68knommu/elia.h1
-rw-r--r--include/asm-m68knommu/entry.h1
-rw-r--r--include/asm-m68knommu/fpu.h1
-rw-r--r--include/asm-m68knommu/hardirq.h1
-rw-r--r--include/asm-m68knommu/io.h1
-rw-r--r--include/asm-m68knommu/irq.h1
-rw-r--r--include/asm-m68knommu/m5206sim.h1
-rw-r--r--include/asm-m68knommu/m520xsim.h1
-rw-r--r--include/asm-m68knommu/m523xsim.h1
-rw-r--r--include/asm-m68knommu/m5272sim.h1
-rw-r--r--include/asm-m68knommu/m527xsim.h1
-rw-r--r--include/asm-m68knommu/m528xsim.h1
-rw-r--r--include/asm-m68knommu/mcfcache.h1
-rw-r--r--include/asm-m68knommu/mcfdma.h1
-rw-r--r--include/asm-m68knommu/mcfmbus.h1
-rw-r--r--include/asm-m68knommu/mcfne.h1
-rw-r--r--include/asm-m68knommu/mcfpci.h1
-rw-r--r--include/asm-m68knommu/mcfpit.h1
-rw-r--r--include/asm-m68knommu/mcfsim.h1
-rw-r--r--include/asm-m68knommu/mcfsmc.h1
-rw-r--r--include/asm-m68knommu/mcftimer.h1
-rw-r--r--include/asm-m68knommu/mcfuart.h1
-rw-r--r--include/asm-m68knommu/mcfwdebug.h1
-rw-r--r--include/asm-m68knommu/mmu_context.h1
-rw-r--r--include/asm-m68knommu/nettel.h1
-rw-r--r--include/asm-m68knommu/page.h1
-rw-r--r--include/asm-m68knommu/page_offset.h1
-rw-r--r--include/asm-m68knommu/param.h1
-rw-r--r--include/asm-m68knommu/pgtable.h1
-rw-r--r--include/asm-m68knommu/processor.h1
-rw-r--r--include/asm-m68knommu/semaphore-helper.h1
-rw-r--r--include/asm-m68knommu/system.h1
-rw-r--r--include/asm-m68knommu/unaligned.h1
-rw-r--r--include/asm-m68knommu/unistd.h7
-rw-r--r--include/asm-mips/a.out.h1
-rw-r--r--include/asm-mips/addrspace.h1
-rw-r--r--include/asm-mips/arc/types.h1
-rw-r--r--include/asm-mips/asm.h1
-rw-r--r--include/asm-mips/asmmacro.h1
-rw-r--r--include/asm-mips/atomic.h1
-rw-r--r--include/asm-mips/bcache.h1
-rw-r--r--include/asm-mips/bitops.h1
-rw-r--r--include/asm-mips/bug.h1
-rw-r--r--include/asm-mips/bugs.h1
-rw-r--r--include/asm-mips/byteorder.h1
-rw-r--r--include/asm-mips/cache.h1
-rw-r--r--include/asm-mips/checksum.h1
-rw-r--r--include/asm-mips/cpu-features.h1
-rw-r--r--include/asm-mips/cpu-info.h1
-rw-r--r--include/asm-mips/ddb5xxx/ddb5477.h1
-rw-r--r--include/asm-mips/ddb5xxx/ddb5xxx.h1
-rw-r--r--include/asm-mips/debug.h1
-rw-r--r--include/asm-mips/dec/prom.h1
-rw-r--r--include/asm-mips/delay.h1
-rw-r--r--include/asm-mips/dma.h1
-rw-r--r--include/asm-mips/elf.h1
-rw-r--r--include/asm-mips/fcntl.h1
-rw-r--r--include/asm-mips/fixmap.h1
-rw-r--r--include/asm-mips/fpu.h1
-rw-r--r--include/asm-mips/futex.h1
-rw-r--r--include/asm-mips/hazards.h1
-rw-r--r--include/asm-mips/highmem.h1
-rw-r--r--include/asm-mips/interrupt.h1
-rw-r--r--include/asm-mips/io.h1
-rw-r--r--include/asm-mips/ip32/machine.h1
-rw-r--r--include/asm-mips/irq.h1
-rw-r--r--include/asm-mips/isadep.h1
-rw-r--r--include/asm-mips/jmr3927/irq.h1
-rw-r--r--include/asm-mips/kmap_types.h1
-rw-r--r--include/asm-mips/local.h1
-rw-r--r--include/asm-mips/mach-au1x00/au1000.h1
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx.h1
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_dbdma.h1
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_ide.h1
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_psc.h1
-rw-r--r--include/asm-mips/mach-au1x00/ioremap.h1
-rw-r--r--include/asm-mips/mach-cobalt/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-db1x00/db1x00.h1
-rw-r--r--include/asm-mips/mach-generic/ide.h1
-rw-r--r--include/asm-mips/mach-generic/kmalloc.h1
-rw-r--r--include/asm-mips/mach-generic/spaces.h1
-rw-r--r--include/asm-mips/mach-ip22/spaces.h1
-rw-r--r--include/asm-mips/mach-ip32/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-ip32/kmalloc.h1
-rw-r--r--include/asm-mips/mach-mips/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-mips/irq.h1
-rw-r--r--include/asm-mips/mach-pb1x00/pb1550.h1
-rw-r--r--include/asm-mips/mach-sim/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mips-boards/generic.h1
-rw-r--r--include/asm-mips/mipsregs.h1
-rw-r--r--include/asm-mips/mmu_context.h1
-rw-r--r--include/asm-mips/mmzone.h1
-rw-r--r--include/asm-mips/module.h1
-rw-r--r--include/asm-mips/msgbuf.h1
-rw-r--r--include/asm-mips/paccess.h1
-rw-r--r--include/asm-mips/page.h1
-rw-r--r--include/asm-mips/pci.h1
-rw-r--r--include/asm-mips/pgalloc.h1
-rw-r--r--include/asm-mips/pgtable-32.h1
-rw-r--r--include/asm-mips/pgtable-64.h1
-rw-r--r--include/asm-mips/pgtable-bits.h1
-rw-r--r--include/asm-mips/pgtable.h1
-rw-r--r--include/asm-mips/prefetch.h1
-rw-r--r--include/asm-mips/processor.h1
-rw-r--r--include/asm-mips/ptrace.h1
-rw-r--r--include/asm-mips/reg.h1
-rw-r--r--include/asm-mips/resource.h1
-rw-r--r--include/asm-mips/serial.h1
-rw-r--r--include/asm-mips/sgiarcs.h1
-rw-r--r--include/asm-mips/sibyte/board.h1
-rw-r--r--include/asm-mips/sibyte/carmel.h1
-rw-r--r--include/asm-mips/sibyte/sentosa.h1
-rw-r--r--include/asm-mips/sibyte/swarm.h1
-rw-r--r--include/asm-mips/siginfo.h1
-rw-r--r--include/asm-mips/signal.h1
-rw-r--r--include/asm-mips/sim.h1
-rw-r--r--include/asm-mips/smp.h1
-rw-r--r--include/asm-mips/sn/addrs.h1
-rw-r--r--include/asm-mips/sn/agent.h1
-rw-r--r--include/asm-mips/sn/arch.h1
-rw-r--r--include/asm-mips/sn/io.h1
-rw-r--r--include/asm-mips/sn/klconfig.h1
-rw-r--r--include/asm-mips/sn/kldir.h1
-rw-r--r--include/asm-mips/sn/launch.h1
-rw-r--r--include/asm-mips/sn/mapped_kernel.h1
-rw-r--r--include/asm-mips/sn/sn0/addrs.h1
-rw-r--r--include/asm-mips/sn/sn0/arch.h1
-rw-r--r--include/asm-mips/sn/sn0/hubmd.h1
-rw-r--r--include/asm-mips/stackframe.h1
-rw-r--r--include/asm-mips/string.h1
-rw-r--r--include/asm-mips/system.h1
-rw-r--r--include/asm-mips/thread_info.h1
-rw-r--r--include/asm-mips/tlbflush.h1
-rw-r--r--include/asm-mips/tx4927/toshiba_rbtx4927.h1
-rw-r--r--include/asm-mips/types.h1
-rw-r--r--include/asm-mips/uaccess.h1
-rw-r--r--include/asm-mips/unistd.h7
-rw-r--r--include/asm-mips/vr41xx/vrc4173.h1
-rw-r--r--include/asm-mips/war.h1
-rw-r--r--include/asm-mips/wbflush.h1
-rw-r--r--include/asm-parisc/atomic.h1
-rw-r--r--include/asm-parisc/cache.h1
-rw-r--r--include/asm-parisc/cacheflush.h1
-rw-r--r--include/asm-parisc/dma-mapping.h1
-rw-r--r--include/asm-parisc/dma.h1
-rw-r--r--include/asm-parisc/io.h1
-rw-r--r--include/asm-parisc/irq.h1
-rw-r--r--include/asm-parisc/kmap_types.h1
-rw-r--r--include/asm-parisc/page.h1
-rw-r--r--include/asm-parisc/param.h1
-rw-r--r--include/asm-parisc/pci.h1
-rw-r--r--include/asm-parisc/pdc.h1
-rw-r--r--include/asm-parisc/pgtable.h1
-rw-r--r--include/asm-parisc/processor.h1
-rw-r--r--include/asm-parisc/psw.h1
-rw-r--r--include/asm-parisc/smp.h1
-rw-r--r--include/asm-parisc/system.h1
-rw-r--r--include/asm-parisc/tlbflush.h1
-rw-r--r--include/asm-parisc/unistd.h4
-rw-r--r--include/asm-powerpc/abs_addr.h1
-rw-r--r--include/asm-powerpc/cache.h1
-rw-r--r--include/asm-powerpc/dma-mapping.h1
-rw-r--r--include/asm-powerpc/dma.h1
-rw-r--r--include/asm-powerpc/eeh.h1
-rw-r--r--include/asm-powerpc/elf.h9
-rw-r--r--include/asm-powerpc/floppy.h1
-rw-r--r--include/asm-powerpc/hw_irq.h1
-rw-r--r--include/asm-powerpc/ide.h1
-rw-r--r--include/asm-powerpc/iommu.h1
-rw-r--r--include/asm-powerpc/irq.h1
-rw-r--r--include/asm-powerpc/iseries/iseries_io.h1
-rw-r--r--include/asm-powerpc/machdep.h1
-rw-r--r--include/asm-powerpc/mmzone.h1
-rw-r--r--include/asm-powerpc/paca.h1
-rw-r--r--include/asm-powerpc/page.h1
-rw-r--r--include/asm-powerpc/pgtable.h1
-rw-r--r--include/asm-powerpc/ppc_asm.h1
-rw-r--r--include/asm-powerpc/prom.h1
-rw-r--r--include/asm-powerpc/smp.h1
-rw-r--r--include/asm-powerpc/smu.h1
-rw-r--r--include/asm-powerpc/spu.h1
-rw-r--r--include/asm-powerpc/thread_info.h1
-rw-r--r--include/asm-powerpc/time.h1
-rw-r--r--include/asm-powerpc/timex.h1
-rw-r--r--include/asm-powerpc/tlb.h1
-rw-r--r--include/asm-powerpc/tlbflush.h1
-rw-r--r--include/asm-powerpc/topology.h1
-rw-r--r--include/asm-powerpc/types.h1
-rw-r--r--include/asm-powerpc/unistd.h8
-rw-r--r--include/asm-powerpc/vga.h1
-rw-r--r--include/asm-powerpc/vio.h1
-rw-r--r--include/asm-ppc/amigahw.h1
-rw-r--r--include/asm-ppc/bootinfo.h1
-rw-r--r--include/asm-ppc/commproc.h1
-rw-r--r--include/asm-ppc/ibm403.h1
-rw-r--r--include/asm-ppc/ibm44x.h1
-rw-r--r--include/asm-ppc/ibm4xx.h1
-rw-r--r--include/asm-ppc/io.h1
-rw-r--r--include/asm-ppc/machdep.h1
-rw-r--r--include/asm-ppc/mmu.h1
-rw-r--r--include/asm-ppc/mmu_context.h1
-rw-r--r--include/asm-ppc/mpc8260.h1
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-ppc/mpc85xx.h1
-rw-r--r--include/asm-ppc/mpc8xx.h1
-rw-r--r--include/asm-ppc/mv64x60.h1
-rw-r--r--include/asm-ppc/ocp.h1
-rw-r--r--include/asm-ppc/open_pic.h1
-rw-r--r--include/asm-ppc/page.h2
-rw-r--r--include/asm-ppc/pc_serial.h1
-rw-r--r--include/asm-ppc/pgalloc.h1
-rw-r--r--include/asm-ppc/pgtable.h1
-rw-r--r--include/asm-ppc/ppc4xx_dma.h1
-rw-r--r--include/asm-ppc/ppc4xx_pic.h1
-rw-r--r--include/asm-ppc/serial.h1
-rw-r--r--include/asm-ppc/smp.h1
-rw-r--r--include/asm-ppc/time.h1
-rw-r--r--include/asm-s390/bitops.h1
-rw-r--r--include/asm-s390/cmb.h2
-rw-r--r--include/asm-s390/debug.h1
-rw-r--r--include/asm-s390/hardirq.h1
-rw-r--r--include/asm-s390/idals.h1
-rw-r--r--include/asm-s390/local.h1
-rw-r--r--include/asm-s390/lowcore.h1
-rw-r--r--include/asm-s390/page.h6
-rw-r--r--include/asm-s390/pgalloc.h1
-rw-r--r--include/asm-s390/posix_types.h44
-rw-r--r--include/asm-s390/ptrace.h6
-rw-r--r--include/asm-s390/sfp-machine.h1
-rw-r--r--include/asm-s390/smp.h1
-rw-r--r--include/asm-s390/system.h1
-rw-r--r--include/asm-s390/tlbflush.h1
-rw-r--r--include/asm-s390/types.h1
-rw-r--r--include/asm-s390/unistd.h8
-rw-r--r--include/asm-s390/vtoc.h38
-rw-r--r--include/asm-s390/z90crypt.h212
-rw-r--r--include/asm-sh/bug.h1
-rw-r--r--include/asm-sh/checksum.h1
-rw-r--r--include/asm-sh/dma-mapping.h1
-rw-r--r--include/asm-sh/dma.h1
-rw-r--r--include/asm-sh/fixmap.h1
-rw-r--r--include/asm-sh/hardirq.h1
-rw-r--r--include/asm-sh/hd64461/hd64461.h1
-rw-r--r--include/asm-sh/hd64465/hd64465.h1
-rw-r--r--include/asm-sh/ide.h1
-rw-r--r--include/asm-sh/io.h1
-rw-r--r--include/asm-sh/irq.h1
-rw-r--r--include/asm-sh/keyboard.h1
-rw-r--r--include/asm-sh/kmap_types.h1
-rw-r--r--include/asm-sh/machvec.h1
-rw-r--r--include/asm-sh/machvec_init.h1
-rw-r--r--include/asm-sh/mpc1211/dma.h1
-rw-r--r--include/asm-sh/overdrive/overdrive.h1
-rw-r--r--include/asm-sh/page.h1
-rw-r--r--include/asm-sh/pgtable.h1
-rw-r--r--include/asm-sh/serial.h1
-rw-r--r--include/asm-sh/smp.h1
-rw-r--r--include/asm-sh/system.h1
-rw-r--r--include/asm-sh/types.h1
-rw-r--r--include/asm-sh/unistd.h7
-rw-r--r--include/asm-sh/watchdog.h1
-rw-r--r--include/asm-sh64/bug.h1
-rw-r--r--include/asm-sh64/dma-mapping.h1
-rw-r--r--include/asm-sh64/hardirq.h1
-rw-r--r--include/asm-sh64/ide.h1
-rw-r--r--include/asm-sh64/irq.h1
-rw-r--r--include/asm-sh64/mmu_context.h1
-rw-r--r--include/asm-sh64/page.h1
-rw-r--r--include/asm-sh64/param.h1
-rw-r--r--include/asm-sh64/pgtable.h1
-rw-r--r--include/asm-sh64/system.h1
-rw-r--r--include/asm-sh64/unistd.h7
-rw-r--r--include/asm-sparc/asmmacro.h1
-rw-r--r--include/asm-sparc/atomic.h1
-rw-r--r--include/asm-sparc/bugs.h1
-rw-r--r--include/asm-sparc/cacheflush.h1
-rw-r--r--include/asm-sparc/delay.h1
-rw-r--r--include/asm-sparc/dma-mapping.h1
-rw-r--r--include/asm-sparc/dma.h1
-rw-r--r--include/asm-sparc/elf.h1
-rw-r--r--include/asm-sparc/fixmap.h1
-rw-r--r--include/asm-sparc/hardirq.h1
-rw-r--r--include/asm-sparc/ide.h1
-rw-r--r--include/asm-sparc/irq.h1
-rw-r--r--include/asm-sparc/mostek.h1
-rw-r--r--include/asm-sparc/page.h1
-rw-r--r--include/asm-sparc/pgalloc.h1
-rw-r--r--include/asm-sparc/pgtable.h1
-rw-r--r--include/asm-sparc/sfp-machine.h1
-rw-r--r--include/asm-sparc/smp.h1
-rw-r--r--include/asm-sparc/system.h2
-rw-r--r--include/asm-sparc/timer.h1
-rw-r--r--include/asm-sparc/tlbflush.h1
-rw-r--r--include/asm-sparc/unistd.h4
-rw-r--r--include/asm-sparc/vac-ops.h1
-rw-r--r--include/asm-sparc/winmacro.h1
-rw-r--r--include/asm-sparc64/atomic.h1
-rw-r--r--include/asm-sparc64/bitops.h1
-rw-r--r--include/asm-sparc64/bugs.h1
-rw-r--r--include/asm-sparc64/cacheflush.h1
-rw-r--r--include/asm-sparc64/delay.h1
-rw-r--r--include/asm-sparc64/dma-mapping.h1
-rw-r--r--include/asm-sparc64/dma.h1
-rw-r--r--include/asm-sparc64/floppy.h1
-rw-r--r--include/asm-sparc64/ide.h1
-rw-r--r--include/asm-sparc64/irq.h1
-rw-r--r--include/asm-sparc64/kprobes.h1
-rw-r--r--include/asm-sparc64/mc146818rtc.h1
-rw-r--r--include/asm-sparc64/mmu.h1
-rw-r--r--include/asm-sparc64/oplib.h1
-rw-r--r--include/asm-sparc64/page.h1
-rw-r--r--include/asm-sparc64/param.h1
-rw-r--r--include/asm-sparc64/pgalloc.h1
-rw-r--r--include/asm-sparc64/pgtable.h1
-rw-r--r--include/asm-sparc64/processor.h1
-rw-r--r--include/asm-sparc64/siginfo.h1
-rw-r--r--include/asm-sparc64/signal.h1
-rw-r--r--include/asm-sparc64/smp.h1
-rw-r--r--include/asm-sparc64/spinlock.h1
-rw-r--r--include/asm-sparc64/system.h1
-rw-r--r--include/asm-sparc64/timer.h1
-rw-r--r--include/asm-sparc64/tlb.h1
-rw-r--r--include/asm-sparc64/tlbflush.h1
-rw-r--r--include/asm-sparc64/ttable.h1
-rw-r--r--include/asm-sparc64/unistd.h4
-rw-r--r--include/asm-um/a.out.h1
-rw-r--r--include/asm-um/cache.h1
-rw-r--r--include/asm-um/elf-ppc.h1
-rw-r--r--include/asm-um/fixmap.h1
-rw-r--r--include/asm-um/hardirq.h1
-rw-r--r--include/asm-um/linkage.h1
-rw-r--r--include/asm-um/mmu_context.h1
-rw-r--r--include/asm-um/page.h1
-rw-r--r--include/asm-um/pgalloc.h1
-rw-r--r--include/asm-um/processor-generic.h1
-rw-r--r--include/asm-um/ptrace-generic.h1
-rw-r--r--include/asm-um/smp.h1
-rw-r--r--include/asm-um/thread_info.h1
-rw-r--r--include/asm-v850/atomic.h1
-rw-r--r--include/asm-v850/bitops.h1
-rw-r--r--include/asm-v850/dma-mapping.h1
-rw-r--r--include/asm-v850/hardirq.h1
-rw-r--r--include/asm-v850/machdep.h1
-rw-r--r--include/asm-v850/pgtable.h1
-rw-r--r--include/asm-v850/processor.h1
-rw-r--r--include/asm-v850/serial.h1
-rw-r--r--include/asm-v850/unistd.h12
-rw-r--r--include/asm-v850/v850e_uart.h1
-rw-r--r--include/asm-x86_64/apic.h1
-rw-r--r--include/asm-x86_64/atomic.h1
-rw-r--r--include/asm-x86_64/bitops.h1
-rw-r--r--include/asm-x86_64/bugs.h1
-rw-r--r--include/asm-x86_64/cache.h1
-rw-r--r--include/asm-x86_64/calling.h1
-rw-r--r--include/asm-x86_64/dma-mapping.h1
-rw-r--r--include/asm-x86_64/dma.h1
-rw-r--r--include/asm-x86_64/dwarf2.h1
-rw-r--r--include/asm-x86_64/fixmap.h1
-rw-r--r--include/asm-x86_64/hardirq.h1
-rw-r--r--include/asm-x86_64/hw_irq.h1
-rw-r--r--include/asm-x86_64/ia32.h1
-rw-r--r--include/asm-x86_64/io.h1
-rw-r--r--include/asm-x86_64/io_apic.h1
-rw-r--r--include/asm-x86_64/mmu_context.h1
-rw-r--r--include/asm-x86_64/mmzone.h1
-rw-r--r--include/asm-x86_64/mtrr.h9
-rw-r--r--include/asm-x86_64/page.h5
-rw-r--r--include/asm-x86_64/param.h1
-rw-r--r--include/asm-x86_64/pci.h1
-rw-r--r--include/asm-x86_64/processor.h1
-rw-r--r--include/asm-x86_64/serial.h1
-rw-r--r--include/asm-x86_64/smp.h1
-rw-r--r--include/asm-x86_64/spinlock.h1
-rw-r--r--include/asm-x86_64/swiotlb.h1
-rw-r--r--include/asm-x86_64/system.h1
-rw-r--r--include/asm-x86_64/tlbflush.h1
-rw-r--r--include/asm-x86_64/topology.h1
-rw-r--r--include/asm-x86_64/uaccess.h1
-rw-r--r--include/asm-x86_64/unistd.h7
-rw-r--r--include/asm-xtensa/atomic.h1
-rw-r--r--include/asm-xtensa/checksum.h1
-rw-r--r--include/asm-xtensa/delay.h1
-rw-r--r--include/asm-xtensa/dma.h1
-rw-r--r--include/asm-xtensa/hardirq.h1
-rw-r--r--include/asm-xtensa/ide.h1
-rw-r--r--include/asm-xtensa/io.h1
-rw-r--r--include/asm-xtensa/irq.h1
-rw-r--r--include/asm-xtensa/mmu_context.h1
-rw-r--r--include/asm-xtensa/page.h1
-rw-r--r--include/asm-xtensa/pgalloc.h1
-rw-r--r--include/asm-xtensa/platform.h1
-rw-r--r--include/asm-xtensa/system.h1
-rw-r--r--include/asm-xtensa/unistd.h21
-rw-r--r--include/linux/acct.h3
-rw-r--r--include/linux/acpi.h1
-rw-r--r--include/linux/affs_hardblocks.h72
-rw-r--r--include/linux/agpgart.h3
-rw-r--r--include/linux/amba/clcd.h1
-rw-r--r--include/linux/atmdev.h1
-rw-r--r--include/linux/audit.h103
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/blkpg.h1
-rw-r--r--include/linux/blktrace_api.h1
-rw-r--r--include/linux/blockgroup_lock.h1
-rw-r--r--include/linux/cache.h1
-rw-r--r--include/linux/coda.h1
-rw-r--r--include/linux/compat.h1
-rw-r--r--include/linux/compiler.h19
-rw-r--r--include/linux/cpufreq.h1
-rw-r--r--include/linux/cramfs_fs.h34
-rw-r--r--include/linux/crypto.h1
-rw-r--r--include/linux/cyclomx.h1
-rw-r--r--include/linux/dcookies.h1
-rw-r--r--include/linux/devfs_fs_kernel.h1
-rw-r--r--include/linux/device.h1
-rw-r--r--include/linux/divert.h20
-rw-r--r--include/linux/dmi.h1
-rw-r--r--include/linux/dnotify.h1
-rw-r--r--include/linux/elf-em.h44
-rw-r--r--include/linux/elf.h59
-rw-r--r--include/linux/errqueue.h1
-rw-r--r--include/linux/ethtool.h169
-rw-r--r--include/linux/ext2_fs.h2
-rw-r--r--include/linux/ext3_fs.h10
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/fsnotify.h32
-rw-r--r--include/linux/ftape.h1
-rw-r--r--include/linux/gameport.h6
-rw-r--r--include/linux/generic_serial.h6
-rw-r--r--include/linux/genhd.h12
-rw-r--r--include/linux/gfp.h1
-rw-r--r--include/linux/hardirq.h1
-rw-r--r--include/linux/highmem.h1
-rw-r--r--include/linux/highuid.h1
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--include/linux/i2c-algo-ite.h7
-rw-r--r--include/linux/i2c.h9
-rw-r--r--include/linux/i2o-dev.h167
-rw-r--r--include/linux/ide.h1
-rw-r--r--include/linux/if_fddi.h2
-rw-r--r--include/linux/if_frad.h1
-rw-r--r--include/linux/if_tr.h1
-rw-r--r--include/linux/init.h1
-rw-r--r--include/linux/inotify.h109
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/interrupt.h1
-rw-r--r--include/linux/ipmi.h2
-rw-r--r--include/linux/ipv6.h1
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/irq_cpustat.h1
-rw-r--r--include/linux/isapnp.h1
-rw-r--r--include/linux/isdn.h1
-rw-r--r--include/linux/isdn/tpam.h1
-rw-r--r--include/linux/isdn_ppp.h1
-rw-r--r--include/linux/isdnif.h1
-rw-r--r--include/linux/jffs2.h56
-rw-r--r--include/linux/joystick.h22
-rw-r--r--include/linux/kallsyms.h1
-rw-r--r--include/linux/kernel_stat.h1
-rw-r--r--include/linux/kmod.h1
-rw-r--r--include/linux/kprobes.h1
-rw-r--r--include/linux/linkage.h1
-rw-r--r--include/linux/lockd/lockd.h1
-rw-r--r--include/linux/lockd/nlm.h1
-rw-r--r--include/linux/mempolicy.h1
-rw-r--r--include/linux/migrate.h1
-rw-r--r--include/linux/mii.h30
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/mman.h12
-rw-r--r--include/linux/mmzone.h1
-rw-r--r--include/linux/module.h10
-rw-r--r--include/linux/msg.h2
-rw-r--r--include/linux/mtd/cfi.h1
-rw-r--r--include/linux/mtd/inftl.h2
-rw-r--r--include/linux/mtd/map.h1
-rw-r--r--include/linux/mtd/mtd.h98
-rw-r--r--include/linux/mtd/nand.h355
-rw-r--r--include/linux/mtd/ndfc.h67
-rw-r--r--include/linux/mtd/nftl.h2
-rw-r--r--include/linux/mtd/onenand.h11
-rw-r--r--include/linux/mtd/onenand_regs.h8
-rw-r--r--include/linux/mtd/partitions.h2
-rw-r--r--include/linux/mtd/physmap.h29
-rw-r--r--include/linux/mtd/xip.h1
-rw-r--r--include/linux/nbd.h12
-rw-r--r--include/linux/ncp_fs.h5
-rw-r--r--include/linux/net.h3
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/linux/netfilter.h1
-rw-r--r--include/linux/netfilter/xt_conntrack.h2
-rw-r--r--include/linux/netfilter_arp.h1
-rw-r--r--include/linux/netfilter_bridge.h1
-rw-r--r--include/linux/netfilter_ipv4.h1
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h1
-rw-r--r--include/linux/netfilter_ipv4/listhelp.h1
-rw-r--r--include/linux/nfs.h8
-rw-r--r--include/linux/nfs4.h6
-rw-r--r--include/linux/nfsd/nfsd.h1
-rw-r--r--include/linux/nfsd/nfsfh.h1
-rw-r--r--include/linux/nfsd/syscall.h1
-rw-r--r--include/linux/numa.h1
-rw-r--r--include/linux/parport.h1
-rw-r--r--include/linux/pci.h5
-rw-r--r--include/linux/percpu_counter.h1
-rw-r--r--include/linux/pm.h1
-rw-r--r--include/linux/pm_legacy.h1
-rw-r--r--include/linux/pmu.h1
-rw-r--r--include/linux/ppp_defs.h14
-rw-r--r--include/linux/preempt.h1
-rw-r--r--include/linux/proc_fs.h1
-rw-r--r--include/linux/profile.h1
-rw-r--r--include/linux/quota.h4
-rw-r--r--include/linux/quotaops.h1
-rw-r--r--include/linux/rbtree.h26
-rw-r--r--include/linux/reiserfs_xattr.h3
-rw-r--r--include/linux/relay.h1
-rw-r--r--include/linux/rio.h1
-rw-r--r--include/linux/rio_drv.h1
-rw-r--r--include/linux/rmap.h1
-rw-r--r--include/linux/rtnetlink.h1
-rw-r--r--include/linux/rwsem.h1
-rw-r--r--include/linux/scc.h1
-rw-r--r--include/linux/sched.h92
-rw-r--r--include/linux/seccomp.h1
-rw-r--r--include/linux/sem.h2
-rw-r--r--include/linux/seqlock.h1
-rw-r--r--include/linux/serialP.h1
-rw-r--r--include/linux/serial_core.h1
-rw-r--r--include/linux/signal.h4
-rw-r--r--include/linux/skbuff.h1
-rw-r--r--include/linux/slab.h1
-rw-r--r--include/linux/smb_fs.h4
-rw-r--r--include/linux/smp.h1
-rw-r--r--include/linux/smp_lock.h1
-rw-r--r--include/linux/socket.h2
-rw-r--r--include/linux/spinlock.h1
-rw-r--r--include/linux/stop_machine.h1
-rw-r--r--include/linux/sunrpc/auth.h1
-rw-r--r--include/linux/sunrpc/debug.h24
-rw-r--r--include/linux/sunrpc/stats.h1
-rw-r--r--include/linux/suspend.h1
-rw-r--r--include/linux/swap.h1
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/sysrq.h1
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/linux/threads.h1
-rw-r--r--include/linux/timer.h1
-rw-r--r--include/linux/timex.h1
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/types.h1
-rw-r--r--include/linux/udp.h1
-rw-r--r--include/linux/ufs_fs.h1
-rw-r--r--include/linux/unistd.h2
-rw-r--r--include/linux/usb.h1
-rw-r--r--include/linux/usb_usual.h1
-rw-r--r--include/linux/usbdevice_fs.h2
-rw-r--r--include/linux/vt_buffer.h1
-rw-r--r--include/linux/vt_kern.h1
-rw-r--r--include/linux/wait.h1
-rw-r--r--include/linux/wanrouter.h4
-rw-r--r--include/mtd/mtd-abi.h95
-rw-r--r--include/mtd/mtd-user.h1
-rw-r--r--include/net/addrconf.h1
-rw-r--r--include/net/af_unix.h1
-rw-r--r--include/net/ax25.h1
-rw-r--r--include/net/compat.h1
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/icmp.h1
-rw-r--r--include/net/inet6_hashtables.h1
-rw-r--r--include/net/inet_hashtables.h1
-rw-r--r--include/net/inet_sock.h1
-rw-r--r--include/net/inet_timewait_sock.h1
-rw-r--r--include/net/ip.h1
-rw-r--r--include/net/ip_fib.h1
-rw-r--r--include/net/ip_mp_alg.h1
-rw-r--r--include/net/ip_vs.h1
-rw-r--r--include/net/ipv6.h1
-rw-r--r--include/net/irda/irda.h1
-rw-r--r--include/net/irda/irda_device.h1
-rw-r--r--include/net/irda/irlap.h1
-rw-r--r--include/net/irda/irlmp.h1
-rw-r--r--include/net/irda/irlmp_frame.h1
-rw-r--r--include/net/irda/qos.h1
-rw-r--r--include/net/ndisc.h1
-rw-r--r--include/net/netfilter/nf_conntrack.h1
-rw-r--r--include/net/pkt_act.h1
-rw-r--r--include/net/protocol.h1
-rw-r--r--include/net/raw.h1
-rw-r--r--include/net/red.h1
-rw-r--r--include/net/route.h1
-rw-r--r--include/net/sch_generic.h1
-rw-r--r--include/net/sctp/sctp.h1
-rw-r--r--include/net/sock.h1
-rw-r--r--include/net/tcp.h1
-rw-r--r--include/pcmcia/ss.h1
-rw-r--r--include/scsi/scsi_transport_fc.h1
-rw-r--r--include/scsi/scsi_transport_spi.h1
-rw-r--r--include/sound/driver.h1
-rw-r--r--include/sound/hdsp.h12
-rw-r--r--include/video/edid.h1
-rw-r--r--include/video/vga.h1
-rw-r--r--init/Kconfig6
-rw-r--r--init/do_mounts.c4
-rw-r--r--ipc/mqueue.c22
-rw-r--r--ipc/msg.c9
-rw-r--r--ipc/sem.c8
-rw-r--r--ipc/shm.c2
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/audit.c205
-rw-r--r--kernel/audit.h61
-rw-r--r--kernel/auditfilter.c899
-rw-r--r--kernel/auditsc.c648
-rw-r--r--kernel/hrtimer.c4
-rw-r--r--kernel/intermodule.c184
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/sysctl.c4
-rw-r--r--kernel/user.c2
-rw-r--r--lib/rbtree.c189
-rw-r--r--security/keys/key.c8
-rw-r--r--security/selinux/ss/services.c2
1170 files changed, 25232 insertions, 10442 deletions
diff --git a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
new file mode 100644
index 000000000000..1e6a23fdf2fc
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
@@ -0,0 +1,61 @@
1README on the ADC/Touchscreen Controller
2========================================
3
4The LH79524 and LH7A404 include a built-in Analog to Digital
5controller (ADC) that is used to process input from a touchscreen.
6The driver only implements a four-wire touch panel protocol.
7
8The touchscreen driver is maintenance free except for the pen-down or
9touch threshold. Some resistive displays and board combinations may
10require tuning of this threshold. The driver exposes some of it's
11internal state in the sys filesystem. If the kernel is configured
12with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
13directory
14
15 /sys/devices/platform/adc-lh7.0
16
17containing these files.
18
19 -r--r--r-- 1 root root 4096 Jan 1 00:00 samples
20 -rw-r--r-- 1 root root 4096 Jan 1 00:00 threshold
21 -r--r--r-- 1 root root 4096 Jan 1 00:00 threshold_range
22
23The threshold is the current touch threshold. It defaults to 750 on
24most targets.
25
26 # cat threshold
27 750
28
29The threshold_range contains the range of valid values for the
30threshold. Values outside of this range will be silently ignored.
31
32 # cat threshold_range
33 0 1023
34
35To change the threshold, write a value to the threshold file.
36
37 # echo 500 > threshold
38 # cat threshold
39 500
40
41The samples file contains the most recently sampled values from the
42ADC. There are 12. Below are typical of the last sampled values when
43the pen has been released. The first two and last two samples are for
44detecting whether or not the pen is down. The third through sixth are
45X coordinate samples. The seventh through tenth are Y coordinate
46samples.
47
48 # cat samples
49 1023 1023 0 0 0 0 530 529 530 529 1023 1023
50
51To determine a reasonable threshold, press on the touch panel with an
52appropriate stylus and read the values from samples.
53
54 # cat samples
55 1023 676 92 103 101 102 855 919 922 922 1023 679
56
57The first and eleventh samples are discarded. Thus, the important
58values are the second and twelfth which are used to determine if the
59pen is down. When both are below the threshold, the driver registers
60that the pen is down. When either is above the threshold, it
61registers then pen is up.
diff --git a/Documentation/arm/Sharp-LH/LCDPanels b/Documentation/arm/Sharp-LH/LCDPanels
new file mode 100644
index 000000000000..fb1b21c2f2f4
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/LCDPanels
@@ -0,0 +1,59 @@
1README on the LCD Panels
2========================
3
4Configuration options for several LCD panels, available from Logic PD,
5are included in the kernel source. This README will help you
6understand the configuration data and give you some guidance for
7adding support for other panels if you wish.
8
9
10lcd-panels.h
11------------
12
13There is no way, at present, to detect which panel is attached to the
14system at runtime. Thus the kernel configuration is static. The file
15arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the
16panel specific parameters.
17
18It should be possible for this data to be shared among several device
19families. The current layout may be insufficiently general, but it is
20amenable to improvement.
21
22
23PIXEL_CLOCK
24-----------
25
26The panel data sheets will give a range of acceptable pixel clocks.
27The fundamental LCDCLK input frequency is divided down by a PCD
28constant in field '.tim2'. It may happen that it is impossible to set
29the pixel clock within this range. A clock which is too slow will
30tend to flicker. For the highest quality image, set the clock as high
31as possible.
32
33
34MARGINS
35-------
36
37These values may be difficult to glean from the panel data sheet. In
38the case of the Sharp panels, the upper margin is explicitly called
39out as a specific number of lines from the top of the frame. The
40other values may not matter as much as the panels tend to
41automatically center the image.
42
43
44Sync Sense
45----------
46
47The sense of the hsync and vsync pulses may be called out in the data
48sheet. On one panel, the sense of these pulses determine the height
49of the visible region on the panel. Most of the Sharp panels use
50negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in
51'.tim2'.
52
53
54Pel Layout
55----------
56
57The Sharp color TFT panels are all configured for 16 bit direct color
58modes. The amba-lcd driver sets the pel mode to 565 for 5 bits of
59each red and blue and 6 bits of green.
diff --git a/Documentation/filesystems/inotify.txt b/Documentation/filesystems/inotify.txt
index 6d501903f68e..59a919f16144 100644
--- a/Documentation/filesystems/inotify.txt
+++ b/Documentation/filesystems/inotify.txt
@@ -69,17 +69,135 @@ Prototypes:
69 int inotify_rm_watch (int fd, __u32 mask); 69 int inotify_rm_watch (int fd, __u32 mask);
70 70
71 71
72(iii) Internal Kernel Implementation 72(iii) Kernel Interface
73 73
74Each inotify instance is associated with an inotify_device structure. 74Inotify's kernel API consists a set of functions for managing watches and an
75event callback.
76
77To use the kernel API, you must first initialize an inotify instance with a set
78of inotify_operations. You are given an opaque inotify_handle, which you use
79for any further calls to inotify.
80
81 struct inotify_handle *ih = inotify_init(my_event_handler);
82
83You must provide a function for processing events and a function for destroying
84the inotify watch.
85
86 void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
87 u32 cookie, const char *name, struct inode *inode)
88
89 watch - the pointer to the inotify_watch that triggered this call
90 wd - the watch descriptor
91 mask - describes the event that occurred
92 cookie - an identifier for synchronizing events
93 name - the dentry name for affected files in a directory-based event
94 inode - the affected inode in a directory-based event
95
96 void destroy_watch(struct inotify_watch *watch)
97
98You may add watches by providing a pre-allocated and initialized inotify_watch
99structure and specifying the inode to watch along with an inotify event mask.
100You must pin the inode during the call. You will likely wish to embed the
101inotify_watch structure in a structure of your own which contains other
102information about the watch. Once you add an inotify watch, it is immediately
103subject to removal depending on filesystem events. You must grab a reference if
104you depend on the watch hanging around after the call.
105
106 inotify_init_watch(&my_watch->iwatch);
107 inotify_get_watch(&my_watch->iwatch); // optional
108 s32 wd = inotify_add_watch(ih, &my_watch->iwatch, inode, mask);
109 inotify_put_watch(&my_watch->iwatch); // optional
110
111You may use the watch descriptor (wd) or the address of the inotify_watch for
112other inotify operations. You must not directly read or manipulate data in the
113inotify_watch. Additionally, you must not call inotify_add_watch() more than
114once for a given inotify_watch structure, unless you have first called either
115inotify_rm_watch() or inotify_rm_wd().
116
117To determine if you have already registered a watch for a given inode, you may
118call inotify_find_watch(), which gives you both the wd and the watch pointer for
119the inotify_watch, or an error if the watch does not exist.
120
121 wd = inotify_find_watch(ih, inode, &watchp);
122
123You may use container_of() on the watch pointer to access your own data
124associated with a given watch. When an existing watch is found,
125inotify_find_watch() bumps the refcount before releasing its locks. You must
126put that reference with:
127
128 put_inotify_watch(watchp);
129
130Call inotify_find_update_watch() to update the event mask for an existing watch.
131inotify_find_update_watch() returns the wd of the updated watch, or an error if
132the watch does not exist.
133
134 wd = inotify_find_update_watch(ih, inode, mask);
135
136An existing watch may be removed by calling either inotify_rm_watch() or
137inotify_rm_wd().
138
139 int ret = inotify_rm_watch(ih, &my_watch->iwatch);
140 int ret = inotify_rm_wd(ih, wd);
141
142A watch may be removed while executing your event handler with the following:
143
144 inotify_remove_watch_locked(ih, iwatch);
145
146Call inotify_destroy() to remove all watches from your inotify instance and
147release it. If there are no outstanding references, inotify_destroy() will call
148your destroy_watch op for each watch.
149
150 inotify_destroy(ih);
151
152When inotify removes a watch, it sends an IN_IGNORED event to your callback.
153You may use this event as an indication to free the watch memory. Note that
154inotify may remove a watch due to filesystem events, as well as by your request.
155If you use IN_ONESHOT, inotify will remove the watch after the first event, at
156which point you may call the final inotify_put_watch.
157
158(iv) Kernel Interface Prototypes
159
160 struct inotify_handle *inotify_init(struct inotify_operations *ops);
161
162 inotify_init_watch(struct inotify_watch *watch);
163
164 s32 inotify_add_watch(struct inotify_handle *ih,
165 struct inotify_watch *watch,
166 struct inode *inode, u32 mask);
167
168 s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
169 struct inotify_watch **watchp);
170
171 s32 inotify_find_update_watch(struct inotify_handle *ih,
172 struct inode *inode, u32 mask);
173
174 int inotify_rm_wd(struct inotify_handle *ih, u32 wd);
175
176 int inotify_rm_watch(struct inotify_handle *ih,
177 struct inotify_watch *watch);
178
179 void inotify_remove_watch_locked(struct inotify_handle *ih,
180 struct inotify_watch *watch);
181
182 void inotify_destroy(struct inotify_handle *ih);
183
184 void get_inotify_watch(struct inotify_watch *watch);
185 void put_inotify_watch(struct inotify_watch *watch);
186
187
188(v) Internal Kernel Implementation
189
190Each inotify instance is represented by an inotify_handle structure.
191Inotify's userspace consumers also have an inotify_device which is
192associated with the inotify_handle, and on which events are queued.
75 193
76Each watch is associated with an inotify_watch structure. Watches are chained 194Each watch is associated with an inotify_watch structure. Watches are chained
77off of each associated device and each associated inode. 195off of each associated inotify_handle and each associated inode.
78 196
79See fs/inotify.c for the locking and lifetime rules. 197See fs/inotify.c and fs/inotify_user.c for the locking and lifetime rules.
80 198
81 199
82(iv) Rationale 200(vi) Rationale
83 201
84Q: What is the design decision behind not tying the watch to the open fd of 202Q: What is the design decision behind not tying the watch to the open fd of
85 the watched object? 203 the watched object?
@@ -145,7 +263,7 @@ A: The poor user-space interface is the second biggest problem with dnotify.
145 file descriptor-based one that allows basic file I/O and poll/select. 263 file descriptor-based one that allows basic file I/O and poll/select.
146 Obtaining the fd and managing the watches could have been done either via a 264 Obtaining the fd and managing the watches could have been done either via a
147 device file or a family of new system calls. We decided to implement a 265 device file or a family of new system calls. We decided to implement a
148 family of system calls because that is the preffered approach for new kernel 266 family of system calls because that is the preferred approach for new kernel
149 interfaces. The only real difference was whether we wanted to use open(2) 267 interfaces. The only real difference was whether we wanted to use open(2)
150 and ioctl(2) or a couple of new system calls. System calls beat ioctls. 268 and ioctl(2) or a couple of new system calls. System calls beat ioctls.
151 269
diff --git a/MAINTAINERS b/MAINTAINERS
index 1421f74b6009..ce37c4b1ef94 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1843,12 +1843,12 @@ S: linux-scsi@vger.kernel.org
1843W: http://megaraid.lsilogic.com 1843W: http://megaraid.lsilogic.com
1844S: Maintained 1844S: Maintained
1845 1845
1846MEMORY TECHNOLOGY DEVICES 1846MEMORY TECHNOLOGY DEVICES (MTD)
1847P: David Woodhouse 1847P: David Woodhouse
1848M: dwmw2@infradead.org 1848M: dwmw2@infradead.org
1849W: http://www.linux-mtd.infradead.org/ 1849W: http://www.linux-mtd.infradead.org/
1850L: linux-mtd@lists.infradead.org 1850L: linux-mtd@lists.infradead.org
1851T: git kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6.git 1851T: git git://git.infradead.org/mtd-2.6.git
1852S: Maintained 1852S: Maintained
1853 1853
1854MICROTEK X6 SCANNER 1854MICROTEK X6 SCANNER
@@ -1895,7 +1895,7 @@ L: linux-kernel@vger.kernel.org
1895W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html 1895W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
1896S: Maintained 1896S: Maintained
1897 1897
1898MULTIMEDIA CARD SUBSYSTEM 1898MULTIMEDIA CARD (MMC) SUBSYSTEM
1899P: Russell King 1899P: Russell King
1900M: rmk+mmc@arm.linux.org.uk 1900M: rmk+mmc@arm.linux.org.uk
1901S: Maintained 1901S: Maintained
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 08b7cc900cae..f47cf9af3bc8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -270,6 +270,11 @@ config ARCH_AT91RM9200
270 Say Y here if you intend to run this kernel on an Atmel 270 Say Y here if you intend to run this kernel on an Atmel
271 AT91RM9200-based board. 271 AT91RM9200-based board.
272 272
273config ARCH_PNX4008
274 bool "Philips Nexperia PNX4008 Mobile"
275 help
276 This enables support for Philips PNX4008 mobile platform.
277
273endchoice 278endchoice
274 279
275source "arch/arm/mach-clps711x/Kconfig" 280source "arch/arm/mach-clps711x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6f8e84c1c1f2..6c97aa70d3bc 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -116,6 +116,7 @@ endif
116 machine-$(CONFIG_ARCH_REALVIEW) := realview 116 machine-$(CONFIG_ARCH_REALVIEW) := realview
117 machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200 117 machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
118 machine-$(CONFIG_ARCH_EP93XX) := ep93xx 118 machine-$(CONFIG_ARCH_EP93XX) := ep93xx
119 machine-$(CONFIG_ARCH_PNX4008) := pnx4008
119 120
120ifeq ($(CONFIG_ARCH_EBSA110),y) 121ifeq ($(CONFIG_ARCH_EBSA110),y)
121# This is what happens if you forget the IOCS16 line. 122# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index b56f5e691d65..23016f6aa645 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -605,8 +605,8 @@ proc_types:
605 b __armv4_mmu_cache_off 605 b __armv4_mmu_cache_off
606 b __armv4_mmu_cache_flush 606 b __armv4_mmu_cache_flush
607 607
608 .word 0x00070000 @ ARMv6 608 .word 0x0007b000 @ ARMv6
609 .word 0x000f0000 609 .word 0x0007f000
610 b __armv4_mmu_cache_on 610 b __armv4_mmu_cache_on
611 b __armv4_mmu_cache_off 611 b __armv4_mmu_cache_off
612 b __armv6_mmu_cache_flush 612 b __armv6_mmu_cache_flush
diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig
index 67eaa26c2647..bf9cf9c6d2df 100644
--- a/arch/arm/configs/lpd7a400_defconfig
+++ b/arch/arm/configs/lpd7a400_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.12
4# Mon Mar 28 00:06:33 2005 4# Thu Nov 3 14:15:32 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y 17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y 19CONFIG_LOCK_KERNEL=y
20CONFIG_INIT_ENV_ARG_LIMIT=32
20 21
21# 22#
22# General setup 23# General setup
@@ -36,6 +37,8 @@ CONFIG_EMBEDDED=y
36CONFIG_KALLSYMS=y 37CONFIG_KALLSYMS=y
37# CONFIG_KALLSYMS_ALL is not set 38# CONFIG_KALLSYMS_ALL is not set
38# CONFIG_KALLSYMS_EXTRA_PASS is not set 39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_PRINTK=y
41CONFIG_BUG=y
39CONFIG_BASE_FULL=y 42CONFIG_BASE_FULL=y
40CONFIG_FUTEX=y 43CONFIG_FUTEX=y
41# CONFIG_EPOLL is not set 44# CONFIG_EPOLL is not set
@@ -71,6 +74,7 @@ CONFIG_BASE_SMALL=0
71# CONFIG_ARCH_SA1100 is not set 74# CONFIG_ARCH_SA1100 is not set
72# CONFIG_ARCH_S3C2410 is not set 75# CONFIG_ARCH_S3C2410 is not set
73# CONFIG_ARCH_SHARK is not set 76# CONFIG_ARCH_SHARK is not set
77# CONFIG_ARCH_LH7952X is not set
74CONFIG_ARCH_LH7A40X=y 78CONFIG_ARCH_LH7A40X=y
75# CONFIG_ARCH_OMAP is not set 79# CONFIG_ARCH_OMAP is not set
76# CONFIG_ARCH_VERSATILE is not set 80# CONFIG_ARCH_VERSATILE is not set
@@ -84,6 +88,7 @@ CONFIG_ARCH_LH7A40X=y
84CONFIG_MACH_LPD7A400=y 88CONFIG_MACH_LPD7A400=y
85# CONFIG_MACH_LPD7A404 is not set 89# CONFIG_MACH_LPD7A404 is not set
86CONFIG_ARCH_LH7A400=y 90CONFIG_ARCH_LH7A400=y
91CONFIG_LPD7A40X_CPLD_SSP=y
87# CONFIG_LH7A40X_CONTIGMEM is not set 92# CONFIG_LH7A40X_CONTIGMEM is not set
88# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set 93# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set
89 94
@@ -110,6 +115,8 @@ CONFIG_ARM_THUMB=y
110# 115#
111# Bus support 116# Bus support
112# 117#
118CONFIG_ARM_AMBA=y
119CONFIG_ISA_DMA_API=y
113 120
114# 121#
115# PCCARD (PCMCIA/CardBus) support 122# PCCARD (PCMCIA/CardBus) support
@@ -119,6 +126,7 @@ CONFIG_ARM_THUMB=y
119# 126#
120# Kernel Features 127# Kernel Features
121# 128#
129# CONFIG_SMP is not set
122CONFIG_PREEMPT=y 130CONFIG_PREEMPT=y
123CONFIG_DISCONTIGMEM=y 131CONFIG_DISCONTIGMEM=y
124CONFIG_ALIGNMENT_TRAP=y 132CONFIG_ALIGNMENT_TRAP=y
@@ -175,7 +183,7 @@ CONFIG_MTD=y
175# CONFIG_MTD_CONCAT is not set 183# CONFIG_MTD_CONCAT is not set
176CONFIG_MTD_PARTITIONS=y 184CONFIG_MTD_PARTITIONS=y
177# CONFIG_MTD_REDBOOT_PARTS is not set 185# CONFIG_MTD_REDBOOT_PARTS is not set
178# CONFIG_MTD_CMDLINE_PARTS is not set 186CONFIG_MTD_CMDLINE_PARTS=y
179# CONFIG_MTD_AFS_PARTS is not set 187# CONFIG_MTD_AFS_PARTS is not set
180 188
181# 189#
@@ -217,7 +225,10 @@ CONFIG_MTD_CFI_UTIL=y
217# Mapping drivers for chip access 225# Mapping drivers for chip access
218# 226#
219# CONFIG_MTD_COMPLEX_MAPPINGS is not set 227# CONFIG_MTD_COMPLEX_MAPPINGS is not set
220# CONFIG_MTD_PHYSMAP is not set 228CONFIG_MTD_PHYSMAP=y
229CONFIG_MTD_PHYSMAP_START=0x00000000
230CONFIG_MTD_PHYSMAP_LEN=0x04000000
231CONFIG_MTD_PHYSMAP_BANKWIDTH=4
221# CONFIG_MTD_ARM_INTEGRATOR is not set 232# CONFIG_MTD_ARM_INTEGRATOR is not set
222# CONFIG_MTD_EDB7312 is not set 233# CONFIG_MTD_EDB7312 is not set
223 234
@@ -254,7 +265,6 @@ CONFIG_MTD_CFI_UTIL=y
254# 265#
255# Block devices 266# Block devices
256# 267#
257# CONFIG_BLK_DEV_FD is not set
258# CONFIG_BLK_DEV_COW_COMMON is not set 268# CONFIG_BLK_DEV_COW_COMMON is not set
259CONFIG_BLK_DEV_LOOP=y 269CONFIG_BLK_DEV_LOOP=y
260# CONFIG_BLK_DEV_CRYPTOLOOP is not set 270# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -288,13 +298,15 @@ CONFIG_BLK_DEV_IDEDISK=y
288# CONFIG_BLK_DEV_IDECD is not set 298# CONFIG_BLK_DEV_IDECD is not set
289# CONFIG_BLK_DEV_IDETAPE is not set 299# CONFIG_BLK_DEV_IDETAPE is not set
290# CONFIG_BLK_DEV_IDEFLOPPY is not set 300# CONFIG_BLK_DEV_IDEFLOPPY is not set
301# CONFIG_BLK_DEV_IDESCSI is not set
291# CONFIG_IDE_TASK_IOCTL is not set 302# CONFIG_IDE_TASK_IOCTL is not set
303CONFIG_IDE_POLL=y
292 304
293# 305#
294# IDE chipset support/bugfixes 306# IDE chipset support/bugfixes
295# 307#
296CONFIG_IDE_GENERIC=y 308CONFIG_IDE_GENERIC=y
297# CONFIG_IDE_ARM is not set 309CONFIG_IDE_ARM=y
298# CONFIG_BLK_DEV_IDEDMA is not set 310# CONFIG_BLK_DEV_IDEDMA is not set
299# CONFIG_IDEDMA_AUTO is not set 311# CONFIG_IDEDMA_AUTO is not set
300# CONFIG_BLK_DEV_HD is not set 312# CONFIG_BLK_DEV_HD is not set
@@ -302,7 +314,37 @@ CONFIG_IDE_GENERIC=y
302# 314#
303# SCSI device support 315# SCSI device support
304# 316#
305# CONFIG_SCSI is not set 317CONFIG_SCSI=y
318# CONFIG_SCSI_PROC_FS is not set
319
320#
321# SCSI support type (disk, tape, CD-ROM)
322#
323# CONFIG_BLK_DEV_SD is not set
324# CONFIG_CHR_DEV_ST is not set
325# CONFIG_CHR_DEV_OSST is not set
326# CONFIG_BLK_DEV_SR is not set
327# CONFIG_CHR_DEV_SG is not set
328
329#
330# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
331#
332# CONFIG_SCSI_MULTI_LUN is not set
333# CONFIG_SCSI_CONSTANTS is not set
334# CONFIG_SCSI_LOGGING is not set
335
336#
337# SCSI Transport Attributes
338#
339# CONFIG_SCSI_SPI_ATTRS is not set
340# CONFIG_SCSI_FC_ATTRS is not set
341# CONFIG_SCSI_ISCSI_ATTRS is not set
342
343#
344# SCSI low-level drivers
345#
346# CONFIG_SCSI_SATA is not set
347# CONFIG_SCSI_DEBUG is not set
306 348
307# 349#
308# Multi-device support (RAID and LVM) 350# Multi-device support (RAID and LVM)
@@ -331,7 +373,6 @@ CONFIG_NET=y
331# 373#
332CONFIG_PACKET=y 374CONFIG_PACKET=y
333# CONFIG_PACKET_MMAP is not set 375# CONFIG_PACKET_MMAP is not set
334# CONFIG_NETLINK_DEV is not set
335CONFIG_UNIX=y 376CONFIG_UNIX=y
336# CONFIG_NET_KEY is not set 377# CONFIG_NET_KEY is not set
337CONFIG_INET=y 378CONFIG_INET=y
@@ -438,13 +479,10 @@ CONFIG_INPUT=y
438# 479#
439# Userland interfaces 480# Userland interfaces
440# 481#
441CONFIG_INPUT_MOUSEDEV=y 482# CONFIG_INPUT_MOUSEDEV is not set
442CONFIG_INPUT_MOUSEDEV_PSAUX=y
443CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
444CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
445# CONFIG_INPUT_JOYDEV is not set 483# CONFIG_INPUT_JOYDEV is not set
446# CONFIG_INPUT_TSDEV is not set 484# CONFIG_INPUT_TSDEV is not set
447# CONFIG_INPUT_EVDEV is not set 485CONFIG_INPUT_EVDEV=y
448# CONFIG_INPUT_EVBUG is not set 486# CONFIG_INPUT_EVBUG is not set
449 487
450# 488#
@@ -453,7 +491,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
453# CONFIG_INPUT_KEYBOARD is not set 491# CONFIG_INPUT_KEYBOARD is not set
454# CONFIG_INPUT_MOUSE is not set 492# CONFIG_INPUT_MOUSE is not set
455# CONFIG_INPUT_JOYSTICK is not set 493# CONFIG_INPUT_JOYSTICK is not set
456# CONFIG_INPUT_TOUCHSCREEN is not set 494CONFIG_INPUT_TOUCHSCREEN=y
495# CONFIG_TOUCHSCREEN_GUNZE is not set
496# CONFIG_TOUCHSCREEN_ELO is not set
497# CONFIG_TOUCHSCREEN_MTOUCH is not set
498# CONFIG_TOUCHSCREEN_MK712 is not set
499CONFIG_TOUCHSCREEN_ADS7843_LH7=y
500CONFIG_HAS_TOUCHSCREEN_ADS7843_LH7=y
457# CONFIG_INPUT_MISC is not set 501# CONFIG_INPUT_MISC is not set
458 502
459# 503#
@@ -461,7 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
461# 505#
462# CONFIG_SERIO is not set 506# CONFIG_SERIO is not set
463# CONFIG_GAMEPORT is not set 507# CONFIG_GAMEPORT is not set
464CONFIG_SOUND_GAMEPORT=y
465 508
466# 509#
467# Character devices 510# Character devices
@@ -479,6 +522,8 @@ CONFIG_HW_CONSOLE=y
479# 522#
480# Non-8250 serial port support 523# Non-8250 serial port support
481# 524#
525# CONFIG_SERIAL_AMBA_PL010 is not set
526# CONFIG_SERIAL_AMBA_PL011 is not set
482CONFIG_SERIAL_CORE=y 527CONFIG_SERIAL_CORE=y
483CONFIG_SERIAL_CORE_CONSOLE=y 528CONFIG_SERIAL_CORE_CONSOLE=y
484CONFIG_SERIAL_LH7A40X=y 529CONFIG_SERIAL_LH7A40X=y
@@ -510,7 +555,6 @@ CONFIG_RTC=y
510# 555#
511# TPM devices 556# TPM devices
512# 557#
513# CONFIG_TCG_TPM is not set
514 558
515# 559#
516# I2C support 560# I2C support
@@ -534,18 +578,73 @@ CONFIG_RTC=y
534# 578#
535# Graphics support 579# Graphics support
536# 580#
537# CONFIG_FB is not set 581CONFIG_FB=y
582CONFIG_FB_CFB_FILLRECT=y
583CONFIG_FB_CFB_COPYAREA=y
584CONFIG_FB_CFB_IMAGEBLIT=y
585CONFIG_FB_SOFT_CURSOR=y
586# CONFIG_FB_MACMODES is not set
587# CONFIG_FB_MODE_HELPERS is not set
588# CONFIG_FB_TILEBLITTING is not set
589CONFIG_FB_ARMCLCD=y
590CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
591# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
592# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
593# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
594# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
595# CONFIG_FB_S1D13XXX is not set
596# CONFIG_FB_VIRTUAL is not set
538 597
539# 598#
540# Console display driver support 599# Console display driver support
541# 600#
542# CONFIG_VGA_CONSOLE is not set 601# CONFIG_VGA_CONSOLE is not set
543CONFIG_DUMMY_CONSOLE=y 602CONFIG_DUMMY_CONSOLE=y
603# CONFIG_FRAMEBUFFER_CONSOLE is not set
604
605#
606# Logo configuration
607#
608# CONFIG_LOGO is not set
609# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
544 610
545# 611#
546# Sound 612# Sound
547# 613#
548# CONFIG_SOUND is not set 614CONFIG_SOUND=y
615
616#
617# Advanced Linux Sound Architecture
618#
619CONFIG_SND=y
620CONFIG_SND_TIMER=y
621CONFIG_SND_PCM=y
622# CONFIG_SND_SEQUENCER is not set
623CONFIG_SND_OSSEMUL=y
624CONFIG_SND_MIXER_OSS=y
625CONFIG_SND_PCM_OSS=y
626# CONFIG_SND_RTCTIMER is not set
627# CONFIG_SND_VERBOSE_PRINTK is not set
628# CONFIG_SND_DEBUG is not set
629
630#
631# Generic devices
632#
633# CONFIG_SND_DUMMY is not set
634# CONFIG_SND_MTPAV is not set
635# CONFIG_SND_SERIAL_U16550 is not set
636# CONFIG_SND_MPU401 is not set
637CONFIG_SND_AC97_CODEC=y
638
639#
640# ALSA ARM devices
641#
642CONFIG_SND_LH7A40X_AC97=y
643
644#
645# Open Sound System
646#
647# CONFIG_SOUND_PRIME is not set
549 648
550# 649#
551# USB support 650# USB support
diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
index 208d591ebfce..3a57be32e849 100644
--- a/arch/arm/configs/lpd7a404_defconfig
+++ b/arch/arm/configs/lpd7a404_defconfig
@@ -1,52 +1,58 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.16
4# Mon Mar 28 00:14:08 2005 4# Thu Mar 23 17:50:31 2006
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
8CONFIG_UID16=y
9CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y 9CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_GENERIC_IOMAP=y
12 10
13# 11#
14# Code maturity level options 12# Code maturity level options
15# 13#
16CONFIG_EXPERIMENTAL=y 14CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y 15CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y 16CONFIG_LOCK_KERNEL=y
17CONFIG_INIT_ENV_ARG_LIMIT=32
20 18
21# 19#
22# General setup 20# General setup
23# 21#
24CONFIG_LOCALVERSION="" 22CONFIG_LOCALVERSION=""
23CONFIG_LOCALVERSION_AUTO=y
25# CONFIG_SWAP is not set 24# CONFIG_SWAP is not set
26CONFIG_SYSVIPC=y 25CONFIG_SYSVIPC=y
27# CONFIG_POSIX_MQUEUE is not set 26# CONFIG_POSIX_MQUEUE is not set
28# CONFIG_BSD_PROCESS_ACCT is not set 27# CONFIG_BSD_PROCESS_ACCT is not set
29CONFIG_SYSCTL=y 28CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set 29# CONFIG_AUDIT is not set
31# CONFIG_HOTPLUG is not set
32CONFIG_KOBJECT_UEVENT=y
33CONFIG_IKCONFIG=y 30CONFIG_IKCONFIG=y
34# CONFIG_IKCONFIG_PROC is not set 31# CONFIG_IKCONFIG_PROC is not set
32CONFIG_INITRAMFS_SOURCE=""
33CONFIG_UID16=y
34CONFIG_CC_OPTIMIZE_FOR_SIZE=y
35CONFIG_EMBEDDED=y 35CONFIG_EMBEDDED=y
36CONFIG_KALLSYMS=y 36CONFIG_KALLSYMS=y
37# CONFIG_KALLSYMS_ALL is not set 37# CONFIG_KALLSYMS_ALL is not set
38# CONFIG_KALLSYMS_EXTRA_PASS is not set 38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39# CONFIG_HOTPLUG is not set
40CONFIG_PRINTK=y
41CONFIG_BUG=y
42CONFIG_ELF_CORE=y
39CONFIG_BASE_FULL=y 43CONFIG_BASE_FULL=y
40CONFIG_FUTEX=y 44CONFIG_FUTEX=y
41# CONFIG_EPOLL is not set 45# CONFIG_EPOLL is not set
42CONFIG_CC_OPTIMIZE_FOR_SIZE=y
43CONFIG_SHMEM=y 46CONFIG_SHMEM=y
44CONFIG_CC_ALIGN_FUNCTIONS=0 47CONFIG_CC_ALIGN_FUNCTIONS=0
45CONFIG_CC_ALIGN_LABELS=0 48CONFIG_CC_ALIGN_LABELS=0
46CONFIG_CC_ALIGN_LOOPS=0 49CONFIG_CC_ALIGN_LOOPS=0
47CONFIG_CC_ALIGN_JUMPS=0 50CONFIG_CC_ALIGN_JUMPS=0
51CONFIG_SLAB=y
48# CONFIG_TINY_SHMEM is not set 52# CONFIG_TINY_SHMEM is not set
49CONFIG_BASE_SMALL=0 53CONFIG_BASE_SMALL=0
54# CONFIG_SLOB is not set
55CONFIG_OBSOLETE_INTERMODULE=y
50 56
51# 57#
52# Loadable module support 58# Loadable module support
@@ -54,6 +60,23 @@ CONFIG_BASE_SMALL=0
54# CONFIG_MODULES is not set 60# CONFIG_MODULES is not set
55 61
56# 62#
63# Block layer
64#
65
66#
67# IO Schedulers
68#
69CONFIG_IOSCHED_NOOP=y
70# CONFIG_IOSCHED_AS is not set
71# CONFIG_IOSCHED_DEADLINE is not set
72CONFIG_IOSCHED_CFQ=y
73# CONFIG_DEFAULT_AS is not set
74# CONFIG_DEFAULT_DEADLINE is not set
75CONFIG_DEFAULT_CFQ=y
76# CONFIG_DEFAULT_NOOP is not set
77CONFIG_DEFAULT_IOSCHED="cfq"
78
79#
57# System Type 80# System Type
58# 81#
59# CONFIG_ARCH_CLPS7500 is not set 82# CONFIG_ARCH_CLPS7500 is not set
@@ -71,11 +94,15 @@ CONFIG_BASE_SMALL=0
71# CONFIG_ARCH_SA1100 is not set 94# CONFIG_ARCH_SA1100 is not set
72# CONFIG_ARCH_S3C2410 is not set 95# CONFIG_ARCH_S3C2410 is not set
73# CONFIG_ARCH_SHARK is not set 96# CONFIG_ARCH_SHARK is not set
97# CONFIG_ARCH_LH7952X is not set
74CONFIG_ARCH_LH7A40X=y 98CONFIG_ARCH_LH7A40X=y
75# CONFIG_ARCH_OMAP is not set 99# CONFIG_ARCH_OMAP is not set
76# CONFIG_ARCH_VERSATILE is not set 100# CONFIG_ARCH_VERSATILE is not set
101# CONFIG_ARCH_REALVIEW is not set
77# CONFIG_ARCH_IMX is not set 102# CONFIG_ARCH_IMX is not set
78# CONFIG_ARCH_H720X is not set 103# CONFIG_ARCH_H720X is not set
104# CONFIG_ARCH_AAEC2000 is not set
105# CONFIG_ARCH_AT91RM9200 is not set
79 106
80# 107#
81# LH7A40X Implementations 108# LH7A40X Implementations
@@ -110,6 +137,7 @@ CONFIG_ARM_THUMB=y
110# 137#
111# Bus support 138# Bus support
112# 139#
140CONFIG_ARM_AMBA=y
113 141
114# 142#
115# PCCARD (PCMCIA/CardBus) support 143# PCCARD (PCMCIA/CardBus) support
@@ -120,7 +148,18 @@ CONFIG_ARM_THUMB=y
120# Kernel Features 148# Kernel Features
121# 149#
122CONFIG_PREEMPT=y 150CONFIG_PREEMPT=y
151# CONFIG_NO_IDLE_HZ is not set
152# CONFIG_AEABI is not set
153CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
154CONFIG_SELECT_MEMORY_MODEL=y
155# CONFIG_FLATMEM_MANUAL is not set
156CONFIG_DISCONTIGMEM_MANUAL=y
157# CONFIG_SPARSEMEM_MANUAL is not set
123CONFIG_DISCONTIGMEM=y 158CONFIG_DISCONTIGMEM=y
159CONFIG_FLAT_NODE_MEM_MAP=y
160CONFIG_NEED_MULTIPLE_NODES=y
161# CONFIG_SPARSEMEM_STATIC is not set
162CONFIG_SPLIT_PTLOCK_CPUS=4096
124CONFIG_ALIGNMENT_TRAP=y 163CONFIG_ALIGNMENT_TRAP=y
125 164
126# 165#
@@ -154,6 +193,84 @@ CONFIG_BINFMT_ELF=y
154# Power management options 193# Power management options
155# 194#
156# CONFIG_PM is not set 195# CONFIG_PM is not set
196# CONFIG_APM is not set
197
198#
199# Networking
200#
201CONFIG_NET=y
202
203#
204# Networking options
205#
206# CONFIG_NETDEBUG is not set
207CONFIG_PACKET=y
208# CONFIG_PACKET_MMAP is not set
209CONFIG_UNIX=y
210# CONFIG_NET_KEY is not set
211CONFIG_INET=y
212# CONFIG_IP_MULTICAST is not set
213# CONFIG_IP_ADVANCED_ROUTER is not set
214CONFIG_IP_FIB_HASH=y
215CONFIG_IP_PNP=y
216CONFIG_IP_PNP_DHCP=y
217CONFIG_IP_PNP_BOOTP=y
218CONFIG_IP_PNP_RARP=y
219# CONFIG_NET_IPIP is not set
220# CONFIG_NET_IPGRE is not set
221# CONFIG_ARPD is not set
222# CONFIG_SYN_COOKIES is not set
223# CONFIG_INET_AH is not set
224# CONFIG_INET_ESP is not set
225# CONFIG_INET_IPCOMP is not set
226# CONFIG_INET_TUNNEL is not set
227CONFIG_INET_DIAG=y
228CONFIG_INET_TCP_DIAG=y
229# CONFIG_TCP_CONG_ADVANCED is not set
230CONFIG_TCP_CONG_BIC=y
231# CONFIG_IPV6 is not set
232# CONFIG_NETFILTER is not set
233
234#
235# DCCP Configuration (EXPERIMENTAL)
236#
237# CONFIG_IP_DCCP is not set
238
239#
240# SCTP Configuration (EXPERIMENTAL)
241#
242# CONFIG_IP_SCTP is not set
243
244#
245# TIPC Configuration (EXPERIMENTAL)
246#
247# CONFIG_TIPC is not set
248# CONFIG_ATM is not set
249# CONFIG_BRIDGE is not set
250# CONFIG_VLAN_8021Q is not set
251# CONFIG_DECNET is not set
252# CONFIG_LLC2 is not set
253# CONFIG_IPX is not set
254# CONFIG_ATALK is not set
255# CONFIG_X25 is not set
256# CONFIG_LAPB is not set
257# CONFIG_NET_DIVERT is not set
258# CONFIG_ECONET is not set
259# CONFIG_WAN_ROUTER is not set
260
261#
262# QoS and/or fair queueing
263#
264# CONFIG_NET_SCHED is not set
265
266#
267# Network testing
268#
269# CONFIG_NET_PKTGEN is not set
270# CONFIG_HAMRADIO is not set
271# CONFIG_IRDA is not set
272# CONFIG_BT is not set
273# CONFIG_IEEE80211 is not set
157 274
158# 275#
159# Device Drivers 276# Device Drivers
@@ -168,6 +285,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
168# CONFIG_DEBUG_DRIVER is not set 285# CONFIG_DEBUG_DRIVER is not set
169 286
170# 287#
288# Connector - unified userspace <-> kernelspace linker
289#
290# CONFIG_CONNECTOR is not set
291
292#
171# Memory Technology Devices (MTD) 293# Memory Technology Devices (MTD)
172# 294#
173CONFIG_MTD=y 295CONFIG_MTD=y
@@ -175,7 +297,7 @@ CONFIG_MTD=y
175# CONFIG_MTD_CONCAT is not set 297# CONFIG_MTD_CONCAT is not set
176CONFIG_MTD_PARTITIONS=y 298CONFIG_MTD_PARTITIONS=y
177# CONFIG_MTD_REDBOOT_PARTS is not set 299# CONFIG_MTD_REDBOOT_PARTS is not set
178# CONFIG_MTD_CMDLINE_PARTS is not set 300CONFIG_MTD_CMDLINE_PARTS=y
179# CONFIG_MTD_AFS_PARTS is not set 301# CONFIG_MTD_AFS_PARTS is not set
180 302
181# 303#
@@ -186,6 +308,7 @@ CONFIG_MTD_BLOCK=y
186# CONFIG_FTL is not set 308# CONFIG_FTL is not set
187# CONFIG_NFTL is not set 309# CONFIG_NFTL is not set
188# CONFIG_INFTL is not set 310# CONFIG_INFTL is not set
311# CONFIG_RFD_FTL is not set
189 312
190# 313#
191# RAM/ROM/Flash chip drivers 314# RAM/ROM/Flash chip drivers
@@ -211,15 +334,18 @@ CONFIG_MTD_CFI_UTIL=y
211# CONFIG_MTD_RAM is not set 334# CONFIG_MTD_RAM is not set
212# CONFIG_MTD_ROM is not set 335# CONFIG_MTD_ROM is not set
213# CONFIG_MTD_ABSENT is not set 336# CONFIG_MTD_ABSENT is not set
214# CONFIG_MTD_XIP is not set 337# CONFIG_MTD_OBSOLETE_CHIPS is not set
215 338
216# 339#
217# Mapping drivers for chip access 340# Mapping drivers for chip access
218# 341#
219# CONFIG_MTD_COMPLEX_MAPPINGS is not set 342# CONFIG_MTD_COMPLEX_MAPPINGS is not set
220# CONFIG_MTD_PHYSMAP is not set 343CONFIG_MTD_PHYSMAP=y
344CONFIG_MTD_PHYSMAP_START=0x00000000
345CONFIG_MTD_PHYSMAP_LEN=0x04000000
346CONFIG_MTD_PHYSMAP_BANKWIDTH=4
221# CONFIG_MTD_ARM_INTEGRATOR is not set 347# CONFIG_MTD_ARM_INTEGRATOR is not set
222# CONFIG_MTD_EDB7312 is not set 348# CONFIG_MTD_PLATRAM is not set
223 349
224# 350#
225# Self-contained MTD device drivers 351# Self-contained MTD device drivers
@@ -243,6 +369,11 @@ CONFIG_MTD_CFI_UTIL=y
243# CONFIG_MTD_NAND is not set 369# CONFIG_MTD_NAND is not set
244 370
245# 371#
372# OneNAND Flash Device Drivers
373#
374# CONFIG_MTD_ONENAND is not set
375
376#
246# Parallel port support 377# Parallel port support
247# 378#
248# CONFIG_PARPORT is not set 379# CONFIG_PARPORT is not set
@@ -254,7 +385,6 @@ CONFIG_MTD_CFI_UTIL=y
254# 385#
255# Block devices 386# Block devices
256# 387#
257# CONFIG_BLK_DEV_FD is not set
258# CONFIG_BLK_DEV_COW_COMMON is not set 388# CONFIG_BLK_DEV_COW_COMMON is not set
259CONFIG_BLK_DEV_LOOP=y 389CONFIG_BLK_DEV_LOOP=y
260# CONFIG_BLK_DEV_CRYPTOLOOP is not set 390# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -262,16 +392,7 @@ CONFIG_BLK_DEV_LOOP=y
262# CONFIG_BLK_DEV_UB is not set 392# CONFIG_BLK_DEV_UB is not set
263# CONFIG_BLK_DEV_RAM is not set 393# CONFIG_BLK_DEV_RAM is not set
264CONFIG_BLK_DEV_RAM_COUNT=16 394CONFIG_BLK_DEV_RAM_COUNT=16
265CONFIG_INITRAMFS_SOURCE=""
266# CONFIG_CDROM_PKTCDVD is not set 395# CONFIG_CDROM_PKTCDVD is not set
267
268#
269# IO Schedulers
270#
271CONFIG_IOSCHED_NOOP=y
272# CONFIG_IOSCHED_AS is not set
273# CONFIG_IOSCHED_DEADLINE is not set
274CONFIG_IOSCHED_CFQ=y
275# CONFIG_ATA_OVER_ETH is not set 396# CONFIG_ATA_OVER_ETH is not set
276 397
277# 398#
@@ -291,12 +412,13 @@ CONFIG_BLK_DEV_IDEDISK=y
291# CONFIG_BLK_DEV_IDEFLOPPY is not set 412# CONFIG_BLK_DEV_IDEFLOPPY is not set
292# CONFIG_BLK_DEV_IDESCSI is not set 413# CONFIG_BLK_DEV_IDESCSI is not set
293# CONFIG_IDE_TASK_IOCTL is not set 414# CONFIG_IDE_TASK_IOCTL is not set
415CONFIG_IDE_POLL=y
294 416
295# 417#
296# IDE chipset support/bugfixes 418# IDE chipset support/bugfixes
297# 419#
298CONFIG_IDE_GENERIC=y 420CONFIG_IDE_GENERIC=y
299# CONFIG_IDE_ARM is not set 421CONFIG_IDE_ARM=y
300# CONFIG_BLK_DEV_IDEDMA is not set 422# CONFIG_BLK_DEV_IDEDMA is not set
301# CONFIG_IDEDMA_AUTO is not set 423# CONFIG_IDEDMA_AUTO is not set
302# CONFIG_BLK_DEV_HD is not set 424# CONFIG_BLK_DEV_HD is not set
@@ -304,6 +426,7 @@ CONFIG_IDE_GENERIC=y
304# 426#
305# SCSI device support 427# SCSI device support
306# 428#
429# CONFIG_RAID_ATTRS is not set
307CONFIG_SCSI=y 430CONFIG_SCSI=y
308# CONFIG_SCSI_PROC_FS is not set 431# CONFIG_SCSI_PROC_FS is not set
309 432
@@ -315,6 +438,7 @@ CONFIG_SCSI=y
315# CONFIG_CHR_DEV_OSST is not set 438# CONFIG_CHR_DEV_OSST is not set
316# CONFIG_BLK_DEV_SR is not set 439# CONFIG_BLK_DEV_SR is not set
317# CONFIG_CHR_DEV_SG is not set 440# CONFIG_CHR_DEV_SG is not set
441# CONFIG_CHR_DEV_SCH is not set
318 442
319# 443#
320# Some SCSI devices (e.g. CD jukebox) support multiple LUNs 444# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -329,10 +453,12 @@ CONFIG_SCSI=y
329# CONFIG_SCSI_SPI_ATTRS is not set 453# CONFIG_SCSI_SPI_ATTRS is not set
330# CONFIG_SCSI_FC_ATTRS is not set 454# CONFIG_SCSI_FC_ATTRS is not set
331# CONFIG_SCSI_ISCSI_ATTRS is not set 455# CONFIG_SCSI_ISCSI_ATTRS is not set
456# CONFIG_SCSI_SAS_ATTRS is not set
332 457
333# 458#
334# SCSI low-level drivers 459# SCSI low-level drivers
335# 460#
461# CONFIG_ISCSI_TCP is not set
336# CONFIG_SCSI_SATA is not set 462# CONFIG_SCSI_SATA is not set
337# CONFIG_SCSI_DEBUG is not set 463# CONFIG_SCSI_DEBUG is not set
338 464
@@ -344,6 +470,7 @@ CONFIG_SCSI=y
344# 470#
345# Fusion MPT device support 471# Fusion MPT device support
346# 472#
473# CONFIG_FUSION is not set
347 474
348# 475#
349# IEEE 1394 (FireWire) support 476# IEEE 1394 (FireWire) support
@@ -354,70 +481,8 @@ CONFIG_SCSI=y
354# 481#
355 482
356# 483#
357# Networking support 484# Network device support
358# 485#
359CONFIG_NET=y
360
361#
362# Networking options
363#
364CONFIG_PACKET=y
365# CONFIG_PACKET_MMAP is not set
366# CONFIG_NETLINK_DEV is not set
367CONFIG_UNIX=y
368# CONFIG_NET_KEY is not set
369CONFIG_INET=y
370# CONFIG_IP_MULTICAST is not set
371# CONFIG_IP_ADVANCED_ROUTER is not set
372CONFIG_IP_PNP=y
373CONFIG_IP_PNP_DHCP=y
374CONFIG_IP_PNP_BOOTP=y
375CONFIG_IP_PNP_RARP=y
376# CONFIG_NET_IPIP is not set
377# CONFIG_NET_IPGRE is not set
378# CONFIG_ARPD is not set
379# CONFIG_SYN_COOKIES is not set
380# CONFIG_INET_AH is not set
381# CONFIG_INET_ESP is not set
382# CONFIG_INET_IPCOMP is not set
383# CONFIG_INET_TUNNEL is not set
384# CONFIG_IP_TCPDIAG is not set
385# CONFIG_IP_TCPDIAG_IPV6 is not set
386# CONFIG_IPV6 is not set
387# CONFIG_NETFILTER is not set
388
389#
390# SCTP Configuration (EXPERIMENTAL)
391#
392# CONFIG_IP_SCTP is not set
393# CONFIG_ATM is not set
394# CONFIG_BRIDGE is not set
395# CONFIG_VLAN_8021Q is not set
396# CONFIG_DECNET is not set
397# CONFIG_LLC2 is not set
398# CONFIG_IPX is not set
399# CONFIG_ATALK is not set
400# CONFIG_X25 is not set
401# CONFIG_LAPB is not set
402# CONFIG_NET_DIVERT is not set
403# CONFIG_ECONET is not set
404# CONFIG_WAN_ROUTER is not set
405
406#
407# QoS and/or fair queueing
408#
409# CONFIG_NET_SCHED is not set
410# CONFIG_NET_CLS_ROUTE is not set
411
412#
413# Network testing
414#
415# CONFIG_NET_PKTGEN is not set
416# CONFIG_NETPOLL is not set
417# CONFIG_NET_POLL_CONTROLLER is not set
418# CONFIG_HAMRADIO is not set
419# CONFIG_IRDA is not set
420# CONFIG_BT is not set
421CONFIG_NETDEVICES=y 486CONFIG_NETDEVICES=y
422# CONFIG_DUMMY is not set 487# CONFIG_DUMMY is not set
423# CONFIG_BONDING is not set 488# CONFIG_BONDING is not set
@@ -425,11 +490,17 @@ CONFIG_NETDEVICES=y
425# CONFIG_TUN is not set 490# CONFIG_TUN is not set
426 491
427# 492#
493# PHY device support
494#
495# CONFIG_PHYLIB is not set
496
497#
428# Ethernet (10 or 100Mbit) 498# Ethernet (10 or 100Mbit)
429# 499#
430CONFIG_NET_ETHERNET=y 500CONFIG_NET_ETHERNET=y
431CONFIG_MII=y 501CONFIG_MII=y
432CONFIG_SMC91X=y 502CONFIG_SMC91X=y
503# CONFIG_DM9000 is not set
433 504
434# 505#
435# Ethernet (1000 Mbit) 506# Ethernet (1000 Mbit)
@@ -456,6 +527,8 @@ CONFIG_SMC91X=y
456# CONFIG_SLIP is not set 527# CONFIG_SLIP is not set
457# CONFIG_SHAPER is not set 528# CONFIG_SHAPER is not set
458# CONFIG_NETCONSOLE is not set 529# CONFIG_NETCONSOLE is not set
530# CONFIG_NETPOLL is not set
531# CONFIG_NET_POLL_CONTROLLER is not set
459 532
460# 533#
461# ISDN subsystem 534# ISDN subsystem
@@ -470,10 +543,13 @@ CONFIG_INPUT=y
470# 543#
471# Userland interfaces 544# Userland interfaces
472# 545#
473# CONFIG_INPUT_MOUSEDEV is not set 546CONFIG_INPUT_MOUSEDEV=y
547# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
548CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
549CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
474# CONFIG_INPUT_JOYDEV is not set 550# CONFIG_INPUT_JOYDEV is not set
475# CONFIG_INPUT_TSDEV is not set 551# CONFIG_INPUT_TSDEV is not set
476# CONFIG_INPUT_EVDEV is not set 552CONFIG_INPUT_EVDEV=y
477# CONFIG_INPUT_EVBUG is not set 553# CONFIG_INPUT_EVBUG is not set
478 554
479# 555#
@@ -482,7 +558,13 @@ CONFIG_INPUT=y
482# CONFIG_INPUT_KEYBOARD is not set 558# CONFIG_INPUT_KEYBOARD is not set
483# CONFIG_INPUT_MOUSE is not set 559# CONFIG_INPUT_MOUSE is not set
484# CONFIG_INPUT_JOYSTICK is not set 560# CONFIG_INPUT_JOYSTICK is not set
485# CONFIG_INPUT_TOUCHSCREEN is not set 561CONFIG_INPUT_TOUCHSCREEN=y
562# CONFIG_TOUCHSCREEN_GUNZE is not set
563# CONFIG_TOUCHSCREEN_ELO is not set
564# CONFIG_TOUCHSCREEN_MTOUCH is not set
565# CONFIG_TOUCHSCREEN_MK712 is not set
566CONFIG_TOUCHSCREEN_ADC_LH7=y
567CONFIG_HAS_TOUCHSCREEN_ADC_LH7=y
486# CONFIG_INPUT_MISC is not set 568# CONFIG_INPUT_MISC is not set
487 569
488# 570#
@@ -490,7 +572,6 @@ CONFIG_INPUT=y
490# 572#
491# CONFIG_SERIO is not set 573# CONFIG_SERIO is not set
492# CONFIG_GAMEPORT is not set 574# CONFIG_GAMEPORT is not set
493CONFIG_SOUND_GAMEPORT=y
494 575
495# 576#
496# Character devices 577# Character devices
@@ -508,6 +589,8 @@ CONFIG_HW_CONSOLE=y
508# 589#
509# Non-8250 serial port support 590# Non-8250 serial port support
510# 591#
592# CONFIG_SERIAL_AMBA_PL010 is not set
593# CONFIG_SERIAL_AMBA_PL011 is not set
511CONFIG_SERIAL_CORE=y 594CONFIG_SERIAL_CORE=y
512CONFIG_SERIAL_CORE_CONSOLE=y 595CONFIG_SERIAL_CORE_CONSOLE=y
513CONFIG_SERIAL_LH7A40X=y 596CONFIG_SERIAL_LH7A40X=y
@@ -533,13 +616,13 @@ CONFIG_RTC=y
533# 616#
534# Ftape, the floppy tape device driver 617# Ftape, the floppy tape device driver
535# 618#
536# CONFIG_DRM is not set
537# CONFIG_RAW_DRIVER is not set 619# CONFIG_RAW_DRIVER is not set
538 620
539# 621#
540# TPM devices 622# TPM devices
541# 623#
542# CONFIG_TCG_TPM is not set 624# CONFIG_TCG_TPM is not set
625# CONFIG_TELCLOCK is not set
543 626
544# 627#
545# I2C support 628# I2C support
@@ -547,10 +630,33 @@ CONFIG_RTC=y
547# CONFIG_I2C is not set 630# CONFIG_I2C is not set
548 631
549# 632#
633# SPI support
634#
635# CONFIG_SPI is not set
636# CONFIG_SPI_MASTER is not set
637
638#
639# Dallas's 1-wire bus
640#
641# CONFIG_W1 is not set
642
643#
644# Hardware Monitoring support
645#
646CONFIG_HWMON=y
647# CONFIG_HWMON_VID is not set
648# CONFIG_SENSORS_F71805F is not set
649# CONFIG_HWMON_DEBUG_CHIP is not set
650
651#
550# Misc devices 652# Misc devices
551# 653#
552 654
553# 655#
656# Multimedia Capabilities Port drivers
657#
658
659#
554# Multimedia devices 660# Multimedia devices
555# 661#
556# CONFIG_VIDEO_DEV is not set 662# CONFIG_VIDEO_DEV is not set
@@ -563,18 +669,83 @@ CONFIG_RTC=y
563# 669#
564# Graphics support 670# Graphics support
565# 671#
566# CONFIG_FB is not set 672CONFIG_FB=y
673CONFIG_FB_CFB_FILLRECT=y
674CONFIG_FB_CFB_COPYAREA=y
675CONFIG_FB_CFB_IMAGEBLIT=y
676# CONFIG_FB_MACMODES is not set
677# CONFIG_FB_MODE_HELPERS is not set
678# CONFIG_FB_TILEBLITTING is not set
679CONFIG_FB_ARMCLCD=y
680CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
681# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
682# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
683# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
684# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
685# CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE is not set
686# CONFIG_FB_ARMCLCD_HITACHI is not set
687# CONFIG_FB_S1D13XXX is not set
688# CONFIG_FB_VIRTUAL is not set
567 689
568# 690#
569# Console display driver support 691# Console display driver support
570# 692#
571# CONFIG_VGA_CONSOLE is not set 693# CONFIG_VGA_CONSOLE is not set
572CONFIG_DUMMY_CONSOLE=y 694CONFIG_DUMMY_CONSOLE=y
695# CONFIG_FRAMEBUFFER_CONSOLE is not set
696
697#
698# Logo configuration
699#
700# CONFIG_LOGO is not set
701# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
573 702
574# 703#
575# Sound 704# Sound
576# 705#
577# CONFIG_SOUND is not set 706CONFIG_SOUND=y
707
708#
709# Advanced Linux Sound Architecture
710#
711CONFIG_SND=y
712CONFIG_SND_TIMER=y
713CONFIG_SND_PCM=y
714# CONFIG_SND_SEQUENCER is not set
715CONFIG_SND_OSSEMUL=y
716CONFIG_SND_MIXER_OSS=y
717CONFIG_SND_PCM_OSS=y
718# CONFIG_SND_RTCTIMER is not set
719# CONFIG_SND_DYNAMIC_MINORS is not set
720CONFIG_SND_SUPPORT_OLD_API=y
721# CONFIG_SND_VERBOSE_PRINTK is not set
722# CONFIG_SND_DEBUG is not set
723
724#
725# Generic devices
726#
727CONFIG_SND_AC97_CODEC=y
728CONFIG_SND_AC97_BUS=y
729# CONFIG_SND_DUMMY is not set
730# CONFIG_SND_MTPAV is not set
731# CONFIG_SND_SERIAL_U16550 is not set
732# CONFIG_SND_MPU401 is not set
733
734#
735# ALSA ARM devices
736#
737# CONFIG_SND_ARMAACI is not set
738CONFIG_SND_LH7A40X_AC97=y
739
740#
741# USB devices
742#
743# CONFIG_SND_USB_AUDIO is not set
744
745#
746# Open Sound System
747#
748# CONFIG_SOUND_PRIME is not set
578 749
579# 750#
580# USB support 751# USB support
@@ -595,6 +766,7 @@ CONFIG_USB_DEVICEFS=y
595# 766#
596# USB Host Controller Drivers 767# USB Host Controller Drivers
597# 768#
769# CONFIG_USB_ISP116X_HCD is not set
598CONFIG_USB_OHCI_HCD=y 770CONFIG_USB_OHCI_HCD=y
599# CONFIG_USB_OHCI_BIG_ENDIAN is not set 771# CONFIG_USB_OHCI_BIG_ENDIAN is not set
600CONFIG_USB_OHCI_LITTLE_ENDIAN=y 772CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -603,16 +775,19 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
603# 775#
604# USB Device Class drivers 776# USB Device Class drivers
605# 777#
606# CONFIG_USB_BLUETOOTH_TTY is not set 778# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
607# CONFIG_USB_ACM is not set 779# CONFIG_USB_ACM is not set
608# CONFIG_USB_PRINTER is not set 780# CONFIG_USB_PRINTER is not set
609 781
610# 782#
611# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 783# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
784#
785
786#
787# may also be needed; see USB_STORAGE Help for more information
612# 788#
613CONFIG_USB_STORAGE=y 789CONFIG_USB_STORAGE=y
614CONFIG_USB_STORAGE_DEBUG=y 790CONFIG_USB_STORAGE_DEBUG=y
615# CONFIG_USB_STORAGE_RW_DETECT is not set
616CONFIG_USB_STORAGE_DATAFAB=y 791CONFIG_USB_STORAGE_DATAFAB=y
617# CONFIG_USB_STORAGE_FREECOM is not set 792# CONFIG_USB_STORAGE_FREECOM is not set
618# CONFIG_USB_STORAGE_ISD200 is not set 793# CONFIG_USB_STORAGE_ISD200 is not set
@@ -621,22 +796,32 @@ CONFIG_USB_STORAGE_DATAFAB=y
621# CONFIG_USB_STORAGE_SDDR09 is not set 796# CONFIG_USB_STORAGE_SDDR09 is not set
622# CONFIG_USB_STORAGE_SDDR55 is not set 797# CONFIG_USB_STORAGE_SDDR55 is not set
623# CONFIG_USB_STORAGE_JUMPSHOT is not set 798# CONFIG_USB_STORAGE_JUMPSHOT is not set
799# CONFIG_USB_STORAGE_ALAUDA is not set
800# CONFIG_USB_STORAGE_ONETOUCH is not set
801# CONFIG_USB_LIBUSUAL is not set
624 802
625# 803#
626# USB Input Devices 804# USB Input Devices
627# 805#
628CONFIG_USB_HID=y 806CONFIG_USB_HID=y
629CONFIG_USB_HIDINPUT=y 807CONFIG_USB_HIDINPUT=y
808# CONFIG_USB_HIDINPUT_POWERBOOK is not set
630# CONFIG_HID_FF is not set 809# CONFIG_HID_FF is not set
631# CONFIG_USB_HIDDEV is not set 810# CONFIG_USB_HIDDEV is not set
632# CONFIG_USB_AIPTEK is not set 811# CONFIG_USB_AIPTEK is not set
633# CONFIG_USB_WACOM is not set 812# CONFIG_USB_WACOM is not set
813# CONFIG_USB_ACECAD is not set
634# CONFIG_USB_KBTAB is not set 814# CONFIG_USB_KBTAB is not set
635# CONFIG_USB_POWERMATE is not set 815# CONFIG_USB_POWERMATE is not set
636# CONFIG_USB_MTOUCH is not set 816# CONFIG_USB_MTOUCH is not set
817# CONFIG_USB_ITMTOUCH is not set
637# CONFIG_USB_EGALAX is not set 818# CONFIG_USB_EGALAX is not set
819# CONFIG_USB_YEALINK is not set
638# CONFIG_USB_XPAD is not set 820# CONFIG_USB_XPAD is not set
639# CONFIG_USB_ATI_REMOTE is not set 821# CONFIG_USB_ATI_REMOTE is not set
822# CONFIG_USB_ATI_REMOTE2 is not set
823# CONFIG_USB_KEYSPAN_REMOTE is not set
824# CONFIG_USB_APPLETOUCH is not set
640 825
641# 826#
642# USB Imaging devices 827# USB Imaging devices
@@ -686,16 +871,33 @@ CONFIG_USB_MON=y
686# CONFIG_USB_PHIDGETKIT is not set 871# CONFIG_USB_PHIDGETKIT is not set
687# CONFIG_USB_PHIDGETSERVO is not set 872# CONFIG_USB_PHIDGETSERVO is not set
688# CONFIG_USB_IDMOUSE is not set 873# CONFIG_USB_IDMOUSE is not set
874# CONFIG_USB_LD is not set
689# CONFIG_USB_TEST is not set 875# CONFIG_USB_TEST is not set
690 876
691# 877#
692# USB ATM/DSL drivers 878# USB DSL modem support
693# 879#
694 880
695# 881#
696# USB Gadget Support 882# USB Gadget Support
697# 883#
698# CONFIG_USB_GADGET is not set 884CONFIG_USB_GADGET=y
885# CONFIG_USB_GADGET_DEBUG_FILES is not set
886CONFIG_USB_GADGET_SELECTED=y
887# CONFIG_USB_GADGET_NET2280 is not set
888# CONFIG_USB_GADGET_PXA2XX is not set
889# CONFIG_USB_GADGET_GOKU is not set
890# CONFIG_USB_GADGET_LH7A40X is not set
891CONFIG_USB_GADGET_LH7=y
892CONFIG_USB_LH7=y
893# CONFIG_USB_GADGET_OMAP is not set
894# CONFIG_USB_GADGET_DUMMY_HCD is not set
895# CONFIG_USB_GADGET_DUALSPEED is not set
896CONFIG_USB_ZERO=y
897# CONFIG_USB_ETH is not set
898# CONFIG_USB_GADGETFS is not set
899# CONFIG_USB_FILE_STORAGE is not set
900# CONFIG_USB_G_SERIAL is not set
699 901
700# 902#
701# MMC/SD Card support 903# MMC/SD Card support
@@ -707,6 +909,7 @@ CONFIG_USB_MON=y
707# 909#
708CONFIG_EXT2_FS=y 910CONFIG_EXT2_FS=y
709# CONFIG_EXT2_FS_XATTR is not set 911# CONFIG_EXT2_FS_XATTR is not set
912# CONFIG_EXT2_FS_XIP is not set
710CONFIG_EXT3_FS=y 913CONFIG_EXT3_FS=y
711CONFIG_EXT3_FS_XATTR=y 914CONFIG_EXT3_FS_XATTR=y
712# CONFIG_EXT3_FS_POSIX_ACL is not set 915# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -716,17 +919,17 @@ CONFIG_JBD=y
716CONFIG_FS_MBCACHE=y 919CONFIG_FS_MBCACHE=y
717# CONFIG_REISERFS_FS is not set 920# CONFIG_REISERFS_FS is not set
718# CONFIG_JFS_FS is not set 921# CONFIG_JFS_FS is not set
719 922# CONFIG_FS_POSIX_ACL is not set
720#
721# XFS support
722#
723# CONFIG_XFS_FS is not set 923# CONFIG_XFS_FS is not set
924# CONFIG_OCFS2_FS is not set
724# CONFIG_MINIX_FS is not set 925# CONFIG_MINIX_FS is not set
725# CONFIG_ROMFS_FS is not set 926# CONFIG_ROMFS_FS is not set
927CONFIG_INOTIFY=y
726# CONFIG_QUOTA is not set 928# CONFIG_QUOTA is not set
727CONFIG_DNOTIFY=y 929CONFIG_DNOTIFY=y
728# CONFIG_AUTOFS_FS is not set 930# CONFIG_AUTOFS_FS is not set
729# CONFIG_AUTOFS4_FS is not set 931# CONFIG_AUTOFS4_FS is not set
932# CONFIG_FUSE_FS is not set
730 933
731# 934#
732# CD-ROM/DVD Filesystems 935# CD-ROM/DVD Filesystems
@@ -749,12 +952,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
749# 952#
750CONFIG_PROC_FS=y 953CONFIG_PROC_FS=y
751CONFIG_SYSFS=y 954CONFIG_SYSFS=y
752# CONFIG_DEVFS_FS is not set
753# CONFIG_DEVPTS_FS_XATTR is not set
754CONFIG_TMPFS=y 955CONFIG_TMPFS=y
755# CONFIG_TMPFS_XATTR is not set
756# CONFIG_HUGETLB_PAGE is not set 956# CONFIG_HUGETLB_PAGE is not set
757CONFIG_RAMFS=y 957CONFIG_RAMFS=y
958# CONFIG_RELAYFS_FS is not set
959# CONFIG_CONFIGFS_FS is not set
758 960
759# 961#
760# Miscellaneous filesystems 962# Miscellaneous filesystems
@@ -769,8 +971,8 @@ CONFIG_RAMFS=y
769# CONFIG_JFFS_FS is not set 971# CONFIG_JFFS_FS is not set
770CONFIG_JFFS2_FS=y 972CONFIG_JFFS2_FS=y
771CONFIG_JFFS2_FS_DEBUG=0 973CONFIG_JFFS2_FS_DEBUG=0
772# CONFIG_JFFS2_FS_NAND is not set 974CONFIG_JFFS2_FS_WRITEBUFFER=y
773# CONFIG_JFFS2_FS_NOR_ECC is not set 975# CONFIG_JFFS2_SUMMARY is not set
774# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 976# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
775CONFIG_JFFS2_ZLIB=y 977CONFIG_JFFS2_ZLIB=y
776CONFIG_JFFS2_RTIME=y 978CONFIG_JFFS2_RTIME=y
@@ -787,12 +989,14 @@ CONFIG_CRAMFS=y
787# 989#
788CONFIG_NFS_FS=y 990CONFIG_NFS_FS=y
789CONFIG_NFS_V3=y 991CONFIG_NFS_V3=y
992# CONFIG_NFS_V3_ACL is not set
790# CONFIG_NFS_V4 is not set 993# CONFIG_NFS_V4 is not set
791# CONFIG_NFS_DIRECTIO is not set 994# CONFIG_NFS_DIRECTIO is not set
792# CONFIG_NFSD is not set 995# CONFIG_NFSD is not set
793CONFIG_ROOT_NFS=y 996CONFIG_ROOT_NFS=y
794CONFIG_LOCKD=y 997CONFIG_LOCKD=y
795CONFIG_LOCKD_V4=y 998CONFIG_LOCKD_V4=y
999CONFIG_NFS_COMMON=y
796CONFIG_SUNRPC=y 1000CONFIG_SUNRPC=y
797# CONFIG_RPCSEC_GSS_KRB5 is not set 1001# CONFIG_RPCSEC_GSS_KRB5 is not set
798# CONFIG_RPCSEC_GSS_SPKM3 is not set 1002# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -801,6 +1005,7 @@ CONFIG_SUNRPC=y
801# CONFIG_NCP_FS is not set 1005# CONFIG_NCP_FS is not set
802# CONFIG_CODA_FS is not set 1006# CONFIG_CODA_FS is not set
803# CONFIG_AFS_FS is not set 1007# CONFIG_AFS_FS is not set
1008# CONFIG_9P_FS is not set
804 1009
805# 1010#
806# Partition Types 1011# Partition Types
@@ -820,6 +1025,7 @@ CONFIG_MSDOS_PARTITION=y
820# CONFIG_SGI_PARTITION is not set 1025# CONFIG_SGI_PARTITION is not set
821# CONFIG_ULTRIX_PARTITION is not set 1026# CONFIG_ULTRIX_PARTITION is not set
822# CONFIG_SUN_PARTITION is not set 1027# CONFIG_SUN_PARTITION is not set
1028# CONFIG_KARMA_PARTITION is not set
823# CONFIG_EFI_PARTITION is not set 1029# CONFIG_EFI_PARTITION is not set
824 1030
825# 1031#
@@ -875,19 +1081,24 @@ CONFIG_NLS_DEFAULT="iso8859-1"
875# Kernel hacking 1081# Kernel hacking
876# 1082#
877# CONFIG_PRINTK_TIME is not set 1083# CONFIG_PRINTK_TIME is not set
878CONFIG_DEBUG_KERNEL=y
879CONFIG_MAGIC_SYSRQ=y 1084CONFIG_MAGIC_SYSRQ=y
880CONFIG_LOG_BUF_SHIFT=14 1085CONFIG_DEBUG_KERNEL=y
1086CONFIG_LOG_BUF_SHIFT=16
1087CONFIG_DETECT_SOFTLOCKUP=y
881# CONFIG_SCHEDSTATS is not set 1088# CONFIG_SCHEDSTATS is not set
882# CONFIG_DEBUG_SLAB is not set 1089# CONFIG_DEBUG_SLAB is not set
883CONFIG_DEBUG_PREEMPT=y 1090CONFIG_DEBUG_PREEMPT=y
1091CONFIG_DEBUG_MUTEXES=y
884# CONFIG_DEBUG_SPINLOCK is not set 1092# CONFIG_DEBUG_SPINLOCK is not set
885# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1093# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
886# CONFIG_DEBUG_KOBJECT is not set 1094# CONFIG_DEBUG_KOBJECT is not set
887CONFIG_DEBUG_BUGVERBOSE=y 1095CONFIG_DEBUG_BUGVERBOSE=y
888CONFIG_DEBUG_INFO=y 1096CONFIG_DEBUG_INFO=y
889# CONFIG_DEBUG_FS is not set 1097# CONFIG_DEBUG_FS is not set
1098# CONFIG_DEBUG_VM is not set
890CONFIG_FRAME_POINTER=y 1099CONFIG_FRAME_POINTER=y
1100CONFIG_FORCED_INLINING=y
1101# CONFIG_RCU_TORTURE_TEST is not set
891CONFIG_DEBUG_USER=y 1102CONFIG_DEBUG_USER=y
892# CONFIG_DEBUG_WAITQ is not set 1103# CONFIG_DEBUG_WAITQ is not set
893CONFIG_DEBUG_ERRORS=y 1104CONFIG_DEBUG_ERRORS=y
@@ -912,6 +1123,7 @@ CONFIG_DEBUG_ERRORS=y
912# Library routines 1123# Library routines
913# 1124#
914# CONFIG_CRC_CCITT is not set 1125# CONFIG_CRC_CCITT is not set
1126# CONFIG_CRC16 is not set
915CONFIG_CRC32=y 1127CONFIG_CRC32=y
916# CONFIG_LIBCRC32C is not set 1128# CONFIG_LIBCRC32C is not set
917CONFIG_ZLIB_INFLATE=y 1129CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig
new file mode 100644
index 000000000000..8a078d479d57
--- /dev/null
+++ b/arch/arm/configs/pnx4008_defconfig
@@ -0,0 +1,2072 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.17-rc1
4# Thu Apr 6 17:05:58 2006
5#
6CONFIG_ARM=y
7CONFIG_MMU=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_VECTORS_BASE=0xffff0000
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_BROKEN_ON_SMP=y
18CONFIG_LOCK_KERNEL=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_LOCALVERSION_AUTO=y
26CONFIG_SWAP=y
27CONFIG_SYSVIPC=y
28CONFIG_POSIX_MQUEUE=y
29CONFIG_BSD_PROCESS_ACCT=y
30# CONFIG_BSD_PROCESS_ACCT_V3 is not set
31CONFIG_SYSCTL=y
32CONFIG_AUDIT=y
33# CONFIG_IKCONFIG is not set
34# CONFIG_RELAY is not set
35CONFIG_INITRAMFS_SOURCE=""
36CONFIG_UID16=y
37CONFIG_CC_OPTIMIZE_FOR_SIZE=y
38CONFIG_EMBEDDED=y
39CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set
42CONFIG_HOTPLUG=y
43CONFIG_PRINTK=y
44CONFIG_BUG=y
45CONFIG_ELF_CORE=y
46CONFIG_BASE_FULL=y
47CONFIG_FUTEX=y
48CONFIG_EPOLL=y
49CONFIG_SHMEM=y
50CONFIG_SLAB=y
51# CONFIG_TINY_SHMEM is not set
52CONFIG_BASE_SMALL=0
53# CONFIG_SLOB is not set
54CONFIG_OBSOLETE_INTERMODULE=m
55
56#
57# Loadable module support
58#
59CONFIG_MODULES=y
60CONFIG_MODULE_UNLOAD=y
61CONFIG_MODULE_FORCE_UNLOAD=y
62CONFIG_MODVERSIONS=y
63CONFIG_MODULE_SRCVERSION_ALL=y
64CONFIG_KMOD=y
65
66#
67# Block layer
68#
69# CONFIG_BLK_DEV_IO_TRACE is not set
70
71#
72# IO Schedulers
73#
74CONFIG_IOSCHED_NOOP=y
75CONFIG_IOSCHED_AS=y
76CONFIG_IOSCHED_DEADLINE=y
77CONFIG_IOSCHED_CFQ=y
78CONFIG_DEFAULT_AS=y
79# CONFIG_DEFAULT_DEADLINE is not set
80# CONFIG_DEFAULT_CFQ is not set
81# CONFIG_DEFAULT_NOOP is not set
82CONFIG_DEFAULT_IOSCHED="anticipatory"
83
84#
85# System Type
86#
87# CONFIG_ARCH_CLPS7500 is not set
88# CONFIG_ARCH_CLPS711X is not set
89# CONFIG_ARCH_CO285 is not set
90# CONFIG_ARCH_EBSA110 is not set
91# CONFIG_ARCH_EP93XX is not set
92# CONFIG_ARCH_FOOTBRIDGE is not set
93# CONFIG_ARCH_INTEGRATOR is not set
94# CONFIG_ARCH_IOP3XX is not set
95# CONFIG_ARCH_IXP4XX is not set
96# CONFIG_ARCH_IXP2000 is not set
97# CONFIG_ARCH_IXP23XX is not set
98# CONFIG_ARCH_L7200 is not set
99# CONFIG_ARCH_PXA is not set
100# CONFIG_ARCH_RPC is not set
101# CONFIG_ARCH_SA1100 is not set
102# CONFIG_ARCH_S3C2410 is not set
103# CONFIG_ARCH_SHARK is not set
104# CONFIG_ARCH_LH7A40X is not set
105# CONFIG_ARCH_OMAP is not set
106# CONFIG_ARCH_VERSATILE is not set
107# CONFIG_ARCH_REALVIEW is not set
108# CONFIG_ARCH_IMX is not set
109# CONFIG_ARCH_H720X is not set
110# CONFIG_ARCH_AAEC2000 is not set
111# CONFIG_ARCH_AT91RM9200 is not set
112CONFIG_ARCH_PNX4008=y
113
114#
115# Processor Type
116#
117CONFIG_CPU_32=y
118CONFIG_CPU_ARM926T=y
119CONFIG_CPU_32v5=y
120CONFIG_CPU_ABRT_EV5TJ=y
121CONFIG_CPU_CACHE_VIVT=y
122CONFIG_CPU_COPY_V4WB=y
123CONFIG_CPU_TLB_V4WBI=y
124
125#
126# Processor Features
127#
128CONFIG_ARM_THUMB=y
129# CONFIG_CPU_ICACHE_DISABLE is not set
130# CONFIG_CPU_DCACHE_DISABLE is not set
131# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
132# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
133
134#
135# Bus support
136#
137
138#
139# PCCARD (PCMCIA/CardBus) support
140#
141CONFIG_PCCARD=m
142# CONFIG_PCMCIA_DEBUG is not set
143CONFIG_PCMCIA=m
144CONFIG_PCMCIA_LOAD_CIS=y
145CONFIG_PCMCIA_IOCTL=y
146
147#
148# PC-card bridges
149#
150
151#
152# Kernel Features
153#
154CONFIG_PREEMPT=y
155# CONFIG_NO_IDLE_HZ is not set
156CONFIG_HZ=100
157# CONFIG_AEABI is not set
158# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
159CONFIG_SELECT_MEMORY_MODEL=y
160CONFIG_FLATMEM_MANUAL=y
161# CONFIG_DISCONTIGMEM_MANUAL is not set
162# CONFIG_SPARSEMEM_MANUAL is not set
163CONFIG_FLATMEM=y
164CONFIG_FLAT_NODE_MEM_MAP=y
165# CONFIG_SPARSEMEM_STATIC is not set
166CONFIG_SPLIT_PTLOCK_CPUS=4096
167CONFIG_ALIGNMENT_TRAP=y
168
169#
170# Boot options
171#
172CONFIG_ZBOOT_ROM_TEXT=0
173CONFIG_ZBOOT_ROM_BSS=0
174CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
175# CONFIG_XIP_KERNEL is not set
176
177#
178# Floating point emulation
179#
180
181#
182# At least one emulation must be selected
183#
184# CONFIG_FPE_NWFPE is not set
185# CONFIG_FPE_FASTFPE is not set
186# CONFIG_VFP is not set
187
188#
189# Userspace binary formats
190#
191CONFIG_BINFMT_ELF=y
192CONFIG_BINFMT_AOUT=m
193CONFIG_BINFMT_MISC=m
194# CONFIG_ARTHUR is not set
195
196#
197# Power management options
198#
199CONFIG_PM=y
200CONFIG_PM_LEGACY=y
201# CONFIG_PM_DEBUG is not set
202CONFIG_APM=m
203
204#
205# Networking
206#
207CONFIG_NET=y
208
209#
210# Networking options
211#
212# CONFIG_NETDEBUG is not set
213CONFIG_PACKET=m
214CONFIG_PACKET_MMAP=y
215CONFIG_UNIX=m
216CONFIG_XFRM=y
217CONFIG_XFRM_USER=m
218CONFIG_NET_KEY=m
219CONFIG_INET=y
220CONFIG_IP_MULTICAST=y
221CONFIG_IP_ADVANCED_ROUTER=y
222CONFIG_ASK_IP_FIB_HASH=y
223# CONFIG_IP_FIB_TRIE is not set
224CONFIG_IP_FIB_HASH=y
225CONFIG_IP_MULTIPLE_TABLES=y
226CONFIG_IP_ROUTE_FWMARK=y
227CONFIG_IP_ROUTE_MULTIPATH=y
228# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
229CONFIG_IP_ROUTE_VERBOSE=y
230# CONFIG_IP_PNP is not set
231CONFIG_NET_IPIP=m
232CONFIG_NET_IPGRE=m
233CONFIG_NET_IPGRE_BROADCAST=y
234CONFIG_IP_MROUTE=y
235CONFIG_IP_PIMSM_V1=y
236CONFIG_IP_PIMSM_V2=y
237# CONFIG_ARPD is not set
238CONFIG_SYN_COOKIES=y
239CONFIG_INET_AH=m
240CONFIG_INET_ESP=m
241CONFIG_INET_IPCOMP=m
242CONFIG_INET_XFRM_TUNNEL=m
243CONFIG_INET_TUNNEL=m
244CONFIG_INET_DIAG=y
245CONFIG_INET_TCP_DIAG=y
246# CONFIG_TCP_CONG_ADVANCED is not set
247CONFIG_TCP_CONG_BIC=y
248
249#
250# IP: Virtual Server Configuration
251#
252CONFIG_IP_VS=m
253# CONFIG_IP_VS_DEBUG is not set
254CONFIG_IP_VS_TAB_BITS=12
255
256#
257# IPVS transport protocol load balancing support
258#
259CONFIG_IP_VS_PROTO_TCP=y
260CONFIG_IP_VS_PROTO_UDP=y
261CONFIG_IP_VS_PROTO_ESP=y
262CONFIG_IP_VS_PROTO_AH=y
263
264#
265# IPVS scheduler
266#
267CONFIG_IP_VS_RR=m
268CONFIG_IP_VS_WRR=m
269CONFIG_IP_VS_LC=m
270CONFIG_IP_VS_WLC=m
271CONFIG_IP_VS_LBLC=m
272CONFIG_IP_VS_LBLCR=m
273CONFIG_IP_VS_DH=m
274CONFIG_IP_VS_SH=m
275CONFIG_IP_VS_SED=m
276CONFIG_IP_VS_NQ=m
277
278#
279# IPVS application helper
280#
281CONFIG_IP_VS_FTP=m
282CONFIG_IPV6=m
283CONFIG_IPV6_PRIVACY=y
284# CONFIG_IPV6_ROUTER_PREF is not set
285CONFIG_INET6_AH=m
286CONFIG_INET6_ESP=m
287CONFIG_INET6_IPCOMP=m
288CONFIG_INET6_XFRM_TUNNEL=m
289CONFIG_INET6_TUNNEL=m
290CONFIG_IPV6_TUNNEL=m
291CONFIG_NETFILTER=y
292# CONFIG_NETFILTER_DEBUG is not set
293CONFIG_BRIDGE_NETFILTER=y
294
295#
296# Core Netfilter Configuration
297#
298# CONFIG_NETFILTER_NETLINK is not set
299# CONFIG_NETFILTER_XTABLES is not set
300
301#
302# IP: Netfilter Configuration
303#
304CONFIG_IP_NF_CONNTRACK=m
305CONFIG_IP_NF_CT_ACCT=y
306CONFIG_IP_NF_CONNTRACK_MARK=y
307# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
308CONFIG_IP_NF_CT_PROTO_SCTP=m
309CONFIG_IP_NF_FTP=m
310CONFIG_IP_NF_IRC=m
311# CONFIG_IP_NF_NETBIOS_NS is not set
312CONFIG_IP_NF_TFTP=m
313CONFIG_IP_NF_AMANDA=m
314# CONFIG_IP_NF_PPTP is not set
315# CONFIG_IP_NF_H323 is not set
316CONFIG_IP_NF_QUEUE=m
317
318#
319# IPv6: Netfilter Configuration (EXPERIMENTAL)
320#
321CONFIG_IP6_NF_QUEUE=m
322
323#
324# DECnet: Netfilter Configuration
325#
326CONFIG_DECNET_NF_GRABULATOR=m
327
328#
329# Bridge: Netfilter Configuration
330#
331CONFIG_BRIDGE_NF_EBTABLES=m
332CONFIG_BRIDGE_EBT_BROUTE=m
333CONFIG_BRIDGE_EBT_T_FILTER=m
334CONFIG_BRIDGE_EBT_T_NAT=m
335CONFIG_BRIDGE_EBT_802_3=m
336CONFIG_BRIDGE_EBT_AMONG=m
337CONFIG_BRIDGE_EBT_ARP=m
338CONFIG_BRIDGE_EBT_IP=m
339CONFIG_BRIDGE_EBT_LIMIT=m
340CONFIG_BRIDGE_EBT_MARK=m
341CONFIG_BRIDGE_EBT_PKTTYPE=m
342CONFIG_BRIDGE_EBT_STP=m
343CONFIG_BRIDGE_EBT_VLAN=m
344CONFIG_BRIDGE_EBT_ARPREPLY=m
345CONFIG_BRIDGE_EBT_DNAT=m
346CONFIG_BRIDGE_EBT_MARK_T=m
347CONFIG_BRIDGE_EBT_REDIRECT=m
348CONFIG_BRIDGE_EBT_SNAT=m
349CONFIG_BRIDGE_EBT_LOG=m
350# CONFIG_BRIDGE_EBT_ULOG is not set
351
352#
353# DCCP Configuration (EXPERIMENTAL)
354#
355# CONFIG_IP_DCCP is not set
356
357#
358# SCTP Configuration (EXPERIMENTAL)
359#
360CONFIG_IP_SCTP=m
361# CONFIG_SCTP_DBG_MSG is not set
362# CONFIG_SCTP_DBG_OBJCNT is not set
363# CONFIG_SCTP_HMAC_NONE is not set
364# CONFIG_SCTP_HMAC_SHA1 is not set
365CONFIG_SCTP_HMAC_MD5=y
366
367#
368# TIPC Configuration (EXPERIMENTAL)
369#
370# CONFIG_TIPC is not set
371CONFIG_ATM=y
372CONFIG_ATM_CLIP=y
373# CONFIG_ATM_CLIP_NO_ICMP is not set
374CONFIG_ATM_LANE=m
375CONFIG_ATM_MPOA=m
376CONFIG_ATM_BR2684=m
377# CONFIG_ATM_BR2684_IPFILTER is not set
378CONFIG_BRIDGE=m
379CONFIG_VLAN_8021Q=m
380CONFIG_DECNET=m
381# CONFIG_DECNET_ROUTER is not set
382CONFIG_LLC=m
383CONFIG_LLC2=m
384CONFIG_IPX=m
385# CONFIG_IPX_INTERN is not set
386CONFIG_ATALK=m
387CONFIG_DEV_APPLETALK=y
388CONFIG_IPDDP=m
389CONFIG_IPDDP_ENCAP=y
390CONFIG_IPDDP_DECAP=y
391CONFIG_X25=m
392CONFIG_LAPB=m
393# CONFIG_NET_DIVERT is not set
394CONFIG_ECONET=m
395CONFIG_ECONET_AUNUDP=y
396CONFIG_ECONET_NATIVE=y
397CONFIG_WAN_ROUTER=m
398
399#
400# QoS and/or fair queueing
401#
402CONFIG_NET_SCHED=y
403CONFIG_NET_SCH_CLK_JIFFIES=y
404# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
405# CONFIG_NET_SCH_CLK_CPU is not set
406
407#
408# Queueing/Scheduling
409#
410CONFIG_NET_SCH_CBQ=m
411CONFIG_NET_SCH_HTB=m
412CONFIG_NET_SCH_HFSC=m
413CONFIG_NET_SCH_ATM=m
414CONFIG_NET_SCH_PRIO=m
415CONFIG_NET_SCH_RED=m
416CONFIG_NET_SCH_SFQ=m
417CONFIG_NET_SCH_TEQL=m
418CONFIG_NET_SCH_TBF=m
419CONFIG_NET_SCH_GRED=m
420CONFIG_NET_SCH_DSMARK=m
421CONFIG_NET_SCH_NETEM=m
422CONFIG_NET_SCH_INGRESS=m
423
424#
425# Classification
426#
427CONFIG_NET_CLS=y
428# CONFIG_NET_CLS_BASIC is not set
429CONFIG_NET_CLS_TCINDEX=m
430CONFIG_NET_CLS_ROUTE4=m
431CONFIG_NET_CLS_ROUTE=y
432CONFIG_NET_CLS_FW=m
433CONFIG_NET_CLS_U32=m
434# CONFIG_CLS_U32_PERF is not set
435# CONFIG_CLS_U32_MARK is not set
436CONFIG_NET_CLS_RSVP=m
437CONFIG_NET_CLS_RSVP6=m
438# CONFIG_NET_EMATCH is not set
439# CONFIG_NET_CLS_ACT is not set
440CONFIG_NET_CLS_POLICE=y
441# CONFIG_NET_CLS_IND is not set
442CONFIG_NET_ESTIMATOR=y
443
444#
445# Network testing
446#
447CONFIG_NET_PKTGEN=m
448CONFIG_HAMRADIO=y
449
450#
451# Packet Radio protocols
452#
453CONFIG_AX25=m
454# CONFIG_AX25_DAMA_SLAVE is not set
455CONFIG_NETROM=m
456CONFIG_ROSE=m
457
458#
459# AX.25 network device drivers
460#
461CONFIG_MKISS=m
462CONFIG_6PACK=m
463CONFIG_BPQETHER=m
464CONFIG_BAYCOM_SER_FDX=m
465CONFIG_BAYCOM_SER_HDX=m
466CONFIG_BAYCOM_PAR=m
467CONFIG_BAYCOM_EPP=m
468CONFIG_YAM=m
469CONFIG_IRDA=m
470
471#
472# IrDA protocols
473#
474CONFIG_IRLAN=m
475CONFIG_IRNET=m
476CONFIG_IRCOMM=m
477# CONFIG_IRDA_ULTRA is not set
478
479#
480# IrDA options
481#
482CONFIG_IRDA_CACHE_LAST_LSAP=y
483CONFIG_IRDA_FAST_RR=y
484CONFIG_IRDA_DEBUG=y
485
486#
487# Infrared-port device drivers
488#
489
490#
491# SIR device drivers
492#
493CONFIG_IRTTY_SIR=m
494
495#
496# Dongle support
497#
498CONFIG_DONGLE=y
499CONFIG_ESI_DONGLE=m
500CONFIG_ACTISYS_DONGLE=m
501CONFIG_TEKRAM_DONGLE=m
502# CONFIG_TOIM3232_DONGLE is not set
503CONFIG_LITELINK_DONGLE=m
504CONFIG_MA600_DONGLE=m
505CONFIG_GIRBIL_DONGLE=m
506CONFIG_MCP2120_DONGLE=m
507CONFIG_OLD_BELKIN_DONGLE=m
508CONFIG_ACT200L_DONGLE=m
509
510#
511# Old SIR device drivers
512#
513CONFIG_IRPORT_SIR=m
514
515#
516# Old Serial dongle support
517#
518# CONFIG_DONGLE_OLD is not set
519
520#
521# FIR device drivers
522#
523CONFIG_USB_IRDA=m
524CONFIG_SIGMATEL_FIR=m
525CONFIG_BT=m
526CONFIG_BT_L2CAP=m
527CONFIG_BT_SCO=m
528CONFIG_BT_RFCOMM=m
529CONFIG_BT_RFCOMM_TTY=y
530CONFIG_BT_BNEP=m
531CONFIG_BT_BNEP_MC_FILTER=y
532CONFIG_BT_BNEP_PROTO_FILTER=y
533CONFIG_BT_CMTP=m
534CONFIG_BT_HIDP=m
535
536#
537# Bluetooth device drivers
538#
539CONFIG_BT_HCIUSB=m
540CONFIG_BT_HCIUSB_SCO=y
541CONFIG_BT_HCIUART=m
542CONFIG_BT_HCIUART_H4=y
543CONFIG_BT_HCIUART_BCSP=y
544CONFIG_BT_HCIBCM203X=m
545# CONFIG_BT_HCIBPA10X is not set
546CONFIG_BT_HCIBFUSB=m
547CONFIG_BT_HCIDTL1=m
548CONFIG_BT_HCIBT3C=m
549CONFIG_BT_HCIBLUECARD=m
550CONFIG_BT_HCIBTUART=m
551CONFIG_BT_HCIVHCI=m
552CONFIG_IEEE80211=m
553# CONFIG_IEEE80211_DEBUG is not set
554# CONFIG_IEEE80211_CRYPT_WEP is not set
555CONFIG_IEEE80211_CRYPT_CCMP=m
556CONFIG_IEEE80211_CRYPT_TKIP=m
557# CONFIG_IEEE80211_SOFTMAC is not set
558CONFIG_WIRELESS_EXT=y
559
560#
561# Device Drivers
562#
563
564#
565# Generic Driver Options
566#
567CONFIG_STANDALONE=y
568CONFIG_PREVENT_FIRMWARE_BUILD=y
569CONFIG_FW_LOADER=m
570# CONFIG_DEBUG_DRIVER is not set
571
572#
573# Connector - unified userspace <-> kernelspace linker
574#
575# CONFIG_CONNECTOR is not set
576
577#
578# Memory Technology Devices (MTD)
579#
580CONFIG_MTD=m
581# CONFIG_MTD_DEBUG is not set
582CONFIG_MTD_CONCAT=m
583CONFIG_MTD_PARTITIONS=y
584CONFIG_MTD_REDBOOT_PARTS=m
585CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
586# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
587# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
588# CONFIG_MTD_CMDLINE_PARTS is not set
589# CONFIG_MTD_AFS_PARTS is not set
590
591#
592# User Modules And Translation Layers
593#
594CONFIG_MTD_CHAR=m
595CONFIG_MTD_BLOCK=m
596CONFIG_MTD_BLOCK_RO=m
597CONFIG_FTL=m
598CONFIG_NFTL=m
599CONFIG_NFTL_RW=y
600CONFIG_INFTL=m
601# CONFIG_RFD_FTL is not set
602
603#
604# RAM/ROM/Flash chip drivers
605#
606CONFIG_MTD_CFI=m
607CONFIG_MTD_JEDECPROBE=m
608CONFIG_MTD_GEN_PROBE=m
609# CONFIG_MTD_CFI_ADV_OPTIONS is not set
610CONFIG_MTD_MAP_BANK_WIDTH_1=y
611CONFIG_MTD_MAP_BANK_WIDTH_2=y
612CONFIG_MTD_MAP_BANK_WIDTH_4=y
613# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
614# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
615# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
616CONFIG_MTD_CFI_I1=y
617CONFIG_MTD_CFI_I2=y
618# CONFIG_MTD_CFI_I4 is not set
619# CONFIG_MTD_CFI_I8 is not set
620CONFIG_MTD_CFI_INTELEXT=m
621CONFIG_MTD_CFI_AMDSTD=m
622CONFIG_MTD_CFI_STAA=m
623CONFIG_MTD_CFI_UTIL=m
624CONFIG_MTD_RAM=m
625CONFIG_MTD_ROM=m
626CONFIG_MTD_ABSENT=m
627# CONFIG_MTD_OBSOLETE_CHIPS is not set
628
629#
630# Mapping drivers for chip access
631#
632CONFIG_MTD_COMPLEX_MAPPINGS=y
633CONFIG_MTD_PHYSMAP=m
634CONFIG_MTD_PHYSMAP_START=0x8000000
635CONFIG_MTD_PHYSMAP_LEN=0x4000000
636CONFIG_MTD_PHYSMAP_BANKWIDTH=2
637# CONFIG_MTD_ARM_INTEGRATOR is not set
638# CONFIG_MTD_IMPA7 is not set
639# CONFIG_MTD_PLATRAM is not set
640
641#
642# Self-contained MTD device drivers
643#
644CONFIG_MTD_SLRAM=m
645CONFIG_MTD_PHRAM=m
646CONFIG_MTD_MTDRAM=m
647CONFIG_MTDRAM_TOTAL_SIZE=4096
648CONFIG_MTDRAM_ERASE_SIZE=128
649CONFIG_MTD_BLKMTD=m
650# CONFIG_MTD_BLOCK2MTD is not set
651
652#
653# Disk-On-Chip Device Drivers
654#
655CONFIG_MTD_DOC2000=m
656CONFIG_MTD_DOC2001=m
657CONFIG_MTD_DOC2001PLUS=m
658CONFIG_MTD_DOCPROBE=m
659CONFIG_MTD_DOCECC=m
660# CONFIG_MTD_DOCPROBE_ADVANCED is not set
661CONFIG_MTD_DOCPROBE_ADDRESS=0
662
663#
664# NAND Flash Device Drivers
665#
666CONFIG_MTD_NAND=m
667# CONFIG_MTD_NAND_VERIFY_WRITE is not set
668CONFIG_MTD_NAND_IDS=m
669CONFIG_MTD_NAND_DISKONCHIP=m
670# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
671CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
672# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
673# CONFIG_MTD_NAND_NANDSIM is not set
674
675#
676# OneNAND Flash Device Drivers
677#
678# CONFIG_MTD_ONENAND is not set
679
680#
681# Parallel port support
682#
683CONFIG_PARPORT=m
684CONFIG_PARPORT_PC=m
685CONFIG_PARPORT_PC_FIFO=y
686# CONFIG_PARPORT_PC_SUPERIO is not set
687CONFIG_PARPORT_PC_PCMCIA=m
688CONFIG_PARPORT_NOT_PC=y
689# CONFIG_PARPORT_ARC is not set
690# CONFIG_PARPORT_GSC is not set
691CONFIG_PARPORT_1284=y
692
693#
694# Plug and Play support
695#
696
697#
698# Block devices
699#
700CONFIG_PARIDE=m
701CONFIG_PARIDE_PARPORT=m
702
703#
704# Parallel IDE high-level drivers
705#
706CONFIG_PARIDE_PD=m
707CONFIG_PARIDE_PCD=m
708CONFIG_PARIDE_PF=m
709CONFIG_PARIDE_PT=m
710CONFIG_PARIDE_PG=m
711
712#
713# Parallel IDE protocol modules
714#
715CONFIG_PARIDE_ATEN=m
716CONFIG_PARIDE_BPCK=m
717CONFIG_PARIDE_BPCK6=m
718CONFIG_PARIDE_COMM=m
719CONFIG_PARIDE_DSTR=m
720CONFIG_PARIDE_FIT2=m
721CONFIG_PARIDE_FIT3=m
722CONFIG_PARIDE_EPAT=m
723# CONFIG_PARIDE_EPATC8 is not set
724CONFIG_PARIDE_EPIA=m
725CONFIG_PARIDE_FRIQ=m
726CONFIG_PARIDE_FRPW=m
727CONFIG_PARIDE_KBIC=m
728CONFIG_PARIDE_KTTI=m
729CONFIG_PARIDE_ON20=m
730CONFIG_PARIDE_ON26=m
731# CONFIG_BLK_DEV_COW_COMMON is not set
732CONFIG_BLK_DEV_LOOP=m
733CONFIG_BLK_DEV_CRYPTOLOOP=m
734CONFIG_BLK_DEV_NBD=m
735# CONFIG_BLK_DEV_UB is not set
736CONFIG_BLK_DEV_RAM=y
737CONFIG_BLK_DEV_RAM_COUNT=16
738CONFIG_BLK_DEV_RAM_SIZE=8192
739CONFIG_BLK_DEV_INITRD=y
740CONFIG_CDROM_PKTCDVD=m
741CONFIG_CDROM_PKTCDVD_BUFFERS=8
742# CONFIG_CDROM_PKTCDVD_WCACHE is not set
743# CONFIG_ATA_OVER_ETH is not set
744
745#
746# ATA/ATAPI/MFM/RLL support
747#
748CONFIG_IDE=m
749CONFIG_BLK_DEV_IDE=m
750
751#
752# Please see Documentation/ide.txt for help/info on IDE drives
753#
754# CONFIG_BLK_DEV_IDE_SATA is not set
755CONFIG_BLK_DEV_IDEDISK=m
756# CONFIG_IDEDISK_MULTI_MODE is not set
757CONFIG_BLK_DEV_IDECS=m
758CONFIG_BLK_DEV_IDECD=m
759CONFIG_BLK_DEV_IDETAPE=m
760CONFIG_BLK_DEV_IDEFLOPPY=m
761CONFIG_BLK_DEV_IDESCSI=m
762# CONFIG_IDE_TASK_IOCTL is not set
763
764#
765# IDE chipset support/bugfixes
766#
767CONFIG_IDE_GENERIC=m
768# CONFIG_IDE_ARM is not set
769# CONFIG_BLK_DEV_IDEDMA is not set
770# CONFIG_IDEDMA_AUTO is not set
771# CONFIG_BLK_DEV_HD is not set
772
773#
774# SCSI device support
775#
776# CONFIG_RAID_ATTRS is not set
777CONFIG_SCSI=m
778CONFIG_SCSI_PROC_FS=y
779
780#
781# SCSI support type (disk, tape, CD-ROM)
782#
783CONFIG_BLK_DEV_SD=m
784CONFIG_CHR_DEV_ST=m
785CONFIG_CHR_DEV_OSST=m
786CONFIG_BLK_DEV_SR=m
787# CONFIG_BLK_DEV_SR_VENDOR is not set
788CONFIG_CHR_DEV_SG=m
789CONFIG_CHR_DEV_SCH=m
790
791#
792# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
793#
794CONFIG_SCSI_MULTI_LUN=y
795CONFIG_SCSI_CONSTANTS=y
796CONFIG_SCSI_LOGGING=y
797
798#
799# SCSI Transport Attributes
800#
801CONFIG_SCSI_SPI_ATTRS=m
802CONFIG_SCSI_FC_ATTRS=m
803# CONFIG_SCSI_ISCSI_ATTRS is not set
804# CONFIG_SCSI_SAS_ATTRS is not set
805
806#
807# SCSI low-level drivers
808#
809# CONFIG_ISCSI_TCP is not set
810CONFIG_SCSI_SATA=m
811CONFIG_SCSI_PPA=m
812CONFIG_SCSI_IMM=m
813# CONFIG_SCSI_IZIP_EPP16 is not set
814# CONFIG_SCSI_IZIP_SLOW_CTR is not set
815CONFIG_SCSI_DEBUG=m
816
817#
818# PCMCIA SCSI adapter support
819#
820CONFIG_PCMCIA_AHA152X=m
821CONFIG_PCMCIA_FDOMAIN=m
822CONFIG_PCMCIA_NINJA_SCSI=m
823CONFIG_PCMCIA_QLOGIC=m
824CONFIG_PCMCIA_SYM53C500=m
825
826#
827# Multi-device support (RAID and LVM)
828#
829CONFIG_MD=y
830CONFIG_BLK_DEV_MD=m
831CONFIG_MD_LINEAR=m
832CONFIG_MD_RAID0=m
833CONFIG_MD_RAID1=m
834CONFIG_MD_RAID10=m
835CONFIG_MD_RAID5=m
836# CONFIG_MD_RAID5_RESHAPE is not set
837CONFIG_MD_RAID6=m
838CONFIG_MD_MULTIPATH=m
839CONFIG_MD_FAULTY=m
840CONFIG_BLK_DEV_DM=m
841CONFIG_DM_CRYPT=m
842CONFIG_DM_SNAPSHOT=m
843CONFIG_DM_MIRROR=m
844CONFIG_DM_ZERO=m
845# CONFIG_DM_MULTIPATH is not set
846
847#
848# Fusion MPT device support
849#
850# CONFIG_FUSION is not set
851
852#
853# IEEE 1394 (FireWire) support
854#
855
856#
857# I2O device support
858#
859
860#
861# Network device support
862#
863CONFIG_NETDEVICES=y
864CONFIG_DUMMY=m
865CONFIG_BONDING=m
866CONFIG_EQUALIZER=m
867CONFIG_TUN=m
868
869#
870# PHY device support
871#
872# CONFIG_PHYLIB is not set
873
874#
875# Ethernet (10 or 100Mbit)
876#
877CONFIG_NET_ETHERNET=y
878CONFIG_MII=m
879# CONFIG_SMC91X is not set
880# CONFIG_DM9000 is not set
881CONFIG_NET_POCKET=y
882CONFIG_DE600=m
883CONFIG_DE620=m
884
885#
886# Ethernet (1000 Mbit)
887#
888
889#
890# Ethernet (10000 Mbit)
891#
892
893#
894# Token Ring devices
895#
896
897#
898# Wireless LAN (non-hamradio)
899#
900CONFIG_NET_RADIO=y
901# CONFIG_NET_WIRELESS_RTNETLINK is not set
902
903#
904# Obsolete Wireless cards support (pre-802.11)
905#
906CONFIG_STRIP=m
907CONFIG_PCMCIA_WAVELAN=m
908CONFIG_PCMCIA_NETWAVE=m
909
910#
911# Wireless 802.11 Frequency Hopping cards support
912#
913CONFIG_PCMCIA_RAYCS=m
914
915#
916# Wireless 802.11b ISA/PCI cards support
917#
918CONFIG_HERMES=m
919CONFIG_ATMEL=m
920
921#
922# Wireless 802.11b Pcmcia/Cardbus cards support
923#
924CONFIG_PCMCIA_HERMES=m
925# CONFIG_PCMCIA_SPECTRUM is not set
926CONFIG_AIRO_CS=m
927CONFIG_PCMCIA_ATMEL=m
928CONFIG_PCMCIA_WL3501=m
929# CONFIG_HOSTAP is not set
930CONFIG_NET_WIRELESS=y
931
932#
933# PCMCIA network device support
934#
935CONFIG_NET_PCMCIA=y
936CONFIG_PCMCIA_3C589=m
937CONFIG_PCMCIA_3C574=m
938CONFIG_PCMCIA_FMVJ18X=m
939CONFIG_PCMCIA_PCNET=m
940CONFIG_PCMCIA_NMCLAN=m
941CONFIG_PCMCIA_SMC91C92=m
942CONFIG_PCMCIA_XIRC2PS=m
943CONFIG_PCMCIA_AXNET=m
944
945#
946# Wan interfaces
947#
948CONFIG_WAN=y
949CONFIG_SYNCLINK_SYNCPPP=m
950CONFIG_HDLC=m
951CONFIG_HDLC_RAW=y
952CONFIG_HDLC_RAW_ETH=y
953CONFIG_HDLC_CISCO=y
954CONFIG_HDLC_FR=y
955CONFIG_HDLC_PPP=y
956CONFIG_HDLC_X25=y
957CONFIG_DLCI=m
958CONFIG_DLCI_COUNT=24
959CONFIG_DLCI_MAX=8
960CONFIG_WAN_ROUTER_DRIVERS=y
961CONFIG_LAPBETHER=m
962CONFIG_X25_ASY=m
963
964#
965# ATM drivers
966#
967# CONFIG_ATM_DUMMY is not set
968CONFIG_ATM_TCP=m
969CONFIG_PLIP=m
970CONFIG_PPP=m
971CONFIG_PPP_MULTILINK=y
972CONFIG_PPP_FILTER=y
973CONFIG_PPP_ASYNC=m
974CONFIG_PPP_SYNC_TTY=m
975CONFIG_PPP_DEFLATE=m
976CONFIG_PPP_BSDCOMP=m
977CONFIG_PPP_MPPE=m
978CONFIG_PPPOE=m
979CONFIG_PPPOATM=m
980CONFIG_SLIP=m
981CONFIG_SLIP_COMPRESSED=y
982CONFIG_SLIP_SMART=y
983CONFIG_SLIP_MODE_SLIP6=y
984CONFIG_SHAPER=m
985CONFIG_NETCONSOLE=m
986CONFIG_NETPOLL=y
987# CONFIG_NETPOLL_RX is not set
988# CONFIG_NETPOLL_TRAP is not set
989CONFIG_NET_POLL_CONTROLLER=y
990
991#
992# ISDN subsystem
993#
994CONFIG_ISDN=m
995
996#
997# Old ISDN4Linux
998#
999CONFIG_ISDN_I4L=m
1000CONFIG_ISDN_PPP=y
1001CONFIG_ISDN_PPP_VJ=y
1002CONFIG_ISDN_MPP=y
1003CONFIG_IPPP_FILTER=y
1004CONFIG_ISDN_PPP_BSDCOMP=m
1005CONFIG_ISDN_AUDIO=y
1006CONFIG_ISDN_TTY_FAX=y
1007CONFIG_ISDN_X25=y
1008
1009#
1010# ISDN feature submodules
1011#
1012CONFIG_ISDN_DRV_LOOP=m
1013CONFIG_ISDN_DIVERSION=m
1014
1015#
1016# ISDN4Linux hardware drivers
1017#
1018
1019#
1020# Passive cards
1021#
1022CONFIG_ISDN_DRV_HISAX=m
1023
1024#
1025# D-channel protocol features
1026#
1027CONFIG_HISAX_EURO=y
1028CONFIG_DE_AOC=y
1029# CONFIG_HISAX_NO_SENDCOMPLETE is not set
1030# CONFIG_HISAX_NO_LLC is not set
1031# CONFIG_HISAX_NO_KEYPAD is not set
1032CONFIG_HISAX_1TR6=y
1033CONFIG_HISAX_NI1=y
1034CONFIG_HISAX_MAX_CARDS=8
1035
1036#
1037# HiSax supported cards
1038#
1039CONFIG_HISAX_16_3=y
1040CONFIG_HISAX_S0BOX=y
1041CONFIG_HISAX_FRITZPCI=y
1042CONFIG_HISAX_AVM_A1_PCMCIA=y
1043CONFIG_HISAX_ELSA=y
1044CONFIG_HISAX_DIEHLDIVA=y
1045CONFIG_HISAX_SEDLBAUER=y
1046CONFIG_HISAX_NICCY=y
1047CONFIG_HISAX_GAZEL=y
1048CONFIG_HISAX_HFC_SX=y
1049# CONFIG_HISAX_DEBUG is not set
1050
1051#
1052# HiSax PCMCIA card service modules
1053#
1054CONFIG_HISAX_SEDLBAUER_CS=m
1055CONFIG_HISAX_ELSA_CS=m
1056CONFIG_HISAX_AVM_A1_CS=m
1057CONFIG_HISAX_TELES_CS=m
1058
1059#
1060# HiSax sub driver modules
1061#
1062CONFIG_HISAX_ST5481=m
1063CONFIG_HISAX_HFCUSB=m
1064# CONFIG_HISAX_HFC4S8S is not set
1065CONFIG_HISAX_HDLC=y
1066
1067#
1068# Active cards
1069#
1070
1071#
1072# Siemens Gigaset
1073#
1074# CONFIG_ISDN_DRV_GIGASET is not set
1075
1076#
1077# CAPI subsystem
1078#
1079CONFIG_ISDN_CAPI=m
1080CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
1081CONFIG_ISDN_CAPI_MIDDLEWARE=y
1082CONFIG_ISDN_CAPI_CAPI20=m
1083CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
1084CONFIG_ISDN_CAPI_CAPIFS=m
1085CONFIG_ISDN_CAPI_CAPIDRV=m
1086
1087#
1088# CAPI hardware drivers
1089#
1090
1091#
1092# Active AVM cards
1093#
1094CONFIG_CAPI_AVM=y
1095CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
1096CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
1097
1098#
1099# Active Eicon DIVA Server cards
1100#
1101CONFIG_CAPI_EICON=y
1102
1103#
1104# Input device support
1105#
1106CONFIG_INPUT=y
1107
1108#
1109# Userland interfaces
1110#
1111CONFIG_INPUT_MOUSEDEV=m
1112CONFIG_INPUT_MOUSEDEV_PSAUX=y
1113CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1114CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1115CONFIG_INPUT_JOYDEV=m
1116CONFIG_INPUT_TSDEV=m
1117CONFIG_INPUT_TSDEV_SCREEN_X=240
1118CONFIG_INPUT_TSDEV_SCREEN_Y=320
1119CONFIG_INPUT_EVDEV=m
1120CONFIG_INPUT_EVBUG=m
1121
1122#
1123# Input Device Drivers
1124#
1125CONFIG_INPUT_KEYBOARD=y
1126CONFIG_KEYBOARD_ATKBD=y
1127CONFIG_KEYBOARD_SUNKBD=m
1128CONFIG_KEYBOARD_LKKBD=m
1129CONFIG_KEYBOARD_XTKBD=m
1130CONFIG_KEYBOARD_NEWTON=m
1131CONFIG_INPUT_MOUSE=y
1132CONFIG_MOUSE_PS2=m
1133CONFIG_MOUSE_SERIAL=m
1134CONFIG_MOUSE_VSXXXAA=m
1135CONFIG_INPUT_JOYSTICK=y
1136CONFIG_JOYSTICK_ANALOG=m
1137CONFIG_JOYSTICK_A3D=m
1138CONFIG_JOYSTICK_ADI=m
1139CONFIG_JOYSTICK_COBRA=m
1140CONFIG_JOYSTICK_GF2K=m
1141CONFIG_JOYSTICK_GRIP=m
1142CONFIG_JOYSTICK_GRIP_MP=m
1143CONFIG_JOYSTICK_GUILLEMOT=m
1144CONFIG_JOYSTICK_INTERACT=m
1145CONFIG_JOYSTICK_SIDEWINDER=m
1146CONFIG_JOYSTICK_TMDC=m
1147CONFIG_JOYSTICK_IFORCE=m
1148CONFIG_JOYSTICK_IFORCE_USB=y
1149CONFIG_JOYSTICK_IFORCE_232=y
1150CONFIG_JOYSTICK_WARRIOR=m
1151CONFIG_JOYSTICK_MAGELLAN=m
1152CONFIG_JOYSTICK_SPACEORB=m
1153CONFIG_JOYSTICK_SPACEBALL=m
1154CONFIG_JOYSTICK_STINGER=m
1155# CONFIG_JOYSTICK_TWIDJOY is not set
1156CONFIG_JOYSTICK_DB9=m
1157CONFIG_JOYSTICK_GAMECON=m
1158CONFIG_JOYSTICK_TURBOGRAFX=m
1159CONFIG_JOYSTICK_JOYDUMP=m
1160CONFIG_INPUT_TOUCHSCREEN=y
1161CONFIG_TOUCHSCREEN_GUNZE=m
1162# CONFIG_TOUCHSCREEN_ELO is not set
1163# CONFIG_TOUCHSCREEN_MTOUCH is not set
1164# CONFIG_TOUCHSCREEN_MK712 is not set
1165CONFIG_INPUT_MISC=y
1166CONFIG_INPUT_UINPUT=m
1167
1168#
1169# Hardware I/O ports
1170#
1171CONFIG_SERIO=y
1172CONFIG_SERIO_SERPORT=m
1173CONFIG_SERIO_PARKBD=m
1174CONFIG_SERIO_LIBPS2=y
1175CONFIG_SERIO_RAW=m
1176CONFIG_GAMEPORT=m
1177CONFIG_GAMEPORT_NS558=m
1178CONFIG_GAMEPORT_L4=m
1179
1180#
1181# Character devices
1182#
1183CONFIG_VT=y
1184CONFIG_VT_CONSOLE=y
1185CONFIG_HW_CONSOLE=y
1186CONFIG_SERIAL_NONSTANDARD=y
1187CONFIG_COMPUTONE=m
1188CONFIG_ROCKETPORT=m
1189CONFIG_CYCLADES=m
1190# CONFIG_CYZ_INTR is not set
1191CONFIG_DIGIEPCA=m
1192CONFIG_MOXA_INTELLIO=m
1193CONFIG_MOXA_SMARTIO=m
1194# CONFIG_ISI is not set
1195CONFIG_SYNCLINKMP=m
1196CONFIG_N_HDLC=m
1197# CONFIG_RISCOM8 is not set
1198# CONFIG_SPECIALIX is not set
1199CONFIG_SX=m
1200CONFIG_RIO=m
1201CONFIG_RIO_OLDPCI=y
1202CONFIG_STALDRV=y
1203CONFIG_STALLION=m
1204CONFIG_ISTALLION=m
1205
1206#
1207# Serial drivers
1208#
1209CONFIG_SERIAL_8250=y
1210CONFIG_SERIAL_8250_CONSOLE=y
1211CONFIG_SERIAL_8250_CS=m
1212CONFIG_SERIAL_8250_NR_UARTS=4
1213CONFIG_SERIAL_8250_RUNTIME_UARTS=4
1214CONFIG_SERIAL_8250_EXTENDED=y
1215CONFIG_SERIAL_8250_MANY_PORTS=y
1216CONFIG_SERIAL_8250_SHARE_IRQ=y
1217# CONFIG_SERIAL_8250_DETECT_IRQ is not set
1218CONFIG_SERIAL_8250_RSA=y
1219
1220#
1221# Non-8250 serial port support
1222#
1223CONFIG_SERIAL_CORE=y
1224CONFIG_SERIAL_CORE_CONSOLE=y
1225CONFIG_UNIX98_PTYS=y
1226CONFIG_LEGACY_PTYS=y
1227CONFIG_LEGACY_PTY_COUNT=256
1228CONFIG_PRINTER=m
1229# CONFIG_LP_CONSOLE is not set
1230CONFIG_PPDEV=m
1231CONFIG_TIPAR=m
1232
1233#
1234# IPMI
1235#
1236CONFIG_IPMI_HANDLER=m
1237# CONFIG_IPMI_PANIC_EVENT is not set
1238CONFIG_IPMI_DEVICE_INTERFACE=m
1239CONFIG_IPMI_SI=m
1240CONFIG_IPMI_WATCHDOG=m
1241CONFIG_IPMI_POWEROFF=m
1242
1243#
1244# Watchdog Cards
1245#
1246CONFIG_WATCHDOG=y
1247# CONFIG_WATCHDOG_NOWAYOUT is not set
1248
1249#
1250# Watchdog Device Drivers
1251#
1252CONFIG_SOFT_WATCHDOG=m
1253
1254#
1255# USB-based Watchdog Cards
1256#
1257CONFIG_USBPCWATCHDOG=m
1258CONFIG_NVRAM=m
1259CONFIG_DTLK=m
1260CONFIG_R3964=m
1261
1262#
1263# Ftape, the floppy tape device driver
1264#
1265
1266#
1267# PCMCIA character devices
1268#
1269CONFIG_SYNCLINK_CS=m
1270# CONFIG_CARDMAN_4000 is not set
1271# CONFIG_CARDMAN_4040 is not set
1272CONFIG_RAW_DRIVER=m
1273CONFIG_MAX_RAW_DEVS=256
1274
1275#
1276# TPM devices
1277#
1278# CONFIG_TCG_TPM is not set
1279# CONFIG_TELCLOCK is not set
1280
1281#
1282# I2C support
1283#
1284CONFIG_I2C=m
1285CONFIG_I2C_CHARDEV=m
1286
1287#
1288# I2C Algorithms
1289#
1290CONFIG_I2C_ALGOBIT=m
1291CONFIG_I2C_ALGOPCF=m
1292CONFIG_I2C_ALGOPCA=m
1293
1294#
1295# I2C Hardware Bus support
1296#
1297CONFIG_I2C_ISA=m
1298CONFIG_I2C_PARPORT=m
1299CONFIG_I2C_PARPORT_LIGHT=m
1300CONFIG_I2C_STUB=m
1301CONFIG_I2C_PCA_ISA=m
1302
1303#
1304# Miscellaneous I2C Chip support
1305#
1306# CONFIG_SENSORS_DS1337 is not set
1307# CONFIG_SENSORS_DS1374 is not set
1308CONFIG_SENSORS_EEPROM=m
1309CONFIG_SENSORS_PCF8574=m
1310# CONFIG_SENSORS_PCA9539 is not set
1311CONFIG_SENSORS_PCF8591=m
1312# CONFIG_SENSORS_MAX6875 is not set
1313# CONFIG_I2C_DEBUG_CORE is not set
1314# CONFIG_I2C_DEBUG_ALGO is not set
1315# CONFIG_I2C_DEBUG_BUS is not set
1316# CONFIG_I2C_DEBUG_CHIP is not set
1317
1318#
1319# SPI support
1320#
1321# CONFIG_SPI is not set
1322# CONFIG_SPI_MASTER is not set
1323
1324#
1325# Dallas's 1-wire bus
1326#
1327CONFIG_W1=m
1328
1329#
1330# 1-wire Bus Masters
1331#
1332# CONFIG_W1_MASTER_DS9490 is not set
1333# CONFIG_W1_MASTER_DS2482 is not set
1334
1335#
1336# 1-wire Slaves
1337#
1338# CONFIG_W1_SLAVE_THERM is not set
1339# CONFIG_W1_SLAVE_SMEM is not set
1340# CONFIG_W1_SLAVE_DS2433 is not set
1341
1342#
1343# Hardware Monitoring support
1344#
1345CONFIG_HWMON=y
1346CONFIG_HWMON_VID=m
1347CONFIG_SENSORS_ADM1021=m
1348CONFIG_SENSORS_ADM1025=m
1349CONFIG_SENSORS_ADM1026=m
1350CONFIG_SENSORS_ADM1031=m
1351# CONFIG_SENSORS_ADM9240 is not set
1352CONFIG_SENSORS_ASB100=m
1353# CONFIG_SENSORS_ATXP1 is not set
1354CONFIG_SENSORS_DS1621=m
1355# CONFIG_SENSORS_F71805F is not set
1356CONFIG_SENSORS_FSCHER=m
1357# CONFIG_SENSORS_FSCPOS is not set
1358CONFIG_SENSORS_GL518SM=m
1359# CONFIG_SENSORS_GL520SM is not set
1360CONFIG_SENSORS_IT87=m
1361CONFIG_SENSORS_LM63=m
1362CONFIG_SENSORS_LM75=m
1363CONFIG_SENSORS_LM77=m
1364CONFIG_SENSORS_LM78=m
1365CONFIG_SENSORS_LM80=m
1366CONFIG_SENSORS_LM83=m
1367CONFIG_SENSORS_LM85=m
1368CONFIG_SENSORS_LM87=m
1369CONFIG_SENSORS_LM90=m
1370# CONFIG_SENSORS_LM92 is not set
1371CONFIG_SENSORS_MAX1619=m
1372CONFIG_SENSORS_PC87360=m
1373CONFIG_SENSORS_SMSC47M1=m
1374# CONFIG_SENSORS_SMSC47B397 is not set
1375CONFIG_SENSORS_W83781D=m
1376# CONFIG_SENSORS_W83792D is not set
1377CONFIG_SENSORS_W83L785TS=m
1378CONFIG_SENSORS_W83627HF=m
1379# CONFIG_SENSORS_W83627EHF is not set
1380# CONFIG_HWMON_DEBUG_CHIP is not set
1381
1382#
1383# Misc devices
1384#
1385
1386#
1387# LED devices
1388#
1389# CONFIG_NEW_LEDS is not set
1390
1391#
1392# Multimedia devices
1393#
1394# CONFIG_VIDEO_DEV is not set
1395
1396#
1397# Digital Video Broadcasting Devices
1398#
1399CONFIG_DVB=y
1400CONFIG_DVB_CORE=m
1401
1402#
1403# Supported USB Adapters
1404#
1405# CONFIG_DVB_USB is not set
1406CONFIG_DVB_TTUSB_BUDGET=m
1407CONFIG_DVB_TTUSB_DEC=m
1408CONFIG_DVB_CINERGYT2=m
1409CONFIG_DVB_CINERGYT2_TUNING=y
1410CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
1411CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
1412CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
1413CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
1414CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
1415
1416#
1417# Supported FlexCopII (B2C2) Adapters
1418#
1419# CONFIG_DVB_B2C2_FLEXCOP is not set
1420
1421#
1422# Supported DVB Frontends
1423#
1424
1425#
1426# Customise DVB Frontends
1427#
1428
1429#
1430# DVB-S (satellite) frontends
1431#
1432CONFIG_DVB_STV0299=m
1433CONFIG_DVB_CX24110=m
1434# CONFIG_DVB_CX24123 is not set
1435CONFIG_DVB_TDA8083=m
1436CONFIG_DVB_MT312=m
1437CONFIG_DVB_VES1X93=m
1438# CONFIG_DVB_S5H1420 is not set
1439
1440#
1441# DVB-T (terrestrial) frontends
1442#
1443CONFIG_DVB_SP8870=m
1444CONFIG_DVB_SP887X=m
1445CONFIG_DVB_CX22700=m
1446CONFIG_DVB_CX22702=m
1447CONFIG_DVB_L64781=m
1448CONFIG_DVB_TDA1004X=m
1449CONFIG_DVB_NXT6000=m
1450CONFIG_DVB_MT352=m
1451# CONFIG_DVB_ZL10353 is not set
1452CONFIG_DVB_DIB3000MB=m
1453CONFIG_DVB_DIB3000MC=m
1454
1455#
1456# DVB-C (cable) frontends
1457#
1458CONFIG_DVB_VES1820=m
1459CONFIG_DVB_TDA10021=m
1460CONFIG_DVB_STV0297=m
1461
1462#
1463# ATSC (North American/Korean Terresterial DTV) frontends
1464#
1465# CONFIG_DVB_NXT200X is not set
1466# CONFIG_DVB_OR51211 is not set
1467# CONFIG_DVB_OR51132 is not set
1468# CONFIG_DVB_BCM3510 is not set
1469# CONFIG_DVB_LGDT330X is not set
1470# CONFIG_USB_DABUSB is not set
1471
1472#
1473# Graphics support
1474#
1475# CONFIG_FB is not set
1476
1477#
1478# Console display driver support
1479#
1480# CONFIG_VGA_CONSOLE is not set
1481CONFIG_DUMMY_CONSOLE=y
1482
1483#
1484# Sound
1485#
1486CONFIG_SOUND=m
1487
1488#
1489# Advanced Linux Sound Architecture
1490#
1491CONFIG_SND=m
1492CONFIG_SND_TIMER=m
1493CONFIG_SND_PCM=m
1494CONFIG_SND_HWDEP=m
1495CONFIG_SND_RAWMIDI=m
1496CONFIG_SND_SEQUENCER=m
1497CONFIG_SND_SEQ_DUMMY=m
1498CONFIG_SND_OSSEMUL=y
1499CONFIG_SND_MIXER_OSS=m
1500CONFIG_SND_PCM_OSS=m
1501CONFIG_SND_PCM_OSS_PLUGINS=y
1502CONFIG_SND_SEQUENCER_OSS=y
1503# CONFIG_SND_DYNAMIC_MINORS is not set
1504CONFIG_SND_SUPPORT_OLD_API=y
1505CONFIG_SND_VERBOSE_PROCFS=y
1506# CONFIG_SND_VERBOSE_PRINTK is not set
1507# CONFIG_SND_DEBUG is not set
1508
1509#
1510# Generic devices
1511#
1512CONFIG_SND_MPU401_UART=m
1513CONFIG_SND_DUMMY=m
1514CONFIG_SND_VIRMIDI=m
1515CONFIG_SND_MTPAV=m
1516CONFIG_SND_SERIAL_U16550=m
1517CONFIG_SND_MPU401=m
1518
1519#
1520# ALSA ARM devices
1521#
1522
1523#
1524# USB devices
1525#
1526CONFIG_SND_USB_AUDIO=m
1527
1528#
1529# PCMCIA devices
1530#
1531
1532#
1533# Open Sound System
1534#
1535CONFIG_SOUND_PRIME=m
1536# CONFIG_OBSOLETE_OSS_DRIVER is not set
1537# CONFIG_SOUND_MSNDCLAS is not set
1538# CONFIG_SOUND_MSNDPIN is not set
1539CONFIG_SOUND_TVMIXER=m
1540
1541#
1542# USB support
1543#
1544CONFIG_USB_ARCH_HAS_HCD=y
1545# CONFIG_USB_ARCH_HAS_OHCI is not set
1546# CONFIG_USB_ARCH_HAS_EHCI is not set
1547CONFIG_USB=m
1548# CONFIG_USB_DEBUG is not set
1549
1550#
1551# Miscellaneous USB options
1552#
1553CONFIG_USB_DEVICEFS=y
1554CONFIG_USB_BANDWIDTH=y
1555# CONFIG_USB_DYNAMIC_MINORS is not set
1556# CONFIG_USB_SUSPEND is not set
1557# CONFIG_USB_OTG is not set
1558
1559#
1560# USB Host Controller Drivers
1561#
1562# CONFIG_USB_ISP116X_HCD is not set
1563CONFIG_USB_SL811_HCD=m
1564# CONFIG_USB_SL811_CS is not set
1565
1566#
1567# USB Device Class drivers
1568#
1569CONFIG_USB_ACM=m
1570CONFIG_USB_PRINTER=m
1571
1572#
1573# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1574#
1575
1576#
1577# may also be needed; see USB_STORAGE Help for more information
1578#
1579CONFIG_USB_STORAGE=m
1580# CONFIG_USB_STORAGE_DEBUG is not set
1581CONFIG_USB_STORAGE_DATAFAB=y
1582CONFIG_USB_STORAGE_FREECOM=y
1583CONFIG_USB_STORAGE_ISD200=y
1584CONFIG_USB_STORAGE_DPCM=y
1585CONFIG_USB_STORAGE_USBAT=y
1586CONFIG_USB_STORAGE_SDDR09=y
1587CONFIG_USB_STORAGE_SDDR55=y
1588CONFIG_USB_STORAGE_JUMPSHOT=y
1589# CONFIG_USB_STORAGE_ALAUDA is not set
1590# CONFIG_USB_LIBUSUAL is not set
1591
1592#
1593# USB Input Devices
1594#
1595CONFIG_USB_HID=m
1596CONFIG_USB_HIDINPUT=y
1597# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1598# CONFIG_HID_FF is not set
1599CONFIG_USB_HIDDEV=y
1600
1601#
1602# USB HID Boot Protocol drivers
1603#
1604CONFIG_USB_KBD=m
1605CONFIG_USB_MOUSE=m
1606CONFIG_USB_AIPTEK=m
1607CONFIG_USB_WACOM=m
1608# CONFIG_USB_ACECAD is not set
1609CONFIG_USB_KBTAB=m
1610CONFIG_USB_POWERMATE=m
1611CONFIG_USB_MTOUCH=m
1612# CONFIG_USB_ITMTOUCH is not set
1613CONFIG_USB_EGALAX=m
1614# CONFIG_USB_YEALINK is not set
1615CONFIG_USB_XPAD=m
1616CONFIG_USB_ATI_REMOTE=m
1617# CONFIG_USB_ATI_REMOTE2 is not set
1618# CONFIG_USB_KEYSPAN_REMOTE is not set
1619# CONFIG_USB_APPLETOUCH is not set
1620
1621#
1622# USB Imaging devices
1623#
1624CONFIG_USB_MDC800=m
1625CONFIG_USB_MICROTEK=m
1626
1627#
1628# USB Network Adapters
1629#
1630CONFIG_USB_CATC=m
1631CONFIG_USB_KAWETH=m
1632CONFIG_USB_PEGASUS=m
1633CONFIG_USB_RTL8150=m
1634CONFIG_USB_USBNET=m
1635CONFIG_USB_NET_AX8817X=m
1636CONFIG_USB_NET_CDCETHER=m
1637# CONFIG_USB_NET_GL620A is not set
1638CONFIG_USB_NET_NET1080=m
1639# CONFIG_USB_NET_PLUSB is not set
1640# CONFIG_USB_NET_RNDIS_HOST is not set
1641# CONFIG_USB_NET_CDC_SUBSET is not set
1642CONFIG_USB_NET_ZAURUS=m
1643# CONFIG_USB_ZD1201 is not set
1644CONFIG_USB_MON=y
1645
1646#
1647# USB port drivers
1648#
1649CONFIG_USB_USS720=m
1650
1651#
1652# USB Serial Converter support
1653#
1654CONFIG_USB_SERIAL=m
1655CONFIG_USB_SERIAL_GENERIC=y
1656# CONFIG_USB_SERIAL_AIRPRIME is not set
1657# CONFIG_USB_SERIAL_ANYDATA is not set
1658CONFIG_USB_SERIAL_BELKIN=m
1659CONFIG_USB_SERIAL_WHITEHEAT=m
1660CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1661# CONFIG_USB_SERIAL_CP2101 is not set
1662CONFIG_USB_SERIAL_CYPRESS_M8=m
1663CONFIG_USB_SERIAL_EMPEG=m
1664CONFIG_USB_SERIAL_FTDI_SIO=m
1665CONFIG_USB_SERIAL_VISOR=m
1666CONFIG_USB_SERIAL_IPAQ=m
1667CONFIG_USB_SERIAL_IR=m
1668CONFIG_USB_SERIAL_EDGEPORT=m
1669CONFIG_USB_SERIAL_EDGEPORT_TI=m
1670# CONFIG_USB_SERIAL_GARMIN is not set
1671CONFIG_USB_SERIAL_IPW=m
1672CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1673CONFIG_USB_SERIAL_KEYSPAN=m
1674# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
1675# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
1676# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
1677# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
1678# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
1679# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
1680# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
1681# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
1682# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
1683# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
1684# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
1685# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
1686CONFIG_USB_SERIAL_KLSI=m
1687CONFIG_USB_SERIAL_KOBIL_SCT=m
1688CONFIG_USB_SERIAL_MCT_U232=m
1689# CONFIG_USB_SERIAL_NAVMAN is not set
1690CONFIG_USB_SERIAL_PL2303=m
1691# CONFIG_USB_SERIAL_HP4X is not set
1692CONFIG_USB_SERIAL_SAFE=m
1693# CONFIG_USB_SERIAL_SAFE_PADDED is not set
1694# CONFIG_USB_SERIAL_TI is not set
1695CONFIG_USB_SERIAL_CYBERJACK=m
1696CONFIG_USB_SERIAL_XIRCOM=m
1697CONFIG_USB_SERIAL_OMNINET=m
1698CONFIG_USB_EZUSB=y
1699
1700#
1701# USB Miscellaneous drivers
1702#
1703# CONFIG_USB_EMI62 is not set
1704# CONFIG_USB_EMI26 is not set
1705CONFIG_USB_AUERSWALD=m
1706CONFIG_USB_RIO500=m
1707CONFIG_USB_LEGOTOWER=m
1708CONFIG_USB_LCD=m
1709CONFIG_USB_LED=m
1710CONFIG_USB_CYTHERM=m
1711CONFIG_USB_PHIDGETKIT=m
1712CONFIG_USB_PHIDGETSERVO=m
1713# CONFIG_USB_IDMOUSE is not set
1714# CONFIG_USB_LD is not set
1715CONFIG_USB_TEST=m
1716
1717#
1718# USB DSL modem support
1719#
1720CONFIG_USB_ATM=m
1721CONFIG_USB_SPEEDTOUCH=m
1722# CONFIG_USB_CXACRU is not set
1723# CONFIG_USB_UEAGLEATM is not set
1724# CONFIG_USB_XUSBATM is not set
1725
1726#
1727# USB Gadget Support
1728#
1729CONFIG_USB_GADGET=m
1730# CONFIG_USB_GADGET_DEBUG_FILES is not set
1731CONFIG_USB_GADGET_SELECTED=y
1732# CONFIG_USB_GADGET_NET2280 is not set
1733# CONFIG_USB_GADGET_PXA2XX is not set
1734# CONFIG_USB_GADGET_GOKU is not set
1735# CONFIG_USB_GADGET_LH7A40X is not set
1736# CONFIG_USB_GADGET_OMAP is not set
1737# CONFIG_USB_GADGET_AT91 is not set
1738CONFIG_USB_GADGET_DUMMY_HCD=y
1739CONFIG_USB_DUMMY_HCD=m
1740CONFIG_USB_GADGET_DUALSPEED=y
1741CONFIG_USB_ZERO=m
1742CONFIG_USB_ETH=m
1743CONFIG_USB_ETH_RNDIS=y
1744CONFIG_USB_GADGETFS=m
1745CONFIG_USB_FILE_STORAGE=m
1746# CONFIG_USB_FILE_STORAGE_TEST is not set
1747CONFIG_USB_G_SERIAL=m
1748
1749#
1750# MMC/SD Card support
1751#
1752CONFIG_MMC=m
1753# CONFIG_MMC_DEBUG is not set
1754CONFIG_MMC_BLOCK=m
1755
1756#
1757# Real Time Clock
1758#
1759CONFIG_RTC_LIB=y
1760# CONFIG_RTC_CLASS is not set
1761
1762#
1763# File systems
1764#
1765CONFIG_EXT2_FS=y
1766CONFIG_EXT2_FS_XATTR=y
1767CONFIG_EXT2_FS_POSIX_ACL=y
1768CONFIG_EXT2_FS_SECURITY=y
1769# CONFIG_EXT2_FS_XIP is not set
1770CONFIG_EXT3_FS=m
1771CONFIG_EXT3_FS_XATTR=y
1772CONFIG_EXT3_FS_POSIX_ACL=y
1773CONFIG_EXT3_FS_SECURITY=y
1774CONFIG_JBD=m
1775# CONFIG_JBD_DEBUG is not set
1776CONFIG_FS_MBCACHE=y
1777CONFIG_REISERFS_FS=m
1778# CONFIG_REISERFS_CHECK is not set
1779# CONFIG_REISERFS_PROC_INFO is not set
1780CONFIG_REISERFS_FS_XATTR=y
1781CONFIG_REISERFS_FS_POSIX_ACL=y
1782CONFIG_REISERFS_FS_SECURITY=y
1783CONFIG_JFS_FS=m
1784CONFIG_JFS_POSIX_ACL=y
1785# CONFIG_JFS_SECURITY is not set
1786# CONFIG_JFS_DEBUG is not set
1787CONFIG_JFS_STATISTICS=y
1788CONFIG_FS_POSIX_ACL=y
1789CONFIG_XFS_FS=m
1790CONFIG_XFS_EXPORT=y
1791CONFIG_XFS_QUOTA=y
1792CONFIG_XFS_SECURITY=y
1793CONFIG_XFS_POSIX_ACL=y
1794CONFIG_XFS_RT=y
1795# CONFIG_OCFS2_FS is not set
1796CONFIG_MINIX_FS=m
1797CONFIG_ROMFS_FS=m
1798CONFIG_INOTIFY=y
1799CONFIG_QUOTA=y
1800CONFIG_QFMT_V1=m
1801CONFIG_QFMT_V2=m
1802CONFIG_QUOTACTL=y
1803CONFIG_DNOTIFY=y
1804CONFIG_AUTOFS_FS=m
1805CONFIG_AUTOFS4_FS=m
1806# CONFIG_FUSE_FS is not set
1807
1808#
1809# CD-ROM/DVD Filesystems
1810#
1811CONFIG_ISO9660_FS=m
1812CONFIG_JOLIET=y
1813CONFIG_ZISOFS=y
1814CONFIG_ZISOFS_FS=m
1815CONFIG_UDF_FS=m
1816CONFIG_UDF_NLS=y
1817
1818#
1819# DOS/FAT/NT Filesystems
1820#
1821CONFIG_FAT_FS=m
1822CONFIG_MSDOS_FS=m
1823CONFIG_VFAT_FS=m
1824CONFIG_FAT_DEFAULT_CODEPAGE=437
1825CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1826CONFIG_NTFS_FS=m
1827# CONFIG_NTFS_DEBUG is not set
1828# CONFIG_NTFS_RW is not set
1829
1830#
1831# Pseudo filesystems
1832#
1833CONFIG_PROC_FS=y
1834CONFIG_SYSFS=y
1835CONFIG_TMPFS=y
1836# CONFIG_HUGETLB_PAGE is not set
1837CONFIG_RAMFS=y
1838# CONFIG_CONFIGFS_FS is not set
1839
1840#
1841# Miscellaneous filesystems
1842#
1843CONFIG_ADFS_FS=m
1844# CONFIG_ADFS_FS_RW is not set
1845CONFIG_AFFS_FS=m
1846CONFIG_HFS_FS=m
1847CONFIG_HFSPLUS_FS=m
1848CONFIG_BEFS_FS=m
1849# CONFIG_BEFS_DEBUG is not set
1850CONFIG_BFS_FS=m
1851CONFIG_EFS_FS=m
1852CONFIG_JFFS_FS=m
1853CONFIG_JFFS_FS_VERBOSE=0
1854CONFIG_JFFS_PROC_FS=y
1855CONFIG_JFFS2_FS=m
1856CONFIG_JFFS2_FS_DEBUG=0
1857CONFIG_JFFS2_FS_WRITEBUFFER=y
1858# CONFIG_JFFS2_SUMMARY is not set
1859# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1860CONFIG_JFFS2_ZLIB=y
1861CONFIG_JFFS2_RTIME=y
1862# CONFIG_JFFS2_RUBIN is not set
1863CONFIG_CRAMFS=y
1864CONFIG_VXFS_FS=m
1865CONFIG_HPFS_FS=m
1866CONFIG_QNX4FS_FS=m
1867CONFIG_SYSV_FS=m
1868CONFIG_UFS_FS=m
1869
1870#
1871# Network File Systems
1872#
1873CONFIG_NFS_FS=m
1874CONFIG_NFS_V3=y
1875# CONFIG_NFS_V3_ACL is not set
1876CONFIG_NFS_V4=y
1877CONFIG_NFS_DIRECTIO=y
1878CONFIG_NFSD=m
1879CONFIG_NFSD_V3=y
1880# CONFIG_NFSD_V3_ACL is not set
1881CONFIG_NFSD_V4=y
1882CONFIG_NFSD_TCP=y
1883CONFIG_LOCKD=m
1884CONFIG_LOCKD_V4=y
1885CONFIG_EXPORTFS=m
1886CONFIG_NFS_COMMON=y
1887CONFIG_SUNRPC=m
1888CONFIG_SUNRPC_GSS=m
1889CONFIG_RPCSEC_GSS_KRB5=m
1890CONFIG_RPCSEC_GSS_SPKM3=m
1891CONFIG_SMB_FS=m
1892# CONFIG_SMB_NLS_DEFAULT is not set
1893CONFIG_CIFS=m
1894# CONFIG_CIFS_STATS is not set
1895# CONFIG_CIFS_XATTR is not set
1896# CONFIG_CIFS_EXPERIMENTAL is not set
1897CONFIG_NCP_FS=m
1898CONFIG_NCPFS_PACKET_SIGNING=y
1899CONFIG_NCPFS_IOCTL_LOCKING=y
1900CONFIG_NCPFS_STRONG=y
1901CONFIG_NCPFS_NFS_NS=y
1902CONFIG_NCPFS_OS2_NS=y
1903# CONFIG_NCPFS_SMALLDOS is not set
1904CONFIG_NCPFS_NLS=y
1905CONFIG_NCPFS_EXTRAS=y
1906CONFIG_CODA_FS=m
1907# CONFIG_CODA_FS_OLD_API is not set
1908CONFIG_AFS_FS=m
1909CONFIG_RXRPC=m
1910# CONFIG_9P_FS is not set
1911
1912#
1913# Partition Types
1914#
1915CONFIG_PARTITION_ADVANCED=y
1916CONFIG_ACORN_PARTITION=y
1917# CONFIG_ACORN_PARTITION_CUMANA is not set
1918# CONFIG_ACORN_PARTITION_EESOX is not set
1919CONFIG_ACORN_PARTITION_ICS=y
1920# CONFIG_ACORN_PARTITION_ADFS is not set
1921# CONFIG_ACORN_PARTITION_POWERTEC is not set
1922CONFIG_ACORN_PARTITION_RISCIX=y
1923CONFIG_OSF_PARTITION=y
1924CONFIG_AMIGA_PARTITION=y
1925CONFIG_ATARI_PARTITION=y
1926CONFIG_MAC_PARTITION=y
1927CONFIG_MSDOS_PARTITION=y
1928CONFIG_BSD_DISKLABEL=y
1929CONFIG_MINIX_SUBPARTITION=y
1930CONFIG_SOLARIS_X86_PARTITION=y
1931CONFIG_UNIXWARE_DISKLABEL=y
1932CONFIG_LDM_PARTITION=y
1933# CONFIG_LDM_DEBUG is not set
1934CONFIG_SGI_PARTITION=y
1935CONFIG_ULTRIX_PARTITION=y
1936CONFIG_SUN_PARTITION=y
1937# CONFIG_KARMA_PARTITION is not set
1938# CONFIG_EFI_PARTITION is not set
1939
1940#
1941# Native Language Support
1942#
1943CONFIG_NLS=y
1944CONFIG_NLS_DEFAULT="cp437"
1945CONFIG_NLS_CODEPAGE_437=m
1946CONFIG_NLS_CODEPAGE_737=m
1947CONFIG_NLS_CODEPAGE_775=m
1948CONFIG_NLS_CODEPAGE_850=m
1949CONFIG_NLS_CODEPAGE_852=m
1950CONFIG_NLS_CODEPAGE_855=m
1951CONFIG_NLS_CODEPAGE_857=m
1952CONFIG_NLS_CODEPAGE_860=m
1953CONFIG_NLS_CODEPAGE_861=m
1954CONFIG_NLS_CODEPAGE_862=m
1955CONFIG_NLS_CODEPAGE_863=m
1956CONFIG_NLS_CODEPAGE_864=m
1957CONFIG_NLS_CODEPAGE_865=m
1958CONFIG_NLS_CODEPAGE_866=m
1959CONFIG_NLS_CODEPAGE_869=m
1960CONFIG_NLS_CODEPAGE_936=m
1961CONFIG_NLS_CODEPAGE_950=m
1962CONFIG_NLS_CODEPAGE_932=m
1963CONFIG_NLS_CODEPAGE_949=m
1964CONFIG_NLS_CODEPAGE_874=m
1965CONFIG_NLS_ISO8859_8=m
1966CONFIG_NLS_CODEPAGE_1250=m
1967CONFIG_NLS_CODEPAGE_1251=m
1968CONFIG_NLS_ASCII=m
1969CONFIG_NLS_ISO8859_1=m
1970CONFIG_NLS_ISO8859_2=m
1971CONFIG_NLS_ISO8859_3=m
1972CONFIG_NLS_ISO8859_4=m
1973CONFIG_NLS_ISO8859_5=m
1974CONFIG_NLS_ISO8859_6=m
1975CONFIG_NLS_ISO8859_7=m
1976CONFIG_NLS_ISO8859_9=m
1977CONFIG_NLS_ISO8859_13=m
1978CONFIG_NLS_ISO8859_14=m
1979CONFIG_NLS_ISO8859_15=m
1980CONFIG_NLS_KOI8_R=m
1981CONFIG_NLS_KOI8_U=m
1982CONFIG_NLS_UTF8=m
1983
1984#
1985# Profiling support
1986#
1987CONFIG_PROFILING=y
1988CONFIG_OPROFILE=m
1989
1990#
1991# Kernel hacking
1992#
1993# CONFIG_PRINTK_TIME is not set
1994CONFIG_MAGIC_SYSRQ=y
1995CONFIG_DEBUG_KERNEL=y
1996CONFIG_LOG_BUF_SHIFT=14
1997CONFIG_DETECT_SOFTLOCKUP=y
1998# CONFIG_SCHEDSTATS is not set
1999# CONFIG_DEBUG_SLAB is not set
2000CONFIG_DEBUG_PREEMPT=y
2001CONFIG_DEBUG_MUTEXES=y
2002# CONFIG_DEBUG_SPINLOCK is not set
2003# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
2004# CONFIG_DEBUG_KOBJECT is not set
2005# CONFIG_DEBUG_BUGVERBOSE is not set
2006CONFIG_DEBUG_INFO=y
2007# CONFIG_DEBUG_FS is not set
2008# CONFIG_DEBUG_VM is not set
2009CONFIG_FRAME_POINTER=y
2010# CONFIG_UNWIND_INFO is not set
2011CONFIG_FORCED_INLINING=y
2012# CONFIG_RCU_TORTURE_TEST is not set
2013# CONFIG_DEBUG_USER is not set
2014# CONFIG_DEBUG_WAITQ is not set
2015# CONFIG_DEBUG_ERRORS is not set
2016CONFIG_DEBUG_LL=y
2017# CONFIG_DEBUG_ICEDCC is not set
2018
2019#
2020# Security options
2021#
2022# CONFIG_KEYS is not set
2023CONFIG_SECURITY=y
2024# CONFIG_SECURITY_NETWORK is not set
2025CONFIG_SECURITY_CAPABILITIES=m
2026CONFIG_SECURITY_ROOTPLUG=m
2027CONFIG_SECURITY_SECLVL=m
2028
2029#
2030# Cryptographic options
2031#
2032CONFIG_CRYPTO=y
2033CONFIG_CRYPTO_HMAC=y
2034CONFIG_CRYPTO_NULL=m
2035CONFIG_CRYPTO_MD4=m
2036CONFIG_CRYPTO_MD5=y
2037CONFIG_CRYPTO_SHA1=m
2038CONFIG_CRYPTO_SHA256=m
2039CONFIG_CRYPTO_SHA512=m
2040CONFIG_CRYPTO_WP512=m
2041# CONFIG_CRYPTO_TGR192 is not set
2042CONFIG_CRYPTO_DES=m
2043CONFIG_CRYPTO_BLOWFISH=m
2044CONFIG_CRYPTO_TWOFISH=m
2045CONFIG_CRYPTO_SERPENT=m
2046CONFIG_CRYPTO_AES=m
2047CONFIG_CRYPTO_CAST5=m
2048CONFIG_CRYPTO_CAST6=m
2049CONFIG_CRYPTO_TEA=m
2050CONFIG_CRYPTO_ARC4=m
2051CONFIG_CRYPTO_KHAZAD=m
2052CONFIG_CRYPTO_ANUBIS=m
2053CONFIG_CRYPTO_DEFLATE=m
2054CONFIG_CRYPTO_MICHAEL_MIC=m
2055CONFIG_CRYPTO_CRC32C=m
2056CONFIG_CRYPTO_TEST=m
2057
2058#
2059# Hardware crypto devices
2060#
2061
2062#
2063# Library routines
2064#
2065CONFIG_CRC_CCITT=m
2066CONFIG_CRC16=m
2067CONFIG_CRC32=y
2068CONFIG_LIBCRC32C=m
2069CONFIG_ZLIB_INFLATE=y
2070CONFIG_ZLIB_DEFLATE=m
2071CONFIG_REED_SOLOMON=m
2072CONFIG_REED_SOLOMON_DEC16=y
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index dbcb11a31f78..b5bcebca1cd6 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -271,7 +271,7 @@ ENTRY(sys_call_table)
271@ r8 = syscall table 271@ r8 = syscall table
272 .type sys_syscall, #function 272 .type sys_syscall, #function
273sys_syscall: 273sys_syscall:
274 eor scno, r0, #__NR_OABI_SYSCALL_BASE 274 bic scno, r0, #__NR_OABI_SYSCALL_BASE
275 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 275 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
276 cmpne scno, #NR_syscalls @ check range 276 cmpne scno, #NR_syscalls @ check range
277 stmloia sp, {r5, r6} @ shuffle args 277 stmloia sp, {r5, r6} @ shuffle args
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 2d5896b36181..bcc19fbb32df 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
342 342
343#ifdef CONFIG_NO_IDLE_HZ 343#ifdef CONFIG_NO_IDLE_HZ
344 if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { 344 if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
345 write_seqlock(&xtime_lock); 345 spin_lock(&system_timer->dyn_tick->lock);
346 if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) 346 if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
347 system_timer->dyn_tick->handler(irq, 0, regs); 347 system_timer->dyn_tick->handler(irq, 0, regs);
348 write_sequnlock(&xtime_lock); 348 spin_unlock(&system_timer->dyn_tick->lock);
349 } 349 }
350#endif 350#endif
351 351
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index d6bd435a6857..9c12d4fefbd3 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void)
379 int ret = -ENODEV; 379 int ret = -ENODEV;
380 380
381 if (dyn_tick) { 381 if (dyn_tick) {
382 write_seqlock_irqsave(&xtime_lock, flags); 382 spin_lock_irqsave(&dyn_tick->lock, flags);
383 ret = 0; 383 ret = 0;
384 if (!(dyn_tick->state & DYN_TICK_ENABLED)) { 384 if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
385 ret = dyn_tick->enable(); 385 ret = dyn_tick->enable();
@@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void)
387 if (ret == 0) 387 if (ret == 0)
388 dyn_tick->state |= DYN_TICK_ENABLED; 388 dyn_tick->state |= DYN_TICK_ENABLED;
389 } 389 }
390 write_sequnlock_irqrestore(&xtime_lock, flags); 390 spin_unlock_irqrestore(&dyn_tick->lock, flags);
391 } 391 }
392 392
393 return ret; 393 return ret;
@@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void)
400 int ret = -ENODEV; 400 int ret = -ENODEV;
401 401
402 if (dyn_tick) { 402 if (dyn_tick) {
403 write_seqlock_irqsave(&xtime_lock, flags); 403 spin_lock_irqsave(&dyn_tick->lock, flags);
404 ret = 0; 404 ret = 0;
405 if (dyn_tick->state & DYN_TICK_ENABLED) { 405 if (dyn_tick->state & DYN_TICK_ENABLED) {
406 ret = dyn_tick->disable(); 406 ret = dyn_tick->disable();
@@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void)
408 if (ret == 0) 408 if (ret == 0)
409 dyn_tick->state &= ~DYN_TICK_ENABLED; 409 dyn_tick->state &= ~DYN_TICK_ENABLED;
410 } 410 }
411 write_sequnlock_irqrestore(&xtime_lock, flags); 411 spin_unlock_irqrestore(&dyn_tick->lock, flags);
412 } 412 }
413 413
414 return ret; 414 return ret;
@@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void)
422void timer_dyn_reprogram(void) 422void timer_dyn_reprogram(void)
423{ 423{
424 struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; 424 struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
425 unsigned long next, seq; 425 unsigned long next, seq, flags;
426 426
427 if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { 427 if (!dyn_tick)
428 return;
429
430 spin_lock_irqsave(&dyn_tick->lock, flags);
431 if (dyn_tick->state & DYN_TICK_ENABLED) {
428 next = next_timer_interrupt(); 432 next = next_timer_interrupt();
429 do { 433 do {
430 seq = read_seqbegin(&xtime_lock); 434 seq = read_seqbegin(&xtime_lock);
431 dyn_tick->reprogram(next_timer_interrupt() - jiffies); 435 dyn_tick->reprogram(next - jiffies);
432 } while (read_seqretry(&xtime_lock, seq)); 436 } while (read_seqretry(&xtime_lock, seq));
433 } 437 }
438 spin_unlock_irqrestore(&dyn_tick->lock, flags);
434} 439}
435 440
436static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) 441static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
@@ -499,5 +504,10 @@ void __init time_init(void)
499 if (system_timer->offset == NULL) 504 if (system_timer->offset == NULL)
500 system_timer->offset = dummy_gettimeoffset; 505 system_timer->offset = dummy_gettimeoffset;
501 system_timer->init(); 506 system_timer->init();
507
508#ifdef CONFIG_NO_IDLE_HZ
509 if (system_timer->dyn_tick)
510 system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED;
511#endif
502} 512}
503 513
diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig
index 8a17867a6a24..558a34f53b1c 100644
--- a/arch/arm/mach-lh7a40x/Kconfig
+++ b/arch/arm/mach-lh7a40x/Kconfig
@@ -14,6 +14,7 @@ config MACH_LPD7A400
14 bool "LPD7A400 Card Engine" 14 bool "LPD7A400 Card Engine"
15 select ARCH_LH7A400 15 select ARCH_LH7A400
16# select IDE_POLL 16# select IDE_POLL
17 select HAS_TOUCHSCREEN_ADS7843_LH7
17 help 18 help
18 Say Y here if you are using Logic Product Development's 19 Say Y here if you are using Logic Product Development's
19 LPD7A400 CardEngine. For the time being, the LPD7A400 and 20 LPD7A400 CardEngine. For the time being, the LPD7A400 and
@@ -23,6 +24,7 @@ config MACH_LPD7A404
23 bool "LPD7A404 Card Engine" 24 bool "LPD7A404 Card Engine"
24 select ARCH_LH7A404 25 select ARCH_LH7A404
25# select IDE_POLL 26# select IDE_POLL
27 select HAS_TOUCHSCREEN_ADC_LH7
26 help 28 help
27 Say Y here if you are using Logic Product Development's 29 Say Y here if you are using Logic Product Development's
28 LPD7A404 CardEngine. For the time being, the LPD7A400 and 30 LPD7A404 CardEngine. For the time being, the LPD7A400 and
@@ -34,6 +36,9 @@ config ARCH_LH7A400
34config ARCH_LH7A404 36config ARCH_LH7A404
35 bool 37 bool
36 38
39config LPD7A40X_CPLD_SSP
40 bool
41
37config LH7A40X_CONTIGMEM 42config LH7A40X_CONTIGMEM
38 bool "Disable NUMA Support" 43 bool "Disable NUMA Support"
39 depends on ARCH_LH7A40X 44 depends on ARCH_LH7A40X
diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile
index e90512dbc2d6..94b8615fb3c3 100644
--- a/arch/arm/mach-lh7a40x/Makefile
+++ b/arch/arm/mach-lh7a40x/Makefile
@@ -4,11 +4,14 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y := time.o 7obj-y := time.o clocks.o
8obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o 8obj-m :=
9obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o 9obj-n :=
10obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o 10obj- :=
11 11
12obj-m := 12obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
13obj-n := 13obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
14obj- := 14obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
15obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o
16obj-$(CONFIG_FB_ARMCLCD) += clcd.o
17
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 12e23277c5ea..c0e6854289f1 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -23,6 +23,28 @@
23 23
24#include "common.h" 24#include "common.h"
25 25
26#define CPLD_INT_NETHERNET (1<<0)
27#define CPLD_INTMASK_ETHERNET (1<<2)
28#if defined (CONFIG_MACH_LPD7A400)
29# define CPLD_INT_NTOUCH (1<<1)
30# define CPLD_INTMASK_TOUCH (1<<3)
31# define CPLD_INT_PEN (1<<4)
32# define CPLD_INTMASK_PEN (1<<4)
33# define CPLD_INT_PIRQ (1<<4)
34#endif
35#define CPLD_INTMASK_CPLD (1<<7)
36#define CPLD_INT_CPLD (1<<6)
37
38#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */
39#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */
40#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */
41#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */
42#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */
43#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */
44#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */
45#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */
46
47
26static struct resource smc91x_resources[] = { 48static struct resource smc91x_resources[] = {
27 [0] = { 49 [0] = {
28 .start = CPLD00_PHYS, 50 .start = CPLD00_PHYS,
@@ -48,12 +70,12 @@ static struct platform_device smc91x_device = {
48static struct resource lh7a40x_usbclient_resources[] = { 70static struct resource lh7a40x_usbclient_resources[] = {
49 [0] = { 71 [0] = {
50 .start = USB_PHYS, 72 .start = USB_PHYS,
51 .end = (USB_PHYS + 0xFF), 73 .end = (USB_PHYS + PAGE_SIZE),
52 .flags = IORESOURCE_MEM, 74 .flags = IORESOURCE_MEM,
53 }, 75 },
54 [1] = { 76 [1] = {
55 .start = IRQ_USBINTR, 77 .start = IRQ_USB,
56 .end = IRQ_USBINTR, 78 .end = IRQ_USB,
57 .flags = IORESOURCE_IRQ, 79 .flags = IORESOURCE_IRQ,
58 }, 80 },
59}; 81};
@@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = {
61static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; 83static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL;
62 84
63static struct platform_device lh7a40x_usbclient_device = { 85static struct platform_device lh7a40x_usbclient_device = {
64 .name = "lh7a40x_udc", 86// .name = "lh7a40x_udc",
87 .name = "lh7-udc",
65 .id = 0, 88 .id = 0,
66 .dev = { 89 .dev = {
67 .dma_mask = &lh7a40x_usbclient_dma_mask, 90 .dma_mask = &lh7a40x_usbclient_dma_mask,
@@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = {
101 124
102#endif 125#endif
103 126
104static struct platform_device *lpd7a40x_devs[] __initdata = { 127static struct platform_device* lpd7a40x_devs[] __initdata = {
105 &smc91x_device, 128 &smc91x_device,
106 &lh7a40x_usbclient_device, 129 &lh7a40x_usbclient_device,
107#if defined (CONFIG_ARCH_LH7A404) 130#if defined (CONFIG_ARCH_LH7A404)
@@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void);
113 136
114static void __init lpd7a40x_init (void) 137static void __init lpd7a40x_init (void)
115{ 138{
116 CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */ 139#if defined (CONFIG_MACH_LPD7A400)
140 CPLD_CONTROL |= 0
141 | CPLD_CONTROL_SWINT /* Disable software interrupt */
142 | CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */
117 CPLD_CONTROL &= ~(0 143 CPLD_CONTROL &= ~(0
118 | (1<<1) /* Disable LCD */ 144 | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */
119 | (1<<0) /* Enable WLAN */ 145 | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
120 ); 146 );
147#endif
148
149#if defined (CONFIG_MACH_LPD7A404)
150 CPLD_CONTROL &= ~(0
151 | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
152 );
153#endif
121 154
122 platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); 155 platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
156#if defined (CONFIG_FB_ARMCLCD)
157 lh7a40x_clcd_init ();
158#endif
123} 159}
124 160
125static void lh7a40x_ack_cpld_irq (u32 irq) 161static void lh7a40x_ack_cpld_irq (u32 irq)
126{ 162{
127 /* CPLD doesn't have ack capability */ 163 /* CPLD doesn't have ack capability, but some devices may */
164
165#if defined (CPLD_INTMASK_TOUCH)
166 /* The touch control *must* mask the the interrupt because the
167 * interrupt bit is read by the driver to determine if the pen
168 * is still down. */
169 if (irq == IRQ_TOUCH)
170 CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
171#endif
128} 172}
129 173
130static void lh7a40x_mask_cpld_irq (u32 irq) 174static void lh7a40x_mask_cpld_irq (u32 irq)
131{ 175{
132 switch (irq) { 176 switch (irq) {
133 case IRQ_LPD7A40X_ETH_INT: 177 case IRQ_LPD7A40X_ETH_INT:
134 CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; 178 CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
135 break; 179 break;
136 case IRQ_LPD7A400_TS: 180#if defined (IRQ_TOUCH)
137 CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; 181 case IRQ_TOUCH:
182 CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
138 break; 183 break;
184#endif
139 } 185 }
140} 186}
141 187
@@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq)
143{ 189{
144 switch (irq) { 190 switch (irq) {
145 case IRQ_LPD7A40X_ETH_INT: 191 case IRQ_LPD7A40X_ETH_INT:
146 CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; 192 CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
147 break; 193 break;
148 case IRQ_LPD7A400_TS: 194#if defined (IRQ_TOUCH)
149 CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; 195 case IRQ_TOUCH:
196 CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH;
150 break; 197 break;
198#endif
151 } 199 }
152} 200}
153 201
@@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
164 212
165 desc->chip->ack (irq); 213 desc->chip->ack (irq);
166 214
167 if ((mask & 0x1) == 0) /* WLAN */ 215 if ((mask & (1<<0)) == 0) /* WLAN */
168 IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); 216 IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
169 217
170 if ((mask & 0x2) == 0) /* Touch */ 218#if defined (IRQ_TOUCH)
171 IRQ_DISPATCH (IRQ_LPD7A400_TS); 219 if ((mask & (1<<1)) == 0) /* Touch */
220 IRQ_DISPATCH (IRQ_TOUCH);
221#endif
172 222
173 desc->chip->unmask (irq); /* Level-triggered need this */ 223 desc->chip->unmask (irq); /* Level-triggered need this */
174} 224}
@@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void)
204 254
205 /* Then, configure CPLD interrupt */ 255 /* Then, configure CPLD interrupt */
206 256
207 CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */ 257 /* Disable all CPLD interrupts */
258#if defined (CONFIG_MACH_LPD7A400)
259 CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN
260 | CPLD_INTMASK_ETHERNET;
261 /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong
262 and 4 is uncefined. */
263 // (1<<7)|(1<<4)|(1<<3)|(1<<2);
264#endif
265#if defined (CONFIG_MACH_LPD7A404)
266 CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET;
267 /* *** FIXME: don't know why we need 6 and 5, neither is defined. */
268 // (1<<6)|(1<<5)|(1<<3);
269#endif
208 GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ 270 GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
209 GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ 271 GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */
210 GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ 272 GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
211 barrier (); 273 barrier ();
212 GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ 274 GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
@@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void)
216 for (irq = IRQ_BOARD_START; 278 for (irq = IRQ_BOARD_START;
217 irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { 279 irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
218 set_irq_chip (irq, &lpd7a40x_cpld_chip); 280 set_irq_chip (irq, &lpd7a40x_cpld_chip);
219 set_irq_handler (irq, do_edge_IRQ); 281 set_irq_handler (irq, do_level_IRQ);
220 set_irq_flags (irq, IRQF_VALID); 282 set_irq_flags (irq, IRQF_VALID);
221 } 283 }
222 284
@@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void)
226 lpd7a40x_cpld_handler); 288 lpd7a40x_cpld_handler);
227} 289}
228 290
229static struct map_desc lpd7a400_io_desc[] __initdata = { 291static struct map_desc lpd7a40x_io_desc[] __initdata = {
230 { 292 {
231 .virtual = IO_VIRT, 293 .virtual = IO_VIRT,
232 .pfn = __phys_to_pfn(IO_PHYS), 294 .pfn = __phys_to_pfn(IO_PHYS),
233 .length = IO_SIZE, 295 .length = IO_SIZE,
234 .type = MT_DEVICE 296 .type = MT_DEVICE
235 }, { /* Mapping added to work around chip select problems */ 297 },
298 { /* Mapping added to work around chip select problems */
236 .virtual = IOBARRIER_VIRT, 299 .virtual = IOBARRIER_VIRT,
237 .pfn = __phys_to_pfn(IOBARRIER_PHYS), 300 .pfn = __phys_to_pfn(IOBARRIER_PHYS),
238 .length = IOBARRIER_SIZE, 301 .length = IOBARRIER_SIZE,
239 .type = MT_DEVICE 302 .type = MT_DEVICE
240 }, { 303 },
304 {
241 .virtual = CF_VIRT, 305 .virtual = CF_VIRT,
242 .pfn = __phys_to_pfn(CF_PHYS), 306 .pfn = __phys_to_pfn(CF_PHYS),
243 .length = CF_SIZE, 307 .length = CF_SIZE,
244 .type = MT_DEVICE 308 .type = MT_DEVICE
245 }, { 309 },
310 {
246 .virtual = CPLD02_VIRT, 311 .virtual = CPLD02_VIRT,
247 .pfn = __phys_to_pfn(CPLD02_PHYS), 312 .pfn = __phys_to_pfn(CPLD02_PHYS),
248 .length = CPLD02_SIZE, 313 .length = CPLD02_SIZE,
249 .type = MT_DEVICE 314 .type = MT_DEVICE
250 }, { 315 },
316 {
251 .virtual = CPLD06_VIRT, 317 .virtual = CPLD06_VIRT,
252 .pfn = __phys_to_pfn(CPLD06_PHYS), 318 .pfn = __phys_to_pfn(CPLD06_PHYS),
253 .length = CPLD06_SIZE, 319 .length = CPLD06_SIZE,
320 .type = MT_DEVICE
321 },
322 {
323 .virtual = CPLD08_VIRT,
324 .pfn = __phys_to_pfn(CPLD08_PHYS),
325 .length = CPLD08_SIZE,
254 .type = MT_DEVICE 326 .type = MT_DEVICE
255 }, { 327 },
328 {
256 .virtual = CPLD08_VIRT, 329 .virtual = CPLD08_VIRT,
257 .pfn = __phys_to_pfn(CPLD08_PHYS), 330 .pfn = __phys_to_pfn(CPLD08_PHYS),
258 .length = CPLD08_SIZE, 331 .length = CPLD08_SIZE,
259 .type = MT_DEVICE 332 .type = MT_DEVICE
260 }, { 333 },
334 {
335 .virtual = CPLD0A_VIRT,
336 .pfn = __phys_to_pfn(CPLD0A_PHYS),
337 .length = CPLD0A_SIZE,
338 .type = MT_DEVICE
339 },
340 {
261 .virtual = CPLD0C_VIRT, 341 .virtual = CPLD0C_VIRT,
262 .pfn = __phys_to_pfn(CPLD0C_PHYS), 342 .pfn = __phys_to_pfn(CPLD0C_PHYS),
263 .length = CPLD0C_SIZE, 343 .length = CPLD0C_SIZE,
264 .type = MT_DEVICE 344 .type = MT_DEVICE
265 }, { 345 },
346 {
266 .virtual = CPLD0E_VIRT, 347 .virtual = CPLD0E_VIRT,
267 .pfn = __phys_to_pfn(CPLD0E_PHYS), 348 .pfn = __phys_to_pfn(CPLD0E_PHYS),
268 .length = CPLD0E_SIZE, 349 .length = CPLD0E_SIZE,
269 .type = MT_DEVICE 350 .type = MT_DEVICE
270 }, { 351 },
352 {
271 .virtual = CPLD10_VIRT, 353 .virtual = CPLD10_VIRT,
272 .pfn = __phys_to_pfn(CPLD10_PHYS), 354 .pfn = __phys_to_pfn(CPLD10_PHYS),
273 .length = CPLD10_SIZE, 355 .length = CPLD10_SIZE,
274 .type = MT_DEVICE 356 .type = MT_DEVICE
275 }, { 357 },
358 {
276 .virtual = CPLD12_VIRT, 359 .virtual = CPLD12_VIRT,
277 .pfn = __phys_to_pfn(CPLD12_PHYS), 360 .pfn = __phys_to_pfn(CPLD12_PHYS),
278 .length = CPLD12_SIZE, 361 .length = CPLD12_SIZE,
279 .type = MT_DEVICE 362 .type = MT_DEVICE
280 }, { 363 },
364 {
281 .virtual = CPLD14_VIRT, 365 .virtual = CPLD14_VIRT,
282 .pfn = __phys_to_pfn(CPLD14_PHYS), 366 .pfn = __phys_to_pfn(CPLD14_PHYS),
283 .length = CPLD14_SIZE, 367 .length = CPLD14_SIZE,
284 .type = MT_DEVICE 368 .type = MT_DEVICE
285 }, { 369 },
370 {
286 .virtual = CPLD16_VIRT, 371 .virtual = CPLD16_VIRT,
287 .pfn = __phys_to_pfn(CPLD16_PHYS), 372 .pfn = __phys_to_pfn(CPLD16_PHYS),
288 .length = CPLD16_SIZE, 373 .length = CPLD16_SIZE,
289 .type = MT_DEVICE 374 .type = MT_DEVICE
290 }, { 375 },
376 {
291 .virtual = CPLD18_VIRT, 377 .virtual = CPLD18_VIRT,
292 .pfn = __phys_to_pfn(CPLD18_PHYS), 378 .pfn = __phys_to_pfn(CPLD18_PHYS),
293 .length = CPLD18_SIZE, 379 .length = CPLD18_SIZE,
294 .type = MT_DEVICE 380 .type = MT_DEVICE
295 }, { 381 },
382 {
296 .virtual = CPLD1A_VIRT, 383 .virtual = CPLD1A_VIRT,
297 .pfn = __phys_to_pfn(CPLD1A_PHYS), 384 .pfn = __phys_to_pfn(CPLD1A_PHYS),
298 .length = CPLD1A_SIZE, 385 .length = CPLD1A_SIZE,
299 .type = MT_DEVICE 386 .type = MT_DEVICE
300 }, 387 },
301 /* This mapping is redundant since the smc driver performs another. */
302/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
303}; 388};
304 389
305void __init 390void __init
306lpd7a400_map_io(void) 391lpd7a40x_map_io(void)
307{ 392{
308 iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc)); 393 iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc));
309
310 /* Fixup (improve) Static Memory Controller settings */
311 SMC_BCR0 = 0x200039af; /* Boot Flash */
312 SMC_BCR6 = 0x1000fbe0; /* CPLD */
313 SMC_BCR7 = 0x1000b2c2; /* Compact Flash */
314} 394}
315 395
316#ifdef CONFIG_MACH_LPD7A400 396#ifdef CONFIG_MACH_LPD7A400
@@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
320 .phys_io = 0x80000000, 400 .phys_io = 0x80000000,
321 .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, 401 .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
322 .boot_params = 0xc0000100, 402 .boot_params = 0xc0000100,
323 .map_io = lpd7a400_map_io, 403 .map_io = lpd7a40x_map_io,
324 .init_irq = lh7a400_init_irq, 404 .init_irq = lh7a400_init_irq,
325 .timer = &lh7a40x_timer, 405 .timer = &lh7a40x_timer,
326 .init_machine = lpd7a40x_init, 406 .init_machine = lpd7a40x_init,
@@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
335 .phys_io = 0x80000000, 415 .phys_io = 0x80000000,
336 .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, 416 .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
337 .boot_params = 0xc0000100, 417 .boot_params = 0xc0000100,
338 .map_io = lpd7a400_map_io, 418 .map_io = lpd7a40x_map_io,
339 .init_irq = lh7a404_init_irq, 419 .init_irq = lh7a404_init_irq,
340 .timer = &lh7a40x_timer, 420 .timer = &lh7a40x_timer,
341 .init_machine = lpd7a40x_init, 421 .init_machine = lpd7a40x_init,
diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c
new file mode 100644
index 000000000000..93751fee793d
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clcd.c
@@ -0,0 +1,241 @@
1/*
2 * arch/arm/mach-lh7a40x/clcd.c
3 *
4 * Copyright (C) 2004 Marc Singer
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 */
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/dma-mapping.h>
15#include <linux/sysdev.h>
16#include <linux/interrupt.h>
17
18//#include <linux/module.h>
19//#include <linux/time.h>
20//#include <asm/hardware.h>
21
22//#include <asm/mach/time.h>
23#include <asm/irq.h>
24#include <asm/mach/irq.h>
25
26#include <asm/system.h>
27#include <asm/hardware.h>
28#include <linux/amba/bus.h>
29#include <linux/amba/clcd.h>
30
31#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
32#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
33#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
34#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
35
36#define ALI_SETUP __REG(ALI_PHYS + 0x00)
37#define ALI_CONTROL __REG(ALI_PHYS + 0x04)
38#define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
39#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
40
41#include "lcd-panel.h"
42
43static void lh7a40x_clcd_disable (struct clcd_fb *fb)
44{
45#if defined (CONFIG_MACH_LPD7A400)
46 CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
47#endif
48
49#if defined (CONFIG_MACH_LPD7A404)
50 GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
51#endif
52
53#if defined (CONFIG_ARCH_LH7A400)
54 HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
55#endif
56
57#if defined (CONFIG_ARCH_LH7A404)
58 ALI_SETUP &= ~(1<<13); /* Disable ALI */
59#endif
60}
61
62static void lh7a40x_clcd_enable (struct clcd_fb *fb)
63{
64 struct clcd_panel_extra* extra
65 = (struct clcd_panel_extra*) fb->board_data;
66
67#if defined (CONFIG_MACH_LPD7A400)
68 CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
69#endif
70
71#if defined (CONFIG_MACH_LPD7A404)
72 GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
73 GPIO_PCD |= (1<<3);
74#endif
75
76#if defined (CONFIG_ARCH_LH7A400)
77
78 if (extra) {
79 HRTFTC_HRSETUP
80 = (1 << 13)
81 | ((fb->fb.var.xres - 1) << 4)
82 | 0xc
83 | (extra->hrmode ? 1 : 0);
84 HRTFTC_HRCON
85 = ((extra->clsen ? 1 : 0) << 1)
86 | ((extra->spsen ? 1 : 0) << 0);
87 HRTFTC_HRTIMING1
88 = (extra->pcdel << 8)
89 | (extra->revdel << 4)
90 | (extra->lpdel << 0);
91 HRTFTC_HRTIMING2
92 = (extra->spldel << 9)
93 | (extra->pc2del << 0);
94 }
95 else
96 HRTFTC_HRSETUP
97 = (1 << 13)
98 | 0xc;
99#endif
100
101#if defined (CONFIG_ARCH_LH7A404)
102
103 if (extra) {
104 ALI_SETUP
105 = (1 << 13)
106 | ((fb->fb.var.xres - 1) << 4)
107 | 0xc
108 | (extra->hrmode ? 1 : 0);
109 ALI_CONTROL
110 = ((extra->clsen ? 1 : 0) << 1)
111 | ((extra->spsen ? 1 : 0) << 0);
112 ALI_TIMING1
113 = (extra->pcdel << 8)
114 | (extra->revdel << 4)
115 | (extra->lpdel << 0);
116 ALI_TIMING2
117 = (extra->spldel << 9)
118 | (extra->pc2del << 0);
119 }
120 else
121 ALI_SETUP
122 = (1 << 13)
123 | 0xc;
124#endif
125
126}
127
128#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
129
130static int lh7a40x_clcd_setup (struct clcd_fb *fb)
131{
132 dma_addr_t dma;
133 u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
134 *(lcd_panel.bpp/8));
135
136 fb->panel = &lcd_panel;
137
138 /* Enforce the sync polarity defaults */
139 if (!(fb->panel->tim2 & TIM2_IHS))
140 fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
141 if (!(fb->panel->tim2 & TIM2_IVS))
142 fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
143
144#if defined (HAS_LCD_PANEL_EXTRA)
145 fb->board_data = &lcd_panel_extra;
146#endif
147
148 fb->fb.screen_base
149 = dma_alloc_writecombine (&fb->dev->dev, len,
150 &dma, GFP_KERNEL);
151 printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
152 fb->fb.screen_base, (void*) dma, len,
153 (void*) io_p2v (CLCDC_PHYS));
154 printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
155
156 if (!fb->fb.screen_base) {
157 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
158 return -ENOMEM;
159 }
160
161#if defined (USE_RGB555)
162 fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
163#endif
164
165 fb->fb.fix.smem_start = dma;
166 fb->fb.fix.smem_len = len;
167
168 /* Drive PE4 high to prevent CPLD crash */
169 GPIO_PEDD |= (1<<4);
170 GPIO_PED |= (1<<4);
171
172 GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
173
174// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
175// fb->fb.fbops->fb_set_par (&fb->fb);
176
177 return 0;
178}
179
180static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
181{
182 return dma_mmap_writecombine(&fb->dev->dev, vma,
183 fb->fb.screen_base,
184 fb->fb.fix.smem_start,
185 fb->fb.fix.smem_len);
186}
187
188static void lh7a40x_clcd_remove (struct clcd_fb *fb)
189{
190 dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
191 fb->fb.screen_base, fb->fb.fix.smem_start);
192}
193
194static struct clcd_board clcd_platform_data = {
195 .name = "lh7a40x FB",
196 .check = clcdfb_check,
197 .decode = clcdfb_decode,
198 .enable = lh7a40x_clcd_enable,
199 .setup = lh7a40x_clcd_setup,
200 .mmap = lh7a40x_clcd_mmap,
201 .remove = lh7a40x_clcd_remove,
202 .disable = lh7a40x_clcd_disable,
203};
204
205#define IRQ_CLCDC (IRQ_LCDINTR)
206
207#define AMBA_DEVICE(name,busid,base,plat,pid) \
208static struct amba_device name##_device = { \
209 .dev = { \
210 .coherent_dma_mask = ~0, \
211 .bus_id = busid, \
212 .platform_data = plat, \
213 }, \
214 .res = { \
215 .start = base##_PHYS, \
216 .end = (base##_PHYS) + (4*1024) - 1, \
217 .flags = IORESOURCE_MEM, \
218 }, \
219 .dma_mask = ~0, \
220 .irq = { IRQ_##base, }, \
221 /* .dma = base##_DMA,*/ \
222 .periphid = pid, \
223}
224
225AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
226
227static struct amba_device *amba_devs[] __initdata = {
228 &clcd_device,
229};
230
231void __init lh7a40x_clcd_init (void)
232{
233 int i;
234 int result;
235 printk ("CLCD: registering amba devices\n");
236 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
237 struct amba_device *d = amba_devs[i];
238 result = amba_device_register(d, &iomem_resource);
239 printk (" %d -> %d\n", i ,result);
240 }
241}
diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c
new file mode 100644
index 000000000000..2291afe9f23e
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clocks.c
@@ -0,0 +1,199 @@
1/* arch/arm/mach-lh7a40x/clocks.c
2 *
3 * Copyright (C) 2004 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/cpufreq.h>
13#include <asm/hardware.h>
14#include <asm/arch/clocks.h>
15#include <linux/err.h>
16
17struct module;
18struct icst525_params;
19
20struct clk {
21 struct list_head node;
22 unsigned long rate;
23 struct module *owner;
24 const char *name;
25// void *data;
26// const struct icst525_params *params;
27// void (*setvco)(struct clk *, struct icst525_vco vco);
28};
29
30int clk_register(struct clk *clk);
31void clk_unregister(struct clk *clk);
32
33/* ----- */
34
35#define MAINDIV1(c) (((c) >> 7) & 0x0f)
36#define MAINDIV2(c) (((c) >> 11) & 0x1f)
37#define PS(c) (((c) >> 18) & 0x03)
38#define PREDIV(c) (((c) >> 2) & 0x1f)
39#define HCLKDIV(c) (((c) >> 0) & 0x02)
40#define PCLKDIV(c) (((c) >> 16) & 0x03)
41
42unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
43{
44 return fclkfreq_get ()/1000;
45}
46EXPORT_SYMBOL(cpufreq_get);
47
48unsigned int fclkfreq_get (void)
49{
50 unsigned int clkset = CSC_CLKSET;
51 unsigned int gclk
52 = XTAL_IN
53 / (1 << PS(clkset))
54 * (MAINDIV1(clkset) + 2)
55 / (PREDIV(clkset) + 2)
56 * (MAINDIV2(clkset) + 2)
57 ;
58 return gclk;
59}
60
61unsigned int hclkfreq_get (void)
62{
63 unsigned int clkset = CSC_CLKSET;
64 unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
65
66 return hclk;
67}
68
69unsigned int pclkfreq_get (void)
70{
71 unsigned int clkset = CSC_CLKSET;
72 int pclkdiv = PCLKDIV(clkset);
73 unsigned int pclk;
74 if (pclkdiv == 0x3)
75 pclkdiv = 0x2;
76 pclk = hclkfreq_get () / (1 << pclkdiv);
77
78 return pclk;
79}
80
81/* ----- */
82
83static LIST_HEAD(clocks);
84static DECLARE_MUTEX(clocks_sem);
85
86struct clk *clk_get (struct device *dev, const char *id)
87{
88 struct clk *p;
89 struct clk *clk = ERR_PTR(-ENOENT);
90
91 down (&clocks_sem);
92 list_for_each_entry (p, &clocks, node) {
93 if (strcmp (id, p->name) == 0
94 && try_module_get(p->owner)) {
95 clk = p;
96 break;
97 }
98 }
99 up (&clocks_sem);
100
101 return clk;
102}
103EXPORT_SYMBOL(clk_get);
104
105void clk_put (struct clk *clk)
106{
107 module_put(clk->owner);
108}
109EXPORT_SYMBOL(clk_put);
110
111int clk_enable (struct clk *clk)
112{
113 return 0;
114}
115EXPORT_SYMBOL(clk_enable);
116
117void clk_disable (struct clk *clk)
118{
119}
120EXPORT_SYMBOL(clk_disable);
121
122int clk_use (struct clk *clk)
123{
124 return 0;
125}
126EXPORT_SYMBOL(clk_use);
127
128void clk_unuse (struct clk *clk)
129{
130}
131EXPORT_SYMBOL(clk_unuse);
132
133unsigned long clk_get_rate (struct clk *clk)
134{
135 return clk->rate;
136}
137EXPORT_SYMBOL(clk_get_rate);
138
139long clk_round_rate (struct clk *clk, unsigned long rate)
140{
141 return rate;
142}
143EXPORT_SYMBOL(clk_round_rate);
144
145int clk_set_rate (struct clk *clk, unsigned long rate)
146{
147 int ret = -EIO;
148 return ret;
149}
150EXPORT_SYMBOL(clk_set_rate);
151
152#if 0
153/*
154 * These are fixed clocks.
155 */
156static struct clk kmi_clk = {
157 .name = "KMIREFCLK",
158 .rate = 24000000,
159};
160
161static struct clk uart_clk = {
162 .name = "UARTCLK",
163 .rate = 24000000,
164};
165
166static struct clk mmci_clk = {
167 .name = "MCLK",
168 .rate = 33000000,
169};
170#endif
171
172static struct clk clcd_clk = {
173 .name = "CLCDCLK",
174 .rate = 0,
175};
176
177int clk_register (struct clk *clk)
178{
179 down (&clocks_sem);
180 list_add (&clk->node, &clocks);
181 up (&clocks_sem);
182 return 0;
183}
184EXPORT_SYMBOL(clk_register);
185
186void clk_unregister (struct clk *clk)
187{
188 down (&clocks_sem);
189 list_del (&clk->node);
190 up (&clocks_sem);
191}
192EXPORT_SYMBOL(clk_unregister);
193
194static int __init clk_init (void)
195{
196 clk_register(&clcd_clk);
197 return 0;
198}
199arch_initcall(clk_init);
diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
index ea8de7e3ab1b..18e8bb4eb202 100644
--- a/arch/arm/mach-lh7a40x/common.h
+++ b/arch/arm/mach-lh7a40x/common.h
@@ -12,6 +12,7 @@ extern struct sys_timer lh7a40x_timer;
12 12
13extern void lh7a400_init_irq (void); 13extern void lh7a400_init_irq (void);
14extern void lh7a404_init_irq (void); 14extern void lh7a404_init_irq (void);
15extern void lh7a40x_clcd_init (void);
15extern void lh7a40x_init_board_irq (void); 16extern void lh7a40x_init_board_irq (void);
16 17
17#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) 18#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
index e902e3d87da4..2685a81454d2 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c
@@ -28,13 +28,17 @@
28 28
29static unsigned char irq_pri_vic1[] = { 29static unsigned char irq_pri_vic1[] = {
30#if defined (USE_PRIORITIES) 30#if defined (USE_PRIORITIES)
31IRQ_GPIO3INTR, 31 IRQ_GPIO3INTR, /* CPLD */
32 IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */
32#endif 33#endif
33}; 34};
34static unsigned char irq_pri_vic2[] = { 35static unsigned char irq_pri_vic2[] = {
35#if defined (USE_PRIORITIES) 36#if defined (USE_PRIORITIES)
36 IRQ_T3UI, IRQ_GPIO7INTR, 37 IRQ_T3UI, /* Timer */
38 IRQ_GPIO7INTR, /* CPLD */
37 IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, 39 IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR,
40 IRQ_LCDINTR, /* LCD */
41 IRQ_TSCINTR, /* ADC/Touchscreen */
38#endif 42#endif
39}; 43};
40 44
@@ -98,10 +102,19 @@ static struct irqchip lh7a404_gpio_vic2_chip = {
98 102
99 /* IRQ initialization */ 103 /* IRQ initialization */
100 104
105#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
106extern void* branch_irq_lh7a400;
107#endif
108
101void __init lh7a404_init_irq (void) 109void __init lh7a404_init_irq (void)
102{ 110{
103 int irq; 111 int irq;
104 112
113#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
114#define NOP 0xe1a00000 /* mov r0, r0 */
115 branch_irq_lh7a400 = NOP;
116#endif
117
105 VIC1_INTENCLR = 0xffffffff; 118 VIC1_INTENCLR = 0xffffffff;
106 VIC2_INTENCLR = 0xffffffff; 119 VIC2_INTENCLR = 0xffffffff;
107 VIC1_INTSEL = 0; /* All IRQs */ 120 VIC1_INTSEL = 0; /* All IRQs */
diff --git a/arch/arm/mach-lh7a40x/lcd-panel.h b/arch/arm/mach-lh7a40x/lcd-panel.h
new file mode 100644
index 000000000000..4fb2efc4950f
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/lcd-panel.h
@@ -0,0 +1,346 @@
1/* lcd-panel.h
2 $Id$
3
4 written by Marc Singer
5 18 Jul 2005
6
7 Copyright (C) 2005 Marc Singer
8
9 -----------
10 DESCRIPTION
11 -----------
12
13 Only one panel may be defined at a time.
14
15 The pixel clock is calculated to be no greater than the target.
16
17 Each timing value is accompanied by a specification comment.
18
19 UNITS/MIN/TYP/MAX
20
21 Most of the units will be in clocks.
22
23 USE_RGB555
24
25 Define this macro to configure the AMBA LCD controller to use an
26 RGB555 encoding for the pels instead of the normal RGB565.
27
28 LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
29
30 These boards are best approximated by 555 for all panels. Some
31 can use an extra low-order bit of blue in bit 16 of the color
32 value, but we don't have a way to communicate this non-linear
33 mapping to the kernel.
34
35*/
36
37#if !defined (__LCD_PANEL_H__)
38# define __LCD_PANEL_H__
39
40#if defined (MACH_LPD79520)\
41 || defined (MACH_LPD79524)\
42 || defined (MACH_LPD7A400)\
43 || defined (MACH_LPD7A404)
44# define USE_RGB555
45#endif
46
47struct clcd_panel_extra {
48 unsigned int hrmode;
49 unsigned int clsen;
50 unsigned int spsen;
51 unsigned int pcdel;
52 unsigned int revdel;
53 unsigned int lpdel;
54 unsigned int spldel;
55 unsigned int pc2del;
56};
57
58#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000))
59#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e))
60
61#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
62
63 /* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
64 /* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
65
66#define PIX_CLOCK_TARGET (6800000)
67#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
68#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
69
70static struct clcd_panel lcd_panel = {
71 .mode = {
72 .name = "3.5in QVGA (LQ035Q7DB02)",
73 .xres = 240,
74 .yres = 320,
75 .pixclock = PIX_CLOCK,
76 .left_margin = 16,
77 .right_margin = 21,
78 .upper_margin = 8, // line/8/8/8
79 .lower_margin = 5,
80 .hsync_len = 61,
81 .vsync_len = NS_TO_CLOCK (60, PIX_CLOCK),
82 .vmode = FB_VMODE_NONINTERLACED,
83 },
84 .width = -1,
85 .height = -1,
86 .tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
87 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
88 .bpp = 16,
89};
90
91#define HAS_LCD_PANEL_EXTRA
92
93static struct clcd_panel_extra lcd_panel_extra = {
94 .hrmode = 1,
95 .clsen = 1,
96 .spsen = 1,
97 .pcdel = 8,
98 .revdel = 7,
99 .lpdel = 13,
100 .spldel = 77,
101 .pc2del = 208,
102};
103
104#endif
105
106#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
107
108 /* Logic Product Development LCD 5.7" QVGA -10 */
109 /* Sharp PN LQ057Q3DC02 */
110 /* QVGA mode, V/Q=LOW */
111
112/* From Sharp on 2006.1.3. I believe some of the values are incorrect
113 * based on the datasheet.
114
115 Timing0 TIMING1 TIMING2 CONTROL
116 0x140A0C4C 0x080504EF 0x013F380D 0x00000829
117 HBP= 20 VBP= 8 BCD= 0
118 HFP= 10 VFP= 5 CPL=319
119 HSW= 12 VSW= 1 IOE= 0
120 PPL= 19 LPP=239 IPC= 1
121 IHS= 1
122 IVS= 1
123 ACB= 0
124 CSEL= 0
125 PCD= 13
126
127 */
128
129/* The full horozontal cycle (Th) is clock/360/400/450. */
130/* The full vertical cycle (Tv) is line/251/262/280. */
131
132#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */
133#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
134#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
135
136static struct clcd_panel lcd_panel = {
137 .mode = {
138 .name = "5.7in QVGA (LQ057Q3DC02)",
139 .xres = 320,
140 .yres = 240,
141 .pixclock = PIX_CLOCK,
142 .left_margin = 11,
143 .right_margin = 400-11-320-2,
144 .upper_margin = 7, // line/7/7/7
145 .lower_margin = 262-7-240-2,
146 .hsync_len = 2, // clk/2/96/200
147 .vsync_len = 2, // line/2/-/34
148 .vmode = FB_VMODE_NONINTERLACED,
149 },
150 .width = -1,
151 .height = -1,
152 .tim2 = TIM2_IHS | TIM2_IVS
153 | (PIX_CLOCK_DIVIDER - 2),
154 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
155 .bpp = 16,
156};
157
158#endif
159
160#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
161
162 /* Logic Product Development LCD 6.4" VGA -10 */
163 /* Sharp PN LQ64D343 */
164
165/* The full horozontal cycle (Th) is clock/750/800/900. */
166/* The full vertical cycle (Tv) is line/515/525/560. */
167
168#define PIX_CLOCK_TARGET (28330000)
169#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
170#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
171
172static struct clcd_panel lcd_panel = {
173 .mode = {
174 .name = "6.4in QVGA (LQ64D343)",
175 .xres = 640,
176 .yres = 480,
177 .pixclock = PIX_CLOCK,
178 .left_margin = 32,
179 .right_margin = 800-32-640-96,
180 .upper_margin = 32, // line/34/34/34
181 .lower_margin = 540-32-480-2,
182 .hsync_len = 96, // clk/2/96/200
183 .vsync_len = 2, // line/2/-/34
184 .vmode = FB_VMODE_NONINTERLACED,
185 },
186 .width = -1,
187 .height = -1,
188 .tim2 = TIM2_IHS | TIM2_IVS
189 | (PIX_CLOCK_DIVIDER - 2),
190 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
191 .bpp = 16,
192};
193
194#endif
195
196#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
197
198 /* Logic Product Development LCD 10.4" VGA -10 */
199 /* Sharp PN LQ10D368 */
200
201#define PIX_CLOCK_TARGET (28330000)
202#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
203#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
204
205static struct clcd_panel lcd_panel = {
206 .mode = {
207 .name = "10.4in VGA (LQ10D368)",
208 .xres = 640,
209 .yres = 480,
210 .pixclock = PIX_CLOCK,
211 .left_margin = 21,
212 .right_margin = 15,
213 .upper_margin = 34,
214 .lower_margin = 5,
215 .hsync_len = 96,
216 .vsync_len = 16,
217 .vmode = FB_VMODE_NONINTERLACED,
218 },
219 .width = -1,
220 .height = -1,
221 .tim2 = TIM2_IHS | TIM2_IVS
222 | (PIX_CLOCK_DIVIDER - 2),
223 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
224 .bpp = 16,
225};
226
227#endif
228
229#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
230
231 /* Logic Product Development LCD 12.1" SVGA -10 */
232 /* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
233
234/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
235 * target clock frequency range of 35MHz to 42MHz. */
236
237/* If the target pixel clock is substantially lower than the panel
238 * spec, this is done to prevent the LCD display from glitching when
239 * the CPU is under load. A pixel clock higher than 25MHz
240 * (empirically determined) will compete with the CPU for bus cycles
241 * for the Ethernet chip. However, even a pixel clock of 10MHz
242 * competes with Compact Flash interface during some operations
243 * (fdisk, e2fsck). And, at that speed the display may have a visible
244 * flicker. */
245
246/* The full horozontal cycle (Th) is clock/832/1056/1395. */
247
248#define PIX_CLOCK_TARGET (20000000)
249#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
250#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
251
252static struct clcd_panel lcd_panel = {
253 .mode = {
254 .name = "12.1in SVGA (LQ121S1DG41)",
255 .xres = 800,
256 .yres = 600,
257 .pixclock = PIX_CLOCK,
258 .left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10
259 .right_margin = 1056-800-89-128,
260 .upper_margin = 23, // line/23/23/23
261 .lower_margin = 44,
262 .hsync_len = 128, // clk/2/128/200
263 .vsync_len = 4, // line/2/4/6
264 .vmode = FB_VMODE_NONINTERLACED,
265 },
266 .width = -1,
267 .height = -1,
268 .tim2 = TIM2_IHS | TIM2_IVS
269 | (PIX_CLOCK_DIVIDER - 2),
270 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
271 .bpp = 16,
272};
273
274#endif
275
276#if defined CONFIG_FB_ARMCLCD_HITACHI
277
278 /* Hitachi*/
279 /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
280
281#define PIX_CLOCK_TARGET (49000000)
282#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
283#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
284
285static struct clcd_panel lcd_panel = {
286 .mode = {
287 .name = "Hitachi 800x480",
288 .xres = 800,
289 .yres = 480,
290 .pixclock = PIX_CLOCK,
291 .left_margin = 88,
292 .right_margin = 40,
293 .upper_margin = 32,
294 .lower_margin = 11,
295 .hsync_len = 128,
296 .vsync_len = 2,
297 .vmode = FB_VMODE_NONINTERLACED,
298 },
299 .width = -1,
300 .height = -1,
301 .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
302 | (PIX_CLOCK_DIVIDER - 2),
303 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
304 .bpp = 16,
305};
306
307#endif
308
309
310#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
311
312 /* AU Optotronics A070VW01 7.0 Wide Screen color Display*/
313 /* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
314
315#define PIX_CLOCK_TARGET (10000000)
316#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
317#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
318
319static struct clcd_panel lcd_panel = {
320 .mode = {
321 .name = "7.0in Wide (A070VW01)",
322 .xres = 480,
323 .yres = 234,
324 .pixclock = PIX_CLOCK,
325 .left_margin = 30,
326 .right_margin = 25,
327 .upper_margin = 14,
328 .lower_margin = 12,
329 .hsync_len = 100,
330 .vsync_len = 1,
331 .vmode = FB_VMODE_NONINTERLACED,
332 },
333 .width = -1,
334 .height = -1,
335 .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
336 | (PIX_CLOCK_DIVIDER - 2),
337 .cntl = CNTL_LCDTFT | CNTL_WATERMARK,
338 .bpp = 16,
339};
340
341#endif
342
343#undef NS_TO_CLOCK
344#undef CLOCK_TO_DIV
345
346#endif /* __LCD_PANEL_H__ */
diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c
new file mode 100644
index 000000000000..a10830186dac
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/ssp-cpld.c
@@ -0,0 +1,343 @@
1/* arch/arm/mach-lh7a40x/ssp-cpld.c
2 *
3 * Copyright (C) 2004,2005 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * SSP/SPI driver for the CardEngine CPLD.
10 *
11 */
12
13/* NOTES
14 -----
15
16 o *** This driver is cribbed from the 7952x implementation.
17 Some comments may not apply.
18
19 o This driver contains sufficient logic to control either the
20 serial EEPROMs or the audio codec. It is included in the kernel
21 to support the codec. The EEPROMs are really the responsibility
22 of the boot loader and should probably be left alone.
23
24 o The code must be augmented to cope with multiple, simultaneous
25 clients.
26 o The audio codec writes to the codec chip whenever playback
27 starts.
28 o The touchscreen driver writes to the ads chip every time it
29 samples.
30 o The audio codec must write 16 bits, but the touch chip writes
31 are 8 bits long.
32 o We need to be able to keep these configurations separate while
33 simultaneously active.
34
35 */
36
37#include <linux/module.h>
38#include <linux/kernel.h>
39//#include <linux/sched.h>
40#include <linux/errno.h>
41#include <linux/interrupt.h>
42//#include <linux/ioport.h>
43#include <linux/init.h>
44#include <linux/delay.h>
45#include <linux/spinlock.h>
46
47#include <asm/io.h>
48#include <asm/irq.h>
49#include <asm/hardware.h>
50
51#include <asm/arch/ssp.h>
52
53//#define TALK
54
55#if defined (TALK)
56#define PRINTK(f...) printk (f)
57#else
58#define PRINTK(f...) do {} while (0)
59#endif
60
61#if defined (CONFIG_ARCH_LH7A400)
62# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */
63# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */
64# define CPLD_SPIC_CS_CODEC (1<<0)
65# define CPLD_SPIC_CS_TOUCH (1<<1)
66# define CPLD_SPIC_WRITE (0<<2)
67# define CPLD_SPIC_READ (1<<2)
68# define CPLD_SPIC_DONE (1<<3) /* r/o */
69# define CPLD_SPIC_LOAD (1<<4)
70# define CPLD_SPIC_START (1<<4)
71# define CPLD_SPIC_LOADED (1<<5) /* r/o */
72#endif
73
74#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */
75#define CPLD_SPI_CS_EEPROM (1<<3)
76#define CPLD_SPI_SCLK (1<<2)
77#define CPLD_SPI_TX_SHIFT (1)
78#define CPLD_SPI_TX (1<<CPLD_SPI_TX_SHIFT)
79#define CPLD_SPI_RX_SHIFT (0)
80#define CPLD_SPI_RX (1<<CPLD_SPI_RX_SHIFT)
81
82/* *** FIXME: these timing values are substantially larger than the
83 *** chip requires. We may implement an nsleep () function. */
84#define T_SKH 1 /* Clock time high (us) */
85#define T_SKL 1 /* Clock time low (us) */
86#define T_CS 1 /* Minimum chip select low time (us) */
87#define T_CSS 1 /* Minimum chip select setup time (us) */
88#define T_DIS 1 /* Data setup time (us) */
89
90 /* EEPROM SPI bits */
91#define P_START (1<<9)
92#define P_WRITE (1<<7)
93#define P_READ (2<<7)
94#define P_ERASE (3<<7)
95#define P_EWDS (0<<7)
96#define P_WRAL (0<<7)
97#define P_ERAL (0<<7)
98#define P_EWEN (0<<7)
99#define P_A_EWDS (0<<5)
100#define P_A_WRAL (1<<5)
101#define P_A_ERAL (2<<5)
102#define P_A_EWEN (3<<5)
103
104struct ssp_configuration {
105 int device;
106 int mode;
107 int speed;
108 int frame_size_write;
109 int frame_size_read;
110};
111
112static struct ssp_configuration ssp_configuration;
113static spinlock_t ssp_lock;
114
115static void enable_cs (void)
116{
117 switch (ssp_configuration.device) {
118 case DEVICE_EEPROM:
119 CPLD_SPI |= CPLD_SPI_CS_EEPROM;
120 break;
121 }
122 udelay (T_CSS);
123}
124
125static void disable_cs (void)
126{
127 switch (ssp_configuration.device) {
128 case DEVICE_EEPROM:
129 CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
130 break;
131 }
132 udelay (T_CS);
133}
134
135static void pulse_clock (void)
136{
137 CPLD_SPI |= CPLD_SPI_SCLK;
138 udelay (T_SKH);
139 CPLD_SPI &= ~CPLD_SPI_SCLK;
140 udelay (T_SKL);
141}
142
143
144/* execute_spi_command
145
146 sends an spi command to a device. It first sends cwrite bits from
147 v. If cread is greater than zero it will read cread bits
148 (discarding the leading 0 bit) and return them. If cread is less
149 than zero it will check for completetion status and return 0 on
150 success or -1 on timeout. If cread is zero it does nothing other
151 than sending the command.
152
153 On the LPD7A400, we can only read or write multiples of 8 bits on
154 the codec and the touch screen device. Here, we round up.
155
156*/
157
158static int execute_spi_command (int v, int cwrite, int cread)
159{
160 unsigned long l = 0;
161
162#if defined (CONFIG_MACH_LPD7A400)
163 /* The codec and touch devices cannot be bit-banged. Instead,
164 * the CPLD provides an eight-bit shift register and a crude
165 * interface. */
166 if ( ssp_configuration.device == DEVICE_CODEC
167 || ssp_configuration.device == DEVICE_TOUCH) {
168 int select = 0;
169
170 PRINTK ("spi(%d %d.%d) 0x%04x",
171 ssp_configuration.device, cwrite, cread,
172 v);
173#if defined (TALK)
174 if (ssp_configuration.device == DEVICE_CODEC)
175 PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
176#endif
177 PRINTK ("\n");
178
179 if (ssp_configuration.device == DEVICE_CODEC)
180 select = CPLD_SPIC_CS_CODEC;
181 if (ssp_configuration.device == DEVICE_TOUCH)
182 select = CPLD_SPIC_CS_TOUCH;
183 if (cwrite) {
184 for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
185 CPLD_SPID = (v >> (8*cwrite)) & 0xff;
186 CPLD_SPIC = select | CPLD_SPIC_LOAD;
187 while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
188 ;
189 CPLD_SPIC = select;
190 while (!(CPLD_SPIC & CPLD_SPIC_DONE))
191 ;
192 }
193 v = 0;
194 }
195 if (cread) {
196 mdelay (2); /* *** FIXME: required by ads7843? */
197 v = 0;
198 for (cread = (cread + 7)/8; cread-- > 0;) {
199 CPLD_SPID = 0;
200 CPLD_SPIC = select | CPLD_SPIC_READ
201 | CPLD_SPIC_START;
202 while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
203 ;
204 CPLD_SPIC = select | CPLD_SPIC_READ;
205 while (!(CPLD_SPIC & CPLD_SPIC_DONE))
206 ;
207 v = (v << 8) | CPLD_SPID;
208 }
209 }
210 return v;
211 }
212#endif
213
214 PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
215 v & 0x1ff, (v >> 9) & 0x7f);
216
217 enable_cs ();
218
219 v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
220 while (cwrite--) {
221 CPLD_SPI
222 = (CPLD_SPI & ~CPLD_SPI_TX)
223 | ((v >> cwrite) & CPLD_SPI_TX);
224 udelay (T_DIS);
225 pulse_clock ();
226 }
227
228 if (cread < 0) {
229 int delay = 10;
230 disable_cs ();
231 udelay (1);
232 enable_cs ();
233
234 l = -1;
235 do {
236 if (CPLD_SPI & CPLD_SPI_RX) {
237 l = 0;
238 break;
239 }
240 } while (udelay (1), --delay);
241 }
242 else
243 /* We pulse the clock before the data to skip the leading zero. */
244 while (cread-- > 0) {
245 pulse_clock ();
246 l = (l<<1)
247 | (((CPLD_SPI & CPLD_SPI_RX)
248 >> CPLD_SPI_RX_SHIFT) & 0x1);
249 }
250
251 disable_cs ();
252 return l;
253}
254
255static int ssp_init (void)
256{
257 spin_lock_init (&ssp_lock);
258 memset (&ssp_configuration, 0, sizeof (ssp_configuration));
259 return 0;
260}
261
262
263/* ssp_chip_select
264
265 drops the chip select line for the CPLD shift-register controlled
266 devices. It doesn't enable chip
267
268*/
269
270static void ssp_chip_select (int enable)
271{
272#if defined (CONFIG_MACH_LPD7A400)
273 int select;
274
275 if (ssp_configuration.device == DEVICE_CODEC)
276 select = CPLD_SPIC_CS_CODEC;
277 else if (ssp_configuration.device == DEVICE_TOUCH)
278 select = CPLD_SPIC_CS_TOUCH;
279 else
280 return;
281
282 if (enable)
283 CPLD_SPIC = select;
284 else
285 CPLD_SPIC = 0;
286#endif
287}
288
289static void ssp_acquire (void)
290{
291 spin_lock (&ssp_lock);
292}
293
294static void ssp_release (void)
295{
296 ssp_chip_select (0); /* just in case */
297 spin_unlock (&ssp_lock);
298}
299
300static int ssp_configure (int device, int mode, int speed,
301 int frame_size_write, int frame_size_read)
302{
303 ssp_configuration.device = device;
304 ssp_configuration.mode = mode;
305 ssp_configuration.speed = speed;
306 ssp_configuration.frame_size_write = frame_size_write;
307 ssp_configuration.frame_size_read = frame_size_read;
308
309 return 0;
310}
311
312static int ssp_read (void)
313{
314 return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
315}
316
317static int ssp_write (u16 data)
318{
319 execute_spi_command (data, ssp_configuration.frame_size_write, 0);
320 return 0;
321}
322
323static int ssp_write_read (u16 data)
324{
325 return execute_spi_command (data, ssp_configuration.frame_size_write,
326 ssp_configuration.frame_size_read);
327}
328
329struct ssp_driver lh7a40x_cpld_ssp_driver = {
330 .init = ssp_init,
331 .acquire = ssp_acquire,
332 .release = ssp_release,
333 .configure = ssp_configure,
334 .chip_select = ssp_chip_select,
335 .read = ssp_read,
336 .write = ssp_write,
337 .write_read = ssp_write_read,
338};
339
340
341MODULE_AUTHOR("Marc Singer");
342MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
343MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index be377e331f25..ef9af375fcc4 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * arch/arm/mach-lh7a40x/time.c 2 * arch/arm/mach-lh7a40x/time.c
3 * 3 *
4 * Copyright (C) 2004 Logic Product Development 4 * Copyright (C) 2004 Logic Product Development
@@ -57,7 +57,7 @@ static struct irqaction lh7a40x_timer_irq = {
57 .handler = lh7a40x_timer_interrupt, 57 .handler = lh7a40x_timer_interrupt,
58}; 58};
59 59
60static void __init lh7a40x_timer_init(void) 60static void __init lh7a40x_timer_init (void)
61{ 61{
62 /* Stop/disable all timers */ 62 /* Stop/disable all timers */
63 TIMER_CONTROL1 = 0; 63 TIMER_CONTROL1 = 0;
diff --git a/arch/arm/mach-pnx4008/Makefile b/arch/arm/mach-pnx4008/Makefile
new file mode 100644
index 000000000000..b457ca0a431a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o
6obj-m :=
7obj-n :=
8obj- :=
9
10# Power Management
11obj-$(CONFIG_PM) += pm.o sleep.o
12
diff --git a/arch/arm/mach-pnx4008/Makefile.boot b/arch/arm/mach-pnx4008/Makefile.boot
new file mode 100644
index 000000000000..44c7117e20dd
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile.boot
@@ -0,0 +1,4 @@
1 zreladdr-y := 0x80008000
2params_phys-y := 0x80000100
3initrd_phys-y := 0x80800000
4
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
new file mode 100644
index 000000000000..285b22f631e9
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -0,0 +1,1010 @@
1/*
2 * arch/arm/mach-pnx4008/clock.c
3 *
4 * Clock control driver for PNX4008
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 * Generic clock management functions are partially based on:
8 * linux/arch/arm/mach-omap/clock.c
9 *
10 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/device.h>
21#include <linux/err.h>
22#include <linux/delay.h>
23
24#include <asm/semaphore.h>
25#include <asm/hardware.h>
26#include <asm/io.h>
27
28#include <asm/arch/clock.h>
29#include "clock.h"
30
31/*forward declaration*/
32static struct clk per_ck;
33static struct clk hclk_ck;
34static struct clk ck_1MHz;
35static struct clk ck_13MHz;
36static struct clk ck_pll1;
37static int local_set_rate(struct clk *clk, u32 rate);
38
39static inline void clock_lock(void)
40{
41 local_irq_disable();
42}
43
44static inline void clock_unlock(void)
45{
46 local_irq_enable();
47}
48
49static void propagate_rate(struct clk *clk)
50{
51 struct clk *tmp_clk;
52
53 tmp_clk = clk;
54 while (tmp_clk->propagate_next) {
55 tmp_clk = tmp_clk->propagate_next;
56 local_set_rate(tmp_clk, tmp_clk->user_rate);
57 }
58}
59
60static inline void clk_reg_disable(struct clk *clk)
61{
62 if (clk->enable_reg)
63 __raw_writel(__raw_readl(clk->enable_reg) &
64 ~(1 << clk->enable_shift), clk->enable_reg);
65}
66
67static inline void clk_reg_enable(struct clk *clk)
68{
69 if (clk->enable_reg)
70 __raw_writel(__raw_readl(clk->enable_reg) |
71 (1 << clk->enable_shift), clk->enable_reg);
72}
73
74static inline void clk_reg_disable1(struct clk *clk)
75{
76 if (clk->enable_reg1)
77 __raw_writel(__raw_readl(clk->enable_reg1) &
78 ~(1 << clk->enable_shift1), clk->enable_reg1);
79}
80
81static inline void clk_reg_enable1(struct clk *clk)
82{
83 if (clk->enable_reg1)
84 __raw_writel(__raw_readl(clk->enable_reg1) |
85 (1 << clk->enable_shift1), clk->enable_reg1);
86}
87
88static int clk_wait_for_pll_lock(struct clk *clk)
89{
90 int i;
91 i = 0;
92 while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
93
94 if (!(__raw_readl(clk->scale_reg) & 1)) {
95 printk(KERN_ERR
96 "%s ERROR: failed to lock, scale reg data: %x\n",
97 clk->name, __raw_readl(clk->scale_reg));
98 return -1;
99 }
100 return 0;
101}
102
103static int switch_to_dirty_13mhz(struct clk *clk)
104{
105 int i;
106 int ret;
107 u32 tmp_reg;
108
109 ret = 0;
110
111 if (!clk->rate)
112 clk_reg_enable1(clk);
113
114 tmp_reg = __raw_readl(clk->parent_switch_reg);
115 /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
116 if (!(tmp_reg & 1)) {
117 tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
118 __raw_writel(tmp_reg, clk->parent_switch_reg);
119 i = 0;
120 while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
121
122 if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
123 printk(KERN_ERR
124 "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
125 clk->name, __raw_readl(clk->parent_switch_reg));
126 ret = -1;
127 }
128 }
129
130 if (!clk->rate)
131 clk_reg_disable1(clk);
132
133 return ret;
134}
135
136static int switch_to_clean_13mhz(struct clk *clk)
137{
138 int i;
139 int ret;
140 u32 tmp_reg;
141
142 ret = 0;
143
144 if (!clk->rate)
145 clk_reg_enable1(clk);
146
147 tmp_reg = __raw_readl(clk->parent_switch_reg);
148 /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
149 if (tmp_reg & 1) {
150 tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
151 __raw_writel(tmp_reg, clk->parent_switch_reg);
152 i = 0;
153 while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
154
155 if (__raw_readl(clk->parent_switch_reg) & 1) {
156 printk(KERN_ERR
157 "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
158 clk->name, __raw_readl(clk->parent_switch_reg));
159 ret = -1;
160 }
161 }
162
163 if (!clk->rate)
164 clk_reg_disable1(clk);
165
166 return ret;
167}
168
169static int set_13MHz_parent(struct clk *clk, struct clk *parent)
170{
171 int ret = -EINVAL;
172
173 if (parent == &ck_13MHz)
174 ret = switch_to_clean_13mhz(clk);
175 else if (parent == &ck_pll1)
176 ret = switch_to_dirty_13mhz(clk);
177
178 return ret;
179}
180
181#define PLL160_MIN_FCCO 156000
182#define PLL160_MAX_FCCO 320000
183
184/*
185 * Calculate pll160 settings.
186 * Possible input: up to 320MHz with step of clk->parent->rate.
187 * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
188 * Ignored paths: "feedback" (bit 13 set), "div-by-N".
189 * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
190 * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
191 * Please refer to PNX4008 IC manual for details.
192 */
193
194static int pll160_set_rate(struct clk *clk, u32 rate)
195{
196 u32 tmp_reg, tmp_m, tmp_2p, i;
197 u32 parent_rate;
198 int ret = -EINVAL;
199
200 parent_rate = clk->parent->rate;
201
202 if (!parent_rate)
203 goto out;
204
205 /* set direct run for ARM or disable output for others */
206 clk_reg_disable(clk);
207
208 /* disable source input as well (ignored for ARM) */
209 clk_reg_disable1(clk);
210
211 tmp_reg = __raw_readl(clk->scale_reg);
212 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
213 __raw_writel(tmp_reg, clk->scale_reg);
214
215 rate -= rate % parent_rate; /*round down the input */
216
217 if (rate > PLL160_MAX_FCCO)
218 rate = PLL160_MAX_FCCO;
219
220 if (!rate) {
221 clk->rate = 0;
222 ret = 0;
223 goto out;
224 }
225
226 clk_reg_enable1(clk);
227 tmp_reg = __raw_readl(clk->scale_reg);
228
229 if (rate == parent_rate) {
230 /*enter direct bypass mode */
231 tmp_reg |= ((1 << 14) | (1 << 15));
232 __raw_writel(tmp_reg, clk->scale_reg);
233 clk->rate = parent_rate;
234 clk_reg_enable(clk);
235 ret = 0;
236 goto out;
237 }
238
239 i = 0;
240 for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
241 if (rate * tmp_2p >= PLL160_MIN_FCCO)
242 break;
243 i++;
244 }
245
246 if (tmp_2p > 1)
247 tmp_reg |= ((i - 1) << 11);
248 else
249 tmp_reg |= (1 << 14); /*direct mode, no divide */
250
251 tmp_m = rate * tmp_2p;
252 tmp_m /= parent_rate;
253
254 tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
255 tmp_reg |= (1 << 16); /*power up PLL */
256 __raw_writel(tmp_reg, clk->scale_reg);
257
258 if (clk_wait_for_pll_lock(clk) < 0) {
259 clk_reg_disable(clk);
260 clk_reg_disable1(clk);
261
262 tmp_reg = __raw_readl(clk->scale_reg);
263 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
264 __raw_writel(tmp_reg, clk->scale_reg);
265 clk->rate = 0;
266 ret = -EFAULT;
267 goto out;
268 }
269
270 clk->rate = (tmp_m * parent_rate) / tmp_2p;
271
272 if (clk->flags & RATE_PROPAGATES)
273 propagate_rate(clk);
274
275 clk_reg_enable(clk);
276 ret = 0;
277
278out:
279 return ret;
280}
281
282/*configure PER_CLK*/
283static int per_clk_set_rate(struct clk *clk, u32 rate)
284{
285 u32 tmp;
286
287 tmp = __raw_readl(clk->scale_reg);
288 tmp &= ~(0x1f << 2);
289 tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
290 __raw_writel(tmp, clk->scale_reg);
291 clk->rate = rate;
292 return 0;
293}
294
295/*configure HCLK*/
296static int hclk_set_rate(struct clk *clk, u32 rate)
297{
298 u32 tmp;
299 tmp = __raw_readl(clk->scale_reg);
300 tmp = tmp & ~0x3;
301 switch (rate) {
302 case 1:
303 break;
304 case 2:
305 tmp |= 1;
306 break;
307 case 4:
308 tmp |= 2;
309 break;
310 }
311
312 __raw_writel(tmp, clk->scale_reg);
313 clk->rate = rate;
314 return 0;
315}
316
317static u32 hclk_round_rate(struct clk *clk, u32 rate)
318{
319 switch (rate) {
320 case 1:
321 case 4:
322 return rate;
323 }
324 return 2;
325}
326
327static u32 per_clk_round_rate(struct clk *clk, u32 rate)
328{
329 return CLK_RATE_13MHZ;
330}
331
332static int on_off_set_rate(struct clk *clk, u32 rate)
333{
334 if (rate) {
335 clk_reg_enable(clk);
336 clk->rate = 1;
337 } else {
338 clk_reg_disable(clk);
339 clk->rate = 0;
340 }
341 return 0;
342}
343
344static int on_off_inv_set_rate(struct clk *clk, u32 rate)
345{
346 if (rate) {
347 clk_reg_disable(clk); /*enable bit is inverted */
348 clk->rate = 1;
349 } else {
350 clk_reg_enable(clk);
351 clk->rate = 0;
352 }
353 return 0;
354}
355
356static u32 on_off_round_rate(struct clk *clk, u32 rate)
357{
358 return (rate ? 1 : 0);
359}
360
361static u32 pll4_round_rate(struct clk *clk, u32 rate)
362{
363 if (rate > CLK_RATE_208MHZ)
364 rate = CLK_RATE_208MHZ;
365 if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
366 rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
367 return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
368}
369
370static u32 pll3_round_rate(struct clk *clk, u32 rate)
371{
372 if (rate > CLK_RATE_208MHZ)
373 rate = CLK_RATE_208MHZ;
374 return (rate - rate % CLK_RATE_13MHZ);
375}
376
377static u32 pll5_round_rate(struct clk *clk, u32 rate)
378{
379 return (rate ? CLK_RATE_48MHZ : 0);
380}
381
382static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
383{
384 return (rate ? CLK_RATE_13MHZ : 0);
385}
386
387static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
388{
389 if (rate) {
390 clk_reg_disable(clk); /*enable bit is inverted */
391 udelay(500);
392 clk->rate = CLK_RATE_13MHZ;
393 ck_1MHz.rate = CLK_RATE_1MHZ;
394 } else {
395 clk_reg_enable(clk);
396 clk->rate = 0;
397 ck_1MHz.rate = 0;
398 }
399 return 0;
400}
401
402static int pll1_set_rate(struct clk *clk, u32 rate)
403{
404#if 0 /* doesn't work on some boards, probably a HW BUG */
405 if (rate) {
406 clk_reg_disable(clk); /*enable bit is inverted */
407 if (!clk_wait_for_pll_lock(clk)) {
408 clk->rate = CLK_RATE_13MHZ;
409 } else {
410 clk_reg_enable(clk);
411 clk->rate = 0;
412 }
413
414 } else {
415 clk_reg_enable(clk);
416 clk->rate = 0;
417 }
418#endif
419 return 0;
420}
421
422/* Clock sources */
423
424static struct clk osc_13MHz = {
425 .name = "osc_13MHz",
426 .flags = FIXED_RATE,
427 .rate = CLK_RATE_13MHZ,
428};
429
430static struct clk ck_13MHz = {
431 .name = "ck_13MHz",
432 .parent = &osc_13MHz,
433 .flags = NEEDS_INITIALIZATION,
434 .round_rate = &ck_13MHz_round_rate,
435 .set_rate = &ck_13MHz_set_rate,
436 .enable_reg = OSC13CTRL_REG,
437 .enable_shift = 0,
438 .rate = CLK_RATE_13MHZ,
439};
440
441static struct clk osc_32KHz = {
442 .name = "osc_32KHz",
443 .flags = FIXED_RATE,
444 .rate = CLK_RATE_32KHZ,
445};
446
447/*attached to PLL5*/
448static struct clk ck_1MHz = {
449 .name = "ck_1MHz",
450 .flags = FIXED_RATE | PARENT_SET_RATE,
451 .parent = &ck_13MHz,
452};
453
454/* PLL1 (397) - provides 13' MHz clock */
455static struct clk ck_pll1 = {
456 .name = "ck_pll1",
457 .parent = &osc_32KHz,
458 .flags = NEEDS_INITIALIZATION,
459 .round_rate = &ck_13MHz_round_rate,
460 .set_rate = &pll1_set_rate,
461 .enable_reg = PLLCTRL_REG,
462 .enable_shift = 1,
463 .scale_reg = PLLCTRL_REG,
464 .rate = CLK_RATE_13MHZ,
465};
466
467/* CPU/Bus PLL */
468static struct clk ck_pll4 = {
469 .name = "ck_pll4",
470 .parent = &ck_pll1,
471 .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
472 .propagate_next = &per_ck,
473 .round_rate = &pll4_round_rate,
474 .set_rate = &pll160_set_rate,
475 .rate = CLK_RATE_208MHZ,
476 .scale_reg = HCLKPLLCTRL_REG,
477 .enable_reg = PWRCTRL_REG,
478 .enable_shift = 2,
479 .parent_switch_reg = SYSCLKCTRL_REG,
480 .set_parent = &set_13MHz_parent,
481};
482
483/* USB PLL */
484static struct clk ck_pll5 = {
485 .name = "ck_pll5",
486 .parent = &ck_1MHz,
487 .flags = NEEDS_INITIALIZATION,
488 .round_rate = &pll5_round_rate,
489 .set_rate = &pll160_set_rate,
490 .scale_reg = USBCTRL_REG,
491 .enable_reg = USBCTRL_REG,
492 .enable_shift = 18,
493 .enable_reg1 = USBCTRL_REG,
494 .enable_shift1 = 17,
495};
496
497/* XPERTTeak DSP PLL */
498static struct clk ck_pll3 = {
499 .name = "ck_pll3",
500 .parent = &ck_pll1,
501 .flags = NEEDS_INITIALIZATION,
502 .round_rate = &pll3_round_rate,
503 .set_rate = &pll160_set_rate,
504 .scale_reg = DSPPLLCTRL_REG,
505 .enable_reg = DSPCLKCTRL_REG,
506 .enable_shift = 3,
507 .enable_reg1 = DSPCLKCTRL_REG,
508 .enable_shift1 = 2,
509 .parent_switch_reg = DSPCLKCTRL_REG,
510 .set_parent = &set_13MHz_parent,
511};
512
513static struct clk hclk_ck = {
514 .name = "hclk_ck",
515 .parent = &ck_pll4,
516 .flags = PARENT_SET_RATE,
517 .set_rate = &hclk_set_rate,
518 .round_rate = &hclk_round_rate,
519 .scale_reg = HCLKDIVCTRL_REG,
520 .rate = 2,
521 .user_rate = 2,
522};
523
524static struct clk per_ck = {
525 .name = "per_ck",
526 .parent = &ck_pll4,
527 .flags = FIXED_RATE,
528 .propagate_next = &hclk_ck,
529 .set_rate = &per_clk_set_rate,
530 .round_rate = &per_clk_round_rate,
531 .scale_reg = HCLKDIVCTRL_REG,
532 .rate = CLK_RATE_13MHZ,
533 .user_rate = CLK_RATE_13MHZ,
534};
535
536static struct clk m2hclk_ck = {
537 .name = "m2hclk_ck",
538 .parent = &hclk_ck,
539 .flags = NEEDS_INITIALIZATION,
540 .round_rate = &on_off_round_rate,
541 .set_rate = &on_off_inv_set_rate,
542 .rate = 1,
543 .enable_shift = 6,
544 .enable_reg = PWRCTRL_REG,
545};
546
547static struct clk vfp9_ck = {
548 .name = "vfp9_ck",
549 .parent = &ck_pll4,
550 .flags = NEEDS_INITIALIZATION,
551 .round_rate = &on_off_round_rate,
552 .set_rate = &on_off_set_rate,
553 .rate = 1,
554 .enable_shift = 4,
555 .enable_reg = VFP9CLKCTRL_REG,
556};
557
558static struct clk keyscan_ck = {
559 .name = "keyscan_ck",
560 .parent = &osc_32KHz,
561 .flags = NEEDS_INITIALIZATION,
562 .round_rate = &on_off_round_rate,
563 .set_rate = &on_off_set_rate,
564 .enable_shift = 0,
565 .enable_reg = KEYCLKCTRL_REG,
566};
567
568static struct clk touch_ck = {
569 .name = "touch_ck",
570 .parent = &osc_32KHz,
571 .flags = NEEDS_INITIALIZATION,
572 .round_rate = &on_off_round_rate,
573 .set_rate = &on_off_set_rate,
574 .enable_shift = 0,
575 .enable_reg = TSCLKCTRL_REG,
576};
577
578static struct clk pwm1_ck = {
579 .name = "pwm1_ck",
580 .parent = &osc_32KHz,
581 .flags = NEEDS_INITIALIZATION,
582 .round_rate = &on_off_round_rate,
583 .set_rate = &on_off_set_rate,
584 .enable_shift = 0,
585 .enable_reg = PWMCLKCTRL_REG,
586};
587
588static struct clk pwm2_ck = {
589 .name = "pwm2_ck",
590 .parent = &osc_32KHz,
591 .flags = NEEDS_INITIALIZATION,
592 .round_rate = &on_off_round_rate,
593 .set_rate = &on_off_set_rate,
594 .enable_shift = 2,
595 .enable_reg = PWMCLKCTRL_REG,
596};
597
598static struct clk jpeg_ck = {
599 .name = "jpeg_ck",
600 .parent = &hclk_ck,
601 .flags = NEEDS_INITIALIZATION,
602 .round_rate = &on_off_round_rate,
603 .set_rate = &on_off_set_rate,
604 .enable_shift = 0,
605 .enable_reg = JPEGCLKCTRL_REG,
606};
607
608static struct clk ms_ck = {
609 .name = "ms_ck",
610 .parent = &ck_pll4,
611 .flags = NEEDS_INITIALIZATION,
612 .round_rate = &on_off_round_rate,
613 .set_rate = &on_off_set_rate,
614 .enable_shift = 5,
615 .enable_reg = MSCTRL_REG,
616};
617
618static struct clk dum_ck = {
619 .name = "dum_ck",
620 .parent = &hclk_ck,
621 .flags = NEEDS_INITIALIZATION,
622 .round_rate = &on_off_round_rate,
623 .set_rate = &on_off_set_rate,
624 .enable_shift = 0,
625 .enable_reg = DUMCLKCTRL_REG,
626};
627
628static struct clk flash_ck = {
629 .name = "flash_ck",
630 .parent = &hclk_ck,
631 .round_rate = &on_off_round_rate,
632 .set_rate = &on_off_set_rate,
633 .enable_shift = 1, /* Only MLC clock supported */
634 .enable_reg = FLASHCLKCTRL_REG,
635};
636
637static struct clk i2c0_ck = {
638 .name = "i2c0_ck",
639 .parent = &per_ck,
640 .flags = NEEDS_INITIALIZATION,
641 .round_rate = &on_off_round_rate,
642 .set_rate = &on_off_set_rate,
643 .enable_shift = 0,
644 .enable_reg = I2CCLKCTRL_REG,
645};
646
647static struct clk i2c1_ck = {
648 .name = "i2c1_ck",
649 .parent = &per_ck,
650 .flags = NEEDS_INITIALIZATION,
651 .round_rate = &on_off_round_rate,
652 .set_rate = &on_off_set_rate,
653 .enable_shift = 1,
654 .enable_reg = I2CCLKCTRL_REG,
655};
656
657static struct clk i2c2_ck = {
658 .name = "i2c2_ck",
659 .parent = &per_ck,
660 .flags = NEEDS_INITIALIZATION,
661 .round_rate = &on_off_round_rate,
662 .set_rate = &on_off_set_rate,
663 .enable_shift = 2,
664 .enable_reg = USB_OTG_CLKCTRL_REG,
665};
666
667static struct clk spi0_ck = {
668 .name = "spi0_ck",
669 .parent = &hclk_ck,
670 .flags = NEEDS_INITIALIZATION,
671 .round_rate = &on_off_round_rate,
672 .set_rate = &on_off_set_rate,
673 .enable_shift = 0,
674 .enable_reg = SPICTRL_REG,
675};
676
677static struct clk spi1_ck = {
678 .name = "spi1_ck",
679 .parent = &hclk_ck,
680 .flags = NEEDS_INITIALIZATION,
681 .round_rate = &on_off_round_rate,
682 .set_rate = &on_off_set_rate,
683 .enable_shift = 4,
684 .enable_reg = SPICTRL_REG,
685};
686
687static struct clk dma_ck = {
688 .name = "dma_ck",
689 .parent = &hclk_ck,
690 .round_rate = &on_off_round_rate,
691 .set_rate = &on_off_set_rate,
692 .enable_shift = 0,
693 .enable_reg = DMACLKCTRL_REG,
694};
695
696static struct clk uart3_ck = {
697 .name = "uart3_ck",
698 .parent = &per_ck,
699 .flags = NEEDS_INITIALIZATION,
700 .round_rate = &on_off_round_rate,
701 .set_rate = &on_off_set_rate,
702 .rate = 1,
703 .enable_shift = 0,
704 .enable_reg = UARTCLKCTRL_REG,
705};
706
707static struct clk uart4_ck = {
708 .name = "uart4_ck",
709 .parent = &per_ck,
710 .flags = NEEDS_INITIALIZATION,
711 .round_rate = &on_off_round_rate,
712 .set_rate = &on_off_set_rate,
713 .enable_shift = 1,
714 .enable_reg = UARTCLKCTRL_REG,
715};
716
717static struct clk uart5_ck = {
718 .name = "uart5_ck",
719 .parent = &per_ck,
720 .flags = NEEDS_INITIALIZATION,
721 .round_rate = &on_off_round_rate,
722 .set_rate = &on_off_set_rate,
723 .rate = 1,
724 .enable_shift = 2,
725 .enable_reg = UARTCLKCTRL_REG,
726};
727
728static struct clk uart6_ck = {
729 .name = "uart6_ck",
730 .parent = &per_ck,
731 .flags = NEEDS_INITIALIZATION,
732 .round_rate = &on_off_round_rate,
733 .set_rate = &on_off_set_rate,
734 .enable_shift = 3,
735 .enable_reg = UARTCLKCTRL_REG,
736};
737
738/* These clocks are visible outside this module
739 * and can be initialized
740 */
741static struct clk *onchip_clks[] = {
742 &ck_13MHz,
743 &ck_pll1,
744 &ck_pll4,
745 &ck_pll5,
746 &ck_pll3,
747 &vfp9_ck,
748 &m2hclk_ck,
749 &hclk_ck,
750 &dma_ck,
751 &flash_ck,
752 &dum_ck,
753 &keyscan_ck,
754 &pwm1_ck,
755 &pwm2_ck,
756 &jpeg_ck,
757 &ms_ck,
758 &touch_ck,
759 &i2c0_ck,
760 &i2c1_ck,
761 &i2c2_ck,
762 &spi0_ck,
763 &spi1_ck,
764 &uart3_ck,
765 &uart4_ck,
766 &uart5_ck,
767 &uart6_ck,
768};
769
770static int local_set_rate(struct clk *clk, u32 rate)
771{
772 int ret = -EINVAL;
773 if (clk->set_rate) {
774
775 if (clk->user_rate == clk->rate && clk->parent->rate) {
776 /* if clock enabled or rate not set */
777 clk->user_rate = clk->round_rate(clk, rate);
778 ret = clk->set_rate(clk, clk->user_rate);
779 } else
780 clk->user_rate = clk->round_rate(clk, rate);
781 ret = 0;
782 }
783 return ret;
784}
785
786int clk_set_rate(struct clk *clk, unsigned long rate)
787{
788 int ret = -EINVAL;
789
790 if (clk->flags & FIXED_RATE)
791 goto out;
792
793 clock_lock();
794 if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
795
796 clk->user_rate = clk->round_rate(clk, rate);
797 /* parent clock needs to be refreshed
798 for the setting to take effect */
799 } else {
800 ret = local_set_rate(clk, rate);
801 }
802 ret = 0;
803 clock_unlock();
804
805out:
806 return ret;
807}
808
809EXPORT_SYMBOL(clk_set_rate);
810
811struct clk *clk_get(struct device *dev, const char *id)
812{
813 struct clk *clk = ERR_PTR(-ENOENT);
814 struct clk **clkp;
815
816 clock_lock();
817 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
818 clkp++) {
819 if (strcmp(id, (*clkp)->name) == 0
820 && try_module_get((*clkp)->owner)) {
821 clk = (*clkp);
822 break;
823 }
824 }
825 clock_unlock();
826
827 return clk;
828}
829EXPORT_SYMBOL(clk_get);
830
831void clk_put(struct clk *clk)
832{
833 clock_lock();
834 if (clk && !IS_ERR(clk))
835 module_put(clk->owner);
836 clock_unlock();
837}
838EXPORT_SYMBOL(clk_put);
839
840unsigned long clk_get_rate(struct clk *clk)
841{
842 unsigned long ret;
843 clock_lock();
844 ret = clk->rate;
845 clock_unlock();
846 return ret;
847}
848EXPORT_SYMBOL(clk_get_rate);
849
850static int local_clk_enable(struct clk *clk)
851{
852 int ret = 0;
853
854 if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
855 && clk->user_rate)
856 ret = clk->set_rate(clk, clk->user_rate);
857 return ret;
858}
859
860static void local_clk_disable(struct clk *clk)
861{
862 if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
863 clk->set_rate(clk, 0);
864}
865
866int clk_enable(struct clk *clk)
867{
868 int ret = 0;
869
870 clock_lock();
871 ret = local_clk_enable(clk);
872 clock_unlock();
873 return ret;
874}
875
876EXPORT_SYMBOL(clk_enable);
877
878void clk_disable(struct clk *clk)
879{
880 clock_lock();
881 local_clk_disable(clk);
882 clock_unlock();
883}
884
885EXPORT_SYMBOL(clk_disable);
886
887static void local_clk_unuse(struct clk *clk)
888{
889 if (clk->usecount > 0 && !(--clk->usecount)) {
890 local_clk_disable(clk);
891 if (clk->parent)
892 local_clk_unuse(clk->parent);
893 }
894}
895
896static int local_clk_use(struct clk *clk)
897{
898 int ret = 0;
899 if (clk->usecount++ == 0) {
900 if (clk->parent)
901 ret = local_clk_use(clk->parent);
902
903 if (ret != 0) {
904 clk->usecount--;
905 goto out;
906 }
907
908 ret = local_clk_enable(clk);
909
910 if (ret != 0 && clk->parent) {
911 local_clk_unuse(clk->parent);
912 clk->usecount--;
913 }
914 }
915out:
916 return ret;
917}
918
919/* The main purpose of clk_use ans clk_unuse functions
920 * is to control switching 13MHz oscillator and PLL1 (13'MHz),
921 * so that they are disabled whenever none of PLL2-5 is using them.
922 * Although in theory these functions should work with any clock,
923 * please use them only on PLL2 - PLL5 to avoid confusion.
924 */
925int clk_use(struct clk *clk)
926{
927 int ret = 0;
928
929 clock_lock();
930 ret = local_clk_use(clk);
931 clock_unlock();
932 return ret;
933}
934EXPORT_SYMBOL(clk_use);
935
936void clk_unuse(struct clk *clk)
937{
938
939 clock_lock();
940 local_clk_unuse(clk);
941 clock_unlock();
942}
943
944EXPORT_SYMBOL(clk_unuse);
945
946long clk_round_rate(struct clk *clk, unsigned long rate)
947{
948 long ret;
949 clock_lock();
950 if (clk->round_rate)
951 ret = clk->round_rate(clk, rate);
952 else
953 ret = clk->rate;
954 clock_unlock();
955 return ret;
956}
957
958EXPORT_SYMBOL(clk_round_rate);
959
960int clk_set_parent(struct clk *clk, struct clk *parent)
961{
962 int ret = -ENODEV;
963 if (!clk->set_parent)
964 goto out;
965
966 clock_lock();
967 ret = clk->set_parent(clk, parent);
968 if (!ret)
969 clk->parent = parent;
970 clock_unlock();
971
972out:
973 return ret;
974}
975
976EXPORT_SYMBOL(clk_set_parent);
977
978static int __init clk_init(void)
979{
980 struct clk **clkp;
981
982 /* Disable autoclocking, as it doesn't seem to work */
983 __raw_writel(0xff, AUTOCLK_CTRL);
984
985 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
986 clkp++) {
987 if (((*clkp)->flags & NEEDS_INITIALIZATION)
988 && ((*clkp)->set_rate)) {
989 (*clkp)->user_rate = (*clkp)->rate;
990 local_set_rate((*clkp), (*clkp)->user_rate);
991 if ((*clkp)->set_parent)
992 (*clkp)->set_parent((*clkp), (*clkp)->parent);
993 }
994 pr_debug("%s: clock %s, rate %ld\n",
995 __FUNCTION__, (*clkp)->name, (*clkp)->rate);
996 }
997
998 clk_use(&ck_pll4);
999
1000 /* if ck_13MHz is not used, disable it. */
1001 if (ck_13MHz.usecount == 0)
1002 local_clk_disable(&ck_13MHz);
1003
1004 /* Disable autoclocking */
1005 __raw_writeb(0xff, AUTOCLK_CTRL);
1006
1007 return 0;
1008}
1009
1010arch_initcall(clk_init);
diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h
new file mode 100644
index 000000000000..cd58f372cfd0
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.h
@@ -0,0 +1,43 @@
1/*
2 * arch/arm/mach-pnx4008/clock.h
3 *
4 * Clock control driver for PNX4008 - internal header file
5 *
6 * Author: Vitaly Wool <source@mvista.com>
7 *
8 * 2006 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#ifndef __ARCH_ARM_PNX4008_CLOCK_H__
14#define __ARCH_ARM_PNX4008_CLOCK_H__
15
16struct clk {
17 struct list_head node;
18 struct module *owner;
19 const char *name;
20 struct clk *parent;
21 struct clk *propagate_next;
22 u32 rate;
23 u32 user_rate;
24 s8 usecount;
25 u32 flags;
26 u32 scale_reg;
27 u8 enable_shift;
28 u32 enable_reg;
29 u8 enable_shift1;
30 u32 enable_reg1;
31 u32 parent_switch_reg;
32 u32(*round_rate) (struct clk *, u32);
33 int (*set_rate) (struct clk *, u32);
34 int (*set_parent) (struct clk * clk, struct clk * parent);
35};
36
37/* Flags */
38#define RATE_PROPAGATES (1<<0)
39#define NEEDS_INITIALIZATION (1<<1)
40#define PARENT_SET_RATE (1<<2)
41#define FIXED_RATE (1<<3)
42
43#endif
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
new file mode 100644
index 000000000000..ba91daad64fb
--- /dev/null
+++ b/arch/arm/mach-pnx4008/core.c
@@ -0,0 +1,207 @@
1/*
2 * arch/arm/mach-pnx4008/core.c
3 *
4 * PNX4008 core startup code
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev,
7 * Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com>
8 *
9 * Based on reference code received from Philips:
10 * Copyright (C) 2003 Philips Semiconductors
11 *
12 * 2005 (c) MontaVista Software, Inc. This file is licensed under
13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express
15 * or implied.
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/mm.h>
21#include <linux/interrupt.h>
22#include <linux/list.h>
23#include <linux/init.h>
24#include <linux/ioport.h>
25#include <linux/serial_8250.h>
26#include <linux/device.h>
27#include <linux/spi/spi.h>
28
29#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/io.h>
32#include <asm/setup.h>
33#include <asm/mach-types.h>
34#include <asm/pgtable.h>
35#include <asm/page.h>
36#include <asm/system.h>
37
38#include <asm/mach/arch.h>
39#include <asm/mach/irq.h>
40#include <asm/mach/map.h>
41#include <asm/mach/time.h>
42
43#include <asm/arch/irq.h>
44#include <asm/arch/clock.h>
45#include <asm/arch/dma.h>
46
47struct resource spipnx_0_resources[] = {
48 {
49 .start = PNX4008_SPI1_BASE,
50 .end = PNX4008_SPI1_BASE + SZ_4K,
51 .flags = IORESOURCE_MEM,
52 }, {
53 .start = PER_SPI1_REC_XMIT,
54 .flags = IORESOURCE_DMA,
55 }, {
56 .start = SPI1_INT,
57 .flags = IORESOURCE_IRQ,
58 }, {
59 .flags = 0,
60 },
61};
62
63struct resource spipnx_1_resources[] = {
64 {
65 .start = PNX4008_SPI2_BASE,
66 .end = PNX4008_SPI2_BASE + SZ_4K,
67 .flags = IORESOURCE_MEM,
68 }, {
69 .start = PER_SPI2_REC_XMIT,
70 .flags = IORESOURCE_DMA,
71 }, {
72 .start = SPI2_INT,
73 .flags = IORESOURCE_IRQ,
74 }, {
75 .flags = 0,
76 }
77};
78
79static struct spi_board_info spi_board_info[] __initdata = {
80 {
81 .modalias = "m25p80",
82 .max_speed_hz = 1000000,
83 .bus_num = 1,
84 .chip_select = 0,
85 },
86};
87
88static struct platform_device spipnx_1 = {
89 .name = "spipnx",
90 .id = 1,
91 .num_resources = ARRAY_SIZE(spipnx_0_resources),
92 .resource = spipnx_0_resources,
93 .dev = {
94 .coherent_dma_mask = 0xFFFFFFFF,
95 },
96};
97
98static struct platform_device spipnx_2 = {
99 .name = "spipnx",
100 .id = 2,
101 .num_resources = ARRAY_SIZE(spipnx_1_resources),
102 .resource = spipnx_1_resources,
103 .dev = {
104 .coherent_dma_mask = 0xFFFFFFFF,
105 },
106};
107
108static struct plat_serial8250_port platform_serial_ports[] = {
109 {
110 .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)),
111 .mapbase = (unsigned long)PNX4008_UART5_BASE,
112 .irq = IIR5_INT,
113 .uartclk = PNX4008_UART_CLK,
114 .regshift = 2,
115 .iotype = UPIO_MEM,
116 .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
117 },
118 {
119 .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)),
120 .mapbase = (unsigned long)PNX4008_UART3_BASE,
121 .irq = IIR3_INT,
122 .uartclk = PNX4008_UART_CLK,
123 .regshift = 2,
124 .iotype = UPIO_MEM,
125 .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
126 },
127 {}
128};
129
130static struct platform_device serial_device = {
131 .name = "serial8250",
132 .id = PLAT8250_DEV_PLATFORM,
133 .dev = {
134 .platform_data = &platform_serial_ports,
135 },
136};
137
138static struct platform_device *devices[] __initdata = {
139 &spipnx_1,
140 &spipnx_2,
141 &serial_device,
142};
143
144
145extern void pnx4008_uart_init(void);
146
147static void __init pnx4008_init(void)
148{
149 /*disable all START interrupt sources,
150 and clear all START interrupt flags */
151 __raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT));
152 __raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT));
153 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
154 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
155
156 platform_add_devices(devices, ARRAY_SIZE(devices));
157 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
158 /* Switch on the UART clocks */
159 pnx4008_uart_init();
160}
161
162static struct map_desc pnx4008_io_desc[] __initdata = {
163 {
164 .virtual = IO_ADDRESS(PNX4008_IRAM_BASE),
165 .pfn = __phys_to_pfn(PNX4008_IRAM_BASE),
166 .length = SZ_64K,
167 .type = MT_DEVICE,
168 }, {
169 .virtual = IO_ADDRESS(PNX4008_NDF_FLASH_BASE),
170 .pfn = __phys_to_pfn(PNX4008_NDF_FLASH_BASE),
171 .length = SZ_1M - SZ_128K,
172 .type = MT_DEVICE,
173 }, {
174 .virtual = IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE),
175 .pfn = __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE),
176 .length = SZ_128K * 3,
177 .type = MT_DEVICE,
178 }, {
179 .virtual = IO_ADDRESS(PNX4008_DMA_CONFIG_BASE),
180 .pfn = __phys_to_pfn(PNX4008_DMA_CONFIG_BASE),
181 .length = SZ_1M,
182 .type = MT_DEVICE,
183 }, {
184 .virtual = IO_ADDRESS(PNX4008_AHB2FAB_BASE),
185 .pfn = __phys_to_pfn(PNX4008_AHB2FAB_BASE),
186 .length = SZ_1M,
187 .type = MT_DEVICE,
188 },
189};
190
191void __init pnx4008_map_io(void)
192{
193 iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc));
194}
195
196extern struct sys_timer pnx4008_timer;
197
198MACHINE_START(PNX4008, "Philips PNX4008")
199 /* Maintainer: MontaVista Software Inc. */
200 .phys_io = 0x40090000,
201 .io_pg_offst = (0xf4090000 >> 18) & 0xfffc,
202 .boot_params = 0x80000100,
203 .map_io = pnx4008_map_io,
204 .init_irq = pnx4008_init_irq,
205 .init_machine = pnx4008_init,
206 .timer = &pnx4008_timer,
207MACHINE_END
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
new file mode 100644
index 000000000000..981aa9dcdede
--- /dev/null
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -0,0 +1,1109 @@
1/*
2 * linux/arch/arm/mach-pnx4008/dma.c
3 *
4 * PNX4008 DMA registration and IRQ dispatching
5 *
6 * Author: Vitaly Wool
7 * Copyright: MontaVista Software Inc. (c) 2005
8 *
9 * Based on the code from Nicolas Pitre
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/interrupt.h>
20#include <linux/errno.h>
21#include <linux/err.h>
22#include <linux/dma-mapping.h>
23#include <linux/clk.h>
24
25#include <asm/system.h>
26#include <asm/irq.h>
27#include <asm/hardware.h>
28#include <asm/dma.h>
29#include <asm/dma-mapping.h>
30#include <asm/io.h>
31#include <asm/mach/dma.h>
32#include <asm/arch/clock.h>
33
34static struct dma_channel {
35 char *name;
36 void (*irq_handler) (int, int, void *, struct pt_regs *);
37 void *data;
38 struct pnx4008_dma_ll *ll;
39 u32 ll_dma;
40 void *target_addr;
41 int target_id;
42} dma_channels[MAX_DMA_CHANNELS];
43
44static struct ll_pool {
45 void *vaddr;
46 void *cur;
47 dma_addr_t dma_addr;
48 int count;
49} ll_pool;
50
51static spinlock_t ll_lock = SPIN_LOCK_UNLOCKED;
52
53struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t * ll_dma)
54{
55 struct pnx4008_dma_ll *ll = NULL;
56 unsigned long flags;
57
58 spin_lock_irqsave(&ll_lock, flags);
59 if (ll_pool.count > 4) { /* can give one more */
60 ll = *(struct pnx4008_dma_ll **) ll_pool.cur;
61 *ll_dma = ll_pool.dma_addr + ((void *)ll - ll_pool.vaddr);
62 *(void **)ll_pool.cur = **(void ***)ll_pool.cur;
63 memset(ll, 0, sizeof(*ll));
64 ll_pool.count--;
65 }
66 spin_unlock_irqrestore(&ll_lock, flags);
67
68 return ll;
69}
70
71EXPORT_SYMBOL_GPL(pnx4008_alloc_ll_entry);
72
73void pnx4008_free_ll_entry(struct pnx4008_dma_ll * ll, dma_addr_t ll_dma)
74{
75 unsigned long flags;
76
77 if (ll) {
78 if ((unsigned long)((long)ll - (long)ll_pool.vaddr) > 0x4000) {
79 printk(KERN_ERR "Trying to free entry not allocated by DMA\n");
80 BUG();
81 }
82
83 if (ll->flags & DMA_BUFFER_ALLOCATED)
84 ll->free(ll->alloc_data);
85
86 spin_lock_irqsave(&ll_lock, flags);
87 *(long *)ll = *(long *)ll_pool.cur;
88 *(long *)ll_pool.cur = (long)ll;
89 ll_pool.count++;
90 spin_unlock_irqrestore(&ll_lock, flags);
91 }
92}
93
94EXPORT_SYMBOL_GPL(pnx4008_free_ll_entry);
95
96void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll * ll)
97{
98 struct pnx4008_dma_ll *ptr;
99 u32 dma;
100
101 while (ll) {
102 dma = ll->next_dma;
103 ptr = ll->next;
104 pnx4008_free_ll_entry(ll, ll_dma);
105
106 ll_dma = dma;
107 ll = ptr;
108 }
109}
110
111EXPORT_SYMBOL_GPL(pnx4008_free_ll);
112
113static int dma_channels_requested = 0;
114
115static inline void dma_increment_usage(void)
116{
117 if (!dma_channels_requested++) {
118 struct clk *clk = clk_get(0, "dma_ck");
119 if (!IS_ERR(clk)) {
120 clk_set_rate(clk, 1);
121 clk_put(clk);
122 }
123 pnx4008_config_dma(-1, -1, 1);
124 }
125}
126static inline void dma_decrement_usage(void)
127{
128 if (!--dma_channels_requested) {
129 struct clk *clk = clk_get(0, "dma_ck");
130 if (!IS_ERR(clk)) {
131 clk_set_rate(clk, 0);
132 clk_put(clk);
133 }
134 pnx4008_config_dma(-1, -1, 0);
135
136 }
137}
138
139static spinlock_t dma_lock = SPIN_LOCK_UNLOCKED;
140
141static inline void pnx4008_dma_lock(void)
142{
143 spin_lock_irq(&dma_lock);
144}
145
146static inline void pnx4008_dma_unlock(void)
147{
148 spin_unlock_irq(&dma_lock);
149}
150
151#define VALID_CHANNEL(c) (((c) >= 0) && ((c) < MAX_DMA_CHANNELS))
152
153int pnx4008_request_channel(char *name, int ch,
154 void (*irq_handler) (int, int, void *,
155 struct pt_regs *), void *data)
156{
157 int i, found = 0;
158
159 /* basic sanity checks */
160 if (!name || (ch != -1 && !VALID_CHANNEL(ch)))
161 return -EINVAL;
162
163 pnx4008_dma_lock();
164
165 /* try grabbing a DMA channel with the requested priority */
166 for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
167 if (!dma_channels[i].name && (ch == -1 || ch == i)) {
168 found = 1;
169 break;
170 }
171 }
172
173 if (found) {
174 dma_increment_usage();
175 dma_channels[i].name = name;
176 dma_channels[i].irq_handler = irq_handler;
177 dma_channels[i].data = data;
178 dma_channels[i].ll = NULL;
179 dma_channels[i].ll_dma = 0;
180 } else {
181 printk(KERN_WARNING "No more available DMA channels for %s\n",
182 name);
183 i = -ENODEV;
184 }
185
186 pnx4008_dma_unlock();
187 return i;
188}
189
190EXPORT_SYMBOL_GPL(pnx4008_request_channel);
191
192void pnx4008_free_channel(int ch)
193{
194 if (!dma_channels[ch].name) {
195 printk(KERN_CRIT
196 "%s: trying to free channel %d which is already freed\n",
197 __FUNCTION__, ch);
198 return;
199 }
200
201 pnx4008_dma_lock();
202 pnx4008_free_ll(dma_channels[ch].ll_dma, dma_channels[ch].ll);
203 dma_channels[ch].ll = NULL;
204 dma_decrement_usage();
205
206 dma_channels[ch].name = NULL;
207 pnx4008_dma_unlock();
208}
209
210EXPORT_SYMBOL_GPL(pnx4008_free_channel);
211
212int pnx4008_config_dma(int ahb_m1_be, int ahb_m2_be, int enable)
213{
214 unsigned long dma_cfg = __raw_readl(DMAC_CONFIG);
215
216 switch (ahb_m1_be) {
217 case 0:
218 dma_cfg &= ~(1 << 1);
219 break;
220 case 1:
221 dma_cfg |= (1 << 1);
222 break;
223 default:
224 break;
225 }
226
227 switch (ahb_m2_be) {
228 case 0:
229 dma_cfg &= ~(1 << 2);
230 break;
231 case 1:
232 dma_cfg |= (1 << 2);
233 break;
234 default:
235 break;
236 }
237
238 switch (enable) {
239 case 0:
240 dma_cfg &= ~(1 << 0);
241 break;
242 case 1:
243 dma_cfg |= (1 << 0);
244 break;
245 default:
246 break;
247 }
248
249 pnx4008_dma_lock();
250 __raw_writel(dma_cfg, DMAC_CONFIG);
251 pnx4008_dma_unlock();
252
253 return 0;
254}
255
256EXPORT_SYMBOL_GPL(pnx4008_config_dma);
257
258int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl * ch_ctrl,
259 unsigned long *ctrl)
260{
261 int i = 0, dbsize, sbsize, err = 0;
262
263 if (!ctrl || !ch_ctrl) {
264 err = -EINVAL;
265 goto out;
266 }
267
268 *ctrl = 0;
269
270 switch (ch_ctrl->tc_mask) {
271 case 0:
272 break;
273 case 1:
274 *ctrl |= (1 << 31);
275 break;
276
277 default:
278 err = -EINVAL;
279 goto out;
280 }
281
282 switch (ch_ctrl->cacheable) {
283 case 0:
284 break;
285 case 1:
286 *ctrl |= (1 << 30);
287 break;
288
289 default:
290 err = -EINVAL;
291 goto out;
292 }
293 switch (ch_ctrl->bufferable) {
294 case 0:
295 break;
296 case 1:
297 *ctrl |= (1 << 29);
298 break;
299
300 default:
301 err = -EINVAL;
302 goto out;
303 }
304 switch (ch_ctrl->priv_mode) {
305 case 0:
306 break;
307 case 1:
308 *ctrl |= (1 << 28);
309 break;
310
311 default:
312 err = -EINVAL;
313 goto out;
314 }
315 switch (ch_ctrl->di) {
316 case 0:
317 break;
318 case 1:
319 *ctrl |= (1 << 27);
320 break;
321
322 default:
323 err = -EINVAL;
324 goto out;
325 }
326 switch (ch_ctrl->si) {
327 case 0:
328 break;
329 case 1:
330 *ctrl |= (1 << 26);
331 break;
332
333 default:
334 err = -EINVAL;
335 goto out;
336 }
337 switch (ch_ctrl->dest_ahb1) {
338 case 0:
339 break;
340 case 1:
341 *ctrl |= (1 << 25);
342 break;
343
344 default:
345 err = -EINVAL;
346 goto out;
347 }
348 switch (ch_ctrl->src_ahb1) {
349 case 0:
350 break;
351 case 1:
352 *ctrl |= (1 << 24);
353 break;
354
355 default:
356 err = -EINVAL;
357 goto out;
358 }
359 switch (ch_ctrl->dwidth) {
360 case WIDTH_BYTE:
361 *ctrl &= ~(7 << 21);
362 break;
363 case WIDTH_HWORD:
364 *ctrl &= ~(7 << 21);
365 *ctrl |= (1 << 21);
366 break;
367 case WIDTH_WORD:
368 *ctrl &= ~(7 << 21);
369 *ctrl |= (2 << 21);
370 break;
371
372 default:
373 err = -EINVAL;
374 goto out;
375 }
376 switch (ch_ctrl->swidth) {
377 case WIDTH_BYTE:
378 *ctrl &= ~(7 << 18);
379 break;
380 case WIDTH_HWORD:
381 *ctrl &= ~(7 << 18);
382 *ctrl |= (1 << 18);
383 break;
384 case WIDTH_WORD:
385 *ctrl &= ~(7 << 18);
386 *ctrl |= (2 << 18);
387 break;
388
389 default:
390 err = -EINVAL;
391 goto out;
392 }
393 dbsize = ch_ctrl->dbsize;
394 while (!(dbsize & 1)) {
395 i++;
396 dbsize >>= 1;
397 }
398 if (ch_ctrl->dbsize != 1 || i > 8 || i == 1) {
399 err = -EINVAL;
400 goto out;
401 } else if (i > 1)
402 i--;
403 *ctrl &= ~(7 << 15);
404 *ctrl |= (i << 15);
405
406 sbsize = ch_ctrl->sbsize;
407 while (!(sbsize & 1)) {
408 i++;
409 sbsize >>= 1;
410 }
411 if (ch_ctrl->sbsize != 1 || i > 8 || i == 1) {
412 err = -EINVAL;
413 goto out;
414 } else if (i > 1)
415 i--;
416 *ctrl &= ~(7 << 12);
417 *ctrl |= (i << 12);
418
419 if (ch_ctrl->tr_size > 0x7ff) {
420 err = -E2BIG;
421 goto out;
422 }
423 *ctrl &= ~0x7ff;
424 *ctrl |= ch_ctrl->tr_size & 0x7ff;
425
426out:
427 return err;
428}
429
430EXPORT_SYMBOL_GPL(pnx4008_dma_pack_control);
431
432int pnx4008_dma_parse_control(unsigned long ctrl,
433 struct pnx4008_dma_ch_ctrl * ch_ctrl)
434{
435 int err = 0;
436
437 if (!ch_ctrl) {
438 err = -EINVAL;
439 goto out;
440 }
441
442 ch_ctrl->tr_size = ctrl & 0x7ff;
443 ctrl >>= 12;
444
445 ch_ctrl->sbsize = 1 << (ctrl & 7);
446 if (ch_ctrl->sbsize > 1)
447 ch_ctrl->sbsize <<= 1;
448 ctrl >>= 3;
449
450 ch_ctrl->dbsize = 1 << (ctrl & 7);
451 if (ch_ctrl->dbsize > 1)
452 ch_ctrl->dbsize <<= 1;
453 ctrl >>= 3;
454
455 switch (ctrl & 7) {
456 case 0:
457 ch_ctrl->swidth = WIDTH_BYTE;
458 break;
459 case 1:
460 ch_ctrl->swidth = WIDTH_HWORD;
461 break;
462 case 2:
463 ch_ctrl->swidth = WIDTH_WORD;
464 break;
465 default:
466 err = -EINVAL;
467 goto out;
468 }
469 ctrl >>= 3;
470
471 switch (ctrl & 7) {
472 case 0:
473 ch_ctrl->dwidth = WIDTH_BYTE;
474 break;
475 case 1:
476 ch_ctrl->dwidth = WIDTH_HWORD;
477 break;
478 case 2:
479 ch_ctrl->dwidth = WIDTH_WORD;
480 break;
481 default:
482 err = -EINVAL;
483 goto out;
484 }
485 ctrl >>= 3;
486
487 ch_ctrl->src_ahb1 = ctrl & 1;
488 ctrl >>= 1;
489
490 ch_ctrl->dest_ahb1 = ctrl & 1;
491 ctrl >>= 1;
492
493 ch_ctrl->si = ctrl & 1;
494 ctrl >>= 1;
495
496 ch_ctrl->di = ctrl & 1;
497 ctrl >>= 1;
498
499 ch_ctrl->priv_mode = ctrl & 1;
500 ctrl >>= 1;
501
502 ch_ctrl->bufferable = ctrl & 1;
503 ctrl >>= 1;
504
505 ch_ctrl->cacheable = ctrl & 1;
506 ctrl >>= 1;
507
508 ch_ctrl->tc_mask = ctrl & 1;
509
510out:
511 return err;
512}
513
514EXPORT_SYMBOL_GPL(pnx4008_dma_parse_control);
515
516int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config * ch_cfg,
517 unsigned long *cfg)
518{
519 int err = 0;
520
521 if (!cfg || !ch_cfg) {
522 err = -EINVAL;
523 goto out;
524 }
525
526 *cfg = 0;
527
528 switch (ch_cfg->halt) {
529 case 0:
530 break;
531 case 1:
532 *cfg |= (1 << 18);
533 break;
534
535 default:
536 err = -EINVAL;
537 goto out;
538 }
539 switch (ch_cfg->active) {
540 case 0:
541 break;
542 case 1:
543 *cfg |= (1 << 17);
544 break;
545
546 default:
547 err = -EINVAL;
548 goto out;
549 }
550 switch (ch_cfg->lock) {
551 case 0:
552 break;
553 case 1:
554 *cfg |= (1 << 16);
555 break;
556
557 default:
558 err = -EINVAL;
559 goto out;
560 }
561 switch (ch_cfg->itc) {
562 case 0:
563 break;
564 case 1:
565 *cfg |= (1 << 15);
566 break;
567
568 default:
569 err = -EINVAL;
570 goto out;
571 }
572 switch (ch_cfg->ie) {
573 case 0:
574 break;
575 case 1:
576 *cfg |= (1 << 14);
577 break;
578
579 default:
580 err = -EINVAL;
581 goto out;
582 }
583 switch (ch_cfg->flow_cntrl) {
584 case FC_MEM2MEM_DMA:
585 *cfg &= ~(7 << 11);
586 break;
587 case FC_MEM2PER_DMA:
588 *cfg &= ~(7 << 11);
589 *cfg |= (1 << 11);
590 break;
591 case FC_PER2MEM_DMA:
592 *cfg &= ~(7 << 11);
593 *cfg |= (2 << 11);
594 break;
595 case FC_PER2PER_DMA:
596 *cfg &= ~(7 << 11);
597 *cfg |= (3 << 11);
598 break;
599 case FC_PER2PER_DPER:
600 *cfg &= ~(7 << 11);
601 *cfg |= (4 << 11);
602 break;
603 case FC_MEM2PER_PER:
604 *cfg &= ~(7 << 11);
605 *cfg |= (5 << 11);
606 break;
607 case FC_PER2MEM_PER:
608 *cfg &= ~(7 << 11);
609 *cfg |= (6 << 11);
610 break;
611 case FC_PER2PER_SPER:
612 *cfg |= (7 << 11);
613 break;
614
615 default:
616 err = -EINVAL;
617 goto out;
618 }
619 *cfg &= ~(0x1f << 6);
620 *cfg |= ((ch_cfg->dest_per & 0x1f) << 6);
621
622 *cfg &= ~(0x1f << 1);
623 *cfg |= ((ch_cfg->src_per & 0x1f) << 1);
624
625out:
626 return err;
627}
628
629EXPORT_SYMBOL_GPL(pnx4008_dma_pack_config);
630
631int pnx4008_dma_parse_config(unsigned long cfg,
632 struct pnx4008_dma_ch_config * ch_cfg)
633{
634 int err = 0;
635
636 if (!ch_cfg) {
637 err = -EINVAL;
638 goto out;
639 }
640
641 cfg >>= 1;
642
643 ch_cfg->src_per = cfg & 0x1f;
644 cfg >>= 5;
645
646 ch_cfg->dest_per = cfg & 0x1f;
647 cfg >>= 5;
648
649 switch (cfg & 7) {
650 case 0:
651 ch_cfg->flow_cntrl = FC_MEM2MEM_DMA;
652 break;
653 case 1:
654 ch_cfg->flow_cntrl = FC_MEM2PER_DMA;
655 break;
656 case 2:
657 ch_cfg->flow_cntrl = FC_PER2MEM_DMA;
658 break;
659 case 3:
660 ch_cfg->flow_cntrl = FC_PER2PER_DMA;
661 break;
662 case 4:
663 ch_cfg->flow_cntrl = FC_PER2PER_DPER;
664 break;
665 case 5:
666 ch_cfg->flow_cntrl = FC_MEM2PER_PER;
667 break;
668 case 6:
669 ch_cfg->flow_cntrl = FC_PER2MEM_PER;
670 break;
671 case 7:
672 ch_cfg->flow_cntrl = FC_PER2PER_SPER;
673 }
674 cfg >>= 3;
675
676 ch_cfg->ie = cfg & 1;
677 cfg >>= 1;
678
679 ch_cfg->itc = cfg & 1;
680 cfg >>= 1;
681
682 ch_cfg->lock = cfg & 1;
683 cfg >>= 1;
684
685 ch_cfg->active = cfg & 1;
686 cfg >>= 1;
687
688 ch_cfg->halt = cfg & 1;
689
690out:
691 return err;
692}
693
694EXPORT_SYMBOL_GPL(pnx4008_dma_parse_config);
695
696void pnx4008_dma_split_head_entry(struct pnx4008_dma_config * config,
697 struct pnx4008_dma_ch_ctrl * ctrl)
698{
699 int new_len = ctrl->tr_size, num_entries = 0;
700 int old_len = new_len;
701 int src_width, dest_width, count = 1;
702
703 switch (ctrl->swidth) {
704 case WIDTH_BYTE:
705 src_width = 1;
706 break;
707 case WIDTH_HWORD:
708 src_width = 2;
709 break;
710 case WIDTH_WORD:
711 src_width = 4;
712 break;
713 default:
714 return;
715 }
716
717 switch (ctrl->dwidth) {
718 case WIDTH_BYTE:
719 dest_width = 1;
720 break;
721 case WIDTH_HWORD:
722 dest_width = 2;
723 break;
724 case WIDTH_WORD:
725 dest_width = 4;
726 break;
727 default:
728 return;
729 }
730
731 while (new_len > 0x7FF) {
732 num_entries++;
733 new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
734 }
735 if (num_entries != 0) {
736 struct pnx4008_dma_ll *ll = NULL;
737 config->ch_ctrl &= ~0x7ff;
738 config->ch_ctrl |= new_len;
739 if (!config->is_ll) {
740 config->is_ll = 1;
741 while (num_entries) {
742 if (!ll) {
743 config->ll =
744 pnx4008_alloc_ll_entry(&config->
745 ll_dma);
746 ll = config->ll;
747 } else {
748 ll->next =
749 pnx4008_alloc_ll_entry(&ll->
750 next_dma);
751 ll = ll->next;
752 }
753
754 if (ctrl->si)
755 ll->src_addr =
756 config->src_addr +
757 src_width * new_len * count;
758 else
759 ll->src_addr = config->src_addr;
760 if (ctrl->di)
761 ll->dest_addr =
762 config->dest_addr +
763 dest_width * new_len * count;
764 else
765 ll->dest_addr = config->dest_addr;
766 ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
767 ll->next_dma = 0;
768 ll->next = NULL;
769 num_entries--;
770 count++;
771 }
772 } else {
773 struct pnx4008_dma_ll *ll_old = config->ll;
774 unsigned long ll_dma_old = config->ll_dma;
775 while (num_entries) {
776 if (!ll) {
777 config->ll =
778 pnx4008_alloc_ll_entry(&config->
779 ll_dma);
780 ll = config->ll;
781 } else {
782 ll->next =
783 pnx4008_alloc_ll_entry(&ll->
784 next_dma);
785 ll = ll->next;
786 }
787
788 if (ctrl->si)
789 ll->src_addr =
790 config->src_addr +
791 src_width * new_len * count;
792 else
793 ll->src_addr = config->src_addr;
794 if (ctrl->di)
795 ll->dest_addr =
796 config->dest_addr +
797 dest_width * new_len * count;
798 else
799 ll->dest_addr = config->dest_addr;
800 ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
801 ll->next_dma = 0;
802 ll->next = NULL;
803 num_entries--;
804 count++;
805 }
806 ll->next_dma = ll_dma_old;
807 ll->next = ll_old;
808 }
809 /* adjust last length/tc */
810 ll->ch_ctrl = config->ch_ctrl & (~0x7ff);
811 ll->ch_ctrl |= old_len - new_len * (count - 1);
812 config->ch_ctrl &= 0x7fffffff;
813 }
814}
815
816EXPORT_SYMBOL_GPL(pnx4008_dma_split_head_entry);
817
818void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll * cur_ll,
819 struct pnx4008_dma_ch_ctrl * ctrl)
820{
821 int new_len = ctrl->tr_size, num_entries = 0;
822 int old_len = new_len;
823 int src_width, dest_width, count = 1;
824
825 switch (ctrl->swidth) {
826 case WIDTH_BYTE:
827 src_width = 1;
828 break;
829 case WIDTH_HWORD:
830 src_width = 2;
831 break;
832 case WIDTH_WORD:
833 src_width = 4;
834 break;
835 default:
836 return;
837 }
838
839 switch (ctrl->dwidth) {
840 case WIDTH_BYTE:
841 dest_width = 1;
842 break;
843 case WIDTH_HWORD:
844 dest_width = 2;
845 break;
846 case WIDTH_WORD:
847 dest_width = 4;
848 break;
849 default:
850 return;
851 }
852
853 while (new_len > 0x7FF) {
854 num_entries++;
855 new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
856 }
857 if (num_entries != 0) {
858 struct pnx4008_dma_ll *ll = NULL;
859 cur_ll->ch_ctrl &= ~0x7ff;
860 cur_ll->ch_ctrl |= new_len;
861 if (!cur_ll->next) {
862 while (num_entries) {
863 if (!ll) {
864 cur_ll->next =
865 pnx4008_alloc_ll_entry(&cur_ll->
866 next_dma);
867 ll = cur_ll->next;
868 } else {
869 ll->next =
870 pnx4008_alloc_ll_entry(&ll->
871 next_dma);
872 ll = ll->next;
873 }
874
875 if (ctrl->si)
876 ll->src_addr =
877 cur_ll->src_addr +
878 src_width * new_len * count;
879 else
880 ll->src_addr = cur_ll->src_addr;
881 if (ctrl->di)
882 ll->dest_addr =
883 cur_ll->dest_addr +
884 dest_width * new_len * count;
885 else
886 ll->dest_addr = cur_ll->dest_addr;
887 ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
888 ll->next_dma = 0;
889 ll->next = NULL;
890 num_entries--;
891 count++;
892 }
893 } else {
894 struct pnx4008_dma_ll *ll_old = cur_ll->next;
895 unsigned long ll_dma_old = cur_ll->next_dma;
896 while (num_entries) {
897 if (!ll) {
898 cur_ll->next =
899 pnx4008_alloc_ll_entry(&cur_ll->
900 next_dma);
901 ll = cur_ll->next;
902 } else {
903 ll->next =
904 pnx4008_alloc_ll_entry(&ll->
905 next_dma);
906 ll = ll->next;
907 }
908
909 if (ctrl->si)
910 ll->src_addr =
911 cur_ll->src_addr +
912 src_width * new_len * count;
913 else
914 ll->src_addr = cur_ll->src_addr;
915 if (ctrl->di)
916 ll->dest_addr =
917 cur_ll->dest_addr +
918 dest_width * new_len * count;
919 else
920 ll->dest_addr = cur_ll->dest_addr;
921 ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
922 ll->next_dma = 0;
923 ll->next = NULL;
924 num_entries--;
925 count++;
926 }
927
928 ll->next_dma = ll_dma_old;
929 ll->next = ll_old;
930 }
931 /* adjust last length/tc */
932 ll->ch_ctrl = cur_ll->ch_ctrl & (~0x7ff);
933 ll->ch_ctrl |= old_len - new_len * (count - 1);
934 cur_ll->ch_ctrl &= 0x7fffffff;
935 }
936}
937
938EXPORT_SYMBOL_GPL(pnx4008_dma_split_ll_entry);
939
940int pnx4008_config_channel(int ch, struct pnx4008_dma_config * config)
941{
942 if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
943 return -EINVAL;
944
945 pnx4008_dma_lock();
946 __raw_writel(config->src_addr, DMAC_Cx_SRC_ADDR(ch));
947 __raw_writel(config->dest_addr, DMAC_Cx_DEST_ADDR(ch));
948
949 if (config->is_ll)
950 __raw_writel(config->ll_dma, DMAC_Cx_LLI(ch));
951 else
952 __raw_writel(0, DMAC_Cx_LLI(ch));
953
954 __raw_writel(config->ch_ctrl, DMAC_Cx_CONTROL(ch));
955 __raw_writel(config->ch_cfg, DMAC_Cx_CONFIG(ch));
956 pnx4008_dma_unlock();
957
958 return 0;
959
960}
961
962EXPORT_SYMBOL_GPL(pnx4008_config_channel);
963
964int pnx4008_channel_get_config(int ch, struct pnx4008_dma_config * config)
965{
966 if (!VALID_CHANNEL(ch) || !dma_channels[ch].name || !config)
967 return -EINVAL;
968
969 pnx4008_dma_lock();
970 config->ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
971 config->ch_ctrl = __raw_readl(DMAC_Cx_CONTROL(ch));
972
973 config->ll_dma = __raw_readl(DMAC_Cx_LLI(ch));
974 config->is_ll = config->ll_dma ? 1 : 0;
975
976 config->src_addr = __raw_readl(DMAC_Cx_SRC_ADDR(ch));
977 config->dest_addr = __raw_readl(DMAC_Cx_DEST_ADDR(ch));
978 pnx4008_dma_unlock();
979
980 return 0;
981}
982
983EXPORT_SYMBOL_GPL(pnx4008_channel_get_config);
984
985int pnx4008_dma_ch_enable(int ch)
986{
987 unsigned long ch_cfg;
988
989 if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
990 return -EINVAL;
991
992 pnx4008_dma_lock();
993 ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
994 ch_cfg |= 1;
995 __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
996 pnx4008_dma_unlock();
997
998 return 0;
999}
1000
1001EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enable);
1002
1003int pnx4008_dma_ch_disable(int ch)
1004{
1005 unsigned long ch_cfg;
1006
1007 if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
1008 return -EINVAL;
1009
1010 pnx4008_dma_lock();
1011 ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
1012 ch_cfg &= ~1;
1013 __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
1014 pnx4008_dma_unlock();
1015
1016 return 0;
1017}
1018
1019EXPORT_SYMBOL_GPL(pnx4008_dma_ch_disable);
1020
1021int pnx4008_dma_ch_enabled(int ch)
1022{
1023 unsigned long ch_cfg;
1024
1025 if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
1026 return -EINVAL;
1027
1028 pnx4008_dma_lock();
1029 ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
1030 pnx4008_dma_unlock();
1031
1032 return ch_cfg & 1;
1033}
1034
1035EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled);
1036
1037static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
1038{
1039 int i;
1040 unsigned long dint = __raw_readl(DMAC_INT_STAT);
1041 unsigned long tcint = __raw_readl(DMAC_INT_TC_STAT);
1042 unsigned long eint = __raw_readl(DMAC_INT_ERR_STAT);
1043 unsigned long i_bit;
1044
1045 for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
1046 i_bit = 1 << i;
1047 if (dint & i_bit) {
1048 struct dma_channel *channel = &dma_channels[i];
1049
1050 if (channel->name && channel->irq_handler) {
1051 int cause = 0;
1052
1053 if (eint & i_bit)
1054 cause |= DMA_ERR_INT;
1055 if (tcint & i_bit)
1056 cause |= DMA_TC_INT;
1057 channel->irq_handler(i, cause, channel->data,
1058 regs);
1059 } else {
1060 /*
1061 * IRQ for an unregistered DMA channel
1062 */
1063 printk(KERN_WARNING
1064 "spurious IRQ for DMA channel %d\n", i);
1065 }
1066 if (tcint & i_bit)
1067 __raw_writel(i_bit, DMAC_INT_TC_CLEAR);
1068 if (eint & i_bit)
1069 __raw_writel(i_bit, DMAC_INT_ERR_CLEAR);
1070 }
1071 }
1072 return IRQ_HANDLED;
1073}
1074
1075static int __init pnx4008_dma_init(void)
1076{
1077 int ret, i;
1078
1079 ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
1080 if (ret) {
1081 printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
1082 goto out;
1083 }
1084
1085 ll_pool.count = 0x4000 / sizeof(struct pnx4008_dma_ll);
1086 ll_pool.cur = ll_pool.vaddr =
1087 dma_alloc_coherent(NULL, ll_pool.count * sizeof(struct pnx4008_dma_ll),
1088 &ll_pool.dma_addr, GFP_KERNEL);
1089
1090 if (!ll_pool.vaddr) {
1091 ret = -ENOMEM;
1092 free_irq(DMA_INT, NULL);
1093 goto out;
1094 }
1095
1096 for (i = 0; i < ll_pool.count - 1; i++) {
1097 void **addr = ll_pool.vaddr + i * sizeof(struct pnx4008_dma_ll);
1098 *addr = (void *)addr + sizeof(struct pnx4008_dma_ll);
1099 }
1100 *(long *)(ll_pool.vaddr +
1101 (ll_pool.count - 1) * sizeof(struct pnx4008_dma_ll)) =
1102 (long)ll_pool.vaddr;
1103
1104 __raw_writel(1, DMAC_CONFIG);
1105
1106out:
1107 return ret;
1108}
1109arch_initcall(pnx4008_dma_init);
diff --git a/arch/arm/mach-pnx4008/gpio.c b/arch/arm/mach-pnx4008/gpio.c
new file mode 100644
index 000000000000..e1ce050d8fe0
--- /dev/null
+++ b/arch/arm/mach-pnx4008/gpio.c
@@ -0,0 +1,330 @@
1/*
2 * arch/arm/mach-pnx4008/gpio.c
3 *
4 * PNX4008 GPIO driver
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
9 * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
10 *
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17#include <linux/config.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <asm/semaphore.h>
22#include <asm/io.h>
23#include <asm/arch/platform.h>
24#include <asm/arch/gpio.h>
25
26/* register definitions */
27#define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
28
29#define PIO_INP_STATE (0x00U)
30#define PIO_OUTP_SET (0x04U)
31#define PIO_OUTP_CLR (0x08U)
32#define PIO_OUTP_STATE (0x0CU)
33#define PIO_DRV_SET (0x10U)
34#define PIO_DRV_CLR (0x14U)
35#define PIO_DRV_STATE (0x18U)
36#define PIO_SDINP_STATE (0x1CU)
37#define PIO_SDOUTP_SET (0x20U)
38#define PIO_SDOUTP_CLR (0x24U)
39#define PIO_MUX_SET (0x28U)
40#define PIO_MUX_CLR (0x2CU)
41#define PIO_MUX_STATE (0x30U)
42
43static inline void gpio_lock(void)
44{
45 local_irq_disable();
46}
47
48static inline void gpio_unlock(void)
49{
50 local_irq_enable();
51}
52
53/* Inline functions */
54static inline int gpio_read_bit(u32 reg, int gpio)
55{
56 u32 bit, val;
57 int ret = -EFAULT;
58
59 if (gpio < 0)
60 goto out;
61
62 bit = GPIO_BIT(gpio);
63 if (bit) {
64 val = __raw_readl(PIO_VA_BASE + reg);
65 ret = (val & bit) ? 1 : 0;
66 }
67out:
68 return ret;
69}
70
71static inline int gpio_set_bit(u32 reg, int gpio)
72{
73 u32 bit, val;
74 int ret = -EFAULT;
75
76 if (gpio < 0)
77 goto out;
78
79 bit = GPIO_BIT(gpio);
80 if (bit) {
81 val = __raw_readl(PIO_VA_BASE + reg);
82 val |= bit;
83 __raw_writel(val, PIO_VA_BASE + reg);
84 ret = 0;
85 }
86out:
87 return ret;
88}
89
90/* Very simple access control, bitmap for allocated/free */
91static unsigned long access_map[4];
92#define INP_INDEX 0
93#define OUTP_INDEX 1
94#define GPIO_INDEX 2
95#define MUX_INDEX 3
96
97/*GPIO to Input Mapping */
98static short gpio_to_inp_map[32] = {
99 -1, -1, -1, -1, -1, -1, -1, -1,
100 -1, -1, -1, -1, -1, -1, -1, -1,
101 -1, -1, -1, -1, -1, -1, -1, -1,
102 -1, 10, 11, 12, 13, 14, 24, -1
103};
104
105/*GPIO to Mux Mapping */
106static short gpio_to_mux_map[32] = {
107 -1, -1, -1, -1, -1, -1, -1, -1,
108 -1, -1, -1, -1, -1, -1, -1, -1,
109 -1, -1, -1, -1, -1, -1, -1, -1,
110 -1, -1, -1, 0, 1, 4, 5, -1
111};
112
113/*Output to Mux Mapping */
114static short outp_to_mux_map[32] = {
115 -1, -1, -1, 6, -1, -1, -1, -1,
116 -1, -1, -1, -1, -1, -1, -1, -1,
117 -1, -1, -1, -1, -1, 2, -1, -1,
118 -1, -1, -1, -1, -1, -1, -1, -1
119};
120
121int pnx4008_gpio_register_pin(unsigned short pin)
122{
123 unsigned long bit = GPIO_BIT(pin);
124 int ret = -EBUSY; /* Already in use */
125
126 gpio_lock();
127
128 if (GPIO_ISBID(pin)) {
129 if (access_map[GPIO_INDEX] & bit)
130 goto out;
131 access_map[GPIO_INDEX] |= bit;
132
133 } else if (GPIO_ISRAM(pin)) {
134 if (access_map[GPIO_INDEX] & bit)
135 goto out;
136 access_map[GPIO_INDEX] |= bit;
137
138 } else if (GPIO_ISMUX(pin)) {
139 if (access_map[MUX_INDEX] & bit)
140 goto out;
141 access_map[MUX_INDEX] |= bit;
142
143 } else if (GPIO_ISOUT(pin)) {
144 if (access_map[OUTP_INDEX] & bit)
145 goto out;
146 access_map[OUTP_INDEX] |= bit;
147
148 } else if (GPIO_ISIN(pin)) {
149 if (access_map[INP_INDEX] & bit)
150 goto out;
151 access_map[INP_INDEX] |= bit;
152 } else
153 goto out;
154 ret = 0;
155
156out:
157 gpio_unlock();
158 return ret;
159}
160
161EXPORT_SYMBOL(pnx4008_gpio_register_pin);
162
163int pnx4008_gpio_unregister_pin(unsigned short pin)
164{
165 unsigned long bit = GPIO_BIT(pin);
166 int ret = -EFAULT; /* Not registered */
167
168 gpio_lock();
169
170 if (GPIO_ISBID(pin)) {
171 if (~access_map[GPIO_INDEX] & bit)
172 goto out;
173 access_map[GPIO_INDEX] &= ~bit;
174 } else if (GPIO_ISRAM(pin)) {
175 if (~access_map[GPIO_INDEX] & bit)
176 goto out;
177 access_map[GPIO_INDEX] &= ~bit;
178 } else if (GPIO_ISMUX(pin)) {
179 if (~access_map[MUX_INDEX] & bit)
180 goto out;
181 access_map[MUX_INDEX] &= ~bit;
182 } else if (GPIO_ISOUT(pin)) {
183 if (~access_map[OUTP_INDEX] & bit)
184 goto out;
185 access_map[OUTP_INDEX] &= ~bit;
186 } else if (GPIO_ISIN(pin)) {
187 if (~access_map[INP_INDEX] & bit)
188 goto out;
189 access_map[INP_INDEX] &= ~bit;
190 } else
191 goto out;
192 ret = 0;
193
194out:
195 gpio_unlock();
196 return ret;
197}
198
199EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
200
201unsigned long pnx4008_gpio_read_pin(unsigned short pin)
202{
203 unsigned long ret = -EFAULT;
204 int gpio = GPIO_BIT_MASK(pin);
205 gpio_lock();
206 if (GPIO_ISOUT(pin)) {
207 ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
208 } else if (GPIO_ISRAM(pin)) {
209 if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
210 ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
211 }
212 } else if (GPIO_ISBID(pin)) {
213 ret = gpio_read_bit(PIO_DRV_STATE, gpio);
214 if (ret > 0)
215 ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
216 else if (ret == 0)
217 ret =
218 gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
219 } else if (GPIO_ISIN(pin)) {
220 ret = gpio_read_bit(PIO_INP_STATE, gpio);
221 }
222 gpio_unlock();
223 return ret;
224}
225
226EXPORT_SYMBOL(pnx4008_gpio_read_pin);
227
228/* Write Value to output */
229int pnx4008_gpio_write_pin(unsigned short pin, int output)
230{
231 int gpio = GPIO_BIT_MASK(pin);
232 int ret = -EFAULT;
233
234 gpio_lock();
235 if (GPIO_ISOUT(pin)) {
236 printk( "writing '%x' to '%x'\n",
237 gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
238 ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
239 } else if (GPIO_ISRAM(pin)) {
240 if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
241 ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
242 PIO_SDOUTP_CLR, gpio);
243 } else if (GPIO_ISBID(pin)) {
244 if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
245 ret = gpio_set_bit(output ? PIO_OUTP_SET :
246 PIO_OUTP_CLR, gpio);
247 }
248 gpio_unlock();
249 return ret;
250}
251
252EXPORT_SYMBOL(pnx4008_gpio_write_pin);
253
254/* Value = 1 : Set GPIO pin as output */
255/* Value = 0 : Set GPIO pin as input */
256int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
257{
258 int gpio = GPIO_BIT_MASK(pin);
259 int ret = -EFAULT;
260
261 gpio_lock();
262 if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
263 ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
264 }
265 gpio_unlock();
266 return ret;
267}
268
269EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
270
271/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
272int pnx4008_gpio_read_pin_direction(unsigned short pin)
273{
274 int gpio = GPIO_BIT_MASK(pin);
275 int ret = -EFAULT;
276
277 gpio_lock();
278 if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
279 ret = gpio_read_bit(PIO_DRV_STATE, gpio);
280 }
281 gpio_unlock();
282 return ret;
283}
284
285EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
286
287/* Value = 1 : Set pin to muxed function */
288/* Value = 0 : Set pin as GPIO */
289int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
290{
291 int gpio = GPIO_BIT_MASK(pin);
292 int ret = -EFAULT;
293
294 gpio_lock();
295 if (GPIO_ISBID(pin)) {
296 ret =
297 gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
298 gpio_to_mux_map[gpio]);
299 } else if (GPIO_ISOUT(pin)) {
300 ret =
301 gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
302 outp_to_mux_map[gpio]);
303 } else if (GPIO_ISMUX(pin)) {
304 ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
305 }
306 gpio_unlock();
307 return ret;
308}
309
310EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
311
312/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
313int pnx4008_gpio_read_pin_mux(unsigned short pin)
314{
315 int gpio = GPIO_BIT_MASK(pin);
316 int ret = -EFAULT;
317
318 gpio_lock();
319 if (GPIO_ISBID(pin)) {
320 ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
321 } else if (GPIO_ISOUT(pin)) {
322 ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
323 } else if (GPIO_ISMUX(pin)) {
324 ret = gpio_read_bit(PIO_MUX_STATE, gpio);
325 }
326 gpio_unlock();
327 return ret;
328}
329
330EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
new file mode 100644
index 000000000000..9b0a8e084e99
--- /dev/null
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -0,0 +1,121 @@
1/*
2 * arch/arm/mach-pnx4008/irq.c
3 *
4 * PNX4008 IRQ controller driver
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * Based on reference code received from Philips:
9 * Copyright (C) 2003 Philips Semiconductors
10 *
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/mm.h>
20#include <linux/interrupt.h>
21#include <linux/list.h>
22#include <linux/init.h>
23#include <linux/ioport.h>
24#include <linux/device.h>
25#include <asm/hardware.h>
26#include <asm/irq.h>
27#include <asm/io.h>
28#include <asm/setup.h>
29#include <asm/mach-types.h>
30#include <asm/pgtable.h>
31#include <asm/page.h>
32#include <asm/system.h>
33#include <asm/mach/arch.h>
34#include <asm/mach/irq.h>
35#include <asm/mach/map.h>
36#include <asm/arch/irq.h>
37
38static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
39
40static void pnx4008_mask_irq(unsigned int irq)
41{
42 __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
43}
44
45static void pnx4008_unmask_irq(unsigned int irq)
46{
47 __raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq)); /* unmask interrupt */
48}
49
50static void pnx4008_mask_ack_irq(unsigned int irq)
51{
52 __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
53 __raw_writel(INTC_BIT(irq), INTC_SR(irq)); /* clear interrupt status */
54}
55
56static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
57{
58 switch (type) {
59 case IRQT_RISING:
60 __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
61 __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */
62 set_irq_handler(irq, do_edge_IRQ);
63 break;
64 case IRQT_FALLING:
65 __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
66 __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */
67 set_irq_handler(irq, do_edge_IRQ);
68 break;
69 case IRQT_LOW:
70 __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
71 __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */
72 set_irq_handler(irq, do_level_IRQ);
73 break;
74 case IRQT_HIGH:
75 __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
76 __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */
77 set_irq_handler(irq, do_level_IRQ);
78 break;
79
80 /* IRQT_BOTHEDGE is not supported */
81 default:
82 printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
83 return -1;
84 }
85 return 0;
86}
87
88static struct irqchip pnx4008_irq_chip = {
89 .ack = pnx4008_mask_ack_irq,
90 .mask = pnx4008_mask_irq,
91 .unmask = pnx4008_unmask_irq,
92 .set_type = pnx4008_set_irq_type,
93};
94
95void __init pnx4008_init_irq(void)
96{
97 unsigned int i;
98
99 /* configure and enable IRQ 0,1,30,31 (cascade interrupts) mask all others */
100 pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
101 pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
102 pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
103 pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
104
105 __raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
106 (1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
107 INTC_ER(MAIN_BASE_INT));
108 __raw_writel(0, INTC_ER(SIC1_BASE_INT));
109 __raw_writel(0, INTC_ER(SIC2_BASE_INT));
110
111 /* configure all other IRQ's */
112 for (i = 0; i < NR_IRQS; i++) {
113 if (i == SUB2_FIQ_N || i == SUB1_FIQ_N ||
114 i == SUB2_IRQ_N || i == SUB1_IRQ_N)
115 continue;
116 set_irq_flags(i, IRQF_VALID);
117 set_irq_chip(i, &pnx4008_irq_chip);
118 pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
119 }
120}
121
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
new file mode 100644
index 000000000000..3649cd3dfc9a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -0,0 +1,184 @@
1/*
2 * arch/arm/mach-pnx4008/pm.c
3 *
4 * Power Management driver for PNX4008
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/pm.h>
15#include <linux/rtc.h>
16#include <linux/sched.h>
17#include <linux/proc_fs.h>
18#include <linux/pm.h>
19#include <linux/delay.h>
20#include <linux/clk.h>
21
22#include <asm/io.h>
23#include <asm/mach-types.h>
24#include <asm/cacheflush.h>
25#include <asm/arch/pm.h>
26#include <asm/arch/clock.h>
27
28#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
29
30static void *saved_sram;
31
32static struct clk *pll4_clk;
33
34static inline void pnx4008_standby(void)
35{
36 void (*pnx4008_cpu_standby_ptr) (void);
37
38 local_irq_disable();
39 local_fiq_disable();
40
41 clk_disable(pll4_clk);
42
43 /*saving portion of SRAM to be used by suspend function. */
44 memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
45
46 /*make sure SRAM copy gets physically written into SDRAM.
47 SDRAM will be placed into self-refresh during power down */
48 flush_cache_all();
49
50 /*copy suspend function into SRAM */
51 memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
52
53 /*do suspend */
54 pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
55 pnx4008_cpu_standby_ptr();
56
57 /*restoring portion of SRAM that was used by suspend function */
58 memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
59
60 clk_enable(pll4_clk);
61
62 local_fiq_enable();
63 local_irq_enable();
64}
65
66static inline void pnx4008_suspend(void)
67{
68 void (*pnx4008_cpu_suspend_ptr) (void);
69
70 local_irq_disable();
71 local_fiq_disable();
72
73 clk_disable(pll4_clk);
74
75 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
76 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
77
78 /*saving portion of SRAM to be used by suspend function. */
79 memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
80
81 /*make sure SRAM copy gets physically written into SDRAM.
82 SDRAM will be placed into self-refresh during power down */
83 flush_cache_all();
84
85 /*copy suspend function into SRAM */
86 memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
87
88 /*do suspend */
89 pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
90 pnx4008_cpu_suspend_ptr();
91
92 /*restoring portion of SRAM that was used by suspend function */
93 memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
94
95 clk_enable(pll4_clk);
96
97 local_fiq_enable();
98 local_irq_enable();
99}
100
101static int pnx4008_pm_enter(suspend_state_t state)
102{
103 switch (state) {
104 case PM_SUSPEND_STANDBY:
105 pnx4008_standby();
106 break;
107 case PM_SUSPEND_MEM:
108 pnx4008_suspend();
109 break;
110 case PM_SUSPEND_DISK:
111 return -ENOTSUPP;
112 default:
113 return -EINVAL;
114 }
115 return 0;
116}
117
118/*
119 * Called after processes are frozen, but before we shut down devices.
120 */
121static int pnx4008_pm_prepare(suspend_state_t state)
122{
123 switch (state) {
124 case PM_SUSPEND_STANDBY:
125 case PM_SUSPEND_MEM:
126 break;
127
128 case PM_SUSPEND_DISK:
129 return -ENOTSUPP;
130 break;
131
132 default:
133 return -EINVAL;
134 break;
135 }
136 return 0;
137}
138
139/*
140 * Called after devices are re-setup, but before processes are thawed.
141 */
142static int pnx4008_pm_finish(suspend_state_t state)
143{
144 return 0;
145}
146
147/*
148 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
149 */
150static struct pm_ops pnx4008_pm_ops = {
151 .prepare = pnx4008_pm_prepare,
152 .enter = pnx4008_pm_enter,
153 .finish = pnx4008_pm_finish,
154};
155
156static int __init pnx4008_pm_init(void)
157{
158 u32 sram_size_to_allocate;
159
160 pll4_clk = clk_get(0, "ck_pll4");
161 if (IS_ERR(pll4_clk)) {
162 printk(KERN_ERR
163 "PM Suspend cannot acquire ARM(PLL4) clock control\n");
164 return PTR_ERR(pll4_clk);
165 }
166
167 if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
168 sram_size_to_allocate = pnx4008_cpu_standby_sz;
169 else
170 sram_size_to_allocate = pnx4008_cpu_suspend_sz;
171
172 saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
173 if (!saved_sram) {
174 printk(KERN_ERR
175 "PM Suspend: cannot allocate memory to save portion of SRAM\n");
176 clk_put(pll4_clk);
177 return -ENOMEM;
178 }
179
180 pm_set_ops(&pnx4008_pm_ops);
181 return 0;
182}
183
184late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-pnx4008/serial.c b/arch/arm/mach-pnx4008/serial.c
new file mode 100644
index 000000000000..2e1e04cc048c
--- /dev/null
+++ b/arch/arm/mach-pnx4008/serial.c
@@ -0,0 +1,69 @@
1/*
2 * linux/arch/arm/mach-pnx4008/serial.c
3 *
4 * PNX4008 UART initialization
5 *
6 * Copyright: MontaVista Software Inc. (c) 2005
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15
16#include <asm/io.h>
17
18#include <asm/arch/platform.h>
19#include <asm/arch/hardware.h>
20
21#include <linux/serial_core.h>
22#include <linux/serial_reg.h>
23#include <asm/arch/pm.h>
24
25#include <asm/arch/clock.h>
26
27#define UART_3 0
28#define UART_4 1
29#define UART_5 2
30#define UART_6 3
31#define UART_UNKNOWN (-1)
32
33#define UART3_BASE_VA IO_ADDRESS(PNX4008_UART3_BASE)
34#define UART4_BASE_VA IO_ADDRESS(PNX4008_UART4_BASE)
35#define UART5_BASE_VA IO_ADDRESS(PNX4008_UART5_BASE)
36#define UART6_BASE_VA IO_ADDRESS(PNX4008_UART6_BASE)
37
38#define UART_FCR_OFFSET 8
39#define UART_FIFO_SIZE 64
40
41void pnx4008_uart_init(void)
42{
43 u32 tmp;
44 int i = UART_FIFO_SIZE;
45
46 __raw_writel(0xC1, UART5_BASE_VA + UART_FCR_OFFSET);
47 __raw_writel(0xC1, UART3_BASE_VA + UART_FCR_OFFSET);
48
49 /* Send a NULL to fix the UART HW bug */
50 __raw_writel(0x00, UART5_BASE_VA);
51 __raw_writel(0x00, UART3_BASE_VA);
52
53 while (i--) {
54 tmp = __raw_readl(UART5_BASE_VA);
55 tmp = __raw_readl(UART3_BASE_VA);
56 }
57 __raw_writel(0, UART5_BASE_VA + UART_FCR_OFFSET);
58 __raw_writel(0, UART3_BASE_VA + UART_FCR_OFFSET);
59
60 /* setup wakeup interrupt */
61 start_int_set_rising_edge(SE_U3_RX_INT);
62 start_int_ack(SE_U3_RX_INT);
63 start_int_umask(SE_U3_RX_INT);
64
65 start_int_set_rising_edge(SE_U5_RX_INT);
66 start_int_ack(SE_U5_RX_INT);
67 start_int_umask(SE_U5_RX_INT);
68}
69
diff --git a/arch/arm/mach-pnx4008/sleep.S b/arch/arm/mach-pnx4008/sleep.S
new file mode 100644
index 000000000000..93c802bac269
--- /dev/null
+++ b/arch/arm/mach-pnx4008/sleep.S
@@ -0,0 +1,196 @@
1/*
2 * linux/arch/arm/mach-pnx4008/sleep.S
3 *
4 * PNX4008 support for STOP mode and SDRAM self-refresh
5 *
6 * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/linkage.h>
16#include <asm/assembler.h>
17#include <asm/hardware.h>
18
19#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
20#define PWR_CTRL_REG_OFFS 0x44
21
22#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
23#define MPMC_STATUS_REG_OFFS 0x4
24
25 .text
26
27ENTRY(pnx4008_cpu_suspend)
28 @this function should be entered in Direct run mode.
29
30 @ save registers on stack
31 stmfd sp!, {r0 - r6, lr}
32
33 @ setup Power Manager base address in r4
34 @ and put it's value in r5
35 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
36 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
37 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
38 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
39 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
40
41 @ setup SDRAM controller base address in r2
42 @ and put it's value in r3
43 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
44 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
45 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
46 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
47 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
48
49 @ clear SDRAM self-refresh bit latch
50 and r5, r5, #(~(1 << 8))
51 @ clear SDRAM self-refresh bit
52 and r5, r5, #(~(1 << 9))
53 str r5, [r4, #PWR_CTRL_REG_OFFS]
54
55 @ do save current bit settings in r1
56 mov r1, r5
57
58 @ set SDRAM self-refresh bit
59 orr r5, r5, #(1 << 9)
60 str r5, [r4, #PWR_CTRL_REG_OFFS]
61
62 @ set SDRAM self-refresh bit latch
63 orr r5, r5, #(1 << 8)
64 str r5, [r4, #PWR_CTRL_REG_OFFS]
65
66 @ clear SDRAM self-refresh bit latch
67 and r5, r5, #(~(1 << 8))
68 str r5, [r4, #PWR_CTRL_REG_OFFS]
69
70 @ clear SDRAM self-refresh bit
71 and r5, r5, #(~(1 << 9))
72 str r5, [r4, #PWR_CTRL_REG_OFFS]
73
74 @ wait for SDRAM to get into self-refresh mode
752: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
76 tst r3, #(1 << 2)
77 beq 2b
78
79 @ to prepare SDRAM to get out of self-refresh mode after wakeup
80 orr r5, r5, #(1 << 7)
81 str r5, [r4, #PWR_CTRL_REG_OFFS]
82
83 @ do enter stop mode
84 orr r5, r5, #(1 << 0)
85 str r5, [r4, #PWR_CTRL_REG_OFFS]
86 nop
87 nop
88 nop
89 nop
90 nop
91 nop
92 nop
93 nop
94 nop
95
96 @ sleeping now...
97
98 @ coming out of STOP mode into Direct Run mode
99 @ clear STOP mode and SDRAM self-refresh bits
100 str r1, [r4, #PWR_CTRL_REG_OFFS]
101
102 @ wait for SDRAM to get out self-refresh mode
1033: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
104 tst r3, #5
105 bne 3b
106
107 @ restore regs and return
108 ldmfd sp!, {r0 - r6, pc}
109
110ENTRY(pnx4008_cpu_suspend_sz)
111 .word . - pnx4008_cpu_suspend
112
113ENTRY(pnx4008_cpu_standby)
114 @ save registers on stack
115 stmfd sp!, {r0 - r6, lr}
116
117 @ setup Power Manager base address in r4
118 @ and put it's value in r5
119 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
120 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
121 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
122 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
123 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
124
125 @ setup SDRAM controller base address in r2
126 @ and put it's value in r3
127 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
128 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
129 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
130 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
131 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
132
133 @ clear SDRAM self-refresh bit latch
134 and r5, r5, #(~(1 << 8))
135 @ clear SDRAM self-refresh bit
136 and r5, r5, #(~(1 << 9))
137 str r5, [r4, #PWR_CTRL_REG_OFFS]
138
139 @ do save current bit settings in r1
140 mov r1, r5
141
142 @ set SDRAM self-refresh bit
143 orr r5, r5, #(1 << 9)
144 str r5, [r4, #PWR_CTRL_REG_OFFS]
145
146 @ set SDRAM self-refresh bit latch
147 orr r5, r5, #(1 << 8)
148 str r5, [r4, #PWR_CTRL_REG_OFFS]
149
150 @ clear SDRAM self-refresh bit latch
151 and r5, r5, #(~(1 << 8))
152 str r5, [r4, #PWR_CTRL_REG_OFFS]
153
154 @ clear SDRAM self-refresh bit
155 and r5, r5, #(~(1 << 9))
156 str r5, [r4, #PWR_CTRL_REG_OFFS]
157
158 @ wait for SDRAM to get into self-refresh mode
1592: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
160 tst r3, #(1 << 2)
161 beq 2b
162
163 @ set 'get out of self-refresh mode after wakeup' bit
164 orr r5, r5, #(1 << 7)
165 str r5, [r4, #PWR_CTRL_REG_OFFS]
166
167 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
168
169 @ set SDRAM self-refresh bit latch
170 orr r5, r5, #(1 << 8)
171 str r5, [r4, #PWR_CTRL_REG_OFFS]
172
173 @ clear SDRAM self-refresh bit latch
174 and r5, r5, #(~(1 << 8))
175 str r5, [r4, #PWR_CTRL_REG_OFFS]
176
177 @ wait for SDRAM to get out self-refresh mode
1783: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
179 tst r3, #5
180 bne 3b
181
182 @ restore regs and return
183 ldmfd sp!, {r0 - r6, pc}
184
185ENTRY(pnx4008_cpu_standby_sz)
186 .word . - pnx4008_cpu_standby
187
188ENTRY(pnx4008_cache_clean_invalidate)
189 stmfd sp!, {r0 - r6, lr}
190#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
191 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
192#else
1931: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
194 bne 1b
195#endif
196 ldmfd sp!, {r0 - r6, pc}
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
new file mode 100644
index 000000000000..4ce680698529
--- /dev/null
+++ b/arch/arm/mach-pnx4008/time.c
@@ -0,0 +1,141 @@
1/*
2 * arch/arm/mach-pnx4008/time.c
3 *
4 * PNX4008 Timers
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev, Grigory Tolstolytkin <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/sched.h>
20#include <linux/spinlock.h>
21#include <linux/module.h>
22#include <linux/kallsyms.h>
23
24#include <asm/system.h>
25#include <asm/hardware.h>
26#include <asm/io.h>
27#include <asm/leds.h>
28#include <asm/irq.h>
29#include <asm/mach/irq.h>
30#include <asm/mach/time.h>
31
32#include <linux/time.h>
33#include <linux/timex.h>
34#include <asm/errno.h>
35
36/*! Note: all timers are UPCOUNTING */
37
38/*!
39 * Returns number of us since last clock interrupt. Note that interrupts
40 * will have been disabled by do_gettimeoffset()
41 */
42static unsigned long pnx4008_gettimeoffset(void)
43{
44 u32 ticks_to_match =
45 __raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER);
46 u32 elapsed = LATCH - ticks_to_match;
47 return (elapsed * (tick_nsec / 1000)) / LATCH;
48}
49
50/*!
51 * IRQ handler for the timer
52 */
53static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
54 struct pt_regs *regs)
55{
56 if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
57
58 write_seqlock(&xtime_lock);
59
60 do {
61 timer_tick(regs);
62
63 /*
64 * this algorithm takes care of possible delay
65 * for this interrupt handling longer than a normal
66 * timer period
67 */
68 __raw_writel(__raw_readl(HSTIM_MATCH0) + LATCH,
69 HSTIM_MATCH0);
70 __raw_writel(MATCH0_INT, HSTIM_INT); /* clear interrupt */
71
72 /*
73 * The goal is to keep incrementing HSTIM_MATCH0
74 * register until HSTIM_MATCH0 indicates time after
75 * what HSTIM_COUNTER indicates.
76 */
77 } while ((signed)
78 (__raw_readl(HSTIM_MATCH0) -
79 __raw_readl(HSTIM_COUNTER)) < 0);
80
81 write_sequnlock(&xtime_lock);
82 }
83
84 return IRQ_HANDLED;
85}
86
87static struct irqaction pnx4008_timer_irq = {
88 .name = "PNX4008 Tick Timer",
89 .flags = SA_INTERRUPT | SA_TIMER,
90 .handler = pnx4008_timer_interrupt
91};
92
93/*!
94 * Set up timer and timer interrupt.
95 */
96static __init void pnx4008_setup_timer(void)
97{
98 __raw_writel(RESET_COUNT, MSTIM_CTRL);
99 while (__raw_readl(MSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
100 __raw_writel(0, MSTIM_CTRL); /* stop the timer */
101 __raw_writel(0, MSTIM_MCTRL);
102
103 __raw_writel(RESET_COUNT, HSTIM_CTRL);
104 while (__raw_readl(HSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
105 __raw_writel(0, HSTIM_CTRL);
106 __raw_writel(0, HSTIM_MCTRL);
107 __raw_writel(0, HSTIM_CCR);
108 __raw_writel(12, HSTIM_PMATCH); /* scale down to 1 MHZ */
109 __raw_writel(LATCH, HSTIM_MATCH0);
110 __raw_writel(MR0_INT, HSTIM_MCTRL);
111
112 setup_irq(HSTIMER_INT, &pnx4008_timer_irq);
113
114 __raw_writel(COUNT_ENAB | DEBUG_EN, HSTIM_CTRL); /*start timer, stop when JTAG active */
115}
116
117/* Timer Clock Control in PM register */
118#define TIMCLK_CTRL_REG IO_ADDRESS((PNX4008_PWRMAN_BASE + 0xBC))
119#define WATCHDOG_CLK_EN 1
120#define TIMER_CLK_EN 2 /* HS and MS timers? */
121
122static u32 timclk_ctrl_reg_save;
123
124void pnx4008_timer_suspend(void)
125{
126 timclk_ctrl_reg_save = __raw_readl(TIMCLK_CTRL_REG);
127 __raw_writel(0, TIMCLK_CTRL_REG); /* disable timers */
128}
129
130void pnx4008_timer_resume(void)
131{
132 __raw_writel(timclk_ctrl_reg_save, TIMCLK_CTRL_REG); /* enable timers */
133}
134
135struct sys_timer pnx4008_timer = {
136 .init = pnx4008_setup_timer,
137 .offset = pnx4008_gettimeoffset,
138 .suspend = pnx4008_timer_suspend,
139 .resume = pnx4008_timer_resume,
140};
141
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 3e26d7ce5bb2..1ab26c6914f2 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -22,6 +22,10 @@
22#include <linux/mtd/mtd.h> 22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h> 23#include <linux/mtd/partitions.h>
24 24
25#include <linux/spi/spi.h>
26#include <linux/spi/ads7846.h>
27#include <asm/arch/pxa2xx_spi.h>
28
25#include <asm/setup.h> 29#include <asm/setup.h>
26#include <asm/memory.h> 30#include <asm/memory.h>
27#include <asm/mach-types.h> 31#include <asm/mach-types.h>
@@ -196,6 +200,78 @@ static struct resource smc91x_resources[] = {
196 }, 200 },
197}; 201};
198 202
203/* ADS7846 is connected through SSP ... and if your board has J5 populated,
204 * you can select it to replace the ucb1400 by switching the touchscreen cable
205 * (to J5) and poking board registers (as done below). Else it's only useful
206 * for the temperature sensors.
207 */
208static struct resource pxa_ssp_resources[] = {
209 [0] = {
210 .start = __PREG(SSCR0_P(1)),
211 .end = __PREG(SSCR0_P(1)) + 0x14,
212 .flags = IORESOURCE_MEM,
213 },
214 [1] = {
215 .start = IRQ_SSP,
216 .end = IRQ_SSP,
217 .flags = IORESOURCE_IRQ,
218 },
219};
220
221static struct pxa2xx_spi_master pxa_ssp_master_info = {
222 .ssp_type = PXA25x_SSP,
223 .clock_enable = CKEN3_SSP,
224 .num_chipselect = 0,
225};
226
227static struct platform_device pxa_ssp = {
228 .name = "pxa2xx-spi",
229 .id = 1,
230 .resource = pxa_ssp_resources,
231 .num_resources = ARRAY_SIZE(pxa_ssp_resources),
232 .dev = {
233 .platform_data = &pxa_ssp_master_info,
234 },
235};
236
237static int lubbock_ads7846_pendown_state(void)
238{
239 /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
240 return 0;
241}
242
243static struct ads7846_platform_data ads_info = {
244 .model = 7846,
245 .vref_delay_usecs = 100, /* internal, no cap */
246 .get_pendown_state = lubbock_ads7846_pendown_state,
247 // .x_plate_ohms = 500, /* GUESS! */
248 // .y_plate_ohms = 500, /* GUESS! */
249};
250
251static void ads7846_cs(u32 command)
252{
253 static const unsigned TS_nCS = 1 << 11;
254 lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
255}
256
257static struct pxa2xx_spi_chip ads_hw = {
258 .tx_threshold = 1,
259 .rx_threshold = 2,
260 .cs_control = ads7846_cs,
261};
262
263static struct spi_board_info spi_board_info[] __initdata = { {
264 .modalias = "ads7846",
265 .platform_data = &ads_info,
266 .controller_data = &ads_hw,
267 .irq = LUBBOCK_BB_IRQ,
268 .max_speed_hz = 120000 /* max sample rate at 3V */
269 * 26 /* command + data + overhead */,
270 .bus_num = 1,
271 .chip_select = 0,
272},
273};
274
199static struct platform_device smc91x_device = { 275static struct platform_device smc91x_device = {
200 .name = "smc91x", 276 .name = "smc91x",
201 .id = -1, 277 .id = -1,
@@ -272,6 +348,7 @@ static struct platform_device *devices[] __initdata = {
272 &smc91x_device, 348 &smc91x_device,
273 &lubbock_flash_device[0], 349 &lubbock_flash_device[0],
274 &lubbock_flash_device[1], 350 &lubbock_flash_device[1],
351 &pxa_ssp,
275}; 352};
276 353
277static struct pxafb_mach_info sharp_lm8v31 __initdata = { 354static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@@ -400,6 +477,8 @@ static void __init lubbock_init(void)
400 lubbock_flash_data[flashboot^1].name = "application-flash"; 477 lubbock_flash_data[flashboot^1].name = "application-flash";
401 lubbock_flash_data[flashboot].name = "boot-rom"; 478 lubbock_flash_data[flashboot].name = "boot-rom";
402 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 479 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
480
481 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
403} 482}
404 483
405static struct map_desc lubbock_io_desc[] __initdata = { 484static struct map_desc lubbock_io_desc[] __initdata = {
@@ -416,6 +495,11 @@ static void __init lubbock_map_io(void)
416 pxa_map_io(); 495 pxa_map_io();
417 iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc)); 496 iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
418 497
498 /* SSP data pins */
499 pxa_gpio_mode(GPIO23_SCLK_MD);
500 pxa_gpio_mode(GPIO25_STXD_MD);
501 pxa_gpio_mode(GPIO26_SRXD_MD);
502
419 /* This enables the BTUART */ 503 /* This enables the BTUART */
420 pxa_gpio_mode(GPIO42_BTRXD_MD); 504 pxa_gpio_mode(GPIO42_BTRXD_MD);
421 pxa_gpio_mode(GPIO43_BTTXD_MD); 505 pxa_gpio_mode(GPIO43_BTTXD_MD);
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 970f98dadffc..0c334136db7c 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -70,6 +70,18 @@ config ARCH_S3C2440
70 help 70 help
71 Say Y here if you are using the SMDK2440. 71 Say Y here if you are using the SMDK2440.
72 72
73config SMDK2440_CPU2440
74 bool "SMDK2440 with S3C2440 cpu module"
75 depends on ARCH_S3C2440
76 default y if ARCH_S3C2440
77 select CPU_S3C2440
78
79config SMDK2440_CPU2442
80 bool "SMDM2440 with S3C2442 cpu module"
81 depends on ARCH_S3C2440
82 select CPU_S3C2442
83
84
73config MACH_VR1000 85config MACH_VR1000
74 bool "Thorcom VR1000" 86 bool "Thorcom VR1000"
75 select CPU_S3C2410 87 select CPU_S3C2410
@@ -109,12 +121,26 @@ config CPU_S3C2410
109 Support for S3C2410 and S3C2410A family from the S3C24XX line 121 Support for S3C2410 and S3C2410A family from the S3C24XX line
110 of Samsung Mobile CPUs. 122 of Samsung Mobile CPUs.
111 123
124config CPU_S3C244X
125 bool
126 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
127 help
128 Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
129
112config CPU_S3C2440 130config CPU_S3C2440
113 bool 131 bool
114 depends on ARCH_S3C2410 132 depends on ARCH_S3C2410
133 select CPU_S3C244X
115 help 134 help
116 Support for S3C2440 Samsung Mobile CPU based systems. 135 Support for S3C2440 Samsung Mobile CPU based systems.
117 136
137config CPU_S3C2442
138 bool
139 depends on ARCH_S3C2420
140 select CPU_S3C244X
141 help
142 Support for S3C2442 Samsung Mobile CPU based systems.
143
118comment "S3C2410 Boot" 144comment "S3C2410 Boot"
119 145
120config S3C2410_BOOT_WATCHDOG 146config S3C2410_BOOT_WATCHDOG
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 3e5712db6b52..5e09355cd4f4 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -24,6 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
24obj-$(CONFIG_PM) += pm.o sleep.o 24obj-$(CONFIG_PM) += pm.o sleep.o
25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o 25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
26 26
27# S3C244X support
28
29obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
30obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
31
27# S3C2440 support 32# S3C2440 support
28 33
29obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o 34obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
@@ -31,6 +36,11 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
31obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o 36obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
32obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o 37obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
33 38
39# S3C2442 support
40
41obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
42obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
43
34# bast extras 44# bast extras
35 45
36obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o 46obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 6de713ad319a..99d174612b53 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -70,7 +70,7 @@ void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
70 clkcon &= ~clocks; 70 clkcon &= ~clocks;
71 71
72 /* ensure none of the special function bits set */ 72 /* ensure none of the special function bits set */
73 clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); 73 clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3);
74 74
75 __raw_writel(clkcon, S3C2410_CLKCON); 75 __raw_writel(clkcon, S3C2410_CLKCON);
76} 76}
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
index c940890f621f..a40eaa656177 100644
--- a/arch/arm/mach-s3c2410/common-smdk.c
+++ b/arch/arm/mach-s3c2410/common-smdk.c
@@ -34,6 +34,7 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35 35
36#include <asm/arch/regs-gpio.h> 36#include <asm/arch/regs-gpio.h>
37#include <asm/arch/leds-gpio.h>
37 38
38#include <asm/arch/nand.h> 39#include <asm/arch/nand.h>
39 40
@@ -41,6 +42,66 @@
41#include "devs.h" 42#include "devs.h"
42#include "pm.h" 43#include "pm.h"
43 44
45/* LED devices */
46
47static struct s3c24xx_led_platdata smdk_pdata_led4 = {
48 .gpio = S3C2410_GPF4,
49 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
50 .name = "led4",
51 .def_trigger = "timer",
52};
53
54static struct s3c24xx_led_platdata smdk_pdata_led5 = {
55 .gpio = S3C2410_GPF5,
56 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
57 .name = "led5",
58 .def_trigger = "nand-disk",
59};
60
61static struct s3c24xx_led_platdata smdk_pdata_led6 = {
62 .gpio = S3C2410_GPF6,
63 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
64 .name = "led6",
65};
66
67static struct s3c24xx_led_platdata smdk_pdata_led7 = {
68 .gpio = S3C2410_GPF7,
69 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
70 .name = "led7",
71};
72
73static struct platform_device smdk_led4 = {
74 .name = "s3c24xx_led",
75 .id = 0,
76 .dev = {
77 .platform_data = &smdk_pdata_led4,
78 },
79};
80
81static struct platform_device smdk_led5 = {
82 .name = "s3c24xx_led",
83 .id = 1,
84 .dev = {
85 .platform_data = &smdk_pdata_led5,
86 },
87};
88
89static struct platform_device smdk_led6 = {
90 .name = "s3c24xx_led",
91 .id = 2,
92 .dev = {
93 .platform_data = &smdk_pdata_led6,
94 },
95};
96
97static struct platform_device smdk_led7 = {
98 .name = "s3c24xx_led",
99 .id = 3,
100 .dev = {
101 .platform_data = &smdk_pdata_led7,
102 },
103};
104
44/* NAND parititon from 2.4.18-swl5 */ 105/* NAND parititon from 2.4.18-swl5 */
45 106
46static struct mtd_partition smdk_default_nand_part[] = { 107static struct mtd_partition smdk_default_nand_part[] = {
@@ -111,6 +172,10 @@ static struct s3c2410_platform_nand smdk_nand_info = {
111 172
112static struct platform_device __initdata *smdk_devs[] = { 173static struct platform_device __initdata *smdk_devs[] = {
113 &s3c_device_nand, 174 &s3c_device_nand,
175 &smdk_led4,
176 &smdk_led5,
177 &smdk_led6,
178 &smdk_led7,
114}; 179};
115 180
116void __init smdk_machine_init(void) 181void __init smdk_machine_init(void)
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 70c34fcf7858..52842e6e86e6 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -37,12 +37,16 @@
37#include <asm/mach/map.h> 37#include <asm/mach/map.h>
38 38
39#include <asm/arch/regs-gpio.h> 39#include <asm/arch/regs-gpio.h>
40#include <asm/arch/regs-serial.h>
40 41
41#include "cpu.h" 42#include "cpu.h"
43#include "devs.h"
42#include "clock.h" 44#include "clock.h"
43#include "s3c2400.h" 45#include "s3c2400.h"
44#include "s3c2410.h" 46#include "s3c2410.h"
47#include "s3c244x.h"
45#include "s3c2440.h" 48#include "s3c2440.h"
49#include "s3c2442.h"
46 50
47struct cpu_table { 51struct cpu_table {
48 unsigned long idcode; 52 unsigned long idcode;
@@ -59,6 +63,7 @@ struct cpu_table {
59static const char name_s3c2400[] = "S3C2400"; 63static const char name_s3c2400[] = "S3C2400";
60static const char name_s3c2410[] = "S3C2410"; 64static const char name_s3c2410[] = "S3C2410";
61static const char name_s3c2440[] = "S3C2440"; 65static const char name_s3c2440[] = "S3C2440";
66static const char name_s3c2442[] = "S3C2442";
62static const char name_s3c2410a[] = "S3C2410A"; 67static const char name_s3c2410a[] = "S3C2410A";
63static const char name_s3c2440a[] = "S3C2440A"; 68static const char name_s3c2440a[] = "S3C2440A";
64 69
@@ -84,22 +89,31 @@ static struct cpu_table cpu_ids[] __initdata = {
84 { 89 {
85 .idcode = 0x32440000, 90 .idcode = 0x32440000,
86 .idmask = 0xffffffff, 91 .idmask = 0xffffffff,
87 .map_io = s3c2440_map_io, 92 .map_io = s3c244x_map_io,
88 .init_clocks = s3c2440_init_clocks, 93 .init_clocks = s3c244x_init_clocks,
89 .init_uarts = s3c2440_init_uarts, 94 .init_uarts = s3c244x_init_uarts,
90 .init = s3c2440_init, 95 .init = s3c2440_init,
91 .name = name_s3c2440 96 .name = name_s3c2440
92 }, 97 },
93 { 98 {
94 .idcode = 0x32440001, 99 .idcode = 0x32440001,
95 .idmask = 0xffffffff, 100 .idmask = 0xffffffff,
96 .map_io = s3c2440_map_io, 101 .map_io = s3c244x_map_io,
97 .init_clocks = s3c2440_init_clocks, 102 .init_clocks = s3c244x_init_clocks,
98 .init_uarts = s3c2440_init_uarts, 103 .init_uarts = s3c244x_init_uarts,
99 .init = s3c2440_init, 104 .init = s3c2440_init,
100 .name = name_s3c2440a 105 .name = name_s3c2440a
101 }, 106 },
102 { 107 {
108 .idcode = 0x32440aaa,
109 .idmask = 0xffffffff,
110 .map_io = s3c244x_map_io,
111 .init_clocks = s3c244x_init_clocks,
112 .init_uarts = s3c244x_init_uarts,
113 .init = s3c2442_init,
114 .name = name_s3c2442
115 },
116 {
103 .idcode = 0x0, /* S3C2400 doesn't have an idcode */ 117 .idcode = 0x0, /* S3C2400 doesn't have an idcode */
104 .idmask = 0xffffffff, 118 .idmask = 0xffffffff,
105 .map_io = s3c2400_map_io, 119 .map_io = s3c2400_map_io,
@@ -175,13 +189,13 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
175 panic("Unknown S3C24XX CPU"); 189 panic("Unknown S3C24XX CPU");
176 } 190 }
177 191
192 printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
193
178 if (cpu->map_io == NULL || cpu->init == NULL) { 194 if (cpu->map_io == NULL || cpu->init == NULL) {
179 printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); 195 printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
180 panic("Unsupported S3C24XX CPU"); 196 panic("Unsupported S3C24XX CPU");
181 } 197 }
182 198
183 printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
184
185 (cpu->map_io)(mach_desc, size); 199 (cpu->map_io)(mach_desc, size);
186} 200}
187 201
@@ -208,6 +222,49 @@ void __init s3c24xx_init_clocks(int xtal)
208 (cpu->init_clocks)(xtal); 222 (cpu->init_clocks)(xtal);
209} 223}
210 224
225/* uart management */
226
227static int nr_uarts __initdata = 0;
228
229static struct s3c2410_uartcfg uart_cfgs[3];
230
231/* s3c24xx_init_uartdevs
232 *
233 * copy the specified platform data and configuration into our central
234 * set of devices, before the data is thrown away after the init process.
235 *
236 * This also fills in the array passed to the serial driver for the
237 * early initialisation of the console.
238*/
239
240void __init s3c24xx_init_uartdevs(char *name,
241 struct s3c24xx_uart_resources *res,
242 struct s3c2410_uartcfg *cfg, int no)
243{
244 struct platform_device *platdev;
245 struct s3c2410_uartcfg *cfgptr = uart_cfgs;
246 struct s3c24xx_uart_resources *resp;
247 int uart;
248
249 memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
250
251 for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
252 platdev = s3c24xx_uart_src[cfgptr->hwport];
253
254 resp = res + cfgptr->hwport;
255
256 s3c24xx_uart_devs[uart] = platdev;
257
258 platdev->name = name;
259 platdev->resource = resp->resources;
260 platdev->num_resources = resp->nr_resources;
261
262 platdev->dev.platform_data = cfgptr;
263 }
264
265 nr_uarts = no;
266}
267
211void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) 268void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
212{ 269{
213 if (cpu == NULL) 270 if (cpu == NULL)
@@ -232,6 +289,10 @@ static int __init s3c_arch_init(void)
232 if (ret != 0) 289 if (ret != 0)
233 return ret; 290 return ret;
234 291
292 ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
293 if (ret != 0)
294 return ret;
295
235 if (board != NULL) { 296 if (board != NULL) {
236 struct platform_device **ptr = board->devices; 297 struct platform_device **ptr = board->devices;
237 int i; 298 int i;
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index fc1067783f6d..40862899b2f1 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -31,6 +31,8 @@
31#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000) 31#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
32 32
33/* forward declaration */ 33/* forward declaration */
34struct s3c24xx_uart_resources;
35struct platform_device;
34struct s3c2410_uartcfg; 36struct s3c2410_uartcfg;
35struct map_desc; 37struct map_desc;
36 38
@@ -44,6 +46,10 @@ extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
44 46
45extern void s3c24xx_init_clocks(int xtal); 47extern void s3c24xx_init_clocks(int xtal);
46 48
49extern void s3c24xx_init_uartdevs(char *name,
50 struct s3c24xx_uart_resources *res,
51 struct s3c2410_uartcfg *cfg, int no);
52
47/* the board structure is used at first initialsation time 53/* the board structure is used at first initialsation time
48 * to get info such as the devices to register for this 54 * to get info such as the devices to register for this
49 * board. This is done because platfrom_add_devices() cannot 55 * board. This is done because platfrom_add_devices() cannot
@@ -68,3 +74,4 @@ extern struct sys_timer s3c24xx_timer;
68/* system device classes */ 74/* system device classes */
69 75
70extern struct sysdev_class s3c2440_sysclass; 76extern struct sysdev_class s3c2440_sysclass;
77extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index ca09ba516e4c..ad3845e329ba 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -38,10 +38,86 @@
38#include <asm/arch/regs-serial.h> 38#include <asm/arch/regs-serial.h>
39 39
40#include "devs.h" 40#include "devs.h"
41#include "cpu.h"
41 42
42/* Serial port registrations */ 43/* Serial port registrations */
43 44
44struct platform_device *s3c24xx_uart_devs[3]; 45static struct resource s3c2410_uart0_resource[] = {
46 [0] = {
47 .start = S3C2410_PA_UART0,
48 .end = S3C2410_PA_UART0 + 0x3fff,
49 .flags = IORESOURCE_MEM,
50 },
51 [1] = {
52 .start = IRQ_S3CUART_RX0,
53 .end = IRQ_S3CUART_ERR0,
54 .flags = IORESOURCE_IRQ,
55 }
56};
57
58static struct resource s3c2410_uart1_resource[] = {
59 [0] = {
60 .start = S3C2410_PA_UART1,
61 .end = S3C2410_PA_UART1 + 0x3fff,
62 .flags = IORESOURCE_MEM,
63 },
64 [1] = {
65 .start = IRQ_S3CUART_RX1,
66 .end = IRQ_S3CUART_ERR1,
67 .flags = IORESOURCE_IRQ,
68 }
69};
70
71static struct resource s3c2410_uart2_resource[] = {
72 [0] = {
73 .start = S3C2410_PA_UART2,
74 .end = S3C2410_PA_UART2 + 0x3fff,
75 .flags = IORESOURCE_MEM,
76 },
77 [1] = {
78 .start = IRQ_S3CUART_RX2,
79 .end = IRQ_S3CUART_ERR2,
80 .flags = IORESOURCE_IRQ,
81 }
82};
83
84struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
85 [0] = {
86 .resources = s3c2410_uart0_resource,
87 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
88 },
89 [1] = {
90 .resources = s3c2410_uart1_resource,
91 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
92 },
93 [2] = {
94 .resources = s3c2410_uart2_resource,
95 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
96 },
97};
98
99/* yart devices */
100
101static struct platform_device s3c24xx_uart_device0 = {
102 .id = 0,
103};
104
105static struct platform_device s3c24xx_uart_device1 = {
106 .id = 1,
107};
108
109static struct platform_device s3c24xx_uart_device2 = {
110 .id = 2,
111};
112
113struct platform_device *s3c24xx_uart_src[3] = {
114 &s3c24xx_uart_device0,
115 &s3c24xx_uart_device1,
116 &s3c24xx_uart_device2,
117};
118
119struct platform_device *s3c24xx_uart_devs[3] = {
120};
45 121
46/* USB Host Controller */ 122/* USB Host Controller */
47 123
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
index 52c4bab5c761..fa124ed920e0 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -17,7 +17,15 @@
17#include <linux/config.h> 17#include <linux/config.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19 19
20struct s3c24xx_uart_resources {
21 struct resource *resources;
22 unsigned long nr_resources;
23};
24
25extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
26
20extern struct platform_device *s3c24xx_uart_devs[]; 27extern struct platform_device *s3c24xx_uart_devs[];
28extern struct platform_device *s3c24xx_uart_src[];
21 29
22extern struct platform_device s3c_device_usb; 30extern struct platform_device s3c_device_usb;
23extern struct platform_device s3c_device_lcd; 31extern struct platform_device s3c_device_lcd;
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index cc97fbf66291..52bf718137d4 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -131,7 +131,7 @@ static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
131}; 131};
132 132
133 133
134static struct s3c2410_uartcfg anubis_uartcfgs[] = { 134static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
135 [0] = { 135 [0] = {
136 .hwport = 0, 136 .hwport = 0,
137 .flags = 0, 137 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 995bb8add331..947234df8160 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -208,7 +208,7 @@ static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
208}; 208};
209 209
210 210
211static struct s3c2410_uartcfg bast_uartcfgs[] = { 211static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
212 [0] = { 212 [0] = {
213 .hwport = 0, 213 .hwport = 0,
214 .flags = 0, 214 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 646a3a5d33a5..aec431b2830a 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -72,7 +72,7 @@ static struct map_desc h1940_iodesc[] __initdata = {
72#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 72#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
73#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 73#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
74 74
75static struct s3c2410_uartcfg h1940_uartcfgs[] = { 75static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
76 [0] = { 76 [0] = {
77 .hwport = 0, 77 .hwport = 0,
78 .flags = 0, 78 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index 07d09509a626..065a1d4e860b 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -51,7 +51,7 @@ static struct map_desc nexcoder_iodesc[] __initdata = {
51#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 51#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
52#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE 52#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
53 53
54static struct s3c2410_uartcfg nexcoder_uartcfgs[] = { 54static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
55 [0] = { 55 [0] = {
56 .hwport = 0, 56 .hwport = 0,
57 .flags = 0, 57 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c
index ae0787557751..858fd03c6bc5 100644
--- a/arch/arm/mach-s3c2410/mach-osiris.c
+++ b/arch/arm/mach-s3c2410/mach-osiris.c
@@ -95,8 +95,7 @@ static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
95 } 95 }
96}; 96};
97 97
98 98static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
99static struct s3c2410_uartcfg osiris_uartcfgs[] = {
100 [0] = { 99 [0] = {
101 .hwport = 0, 100 .hwport = 0,
102 .flags = 0, 101 .flags = 0,
@@ -107,7 +106,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] = {
107 .clocks_size = ARRAY_SIZE(osiris_serial_clocks) 106 .clocks_size = ARRAY_SIZE(osiris_serial_clocks)
108 }, 107 },
109 [1] = { 108 [1] = {
110 .hwport = 2, 109 .hwport = 1,
111 .flags = 0, 110 .flags = 0,
112 .ucon = UCON, 111 .ucon = UCON,
113 .ulcon = ULCON, 112 .ulcon = ULCON,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index b39daedf93ca..c71673fd9955 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -45,7 +45,7 @@ static struct map_desc otom11_iodesc[] __initdata = {
45#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 45#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
46#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE 46#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
47 47
48static struct s3c2410_uartcfg otom11_uartcfgs[] = { 48static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
49 [0] = { 49 [0] = {
50 .hwport = 0, 50 .hwport = 0,
51 .flags = 0, 51 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 2db932d72c5a..25f7e9f4dcee 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -65,7 +65,7 @@ static struct map_desc smdk2410_iodesc[] __initdata = {
65#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 65#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
66#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 66#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
67 67
68static struct s3c2410_uartcfg smdk2410_uartcfgs[] = { 68static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
69 [0] = { 69 [0] = {
70 .hwport = 0, 70 .hwport = 0,
71 .flags = 0, 71 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 5fffd1d51047..d661c6b7ff56 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -86,7 +86,7 @@ static struct map_desc smdk2440_iodesc[] __initdata = {
86#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 86#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
87#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 87#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
88 88
89static struct s3c2410_uartcfg smdk2440_uartcfgs[] = { 89static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
90 [0] = { 90 [0] = {
91 .hwport = 0, 91 .hwport = 0,
92 .flags = 0, 92 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 785fc9cdcf7c..d18efb279d3d 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -166,7 +166,7 @@ static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
166 } 166 }
167}; 167};
168 168
169static struct s3c2410_uartcfg vr1000_uartcfgs[] = { 169static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
170 [0] = { 170 [0] = {
171 .hwport = 0, 171 .hwport = 0,
172 .flags = 0, 172 .flags = 0,
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index fe57d966a34d..43e9a550a203 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -58,7 +58,11 @@ unsigned long s3c_pm_flags;
58 58
59/* cache functions from arch/arm/mm/proc-arm920.S */ 59/* cache functions from arch/arm/mm/proc-arm920.S */
60 60
61#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
61extern void arm920_flush_kern_cache_all(void); 62extern void arm920_flush_kern_cache_all(void);
63#else
64static void arm920_flush_kern_cache_all(void) { }
65#endif
62 66
63#define PFX "s3c24xx-pm: " 67#define PFX "s3c24xx-pm: "
64 68
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 0a2013a76549..0852e87a79c4 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -42,6 +42,7 @@
42 42
43#include "s3c2410.h" 43#include "s3c2410.h"
44#include "cpu.h" 44#include "cpu.h"
45#include "devs.h"
45#include "clock.h" 46#include "clock.h"
46 47
47/* Initial IO mappings */ 48/* Initial IO mappings */
@@ -55,93 +56,13 @@ static struct map_desc s3c2410_iodesc[] __initdata = {
55 IODESC_ENT(WATCHDOG), 56 IODESC_ENT(WATCHDOG),
56}; 57};
57 58
58static struct resource s3c_uart0_resource[] = {
59 [0] = {
60 .start = S3C2410_PA_UART0,
61 .end = S3C2410_PA_UART0 + 0x3fff,
62 .flags = IORESOURCE_MEM,
63 },
64 [1] = {
65 .start = IRQ_S3CUART_RX0,
66 .end = IRQ_S3CUART_ERR0,
67 .flags = IORESOURCE_IRQ,
68 }
69
70};
71
72static struct resource s3c_uart1_resource[] = {
73 [0] = {
74 .start = S3C2410_PA_UART1,
75 .end = S3C2410_PA_UART1 + 0x3fff,
76 .flags = IORESOURCE_MEM,
77 },
78 [1] = {
79 .start = IRQ_S3CUART_RX1,
80 .end = IRQ_S3CUART_ERR1,
81 .flags = IORESOURCE_IRQ,
82 }
83};
84
85static struct resource s3c_uart2_resource[] = {
86 [0] = {
87 .start = S3C2410_PA_UART2,
88 .end = S3C2410_PA_UART2 + 0x3fff,
89 .flags = IORESOURCE_MEM,
90 },
91 [1] = {
92 .start = IRQ_S3CUART_RX2,
93 .end = IRQ_S3CUART_ERR2,
94 .flags = IORESOURCE_IRQ,
95 }
96};
97
98/* our uart devices */ 59/* our uart devices */
99 60
100static struct platform_device s3c_uart0 = {
101 .name = "s3c2410-uart",
102 .id = 0,
103 .num_resources = ARRAY_SIZE(s3c_uart0_resource),
104 .resource = s3c_uart0_resource,
105};
106
107
108static struct platform_device s3c_uart1 = {
109 .name = "s3c2410-uart",
110 .id = 1,
111 .num_resources = ARRAY_SIZE(s3c_uart1_resource),
112 .resource = s3c_uart1_resource,
113};
114
115static struct platform_device s3c_uart2 = {
116 .name = "s3c2410-uart",
117 .id = 2,
118 .num_resources = ARRAY_SIZE(s3c_uart2_resource),
119 .resource = s3c_uart2_resource,
120};
121
122static struct platform_device *uart_devices[] __initdata = {
123 &s3c_uart0,
124 &s3c_uart1,
125 &s3c_uart2
126};
127
128static int s3c2410_uart_count = 0;
129
130/* uart registration process */ 61/* uart registration process */
131 62
132void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) 63void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
133{ 64{
134 struct platform_device *platdev; 65 s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
135 int uart;
136
137 for (uart = 0; uart < no; uart++, cfg++) {
138 platdev = uart_devices[cfg->hwport];
139
140 s3c24xx_uart_devs[uart] = platdev;
141 platdev->dev.platform_data = cfg;
142 }
143
144 s3c2410_uart_count = uart;
145} 66}
146 67
147/* s3c2410_map_io 68/* s3c2410_map_io
@@ -193,5 +114,5 @@ int __init s3c2410_init(void)
193{ 114{
194 printk("S3C2410: Initialising architecture\n"); 115 printk("S3C2410: Initialising architecture\n");
195 116
196 return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count); 117 return 0;
197} 118}
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
index 278d0044c85d..acfe3870727b 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -100,73 +100,12 @@ static struct irqchip s3c_irq_wdtac97 = {
100 .ack = s3c_irq_wdtac97_ack, 100 .ack = s3c_irq_wdtac97_ack,
101}; 101};
102 102
103/* camera irq */
104
105static void s3c_irq_demux_cam(unsigned int irq,
106 struct irqdesc *desc,
107 struct pt_regs *regs)
108{
109 unsigned int subsrc, submsk;
110 struct irqdesc *mydesc;
111
112 /* read the current pending interrupts, and the mask
113 * for what it is available */
114
115 subsrc = __raw_readl(S3C2410_SUBSRCPND);
116 submsk = __raw_readl(S3C2410_INTSUBMSK);
117
118 subsrc &= ~submsk;
119 subsrc >>= 11;
120 subsrc &= 3;
121
122 if (subsrc != 0) {
123 if (subsrc & 1) {
124 mydesc = irq_desc + IRQ_S3C2440_CAM_C;
125 desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
126 }
127 if (subsrc & 2) {
128 mydesc = irq_desc + IRQ_S3C2440_CAM_P;
129 desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
130 }
131 }
132}
133
134#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
135
136static void
137s3c_irq_cam_mask(unsigned int irqno)
138{
139 s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
140}
141
142static void
143s3c_irq_cam_unmask(unsigned int irqno)
144{
145 s3c_irqsub_unmask(irqno, INTMSK_CAM);
146}
147
148static void
149s3c_irq_cam_ack(unsigned int irqno)
150{
151 s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
152}
153
154static struct irqchip s3c_irq_cam = {
155 .mask = s3c_irq_cam_mask,
156 .unmask = s3c_irq_cam_unmask,
157 .ack = s3c_irq_cam_ack,
158};
159
160static int s3c2440_irq_add(struct sys_device *sysdev) 103static int s3c2440_irq_add(struct sys_device *sysdev)
161{ 104{
162 unsigned int irqno; 105 unsigned int irqno;
163 106
164 printk("S3C2440: IRQ Support\n"); 107 printk("S3C2440: IRQ Support\n");
165 108
166 set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
167 set_irq_handler(IRQ_NFCON, do_level_IRQ);
168 set_irq_flags(IRQ_NFCON, IRQF_VALID);
169
170 /* add new chained handler for wdt, ac7 */ 109 /* add new chained handler for wdt, ac7 */
171 110
172 set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); 111 set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
@@ -179,18 +118,6 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
179 set_irq_flags(irqno, IRQF_VALID); 118 set_irq_flags(irqno, IRQF_VALID);
180 } 119 }
181 120
182 /* add chained handler for camera */
183
184 set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
185 set_irq_handler(IRQ_CAM, do_level_IRQ);
186 set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
187
188 for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
189 set_irq_chip(irqno, &s3c_irq_cam);
190 set_irq_handler(irqno, do_level_IRQ);
191 set_irq_flags(irqno, IRQF_VALID);
192 }
193
194 return 0; 121 return 0;
195} 122}
196 123
@@ -198,10 +125,10 @@ static struct sysdev_driver s3c2440_irq_driver = {
198 .add = s3c2440_irq_add, 125 .add = s3c2440_irq_add,
199}; 126};
200 127
201static int s3c24xx_irq_driver(void) 128static int s3c2440_irq_init(void)
202{ 129{
203 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); 130 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
204} 131}
205 132
206arch_initcall(s3c24xx_irq_driver); 133arch_initcall(s3c2440_irq_init);
207 134
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index b7fe6d9453fb..0ab50f44f318 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440.c 1/* linux/arch/arm/mach-s3c2410/s3c2440.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * Samsung S3C2440 Mobile CPU support 6 * Samsung S3C2440 Mobile CPU support
@@ -8,16 +8,6 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 24-Aug-2004 BJD Start of s3c2440 support
14 * 12-Oct-2004 BJD Moved clock info out to clock.c
15 * 01-Nov-2004 BJD Fixed clock build code
16 * 09-Nov-2004 BJD Added sysdev for power management
17 * 04-Nov-2004 BJD New serial registration
18 * 15-Nov-2004 BJD Rename the i2c device for the s3c2440
19 * 14-Jan-2005 BJD Moved clock init code into seperate function
20 * 14-Jan-2005 BJD Removed un-used clock bits
21*/ 11*/
22 12
23#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -50,234 +40,20 @@
50#include "cpu.h" 40#include "cpu.h"
51#include "pm.h" 41#include "pm.h"
52 42
53
54static struct map_desc s3c2440_iodesc[] __initdata = {
55 IODESC_ENT(USBHOST),
56 IODESC_ENT(CLKPWR),
57 IODESC_ENT(LCD),
58 IODESC_ENT(TIMER),
59 IODESC_ENT(ADC),
60 IODESC_ENT(WATCHDOG),
61};
62
63static struct resource s3c_uart0_resource[] = {
64 [0] = {
65 .start = S3C2410_PA_UART0,
66 .end = S3C2410_PA_UART0 + 0x3fff,
67 .flags = IORESOURCE_MEM,
68 },
69 [1] = {
70 .start = IRQ_S3CUART_RX0,
71 .end = IRQ_S3CUART_ERR0,
72 .flags = IORESOURCE_IRQ,
73 }
74
75};
76
77static struct resource s3c_uart1_resource[] = {
78 [0] = {
79 .start = S3C2410_PA_UART1,
80 .end = S3C2410_PA_UART1 + 0x3fff,
81 .flags = IORESOURCE_MEM,
82 },
83 [1] = {
84 .start = IRQ_S3CUART_RX1,
85 .end = IRQ_S3CUART_ERR1,
86 .flags = IORESOURCE_IRQ,
87 }
88};
89
90static struct resource s3c_uart2_resource[] = {
91 [0] = {
92 .start = S3C2410_PA_UART2,
93 .end = S3C2410_PA_UART2 + 0x3fff,
94 .flags = IORESOURCE_MEM,
95 },
96 [1] = {
97 .start = IRQ_S3CUART_RX2,
98 .end = IRQ_S3CUART_ERR2,
99 .flags = IORESOURCE_IRQ,
100 }
101};
102
103/* our uart devices */
104
105static struct platform_device s3c_uart0 = {
106 .name = "s3c2440-uart",
107 .id = 0,
108 .num_resources = ARRAY_SIZE(s3c_uart0_resource),
109 .resource = s3c_uart0_resource,
110};
111
112static struct platform_device s3c_uart1 = {
113 .name = "s3c2440-uart",
114 .id = 1,
115 .num_resources = ARRAY_SIZE(s3c_uart1_resource),
116 .resource = s3c_uart1_resource,
117};
118
119static struct platform_device s3c_uart2 = {
120 .name = "s3c2440-uart",
121 .id = 2,
122 .num_resources = ARRAY_SIZE(s3c_uart2_resource),
123 .resource = s3c_uart2_resource,
124};
125
126static struct platform_device *uart_devices[] __initdata = {
127 &s3c_uart0,
128 &s3c_uart1,
129 &s3c_uart2
130};
131
132/* uart initialisation */
133
134static int __initdata s3c2440_uart_count;
135
136void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
137{
138 struct platform_device *platdev;
139 int uart;
140
141 for (uart = 0; uart < no; uart++, cfg++) {
142 platdev = uart_devices[cfg->hwport];
143
144 s3c24xx_uart_devs[uart] = platdev;
145 platdev->dev.platform_data = cfg;
146 }
147
148 s3c2440_uart_count = uart;
149}
150
151
152#ifdef CONFIG_PM
153
154static struct sleep_save s3c2440_sleep[] = {
155 SAVE_ITEM(S3C2440_DSC0),
156 SAVE_ITEM(S3C2440_DSC1),
157 SAVE_ITEM(S3C2440_GPJDAT),
158 SAVE_ITEM(S3C2440_GPJCON),
159 SAVE_ITEM(S3C2440_GPJUP)
160};
161
162static int s3c2440_suspend(struct sys_device *dev, pm_message_t state)
163{
164 s3c2410_pm_do_save(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
165 return 0;
166}
167
168static int s3c2440_resume(struct sys_device *dev)
169{
170 s3c2410_pm_do_restore(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
171 return 0;
172}
173
174#else
175#define s3c2440_suspend NULL
176#define s3c2440_resume NULL
177#endif
178
179struct sysdev_class s3c2440_sysclass = {
180 set_kset_name("s3c2440-core"),
181 .suspend = s3c2440_suspend,
182 .resume = s3c2440_resume
183};
184
185static struct sys_device s3c2440_sysdev = { 43static struct sys_device s3c2440_sysdev = {
186 .cls = &s3c2440_sysclass, 44 .cls = &s3c2440_sysclass,
187}; 45};
188 46
189void __init s3c2440_map_io(struct map_desc *mach_desc, int size) 47int __init s3c2440_init(void)
190{ 48{
191 /* register our io-tables */ 49 printk("S3C2440: Initialising architecture\n");
192
193 iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
194 iotable_init(mach_desc, size);
195
196 /* rename any peripherals used differing from the s3c2410 */
197
198 s3c_device_i2c.name = "s3c2440-i2c";
199 s3c_device_nand.name = "s3c2440-nand";
200 50
201 /* change irq for watchdog */ 51 /* change irq for watchdog */
202 52
203 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; 53 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
204 s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT; 54 s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT;
205}
206
207void __init s3c2440_init_clocks(int xtal)
208{
209 unsigned long clkdiv;
210 unsigned long camdiv;
211 unsigned long hclk, fclk, pclk;
212 int hdiv = 1;
213
214 /* now we've got our machine bits initialised, work out what
215 * clocks we've got */
216
217 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
218
219 clkdiv = __raw_readl(S3C2410_CLKDIVN);
220 camdiv = __raw_readl(S3C2440_CAMDIVN);
221
222 /* work out clock scalings */
223
224 switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
225 case S3C2440_CLKDIVN_HDIVN_1:
226 hdiv = 1;
227 break;
228
229 case S3C2440_CLKDIVN_HDIVN_2:
230 hdiv = 2;
231 break;
232
233 case S3C2440_CLKDIVN_HDIVN_4_8:
234 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
235 break;
236
237 case S3C2440_CLKDIVN_HDIVN_3_6:
238 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
239 break;
240 }
241
242 hclk = fclk / hdiv;
243 pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
244
245 /* print brief summary of clocks, etc */
246
247 printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
248 print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
249
250 /* initialise the clocks here, to allow other things like the
251 * console to use them, and to add new ones after the initialisation
252 */
253
254 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
255}
256
257/* need to register class before we actually register the device, and
258 * we also need to ensure that it has been initialised before any of the
259 * drivers even try to use it (even if not on an s3c2440 based system)
260 * as a driver which may support both 2410 and 2440 may try and use it.
261*/
262
263static int __init s3c2440_core_init(void)
264{
265 return sysdev_class_register(&s3c2440_sysclass);
266}
267
268core_initcall(s3c2440_core_init);
269
270int __init s3c2440_init(void)
271{
272 int ret;
273
274 printk("S3C2440: Initialising architecture\n");
275 55
276 ret = sysdev_register(&s3c2440_sysdev); 56 /* register our system device for everything else */
277 if (ret != 0)
278 printk(KERN_ERR "failed to register sysdev for s3c2440\n");
279 else
280 ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
281 57
282 return ret; 58 return sysdev_register(&s3c2440_sysdev);
283} 59}
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2410/s3c2442-clock.c
new file mode 100644
index 000000000000..5b7b301eb522
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442-clock.c
@@ -0,0 +1,171 @@
1/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C2442 Clock support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/list.h>
28#include <linux/errno.h>
29#include <linux/err.h>
30#include <linux/device.h>
31#include <linux/sysdev.h>
32#include <linux/interrupt.h>
33#include <linux/ioport.h>
34#include <linux/mutex.h>
35#include <linux/clk.h>
36
37#include <asm/hardware.h>
38#include <asm/atomic.h>
39#include <asm/irq.h>
40#include <asm/io.h>
41
42#include <asm/arch/regs-clock.h>
43
44#include "clock.h"
45#include "cpu.h"
46
47/* S3C2442 extended clock support */
48
49static unsigned long s3c2442_camif_upll_round(struct clk *clk,
50 unsigned long rate)
51{
52 unsigned long parent_rate = clk_get_rate(clk->parent);
53 int div;
54
55 if (rate > parent_rate)
56 return parent_rate;
57
58 div = parent_rate / rate;
59
60 if (div == 3)
61 return parent_rate / 3;
62
63 /* note, we remove the +/- 1 calculations for the divisor */
64
65 div /= 2;
66
67 if (div < 1)
68 div = 1;
69 else if (div > 16)
70 div = 16;
71
72 return parent_rate / (div * 2);
73}
74
75static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
76{
77 unsigned long parent_rate = clk_get_rate(clk->parent);
78 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
79
80 rate = s3c2442_camif_upll_round(clk, rate);
81
82 camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
83
84 if (rate == parent_rate) {
85 camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
86 } else if ((parent_rate / rate) == 3) {
87 camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
88 camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
89 } else {
90 camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
91 camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
92 camdivn |= (((parent_rate / rate) / 2) - 1);
93 }
94
95 __raw_writel(camdivn, S3C2440_CAMDIVN);
96
97 return 0;
98}
99
100/* Extra S3C2442 clocks */
101
102static struct clk s3c2442_clk_cam = {
103 .name = "camif",
104 .id = -1,
105 .enable = s3c24xx_clkcon_enable,
106 .ctrlbit = S3C2440_CLKCON_CAMERA,
107};
108
109static struct clk s3c2442_clk_cam_upll = {
110 .name = "camif-upll",
111 .id = -1,
112 .set_rate = s3c2442_camif_upll_setrate,
113 .round_rate = s3c2442_camif_upll_round,
114};
115
116static int s3c2442_clk_add(struct sys_device *sysdev)
117{
118 unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
119 unsigned long clkdivn;
120 struct clk *clk_h;
121 struct clk *clk_p;
122 struct clk *clk_upll;
123
124 printk("S3C2442: Clock Support, DVS %s\n",
125 (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
126
127 clk_p = clk_get(NULL, "pclk");
128 clk_h = clk_get(NULL, "hclk");
129 clk_upll = clk_get(NULL, "upll");
130
131 if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
132 printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
133 return -EINVAL;
134 }
135
136 /* check rate of UPLL, and if it is near 96MHz, then change
137 * to using half the UPLL rate for the system */
138
139 if (clk_get_rate(clk_upll) > (94 * MHZ)) {
140 clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
141
142 mutex_lock(&clocks_mutex);
143
144 clkdivn = __raw_readl(S3C2410_CLKDIVN);
145 clkdivn |= S3C2440_CLKDIVN_UCLK;
146 __raw_writel(clkdivn, S3C2410_CLKDIVN);
147
148 mutex_unlock(&clocks_mutex);
149 }
150
151 s3c2442_clk_cam.parent = clk_h;
152 s3c2442_clk_cam_upll.parent = clk_upll;
153
154 s3c24xx_register_clock(&s3c2442_clk_cam);
155 s3c24xx_register_clock(&s3c2442_clk_cam_upll);
156
157 clk_disable(&s3c2442_clk_cam);
158
159 return 0;
160}
161
162static struct sysdev_driver s3c2442_clk_driver = {
163 .add = s3c2442_clk_add,
164};
165
166static __init int s3c2442_clk_init(void)
167{
168 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
169}
170
171arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
new file mode 100644
index 000000000000..debae2430557
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.c
@@ -0,0 +1,52 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Samsung S3C2442 Mobile CPU support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/sysdev.h>
21#include <linux/clk.h>
22
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25#include <asm/mach/irq.h>
26
27#include <asm/hardware.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30
31#include <asm/arch/regs-clock.h>
32#include <asm/arch/regs-serial.h>
33#include <asm/arch/regs-gpio.h>
34#include <asm/arch/regs-gpioj.h>
35#include <asm/arch/regs-dsc.h>
36
37#include "s3c2442.h"
38#include "clock.h"
39#include "devs.h"
40#include "cpu.h"
41#include "pm.h"
42
43static struct sys_device s3c2442_sysdev = {
44 .cls = &s3c2442_sysclass,
45};
46
47int __init s3c2442_init(void)
48{
49 printk("S3C2442: Initialising architecture\n");
50
51 return sysdev_register(&s3c2442_sysdev);
52}
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/arch/arm/mach-s3c2410/s3c2442.h
new file mode 100644
index 000000000000..0ae37d24866c
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.h
@@ -0,0 +1,17 @@
1/* arch/arm/mach-s3c2410/s3c2442.h
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for s3c2442 cpu support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifdef CONFIG_CPU_S3C2442
14extern int s3c2442_init(void);
15#else
16#define s3c2442_init NULL
17#endif
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
new file mode 100644
index 000000000000..2aadca1ce7eb
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x-irq.c
@@ -0,0 +1,142 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
2 *
3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Changelog:
21 * 25-Jul-2005 BJD Split from irq.c
22 *
23*/
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/interrupt.h>
28#include <linux/ioport.h>
29#include <linux/ptrace.h>
30#include <linux/sysdev.h>
31
32#include <asm/hardware.h>
33#include <asm/irq.h>
34#include <asm/io.h>
35
36#include <asm/mach/irq.h>
37
38#include <asm/arch/regs-irq.h>
39#include <asm/arch/regs-gpio.h>
40
41#include "cpu.h"
42#include "pm.h"
43#include "irq.h"
44
45/* camera irq */
46
47static void s3c_irq_demux_cam(unsigned int irq,
48 struct irqdesc *desc,
49 struct pt_regs *regs)
50{
51 unsigned int subsrc, submsk;
52 struct irqdesc *mydesc;
53
54 /* read the current pending interrupts, and the mask
55 * for what it is available */
56
57 subsrc = __raw_readl(S3C2410_SUBSRCPND);
58 submsk = __raw_readl(S3C2410_INTSUBMSK);
59
60 subsrc &= ~submsk;
61 subsrc >>= 11;
62 subsrc &= 3;
63
64 if (subsrc != 0) {
65 if (subsrc & 1) {
66 mydesc = irq_desc + IRQ_S3C2440_CAM_C;
67 desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
68 }
69 if (subsrc & 2) {
70 mydesc = irq_desc + IRQ_S3C2440_CAM_P;
71 desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
72 }
73 }
74}
75
76#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
77
78static void
79s3c_irq_cam_mask(unsigned int irqno)
80{
81 s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
82}
83
84static void
85s3c_irq_cam_unmask(unsigned int irqno)
86{
87 s3c_irqsub_unmask(irqno, INTMSK_CAM);
88}
89
90static void
91s3c_irq_cam_ack(unsigned int irqno)
92{
93 s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
94}
95
96static struct irqchip s3c_irq_cam = {
97 .mask = s3c_irq_cam_mask,
98 .unmask = s3c_irq_cam_unmask,
99 .ack = s3c_irq_cam_ack,
100};
101
102static int s3c244x_irq_add(struct sys_device *sysdev)
103{
104 unsigned int irqno;
105
106 set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
107 set_irq_handler(IRQ_NFCON, do_level_IRQ);
108 set_irq_flags(IRQ_NFCON, IRQF_VALID);
109
110 /* add chained handler for camera */
111
112 set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
113 set_irq_handler(IRQ_CAM, do_level_IRQ);
114 set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
115
116 for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
117 set_irq_chip(irqno, &s3c_irq_cam);
118 set_irq_handler(irqno, do_level_IRQ);
119 set_irq_flags(irqno, IRQF_VALID);
120 }
121
122 return 0;
123}
124
125static struct sysdev_driver s3c244x_irq_driver = {
126 .add = s3c244x_irq_add,
127};
128
129static int s3c2440_irq_init(void)
130{
131 return sysdev_driver_register(&s3c2440_sysclass, &s3c244x_irq_driver);
132}
133
134arch_initcall(s3c2440_irq_init);
135
136
137static int s3c2442_irq_init(void)
138{
139 return sysdev_driver_register(&s3c2442_sysclass, &s3c244x_irq_driver);
140}
141
142arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c
new file mode 100644
index 000000000000..96852a7000db
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.c
@@ -0,0 +1,182 @@
1/* linux/arch/arm/mach-s3c2410/s3c244x.c
2 *
3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Samsung S3C2440 and S3C2442 Mobile CPU support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/sysdev.h>
21#include <linux/clk.h>
22
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25#include <asm/mach/irq.h>
26
27#include <asm/hardware.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30
31#include <asm/arch/regs-clock.h>
32#include <asm/arch/regs-serial.h>
33#include <asm/arch/regs-gpio.h>
34#include <asm/arch/regs-gpioj.h>
35#include <asm/arch/regs-dsc.h>
36
37#include "s3c2440.h"
38#include "s3c244x.h"
39#include "clock.h"
40#include "devs.h"
41#include "cpu.h"
42#include "pm.h"
43
44static struct map_desc s3c244x_iodesc[] __initdata = {
45 IODESC_ENT(CLKPWR),
46 IODESC_ENT(TIMER),
47 IODESC_ENT(WATCHDOG),
48 IODESC_ENT(LCD),
49 IODESC_ENT(ADC),
50 IODESC_ENT(USBHOST),
51};
52
53/* uart initialisation */
54
55void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
56{
57 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
58}
59
60void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
61{
62 /* register our io-tables */
63
64 iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
65 iotable_init(mach_desc, size);
66
67 /* rename any peripherals used differing from the s3c2410 */
68
69 s3c_device_i2c.name = "s3c2440-i2c";
70 s3c_device_nand.name = "s3c2440-nand";
71}
72
73void __init s3c244x_init_clocks(int xtal)
74{
75 unsigned long clkdiv;
76 unsigned long camdiv;
77 unsigned long hclk, fclk, pclk;
78 int hdiv = 1;
79
80 /* now we've got our machine bits initialised, work out what
81 * clocks we've got */
82
83 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
84
85 clkdiv = __raw_readl(S3C2410_CLKDIVN);
86 camdiv = __raw_readl(S3C2440_CAMDIVN);
87
88 /* work out clock scalings */
89
90 switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
91 case S3C2440_CLKDIVN_HDIVN_1:
92 hdiv = 1;
93 break;
94
95 case S3C2440_CLKDIVN_HDIVN_2:
96 hdiv = 2;
97 break;
98
99 case S3C2440_CLKDIVN_HDIVN_4_8:
100 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
101 break;
102
103 case S3C2440_CLKDIVN_HDIVN_3_6:
104 hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
105 break;
106 }
107
108 hclk = fclk / hdiv;
109 pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
110
111 /* print brief summary of clocks, etc */
112
113 printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
114 print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
115
116 /* initialise the clocks here, to allow other things like the
117 * console to use them, and to add new ones after the initialisation
118 */
119
120 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
121}
122
123#ifdef CONFIG_PM
124
125static struct sleep_save s3c244x_sleep[] = {
126 SAVE_ITEM(S3C2440_DSC0),
127 SAVE_ITEM(S3C2440_DSC1),
128 SAVE_ITEM(S3C2440_GPJDAT),
129 SAVE_ITEM(S3C2440_GPJCON),
130 SAVE_ITEM(S3C2440_GPJUP)
131};
132
133static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
134{
135 s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
136 return 0;
137}
138
139static int s3c244x_resume(struct sys_device *dev)
140{
141 s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
142 return 0;
143}
144
145#else
146#define s3c244x_suspend NULL
147#define s3c244x_resume NULL
148#endif
149
150/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
151
152struct sysdev_class s3c2440_sysclass = {
153 set_kset_name("s3c2440-core"),
154 .suspend = s3c244x_suspend,
155 .resume = s3c244x_resume
156};
157
158struct sysdev_class s3c2442_sysclass = {
159 set_kset_name("s3c2442-core"),
160 .suspend = s3c244x_suspend,
161 .resume = s3c244x_resume
162};
163
164/* need to register class before we actually register the device, and
165 * we also need to ensure that it has been initialised before any of the
166 * drivers even try to use it (even if not on an s3c2440 based system)
167 * as a driver which may support both 2410 and 2440 may try and use it.
168*/
169
170static int __init s3c2440_core_init(void)
171{
172 return sysdev_class_register(&s3c2440_sysclass);
173}
174
175core_initcall(s3c2440_core_init);
176
177static int __init s3c2442_core_init(void)
178{
179 return sysdev_class_register(&s3c2442_sysclass);
180}
181
182core_initcall(s3c2442_core_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/mach-s3c2410/s3c244x.h
new file mode 100644
index 000000000000..3e7f5f75134d
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.h
@@ -0,0 +1,25 @@
1/* arch/arm/mach-s3c2410/s3c2440.h
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for S3C2440 and S3C2442 cpu support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
14
15extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
16
17extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
18
19extern void s3c244x_init_clocks(int xtal);
20
21#else
22#define s3c244x_init_clocks NULL
23#define s3c244x_init_uarts NULL
24#define s3c244x_map_io NULL
25#endif
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 73de2eaca22a..5f6761ed96b2 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -66,7 +66,9 @@ ENTRY(s3c2410_cpu_suspend)
66 @@ flush the caches to ensure everything is back out to 66 @@ flush the caches to ensure everything is back out to
67 @@ SDRAM before the core powers down 67 @@ SDRAM before the core powers down
68 68
69#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
69 bl arm920_flush_kern_cache_all 70 bl arm920_flush_kern_cache_all
71#endif
70 72
71 @@ prepare cpu to sleep 73 @@ prepare cpu to sleep
72 74
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c55b739e10ba..1ff2f073a55d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -121,8 +121,8 @@ config CPU_ARM925T
121# ARM926T 121# ARM926T
122config CPU_ARM926T 122config CPU_ARM926T
123 bool "Support ARM926T processor" 123 bool "Support ARM926T processor"
124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB 124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008
125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX 125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008
126 select CPU_32v5 126 select CPU_32v5
127 select CPU_ABRT_EV5TJ 127 select CPU_ABRT_EV5TJ
128 select CPU_CACHE_VIVT 128 select CPU_CACHE_VIVT
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index fc0f0b085ca7..166cb09cae4c 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -69,7 +69,7 @@ static void insert_phys_mapping(struct phys_desc *desc)
69 panic("Physical remapping for %p already present", 69 panic("Physical remapping for %p already present",
70 desc->virt); 70 desc->virt);
71 71
72 rb_link_node(&desc->rb, (*n)->rb_parent, n); 72 rb_link_node(&desc->rb, rb_parent(*n), n);
73 rb_insert_color(&desc->rb, &phys_mappings); 73 rb_insert_color(&desc->rb, &phys_mappings);
74} 74}
75 75
diff --git a/block/as-iosched.c b/block/as-iosched.c
index a7caf35ca0c2..0c750393be4a 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -353,10 +353,9 @@ static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
353/* 353/*
354 * rb tree support functions 354 * rb tree support functions
355 */ 355 */
356#define RB_NONE (2)
357#define RB_EMPTY(root) ((root)->rb_node == NULL) 356#define RB_EMPTY(root) ((root)->rb_node == NULL)
358#define ON_RB(node) ((node)->rb_color != RB_NONE) 357#define ON_RB(node) (rb_parent(node) != node)
359#define RB_CLEAR(node) ((node)->rb_color = RB_NONE) 358#define RB_CLEAR(node) (rb_set_parent(node, node))
360#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node) 359#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node)
361#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync]) 360#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync])
362#define rq_rb_key(rq) (rq)->sector 361#define rq_rb_key(rq) (rq)->sector
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 052b17487625..6200d9b9af28 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -60,14 +60,9 @@ static DEFINE_SPINLOCK(cfq_exit_lock);
60/* 60/*
61 * rb-tree defines 61 * rb-tree defines
62 */ 62 */
63#define RB_NONE (2)
64#define RB_EMPTY(node) ((node)->rb_node == NULL) 63#define RB_EMPTY(node) ((node)->rb_node == NULL)
65#define RB_CLEAR_COLOR(node) (node)->rb_color = RB_NONE
66#define RB_CLEAR(node) do { \ 64#define RB_CLEAR(node) do { \
67 (node)->rb_parent = NULL; \ 65 memset(node, 0, sizeof(*node)); \
68 RB_CLEAR_COLOR((node)); \
69 (node)->rb_right = NULL; \
70 (node)->rb_left = NULL; \
71} while (0) 66} while (0)
72#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL) 67#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
73#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node) 68#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
@@ -567,7 +562,6 @@ static inline void cfq_del_crq_rb(struct cfq_rq *crq)
567 cfq_update_next_crq(crq); 562 cfq_update_next_crq(crq);
568 563
569 rb_erase(&crq->rb_node, &cfqq->sort_list); 564 rb_erase(&crq->rb_node, &cfqq->sort_list);
570 RB_CLEAR_COLOR(&crq->rb_node);
571 565
572 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list)) 566 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
573 cfq_del_cfqq_rr(cfqd, cfqq); 567 cfq_del_cfqq_rr(cfqd, cfqq);
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index 3bd0415a9828..c94de8e12fbf 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -165,10 +165,9 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
165/* 165/*
166 * rb tree support functions 166 * rb tree support functions
167 */ 167 */
168#define RB_NONE (2)
169#define RB_EMPTY(root) ((root)->rb_node == NULL) 168#define RB_EMPTY(root) ((root)->rb_node == NULL)
170#define ON_RB(node) ((node)->rb_color != RB_NONE) 169#define ON_RB(node) (rb_parent(node) != node)
171#define RB_CLEAR(node) ((node)->rb_color = RB_NONE) 170#define RB_CLEAR(node) (rb_set_parent(node, node))
172#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node) 171#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node)
173#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)]) 172#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)])
174#define rq_rb_key(rq) (rq)->sector 173#define rq_rb_key(rq) (rq)->sector
diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h
index 5818a8aa46e0..6e63f8b2c479 100644
--- a/drivers/char/rio/daemon.h
+++ b/drivers/char/rio/daemon.h
@@ -51,7 +51,7 @@ struct Error {
51}; 51};
52 52
53struct DownLoad { 53struct DownLoad {
54 char *DataP; 54 char __user *DataP;
55 unsigned int Count; 55 unsigned int Count;
56 unsigned int ProductCode; 56 unsigned int ProductCode;
57}; 57};
@@ -83,18 +83,18 @@ struct PortSetup {
83struct LpbReq { 83struct LpbReq {
84 unsigned int Host; 84 unsigned int Host;
85 unsigned int Link; 85 unsigned int Link;
86 struct LPB *LpbP; 86 struct LPB __user *LpbP;
87}; 87};
88 88
89struct RupReq { 89struct RupReq {
90 unsigned int HostNum; 90 unsigned int HostNum;
91 unsigned int RupNum; 91 unsigned int RupNum;
92 struct RUP *RupP; 92 struct RUP __user *RupP;
93}; 93};
94 94
95struct PortReq { 95struct PortReq {
96 unsigned int SysPort; 96 unsigned int SysPort;
97 struct Port *PortP; 97 struct Port __user *PortP;
98}; 98};
99 99
100struct StreamInfo { 100struct StreamInfo {
@@ -105,12 +105,12 @@ struct StreamInfo {
105 105
106struct HostReq { 106struct HostReq {
107 unsigned int HostNum; 107 unsigned int HostNum;
108 struct Host *HostP; 108 struct Host __user *HostP;
109}; 109};
110 110
111struct HostDpRam { 111struct HostDpRam {
112 unsigned int HostNum; 112 unsigned int HostNum;
113 struct DpRam *DpRamP; 113 struct DpRam __user *DpRamP;
114}; 114};
115 115
116struct DebugCtrl { 116struct DebugCtrl {
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index e64fe9912394..6b039186856d 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -46,7 +46,7 @@ int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
46int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); 46int RIOBootCodeHOST(struct rio_info *, struct DownLoad *);
47int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *); 47int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *);
48void msec_timeout(struct Host *); 48void msec_timeout(struct Host *);
49int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT *); 49int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
50int RIOBootOk(struct rio_info *, struct Host *, unsigned long); 50int RIOBootOk(struct rio_info *, struct Host *, unsigned long);
51int RIORtaBound(struct rio_info *, unsigned int); 51int RIORtaBound(struct rio_info *, unsigned int);
52void rio_fill_host_slot(int, int, unsigned int, struct Host *); 52void rio_fill_host_slot(int, int, unsigned int, struct Host *);
@@ -55,8 +55,8 @@ void rio_fill_host_slot(int, int, unsigned int, struct Host *);
55int RIOFoadRta(struct Host *, struct Map *); 55int RIOFoadRta(struct Host *, struct Map *);
56int RIOZombieRta(struct Host *, struct Map *); 56int RIOZombieRta(struct Host *, struct Map *);
57int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *)); 57int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *));
58int RIOIdentifyRta(struct rio_info *, void *); 58int RIOIdentifyRta(struct rio_info *, void __user *);
59int RIOKillNeighbour(struct rio_info *, void *); 59int RIOKillNeighbour(struct rio_info *, void __user *);
60int RIOSuspendBootRta(struct Host *, int, int); 60int RIOSuspendBootRta(struct Host *, int, int);
61int RIOFoadWakeup(struct rio_info *); 61int RIOFoadWakeup(struct rio_info *);
62struct CmdBlk *RIOGetCmdBlk(void); 62struct CmdBlk *RIOGetCmdBlk(void);
@@ -68,7 +68,8 @@ int RIORFlushEnable(unsigned long, struct CmdBlk *);
68int RIOUnUse(unsigned long, struct CmdBlk *); 68int RIOUnUse(unsigned long, struct CmdBlk *);
69 69
70/* rioctrl.c */ 70/* rioctrl.c */
71int riocontrol(struct rio_info *, dev_t, int, caddr_t, int); 71int riocontrol(struct rio_info *, dev_t, int, unsigned long, int);
72
72int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char); 73int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char);
73 74
74/* rioinit.c */ 75/* rioinit.c */
@@ -77,13 +78,13 @@ void RIOInitHosts(struct rio_info *, struct RioHostInfo *);
77void RIOISAinit(struct rio_info *, int); 78void RIOISAinit(struct rio_info *, int);
78int RIODoAT(struct rio_info *, int, int); 79int RIODoAT(struct rio_info *, int, int);
79caddr_t RIOCheckForATCard(int); 80caddr_t RIOCheckForATCard(int);
80int RIOAssignAT(struct rio_info *, int, caddr_t, int); 81int RIOAssignAT(struct rio_info *, int, void __iomem *, int);
81int RIOBoardTest(unsigned long, caddr_t, unsigned char, int); 82int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int);
82void RIOAllocDataStructs(struct rio_info *); 83void RIOAllocDataStructs(struct rio_info *);
83void RIOSetupDataStructs(struct rio_info *); 84void RIOSetupDataStructs(struct rio_info *);
84int RIODefaultName(struct rio_info *, struct Host *, unsigned int); 85int RIODefaultName(struct rio_info *, struct Host *, unsigned int);
85struct rioVersion *RIOVersid(void); 86struct rioVersion *RIOVersid(void);
86void RIOHostReset(unsigned int, struct DpRam *, unsigned int); 87void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int);
87 88
88/* riointr.c */ 89/* riointr.c */
89void RIOTxEnable(char *); 90void RIOTxEnable(char *);
@@ -95,14 +96,14 @@ int RIOParam(struct Port *, int, int, int);
95int RIODelay(struct Port *PortP, int); 96int RIODelay(struct Port *PortP, int);
96int RIODelay_ni(struct Port *PortP, int); 97int RIODelay_ni(struct Port *PortP, int);
97void ms_timeout(struct Port *); 98void ms_timeout(struct Port *);
98int can_add_transmit(struct PKT **, struct Port *); 99int can_add_transmit(struct PKT __iomem **, struct Port *);
99void add_transmit(struct Port *); 100void add_transmit(struct Port *);
100void put_free_end(struct Host *, struct PKT *); 101void put_free_end(struct Host *, struct PKT __iomem *);
101int can_remove_receive(struct PKT **, struct Port *); 102int can_remove_receive(struct PKT __iomem **, struct Port *);
102void remove_receive(struct Port *); 103void remove_receive(struct Port *);
103 104
104/* rioroute.c */ 105/* rioroute.c */
105int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT *); 106int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
106void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int); 107void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int);
107unsigned int GetUnitType(unsigned int); 108unsigned int GetUnitType(unsigned int);
108int RIOSetChange(struct rio_info *); 109int RIOSetChange(struct rio_info *);
@@ -139,7 +140,7 @@ int rio_isr_thread(char *);
139struct rio_info *rio_info_store(int cmd, struct rio_info *p); 140struct rio_info *rio_info_store(int cmd, struct rio_info *p);
140#endif 141#endif
141 142
142extern void rio_copy_to_card(void *to, void *from, int len); 143extern void rio_copy_to_card(void *from, void __iomem *to, int len);
143extern int rio_minor(struct tty_struct *tty); 144extern int rio_minor(struct tty_struct *tty);
144extern int rio_ismodem(struct tty_struct *tty); 145extern int rio_ismodem(struct tty_struct *tty);
145 146
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h
index 179cdbea712b..ee2ddea7a63a 100644
--- a/drivers/char/rio/host.h
+++ b/drivers/char/rio/host.h
@@ -48,8 +48,8 @@ struct Host {
48 unsigned char Ivec; /* POLLED or ivec number */ 48 unsigned char Ivec; /* POLLED or ivec number */
49 unsigned char Mode; /* Control stuff */ 49 unsigned char Mode; /* Control stuff */
50 unsigned char Slot; /* Slot */ 50 unsigned char Slot; /* Slot */
51 caddr_t Caddr; /* KV address of DPRAM */ 51 void __iomem *Caddr; /* KV address of DPRAM */
52 struct DpRam *CardP; /* KV address of DPRAM, with overlay */ 52 struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */
53 unsigned long PaddrP; /* Phys. address of DPRAM */ 53 unsigned long PaddrP; /* Phys. address of DPRAM */
54 char Name[MAX_NAME_LEN]; /* The name of the host */ 54 char Name[MAX_NAME_LEN]; /* The name of the host */
55 unsigned int UniqueNum; /* host unique number */ 55 unsigned int UniqueNum; /* host unique number */
@@ -57,7 +57,7 @@ struct Host {
57 unsigned int WorkToBeDone; /* set to true each interrupt */ 57 unsigned int WorkToBeDone; /* set to true each interrupt */
58 unsigned int InIntr; /* Being serviced? */ 58 unsigned int InIntr; /* Being serviced? */
59 unsigned int IntSrvDone; /* host's interrupt has been serviced */ 59 unsigned int IntSrvDone; /* host's interrupt has been serviced */
60 void (*Copy) (void *, void *, int); /* copy func */ 60 void (*Copy) (void *, void __iomem *, int); /* copy func */
61 struct timer_list timer; 61 struct timer_list timer;
62 /* 62 /*
63 ** I M P O R T A N T ! 63 ** I M P O R T A N T !
@@ -83,11 +83,11 @@ struct Host {
83 83
84 struct Top Topology[LINKS_PER_UNIT]; /* one per link */ 84 struct Top Topology[LINKS_PER_UNIT]; /* one per link */
85 struct Map Mapping[MAX_RUP]; /* Mappings for host */ 85 struct Map Mapping[MAX_RUP]; /* Mappings for host */
86 struct PHB *PhbP; /* Pointer to the PHB array */ 86 struct PHB __iomem *PhbP; /* Pointer to the PHB array */
87 unsigned short *PhbNumP; /* Ptr to Number of PHB's */ 87 unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */
88 struct LPB *LinkStrP; /* Link Structure Array */ 88 struct LPB __iomem *LinkStrP; /* Link Structure Array */
89 struct RUP *RupP; /* Sixteen real rups here */ 89 struct RUP __iomem *RupP; /* Sixteen real rups here */
90 struct PARM_MAP *ParmMapP; /* points to the parmmap */ 90 struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */
91 unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */ 91 unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */
92 unsigned int NumExtraBooted; /* how many of the above */ 92 unsigned int NumExtraBooted; /* how many of the above */
93 /* 93 /*
diff --git a/drivers/char/rio/port.h b/drivers/char/rio/port.h
index 9b5fa3eb0402..49cf6d15ee54 100644
--- a/drivers/char/rio/port.h
+++ b/drivers/char/rio/port.h
@@ -40,7 +40,7 @@ struct Port {
40 struct gs_port gs; 40 struct gs_port gs;
41 int PortNum; /* RIO port no., 0-511 */ 41 int PortNum; /* RIO port no., 0-511 */
42 struct Host *HostP; 42 struct Host *HostP;
43 caddr_t Caddr; 43 void __iomem *Caddr;
44 unsigned short HostPort; /* Port number on host card */ 44 unsigned short HostPort; /* Port number on host card */
45 unsigned char RupNum; /* Number of RUP for port */ 45 unsigned char RupNum; /* Number of RUP for port */
46 unsigned char ID2; /* Second ID of RTA for port */ 46 unsigned char ID2; /* Second ID of RTA for port */
@@ -92,13 +92,13 @@ struct Port {
92#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */ 92#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */
93 93
94 94
95 struct PHB *PhbP; /* pointer to PHB for port */ 95 struct PHB __iomem *PhbP; /* pointer to PHB for port */
96 u16 *TxAdd; /* Add packets here */ 96 u16 __iomem *TxAdd; /* Add packets here */
97 u16 *TxStart; /* Start of add array */ 97 u16 __iomem *TxStart; /* Start of add array */
98 u16 *TxEnd; /* End of add array */ 98 u16 __iomem *TxEnd; /* End of add array */
99 u16 *RxRemove; /* Remove packets here */ 99 u16 __iomem *RxRemove; /* Remove packets here */
100 u16 *RxStart; /* Start of remove array */ 100 u16 __iomem *RxStart; /* Start of remove array */
101 u16 *RxEnd; /* End of remove array */ 101 u16 __iomem *RxEnd; /* End of remove array */
102 unsigned int RtaUniqueNum; /* Unique number of RTA */ 102 unsigned int RtaUniqueNum; /* Unique number of RTA */
103 unsigned short PortState; /* status of port */ 103 unsigned short PortState; /* status of port */
104 unsigned short ModemState; /* status of modem lines */ 104 unsigned short ModemState; /* status of modem lines */
diff --git a/drivers/char/rio/rio.h b/drivers/char/rio/rio.h
index b4c91871ba28..1bf36223a4e8 100644
--- a/drivers/char/rio/rio.h
+++ b/drivers/char/rio/rio.h
@@ -129,8 +129,8 @@
129** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and 129** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and
130** returns the offset into the DP RAM area. 130** returns the offset into the DP RAM area.
131*/ 131*/
132#define RIO_PTR(C,O) (((unsigned char *)(C))+(0xFFFF&(O))) 132#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O)))
133#define RIO_OFF(C,O) ((long)(O)-(long)(C)) 133#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C))
134 134
135/* 135/*
136** How to convert from various different device number formats: 136** How to convert from various different device number formats:
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 78dd856534ce..aa43436d5d1b 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -333,9 +333,9 @@ int RIODelay_ni(struct Port *PortP, int njiffies)
333 return !RIO_FAIL; 333 return !RIO_FAIL;
334} 334}
335 335
336void rio_copy_to_card(void *to, void *from, int len) 336void rio_copy_to_card(void *from, void __iomem *to, int len)
337{ 337{
338 rio_memcpy_toio(NULL, to, from, len); 338 rio_copy_toio(to, from, len);
339} 339}
340 340
341int rio_minor(struct tty_struct *tty) 341int rio_minor(struct tty_struct *tty)
@@ -573,7 +573,7 @@ static int rio_fw_ioctl(struct inode *inode, struct file *filp, unsigned int cmd
573 func_enter(); 573 func_enter();
574 574
575 /* The "dev" argument isn't used. */ 575 /* The "dev" argument isn't used. */
576 rc = riocontrol(p, 0, cmd, (void *) arg, capable(CAP_SYS_ADMIN)); 576 rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN));
577 577
578 func_exit(); 578 func_exit();
579 return rc; 579 return rc;
@@ -583,6 +583,7 @@ extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command,
583 583
584static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) 584static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
585{ 585{
586 void __user *argp = (void __user *)arg;
586 int rc; 587 int rc;
587 struct Port *PortP; 588 struct Port *PortP;
588 int ival; 589 int ival;
@@ -594,14 +595,14 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
594 rc = 0; 595 rc = 0;
595 switch (cmd) { 596 switch (cmd) {
596 case TIOCSSOFTCAR: 597 case TIOCSSOFTCAR:
597 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) { 598 if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) {
598 tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); 599 tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0);
599 } 600 }
600 break; 601 break;
601 case TIOCGSERIAL: 602 case TIOCGSERIAL:
602 rc = -EFAULT; 603 rc = -EFAULT;
603 if (access_ok(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) 604 if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct)))
604 rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg); 605 rc = gs_getserial(&PortP->gs, argp);
605 break; 606 break;
606 case TCSBRK: 607 case TCSBRK:
607 if (PortP->State & RIO_DELETED) { 608 if (PortP->State & RIO_DELETED) {
@@ -631,8 +632,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
631 break; 632 break;
632 case TIOCSSERIAL: 633 case TIOCSSERIAL:
633 rc = -EFAULT; 634 rc = -EFAULT;
634 if (access_ok(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) 635 if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct)))
635 rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg); 636 rc = gs_setserial(&PortP->gs, argp);
636 break; 637 break;
637 default: 638 default:
638 rc = -ENOIOCTLCMD; 639 rc = -ENOIOCTLCMD;
@@ -919,7 +920,7 @@ static void __exit rio_release_drivers(void)
919static void fix_rio_pci(struct pci_dev *pdev) 920static void fix_rio_pci(struct pci_dev *pdev)
920{ 921{
921 unsigned long hwbase; 922 unsigned long hwbase;
922 unsigned char *rebase; 923 unsigned char __iomem *rebase;
923 unsigned int t; 924 unsigned int t;
924 925
925#define CNTRL_REG_OFFSET 0x50 926#define CNTRL_REG_OFFSET 0x50
@@ -999,7 +1000,7 @@ static int __init rio_init(void)
999 if (((1 << hp->Ivec) & rio_irqmask) == 0) 1000 if (((1 << hp->Ivec) & rio_irqmask) == 0)
1000 hp->Ivec = 0; 1001 hp->Ivec = 0;
1001 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); 1002 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1002 hp->CardP = (struct DpRam *) hp->Caddr; 1003 hp->CardP = (struct DpRam __iomem *) hp->Caddr;
1003 hp->Type = RIO_PCI; 1004 hp->Type = RIO_PCI;
1004 hp->Copy = rio_copy_to_card; 1005 hp->Copy = rio_copy_to_card;
1005 hp->Mode = RIO_PCI_BOOT_FROM_RAM; 1006 hp->Mode = RIO_PCI_BOOT_FROM_RAM;
@@ -1021,7 +1022,7 @@ static int __init rio_init(void)
1021 p->RIONumHosts++; 1022 p->RIONumHosts++;
1022 found++; 1023 found++;
1023 } else { 1024 } else {
1024 iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr)); 1025 iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
1025 } 1026 }
1026 } 1027 }
1027 1028
@@ -1047,7 +1048,7 @@ static int __init rio_init(void)
1047 hp->Ivec = 0; 1048 hp->Ivec = 0;
1048 hp->Ivec |= 0x8000; /* Mark as non-sharable */ 1049 hp->Ivec |= 0x8000; /* Mark as non-sharable */
1049 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); 1050 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1050 hp->CardP = (struct DpRam *) hp->Caddr; 1051 hp->CardP = (struct DpRam __iomem *) hp->Caddr;
1051 hp->Type = RIO_PCI; 1052 hp->Type = RIO_PCI;
1052 hp->Copy = rio_copy_to_card; 1053 hp->Copy = rio_copy_to_card;
1053 hp->Mode = RIO_PCI_BOOT_FROM_RAM; 1054 hp->Mode = RIO_PCI_BOOT_FROM_RAM;
@@ -1070,7 +1071,7 @@ static int __init rio_init(void)
1070 p->RIONumHosts++; 1071 p->RIONumHosts++;
1071 found++; 1072 found++;
1072 } else { 1073 } else {
1073 iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr)); 1074 iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
1074 } 1075 }
1075#else 1076#else
1076 printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); 1077 printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n");
@@ -1085,7 +1086,7 @@ static int __init rio_init(void)
1085 /* There was something about the IRQs of these cards. 'Forget what.--REW */ 1086 /* There was something about the IRQs of these cards. 'Forget what.--REW */
1086 hp->Ivec = 0; 1087 hp->Ivec = 0;
1087 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); 1088 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1088 hp->CardP = (struct DpRam *) hp->Caddr; 1089 hp->CardP = (struct DpRam __iomem *) hp->Caddr;
1089 hp->Type = RIO_AT; 1090 hp->Type = RIO_AT;
1090 hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL 1091 hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL
1091 * -- YES! this is now a normal copy. Only the 1092 * -- YES! this is now a normal copy. Only the
@@ -1111,7 +1112,7 @@ static int __init rio_init(void)
1111 } 1112 }
1112 1113
1113 if (!okboard) 1114 if (!okboard)
1114 iounmap((char *) (hp->Caddr)); 1115 iounmap(hp->Caddr);
1115 } 1116 }
1116 } 1117 }
1117 1118
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h
index 4ce77fb1fae5..55b9c97e8477 100644
--- a/drivers/char/rio/rio_linux.h
+++ b/drivers/char/rio/rio_linux.h
@@ -131,9 +131,9 @@ struct vpd_prom {
131 131
132 132
133#ifdef CONFIG_RIO_OLDPCI 133#ifdef CONFIG_RIO_OLDPCI
134static inline void *rio_memcpy_toio(void *dummy, void *dest, void *source, int n) 134static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n)
135{ 135{
136 char *dst = dest; 136 char __iomem *dst = dest;
137 char *src = source; 137 char *src = source;
138 138
139 while (n--) { 139 while (n--) {
@@ -144,11 +144,22 @@ static inline void *rio_memcpy_toio(void *dummy, void *dest, void *source, int n
144 return dest; 144 return dest;
145} 145}
146 146
147static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n)
148{
149 char __iomem *dst = dest;
150 char *src = source;
151
152 while (n--)
153 writeb(*src++, dst++);
147 154
148static inline void *rio_memcpy_fromio(void *dest, void *source, int n) 155 return dest;
156}
157
158
159static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n)
149{ 160{
150 char *dst = dest; 161 char *dst = dest;
151 char *src = source; 162 char __iomem *src = source;
152 163
153 while (n--) 164 while (n--)
154 *dst++ = readb(src++); 165 *dst++ = readb(src++);
@@ -158,6 +169,7 @@ static inline void *rio_memcpy_fromio(void *dest, void *source, int n)
158 169
159#else 170#else
160#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) 171#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n)
172#define rio_copy_toio memcpy_toio
161#define rio_memcpy_fromio memcpy_fromio 173#define rio_memcpy_fromio memcpy_fromio
162#endif 174#endif
163 175
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
index 290143addd34..eca2b95343e2 100644
--- a/drivers/char/rio/rioboot.c
+++ b/drivers/char/rio/rioboot.c
@@ -71,7 +71,7 @@
71#include "cmdblk.h" 71#include "cmdblk.h"
72#include "route.h" 72#include "route.h"
73 73
74static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd *PktCmdP); 74static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP);
75 75
76static const unsigned char RIOAtVec2Ctrl[] = { 76static const unsigned char RIOAtVec2Ctrl[] = {
77 /* 0 */ INTERRUPT_DISABLE, 77 /* 0 */ INTERRUPT_DISABLE,
@@ -204,13 +204,13 @@ void rio_start_card_running(struct Host *HostP)
204int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) 204int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
205{ 205{
206 struct Host *HostP; 206 struct Host *HostP;
207 u8 *Cad; 207 u8 __iomem *Cad;
208 PARM_MAP *ParmMapP; 208 PARM_MAP __iomem *ParmMapP;
209 int RupN; 209 int RupN;
210 int PortN; 210 int PortN;
211 unsigned int host; 211 unsigned int host;
212 u8 *StartP; 212 u8 __iomem *StartP;
213 u8 *DestP; 213 u8 __iomem *DestP;
214 int wait_count; 214 int wait_count;
215 u16 OldParmMap; 215 u16 OldParmMap;
216 u16 offset; /* It is very important that this is a u16 */ 216 u16 offset; /* It is very important that this is a u16 */
@@ -262,7 +262,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
262 ** Ensure that the host really is stopped. 262 ** Ensure that the host really is stopped.
263 ** Disable it's external bus & twang its reset line. 263 ** Disable it's external bus & twang its reset line.
264 */ 264 */
265 RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot); 265 RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot);
266 266
267 /* 267 /*
268 ** Copy the data directly from user space to the SRAM. 268 ** Copy the data directly from user space to the SRAM.
@@ -280,7 +280,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
280 func_exit(); 280 func_exit();
281 return -ENOMEM; 281 return -ENOMEM;
282 } 282 }
283 if (copy_from_user(rbp->DataP, DownCode, rbp->Count)) { 283 if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) {
284 kfree(DownCode); 284 kfree(DownCode);
285 p->RIOError.Error = COPYIN_FAILED; 285 p->RIOError.Error = COPYIN_FAILED;
286 func_exit(); 286 func_exit();
@@ -366,7 +366,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
366 ** a short branch to 0x7FF8, where a long branch is coded. 366 ** a short branch to 0x7FF8, where a long branch is coded.
367 */ 367 */
368 368
369 DestP = (u8 *) &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ 369 DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */
370 370
371#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ 371#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */
372#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ 372#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */
@@ -438,7 +438,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
438 rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); 438 rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
439 HostP->Flags &= ~RUN_STATE; 439 HostP->Flags &= ~RUN_STATE;
440 HostP->Flags |= RC_STUFFED; 440 HostP->Flags |= RC_STUFFED;
441 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot ); 441 RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
442 continue; 442 continue;
443 } 443 }
444 444
@@ -453,9 +453,9 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
453 /* 453 /*
454 ** Grab a 32 bit pointer to the parmmap structure 454 ** Grab a 32 bit pointer to the parmmap structure
455 */ 455 */
456 ParmMapP = (PARM_MAP *) RIO_PTR(Cad, readw(&HostP->__ParmMapR)); 456 ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR));
457 rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); 457 rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP);
458 ParmMapP = (PARM_MAP *) ((unsigned long) Cad + readw(&HostP->__ParmMapR)); 458 ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR));
459 rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); 459 rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP);
460 460
461 /* 461 /*
@@ -468,7 +468,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
468 rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links)); 468 rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links));
469 HostP->Flags &= ~RUN_STATE; 469 HostP->Flags &= ~RUN_STATE;
470 HostP->Flags |= RC_STUFFED; 470 HostP->Flags |= RC_STUFFED;
471 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot ); 471 RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
472 continue; 472 continue;
473 } 473 }
474 474
@@ -491,7 +491,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
491 rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); 491 rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
492 HostP->Flags &= ~RUN_STATE; 492 HostP->Flags &= ~RUN_STATE;
493 HostP->Flags |= RC_STUFFED; 493 HostP->Flags |= RC_STUFFED;
494 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot ); 494 RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
495 continue; 495 continue;
496 } 496 }
497 497
@@ -512,10 +512,10 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
512 ** 32 bit pointers for the driver in ioremap space. 512 ** 32 bit pointers for the driver in ioremap space.
513 */ 513 */
514 HostP->ParmMapP = ParmMapP; 514 HostP->ParmMapP = ParmMapP;
515 HostP->PhbP = (struct PHB *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr)); 515 HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr));
516 HostP->RupP = (struct RUP *) RIO_PTR(Cad, readw(&ParmMapP->rups)); 516 HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups));
517 HostP->PhbNumP = (unsigned short *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr)); 517 HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr));
518 HostP->LinkStrP = (struct LPB *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr)); 518 HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr));
519 519
520 /* 520 /*
521 ** point the UnixRups at the real Rups 521 ** point the UnixRups at the real Rups
@@ -540,7 +540,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
540 for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { 540 for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) {
541 if (p->RIOPortp[PortN]->HostP == HostP) { 541 if (p->RIOPortp[PortN]->HostP == HostP) {
542 struct Port *PortP = p->RIOPortp[PortN]; 542 struct Port *PortP = p->RIOPortp[PortN];
543 struct PHB *PhbP; 543 struct PHB __iomem *PhbP;
544 /* int oldspl; */ 544 /* int oldspl; */
545 545
546 if (!PortP->Mapped) 546 if (!PortP->Mapped)
@@ -551,12 +551,12 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
551 551
552 PortP->PhbP = PhbP; 552 PortP->PhbP = PhbP;
553 553
554 PortP->TxAdd = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_add)); 554 PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add));
555 PortP->TxStart = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_start)); 555 PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start));
556 PortP->TxEnd = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_end)); 556 PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end));
557 PortP->RxRemove = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_remove)); 557 PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove));
558 PortP->RxStart = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_start)); 558 PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start));
559 PortP->RxEnd = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_end)); 559 PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end));
560 560
561 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 561 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
562 /* 562 /*
@@ -601,9 +601,9 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
601 * return 1. If we havent, then return 0. 601 * return 1. If we havent, then return 0.
602 */ 602 */
603 603
604int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT *PacketP) 604int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP)
605{ 605{
606 struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data; 606 struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data;
607 struct PktCmd_M *PktReplyP; 607 struct PktCmd_M *PktReplyP;
608 struct CmdBlk *CmdBlkP; 608 struct CmdBlk *CmdBlkP;
609 unsigned int sequence; 609 unsigned int sequence;
@@ -722,7 +722,7 @@ int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
722 * RtaUniq is the booted RTA. 722 * RtaUniq is the booted RTA.
723 */ 723 */
724 724
725static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd *PktCmdP) 725static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP)
726{ 726{
727 struct Map *MapP = NULL; 727 struct Map *MapP = NULL;
728 struct Map *MapP2 = NULL; 728 struct Map *MapP2 = NULL;
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index e6d2b14b5e65..4df6ab2206a1 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -180,7 +180,7 @@ int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (stru
180} 180}
181 181
182 182
183int RIOIdentifyRta(struct rio_info *p, void * arg) 183int RIOIdentifyRta(struct rio_info *p, void __user * arg)
184{ 184{
185 unsigned int Host; 185 unsigned int Host;
186 186
@@ -245,7 +245,7 @@ int RIOIdentifyRta(struct rio_info *p, void * arg)
245} 245}
246 246
247 247
248int RIOKillNeighbour(struct rio_info *p, void * arg) 248int RIOKillNeighbour(struct rio_info *p, void __user * arg)
249{ 249{
250 uint Host; 250 uint Host;
251 uint ID; 251 uint ID;
@@ -370,9 +370,9 @@ int RIOFoadWakeup(struct rio_info *p)
370/* 370/*
371** Incoming command on the COMMAND_RUP to be processed. 371** Incoming command on the COMMAND_RUP to be processed.
372*/ 372*/
373static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT * PacketP) 373static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP)
374{ 374{
375 struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data; 375 struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data;
376 struct Port *PortP; 376 struct Port *PortP;
377 struct UnixRup *UnixRupP; 377 struct UnixRup *UnixRupP;
378 unsigned short SysPort; 378 unsigned short SysPort;
@@ -407,12 +407,12 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
407 } else 407 } else
408 rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name); 408 rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name);
409 409
410 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", PacketP->dest_unit, PacketP->dest_port); 410 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port));
411 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", PacketP->src_unit, PacketP->src_port); 411 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port));
412 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len, PacketP->len); 412 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len));
413 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control); 413 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control));
414 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum); 414 rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum));
415 rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command); 415 rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command));
416 return 1; 416 return 1;
417 } 417 }
418 PortP = p->RIOPortp[SysPort]; 418 PortP = p->RIOPortp[SysPort];
@@ -601,7 +601,7 @@ int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
601 /* 601 /*
602 ** Whammy! blat that pack! 602 ** Whammy! blat that pack!
603 */ 603 */
604 HostP->Copy((caddr_t) & CmdBlkP->Packet, RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(struct PKT)); 604 HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
605 605
606 /* 606 /*
607 ** place command packet on the pending position. 607 ** place command packet on the pending position.
@@ -655,7 +655,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
655{ 655{
656 struct CmdBlk *CmdBlkP; 656 struct CmdBlk *CmdBlkP;
657 struct UnixRup *UnixRupP; 657 struct UnixRup *UnixRupP;
658 struct PKT *PacketP; 658 struct PKT __iomem *PacketP;
659 unsigned short Rup; 659 unsigned short Rup;
660 unsigned long flags; 660 unsigned long flags;
661 661
@@ -676,7 +676,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
676 if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) { 676 if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) {
677 int FreeMe; 677 int FreeMe;
678 678
679 PacketP = (struct PKT *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt)); 679 PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt));
680 680
681 switch (readb(&PacketP->dest_port)) { 681 switch (readb(&PacketP->dest_port)) {
682 case BOOT_RUP: 682 case BOOT_RUP:
@@ -694,9 +694,9 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
694 */ 694 */
695 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); 695 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
696 FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); 696 FreeMe = RIOCommandRup(p, Rup, HostP, PacketP);
697 if (PacketP->data[5] == MEMDUMP) { 697 if (readb(&PacketP->data[5]) == MEMDUMP) {
698 rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", *(unsigned short *) & (PacketP->data[6])); 698 rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6])));
699 HostP->Copy((caddr_t) & (PacketP->data[8]), (caddr_t) p->RIOMemDump, 32); 699 rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32);
700 } 700 }
701 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); 701 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
702 break; 702 break;
@@ -782,7 +782,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
782 /* 782 /*
783 ** Whammy! blat that pack! 783 ** Whammy! blat that pack!
784 */ 784 */
785 HostP->Copy((caddr_t) & CmdBlkP->Packet, RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(struct PKT)); 785 HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
786 786
787 /* 787 /*
788 ** remove the command from the rup command queue... 788 ** remove the command from the rup command queue...
@@ -824,7 +824,7 @@ int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP)
824int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP) 824int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP)
825{ 825{
826 struct Port *PortP = (struct Port *) iPortP; 826 struct Port *PortP = (struct Port *) iPortP;
827 struct PKT *PacketP; 827 struct PKT __iomem *PacketP;
828 unsigned long flags; 828 unsigned long flags;
829 829
830 rio_spin_lock_irqsave(&PortP->portSem, flags); 830 rio_spin_lock_irqsave(&PortP->portSem, flags);
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index 75b2557c37ec..052e8120a471 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -80,7 +80,7 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
80static struct LpbReq LpbReq; 80static struct LpbReq LpbReq;
81static struct RupReq RupReq; 81static struct RupReq RupReq;
82static struct PortReq PortReq; 82static struct PortReq PortReq;
83static struct HostReq HostReq; 83static struct HostReq HostReq; /* oh really? global? and no locking? */
84static struct HostDpRam HostDpRam; 84static struct HostDpRam HostDpRam;
85static struct DebugCtrl DebugCtrl; 85static struct DebugCtrl DebugCtrl;
86static struct Map MapEnt; 86static struct Map MapEnt;
@@ -126,12 +126,19 @@ static int
126 126
127#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) 127#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
128 128
129int riocontrol(p, dev, cmd, arg, su) 129static int copy_from_io(void __user *to, void __iomem *from, size_t size)
130struct rio_info *p; 130{
131dev_t dev; 131 void *buf = kmalloc(size, GFP_KERNEL);
132int cmd; 132 int res = -ENOMEM;
133caddr_t arg; 133 if (buf) {
134int su; 134 rio_memcpy_fromio(buf, from, size);
135 res = copy_to_user(to, buf, size);
136 kfree(buf);
137 }
138 return res;
139}
140
141int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su)
135{ 142{
136 uint Host; /* leave me unsigned! */ 143 uint Host; /* leave me unsigned! */
137 uint port; /* and me! */ 144 uint port; /* and me! */
@@ -139,9 +146,10 @@ int su;
139 ushort loop; 146 ushort loop;
140 int Entry; 147 int Entry;
141 struct Port *PortP; 148 struct Port *PortP;
142 struct PKT *PacketP; 149 struct PKT __iomem *PacketP;
143 int retval = 0; 150 int retval = 0;
144 unsigned long flags; 151 unsigned long flags;
152 void __user *argp = (void __user *)arg;
145 153
146 func_enter(); 154 func_enter();
147 155
@@ -149,7 +157,7 @@ int su;
149 Host = 0; 157 Host = 0;
150 PortP = NULL; 158 PortP = NULL;
151 159
152 rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, arg); 160 rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp);
153 161
154 switch (cmd) { 162 switch (cmd) {
155 /* 163 /*
@@ -160,11 +168,11 @@ int su;
160 ** otherwise just the specified host card will be changed. 168 ** otherwise just the specified host card will be changed.
161 */ 169 */
162 case RIO_SET_TIMER: 170 case RIO_SET_TIMER:
163 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", (unsigned long)arg); 171 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg);
164 { 172 {
165 int host, value; 173 int host, value;
166 host = ((unsigned long) arg >> 16) & 0x0000FFFF; 174 host = (arg >> 16) & 0x0000FFFF;
167 value = (unsigned long) arg & 0x0000ffff; 175 value = arg & 0x0000ffff;
168 if (host == -1) { 176 if (host == -1) {
169 for (host = 0; host < p->RIONumHosts; host++) { 177 for (host = 0; host < p->RIONumHosts; host++) {
170 if (p->RIOHosts[host].Flags == RC_RUNNING) { 178 if (p->RIOHosts[host].Flags == RC_RUNNING) {
@@ -183,26 +191,26 @@ int su;
183 191
184 case RIO_FOAD_RTA: 192 case RIO_FOAD_RTA:
185 rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); 193 rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
186 return RIOCommandRta(p, (unsigned long)arg, RIOFoadRta); 194 return RIOCommandRta(p, arg, RIOFoadRta);
187 195
188 case RIO_ZOMBIE_RTA: 196 case RIO_ZOMBIE_RTA:
189 rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); 197 rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
190 return RIOCommandRta(p, (unsigned long)arg, RIOZombieRta); 198 return RIOCommandRta(p, arg, RIOZombieRta);
191 199
192 case RIO_IDENTIFY_RTA: 200 case RIO_IDENTIFY_RTA:
193 rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); 201 rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
194 return RIOIdentifyRta(p, arg); 202 return RIOIdentifyRta(p, argp);
195 203
196 case RIO_KILL_NEIGHBOUR: 204 case RIO_KILL_NEIGHBOUR:
197 rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); 205 rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
198 return RIOKillNeighbour(p, arg); 206 return RIOKillNeighbour(p, argp);
199 207
200 case SPECIAL_RUP_CMD: 208 case SPECIAL_RUP_CMD:
201 { 209 {
202 struct CmdBlk *CmdBlkP; 210 struct CmdBlk *CmdBlkP;
203 211
204 rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); 212 rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
205 if (copy_from_user(&SpecialRupCmd, arg, sizeof(SpecialRupCmd))) { 213 if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) {
206 rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); 214 rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
207 p->RIOError.Error = COPYIN_FAILED; 215 p->RIOError.Error = COPYIN_FAILED;
208 return -EFAULT; 216 return -EFAULT;
@@ -239,7 +247,7 @@ int su;
239 if ((retval = RIOApel(p)) != 0) 247 if ((retval = RIOApel(p)) != 0)
240 return retval; 248 return retval;
241 249
242 if (copy_to_user(arg, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { 250 if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
243 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); 251 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
244 p->RIOError.Error = COPYOUT_FAILED; 252 p->RIOError.Error = COPYOUT_FAILED;
245 return -EFAULT; 253 return -EFAULT;
@@ -284,7 +292,7 @@ int su;
284 p->RIOError.Error = NOT_SUPER_USER; 292 p->RIOError.Error = NOT_SUPER_USER;
285 return -EPERM; 293 return -EPERM;
286 } 294 }
287 if (copy_from_user(&p->RIOConnectTable[0], arg, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { 295 if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
288 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); 296 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
289 p->RIOError.Error = COPYIN_FAILED; 297 p->RIOError.Error = COPYIN_FAILED;
290 return -EFAULT; 298 return -EFAULT;
@@ -330,7 +338,7 @@ int su;
330 p->RIOError.Error = NOT_SUPER_USER; 338 p->RIOError.Error = NOT_SUPER_USER;
331 return -EPERM; 339 return -EPERM;
332 } 340 }
333 if (copy_to_user(arg, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) { 341 if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
334 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); 342 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
335 p->RIOError.Error = COPYOUT_FAILED; 343 p->RIOError.Error = COPYOUT_FAILED;
336 return -EFAULT; 344 return -EFAULT;
@@ -349,7 +357,7 @@ int su;
349 p->RIOError.Error = NOT_SUPER_USER; 357 p->RIOError.Error = NOT_SUPER_USER;
350 return -EPERM; 358 return -EPERM;
351 } 359 }
352 if (copy_from_user(&p->RIOBindTab[0], arg, (sizeof(ulong) * MAX_RTA_BINDINGS))) { 360 if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
353 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); 361 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
354 p->RIOError.Error = COPYIN_FAILED; 362 p->RIOError.Error = COPYIN_FAILED;
355 return -EFAULT; 363 return -EFAULT;
@@ -373,12 +381,12 @@ int su;
373 for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { 381 for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
374 if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) 382 if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
375 EmptySlot = Entry; 383 EmptySlot = Entry;
376 else if (p->RIOBindTab[Entry] == (long)arg) { 384 else if (p->RIOBindTab[Entry] == arg) {
377 /* 385 /*
378 ** Already exists - delete 386 ** Already exists - delete
379 */ 387 */
380 p->RIOBindTab[Entry] = 0L; 388 p->RIOBindTab[Entry] = 0L;
381 rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", (unsigned long)arg); 389 rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg);
382 return 0; 390 return 0;
383 } 391 }
384 } 392 }
@@ -386,10 +394,10 @@ int su;
386 ** Dosen't exist - add 394 ** Dosen't exist - add
387 */ 395 */
388 if (EmptySlot != -1) { 396 if (EmptySlot != -1) {
389 p->RIOBindTab[EmptySlot] = (unsigned long)arg; 397 p->RIOBindTab[EmptySlot] = arg;
390 rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", (unsigned long) arg); 398 rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg);
391 } else { 399 } else {
392 rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", (unsigned long) arg); 400 rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg);
393 return -ENOMEM; 401 return -ENOMEM;
394 } 402 }
395 return 0; 403 return 0;
@@ -397,7 +405,7 @@ int su;
397 405
398 case RIO_RESUME: 406 case RIO_RESUME:
399 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); 407 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");
400 port = (unsigned long) arg; 408 port = arg;
401 if ((port < 0) || (port > 511)) { 409 if ((port < 0) || (port > 511)) {
402 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); 410 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
403 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; 411 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@@ -433,7 +441,7 @@ int su;
433 p->RIOError.Error = NOT_SUPER_USER; 441 p->RIOError.Error = NOT_SUPER_USER;
434 return -EPERM; 442 return -EPERM;
435 } 443 }
436 if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) { 444 if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
437 rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); 445 rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
438 p->RIOError.Error = COPYIN_FAILED; 446 p->RIOError.Error = COPYIN_FAILED;
439 return -EFAULT; 447 return -EFAULT;
@@ -447,7 +455,7 @@ int su;
447 p->RIOError.Error = NOT_SUPER_USER; 455 p->RIOError.Error = NOT_SUPER_USER;
448 return -EPERM; 456 return -EPERM;
449 } 457 }
450 if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) { 458 if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
451 rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); 459 rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
452 p->RIOError.Error = COPYIN_FAILED; 460 p->RIOError.Error = COPYIN_FAILED;
453 return -EFAULT; 461 return -EFAULT;
@@ -461,7 +469,7 @@ int su;
461 p->RIOError.Error = NOT_SUPER_USER; 469 p->RIOError.Error = NOT_SUPER_USER;
462 return -EPERM; 470 return -EPERM;
463 } 471 }
464 if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) { 472 if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
465 rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); 473 rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n");
466 p->RIOError.Error = COPYIN_FAILED; 474 p->RIOError.Error = COPYIN_FAILED;
467 return -EFAULT; 475 return -EFAULT;
@@ -469,14 +477,14 @@ int su;
469 return RIODeleteRta(p, &MapEnt); 477 return RIODeleteRta(p, &MapEnt);
470 478
471 case RIO_QUICK_CHECK: 479 case RIO_QUICK_CHECK:
472 if (copy_to_user(arg, &p->RIORtaDisCons, sizeof(unsigned int))) { 480 if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) {
473 p->RIOError.Error = COPYOUT_FAILED; 481 p->RIOError.Error = COPYOUT_FAILED;
474 return -EFAULT; 482 return -EFAULT;
475 } 483 }
476 return 0; 484 return 0;
477 485
478 case RIO_LAST_ERROR: 486 case RIO_LAST_ERROR:
479 if (copy_to_user(arg, &p->RIOError, sizeof(struct Error))) 487 if (copy_to_user(argp, &p->RIOError, sizeof(struct Error)))
480 return -EFAULT; 488 return -EFAULT;
481 return 0; 489 return 0;
482 490
@@ -485,7 +493,7 @@ int su;
485 return -EINVAL; 493 return -EINVAL;
486 494
487 case RIO_GET_MODTYPE: 495 case RIO_GET_MODTYPE:
488 if (copy_from_user(&port, arg, sizeof(unsigned int))) { 496 if (copy_from_user(&port, argp, sizeof(unsigned int))) {
489 p->RIOError.Error = COPYIN_FAILED; 497 p->RIOError.Error = COPYIN_FAILED;
490 return -EFAULT; 498 return -EFAULT;
491 } 499 }
@@ -505,7 +513,7 @@ int su;
505 ** Return module type of port 513 ** Return module type of port
506 */ 514 */
507 port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; 515 port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
508 if (copy_to_user(arg, &port, sizeof(unsigned int))) { 516 if (copy_to_user(argp, &port, sizeof(unsigned int))) {
509 p->RIOError.Error = COPYOUT_FAILED; 517 p->RIOError.Error = COPYOUT_FAILED;
510 return -EFAULT; 518 return -EFAULT;
511 } 519 }
@@ -521,7 +529,7 @@ int su;
521 529
522 case RIO_SETUP_PORTS: 530 case RIO_SETUP_PORTS:
523 rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); 531 rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n");
524 if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) { 532 if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
525 p->RIOError.Error = COPYIN_FAILED; 533 p->RIOError.Error = COPYIN_FAILED;
526 rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); 534 rio_dprintk(RIO_DEBUG_CTRL, "EFAULT");
527 return -EFAULT; 535 return -EFAULT;
@@ -551,7 +559,7 @@ int su;
551 559
552 case RIO_GET_PORT_SETUP: 560 case RIO_GET_PORT_SETUP:
553 rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); 561 rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n");
554 if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) { 562 if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
555 p->RIOError.Error = COPYIN_FAILED; 563 p->RIOError.Error = COPYIN_FAILED;
556 return -EFAULT; 564 return -EFAULT;
557 } 565 }
@@ -572,7 +580,7 @@ int su;
572 PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; 580 PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';
573 PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; 581 PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';
574 582
575 if (copy_to_user(arg, &PortSetup, sizeof(PortSetup))) { 583 if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) {
576 p->RIOError.Error = COPYOUT_FAILED; 584 p->RIOError.Error = COPYOUT_FAILED;
577 return -EFAULT; 585 return -EFAULT;
578 } 586 }
@@ -580,7 +588,7 @@ int su;
580 588
581 case RIO_GET_PORT_PARAMS: 589 case RIO_GET_PORT_PARAMS:
582 rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); 590 rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");
583 if (copy_from_user(&PortParams, arg, sizeof(struct PortParams))) { 591 if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) {
584 p->RIOError.Error = COPYIN_FAILED; 592 p->RIOError.Error = COPYIN_FAILED;
585 return -EFAULT; 593 return -EFAULT;
586 } 594 }
@@ -593,7 +601,7 @@ int su;
593 PortParams.State = PortP->State; 601 PortParams.State = PortP->State;
594 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); 602 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
595 603
596 if (copy_to_user(arg, &PortParams, sizeof(struct PortParams))) { 604 if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) {
597 p->RIOError.Error = COPYOUT_FAILED; 605 p->RIOError.Error = COPYOUT_FAILED;
598 return -EFAULT; 606 return -EFAULT;
599 } 607 }
@@ -601,7 +609,7 @@ int su;
601 609
602 case RIO_GET_PORT_TTY: 610 case RIO_GET_PORT_TTY:
603 rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); 611 rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");
604 if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) { 612 if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
605 p->RIOError.Error = COPYIN_FAILED; 613 p->RIOError.Error = COPYIN_FAILED;
606 return -EFAULT; 614 return -EFAULT;
607 } 615 }
@@ -612,14 +620,14 @@ int su;
612 620
613 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); 621 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
614 PortP = (p->RIOPortp[PortTty.port]); 622 PortP = (p->RIOPortp[PortTty.port]);
615 if (copy_to_user(arg, &PortTty, sizeof(struct PortTty))) { 623 if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) {
616 p->RIOError.Error = COPYOUT_FAILED; 624 p->RIOError.Error = COPYOUT_FAILED;
617 return -EFAULT; 625 return -EFAULT;
618 } 626 }
619 return retval; 627 return retval;
620 628
621 case RIO_SET_PORT_TTY: 629 case RIO_SET_PORT_TTY:
622 if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) { 630 if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
623 p->RIOError.Error = COPYIN_FAILED; 631 p->RIOError.Error = COPYIN_FAILED;
624 return -EFAULT; 632 return -EFAULT;
625 } 633 }
@@ -634,7 +642,7 @@ int su;
634 642
635 case RIO_SET_PORT_PARAMS: 643 case RIO_SET_PORT_PARAMS:
636 rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); 644 rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n");
637 if (copy_from_user(&PortParams, arg, sizeof(PortParams))) { 645 if (copy_from_user(&PortParams, argp, sizeof(PortParams))) {
638 p->RIOError.Error = COPYIN_FAILED; 646 p->RIOError.Error = COPYIN_FAILED;
639 return -EFAULT; 647 return -EFAULT;
640 } 648 }
@@ -650,7 +658,7 @@ int su;
650 658
651 case RIO_GET_PORT_STATS: 659 case RIO_GET_PORT_STATS:
652 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); 660 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
653 if (copy_from_user(&portStats, arg, sizeof(struct portStats))) { 661 if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
654 p->RIOError.Error = COPYIN_FAILED; 662 p->RIOError.Error = COPYIN_FAILED;
655 return -EFAULT; 663 return -EFAULT;
656 } 664 }
@@ -665,14 +673,14 @@ int su;
665 portStats.opens = PortP->opens; 673 portStats.opens = PortP->opens;
666 portStats.closes = PortP->closes; 674 portStats.closes = PortP->closes;
667 portStats.ioctls = PortP->ioctls; 675 portStats.ioctls = PortP->ioctls;
668 if (copy_to_user(arg, &portStats, sizeof(struct portStats))) { 676 if (copy_to_user(argp, &portStats, sizeof(struct portStats))) {
669 p->RIOError.Error = COPYOUT_FAILED; 677 p->RIOError.Error = COPYOUT_FAILED;
670 return -EFAULT; 678 return -EFAULT;
671 } 679 }
672 return retval; 680 return retval;
673 681
674 case RIO_RESET_PORT_STATS: 682 case RIO_RESET_PORT_STATS:
675 port = (unsigned long) arg; 683 port = arg;
676 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); 684 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
677 if (port >= RIO_PORTS) { 685 if (port >= RIO_PORTS) {
678 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; 686 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@@ -690,7 +698,7 @@ int su;
690 698
691 case RIO_GATHER_PORT_STATS: 699 case RIO_GATHER_PORT_STATS:
692 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); 700 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
693 if (copy_from_user(&portStats, arg, sizeof(struct portStats))) { 701 if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
694 p->RIOError.Error = COPYIN_FAILED; 702 p->RIOError.Error = COPYIN_FAILED;
695 return -EFAULT; 703 return -EFAULT;
696 } 704 }
@@ -706,7 +714,7 @@ int su;
706 714
707 case RIO_READ_CONFIG: 715 case RIO_READ_CONFIG:
708 rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); 716 rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
709 if (copy_to_user(arg, &p->RIOConf, sizeof(struct Conf))) { 717 if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) {
710 p->RIOError.Error = COPYOUT_FAILED; 718 p->RIOError.Error = COPYOUT_FAILED;
711 return -EFAULT; 719 return -EFAULT;
712 } 720 }
@@ -718,7 +726,7 @@ int su;
718 p->RIOError.Error = NOT_SUPER_USER; 726 p->RIOError.Error = NOT_SUPER_USER;
719 return -EPERM; 727 return -EPERM;
720 } 728 }
721 if (copy_from_user(&p->RIOConf, arg, sizeof(struct Conf))) { 729 if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) {
722 p->RIOError.Error = COPYIN_FAILED; 730 p->RIOError.Error = COPYIN_FAILED;
723 return -EFAULT; 731 return -EFAULT;
724 } 732 }
@@ -746,7 +754,7 @@ int su;
746 case RIO_SETDEBUG: 754 case RIO_SETDEBUG:
747 case RIO_GETDEBUG: 755 case RIO_GETDEBUG:
748 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); 756 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
749 if (copy_from_user(&DebugCtrl, arg, sizeof(DebugCtrl))) { 757 if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) {
750 p->RIOError.Error = COPYIN_FAILED; 758 p->RIOError.Error = COPYIN_FAILED;
751 return -EFAULT; 759 return -EFAULT;
752 } 760 }
@@ -763,7 +771,7 @@ int su;
763 rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); 771 rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait);
764 DebugCtrl.Debug = p->rio_debug; 772 DebugCtrl.Debug = p->rio_debug;
765 DebugCtrl.Wait = p->RIODebugWait; 773 DebugCtrl.Wait = p->RIODebugWait;
766 if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) { 774 if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
767 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); 775 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
768 p->RIOError.Error = COPYOUT_FAILED; 776 p->RIOError.Error = COPYOUT_FAILED;
769 return -EFAULT; 777 return -EFAULT;
@@ -785,7 +793,7 @@ int su;
785 } else { 793 } else {
786 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); 794 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
787 DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; 795 DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
788 if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) { 796 if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
789 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); 797 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
790 p->RIOError.Error = COPYOUT_FAILED; 798 p->RIOError.Error = COPYOUT_FAILED;
791 return -EFAULT; 799 return -EFAULT;
@@ -800,7 +808,7 @@ int su;
800 ** textual null terminated string. 808 ** textual null terminated string.
801 */ 809 */
802 rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); 810 rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n");
803 if (copy_to_user(arg, RIOVersid(), sizeof(struct rioVersion))) { 811 if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) {
804 rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); 812 rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
805 p->RIOError.Error = COPYOUT_FAILED; 813 p->RIOError.Error = COPYOUT_FAILED;
806 return -EFAULT; 814 return -EFAULT;
@@ -813,7 +821,7 @@ int su;
813 ** at init time. 821 ** at init time.
814 */ 822 */
815 rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); 823 rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
816 if (copy_to_user(arg, &p->RIONumHosts, sizeof(p->RIONumHosts))) { 824 if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) {
817 rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); 825 rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
818 p->RIOError.Error = COPYOUT_FAILED; 826 p->RIOError.Error = COPYOUT_FAILED;
819 return -EFAULT; 827 return -EFAULT;
@@ -824,7 +832,7 @@ int su;
824 /* 832 /*
825 ** Kill host. This may not be in the final version... 833 ** Kill host. This may not be in the final version...
826 */ 834 */
827 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", (unsigned long) arg); 835 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg);
828 if (!su) { 836 if (!su) {
829 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); 837 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
830 p->RIOError.Error = NOT_SUPER_USER; 838 p->RIOError.Error = NOT_SUPER_USER;
@@ -858,7 +866,7 @@ int su;
858 p->RIOError.Error = NOT_SUPER_USER; 866 p->RIOError.Error = NOT_SUPER_USER;
859 return -EPERM; 867 return -EPERM;
860 } 868 }
861 if (copy_from_user(&DownLoad, arg, sizeof(DownLoad))) { 869 if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) {
862 rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); 870 rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
863 p->RIOError.Error = COPYIN_FAILED; 871 p->RIOError.Error = COPYIN_FAILED;
864 return -EFAULT; 872 return -EFAULT;
@@ -888,7 +896,7 @@ int su;
888 { 896 {
889 unsigned int host; 897 unsigned int host;
890 898
891 if (copy_from_user(&host, arg, sizeof(host))) { 899 if (copy_from_user(&host, argp, sizeof(host))) {
892 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); 900 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
893 p->RIOError.Error = COPYIN_FAILED; 901 p->RIOError.Error = COPYIN_FAILED;
894 return -EFAULT; 902 return -EFAULT;
@@ -897,7 +905,7 @@ int su;
897 ** Fetch the parmmap 905 ** Fetch the parmmap
898 */ 906 */
899 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); 907 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n");
900 if (copy_to_user(arg, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { 908 if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) {
901 p->RIOError.Error = COPYOUT_FAILED; 909 p->RIOError.Error = COPYOUT_FAILED;
902 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); 910 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
903 return -EFAULT; 911 return -EFAULT;
@@ -907,7 +915,7 @@ int su;
907 915
908 case RIO_HOST_REQ: 916 case RIO_HOST_REQ:
909 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); 917 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
910 if (copy_from_user(&HostReq, arg, sizeof(HostReq))) { 918 if (copy_from_user(&HostReq, argp, sizeof(HostReq))) {
911 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); 919 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
912 p->RIOError.Error = COPYIN_FAILED; 920 p->RIOError.Error = COPYIN_FAILED;
913 return -EFAULT; 921 return -EFAULT;
@@ -928,7 +936,7 @@ int su;
928 936
929 case RIO_HOST_DPRAM: 937 case RIO_HOST_DPRAM:
930 rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); 938 rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n");
931 if (copy_from_user(&HostDpRam, arg, sizeof(HostDpRam))) { 939 if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) {
932 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); 940 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
933 p->RIOError.Error = COPYIN_FAILED; 941 p->RIOError.Error = COPYIN_FAILED;
934 return -EFAULT; 942 return -EFAULT;
@@ -945,13 +953,13 @@ int su;
945 /* It's hardware like this that really gets on my tits. */ 953 /* It's hardware like this that really gets on my tits. */
946 static unsigned char copy[sizeof(struct DpRam)]; 954 static unsigned char copy[sizeof(struct DpRam)];
947 for (off = 0; off < sizeof(struct DpRam); off++) 955 for (off = 0; off < sizeof(struct DpRam); off++)
948 copy[off] = readb(&p->RIOHosts[HostDpRam.HostNum].Caddr[off]); 956 copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off);
949 if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { 957 if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) {
950 p->RIOError.Error = COPYOUT_FAILED; 958 p->RIOError.Error = COPYOUT_FAILED;
951 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); 959 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
952 return -EFAULT; 960 return -EFAULT;
953 } 961 }
954 } else if (copy_to_user(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { 962 } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) {
955 p->RIOError.Error = COPYOUT_FAILED; 963 p->RIOError.Error = COPYOUT_FAILED;
956 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); 964 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
957 return -EFAULT; 965 return -EFAULT;
@@ -960,13 +968,13 @@ int su;
960 968
961 case RIO_SET_BUSY: 969 case RIO_SET_BUSY:
962 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); 970 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
963 if ((unsigned long) arg > 511) { 971 if (arg > 511) {
964 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", (unsigned long) arg); 972 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg);
965 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; 973 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
966 return -EINVAL; 974 return -EINVAL;
967 } 975 }
968 rio_spin_lock_irqsave(&PortP->portSem, flags); 976 rio_spin_lock_irqsave(&PortP->portSem, flags);
969 p->RIOPortp[(unsigned long) arg]->State |= RIO_BUSY; 977 p->RIOPortp[arg]->State |= RIO_BUSY;
970 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 978 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
971 return retval; 979 return retval;
972 980
@@ -976,7 +984,7 @@ int su;
976 ** (probably for debug reasons) 984 ** (probably for debug reasons)
977 */ 985 */
978 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); 986 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
979 if (copy_from_user(&PortReq, arg, sizeof(PortReq))) { 987 if (copy_from_user(&PortReq, argp, sizeof(PortReq))) {
980 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); 988 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
981 p->RIOError.Error = COPYIN_FAILED; 989 p->RIOError.Error = COPYIN_FAILED;
982 return -EFAULT; 990 return -EFAULT;
@@ -1001,7 +1009,7 @@ int su;
1001 ** (probably for debug reasons) 1009 ** (probably for debug reasons)
1002 */ 1010 */
1003 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); 1011 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
1004 if (copy_from_user(&RupReq, arg, sizeof(RupReq))) { 1012 if (copy_from_user(&RupReq, argp, sizeof(RupReq))) {
1005 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); 1013 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
1006 p->RIOError.Error = COPYIN_FAILED; 1014 p->RIOError.Error = COPYIN_FAILED;
1007 return -EFAULT; 1015 return -EFAULT;
@@ -1025,7 +1033,7 @@ int su;
1025 } 1033 }
1026 rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); 1034 rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum);
1027 1035
1028 if (copy_to_user(HostP->UnixRups[RupReq.RupNum].RupP, RupReq.RupP, sizeof(struct RUP))) { 1036 if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) {
1029 p->RIOError.Error = COPYOUT_FAILED; 1037 p->RIOError.Error = COPYOUT_FAILED;
1030 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); 1038 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
1031 return -EFAULT; 1039 return -EFAULT;
@@ -1038,7 +1046,7 @@ int su;
1038 ** (probably for debug reasons) 1046 ** (probably for debug reasons)
1039 */ 1047 */
1040 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); 1048 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
1041 if (copy_from_user(&LpbReq, arg, sizeof(LpbReq))) { 1049 if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) {
1042 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); 1050 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
1043 p->RIOError.Error = COPYIN_FAILED; 1051 p->RIOError.Error = COPYIN_FAILED;
1044 return -EFAULT; 1052 return -EFAULT;
@@ -1062,7 +1070,7 @@ int su;
1062 } 1070 }
1063 rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); 1071 rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host);
1064 1072
1065 if (copy_to_user(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { 1073 if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) {
1066 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); 1074 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
1067 p->RIOError.Error = COPYOUT_FAILED; 1075 p->RIOError.Error = COPYOUT_FAILED;
1068 return -EFAULT; 1076 return -EFAULT;
@@ -1136,7 +1144,7 @@ int su;
1136 case RIO_MAP_B110_TO_110: 1144 case RIO_MAP_B110_TO_110:
1137 case RIO_MAP_B110_TO_115200: 1145 case RIO_MAP_B110_TO_115200:
1138 rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); 1146 rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n");
1139 port = (unsigned long) arg; 1147 port = arg;
1140 if (port < 0 || port > 511) { 1148 if (port < 0 || port > 511) {
1141 rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); 1149 rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
1142 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; 1150 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@@ -1166,7 +1174,7 @@ int su;
1166 1174
1167 case RIO_SEND_PACKET: 1175 case RIO_SEND_PACKET:
1168 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); 1176 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
1169 if (copy_from_user(&SendPack, arg, sizeof(SendPack))) { 1177 if (copy_from_user(&SendPack, argp, sizeof(SendPack))) {
1170 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); 1178 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
1171 p->RIOError.Error = COPYIN_FAILED; 1179 p->RIOError.Error = COPYIN_FAILED;
1172 return -EFAULT; 1180 return -EFAULT;
@@ -1210,7 +1218,7 @@ int su;
1210 return su ? 0 : -EPERM; 1218 return su ? 0 : -EPERM;
1211 1219
1212 case RIO_WHAT_MESG: 1220 case RIO_WHAT_MESG:
1213 if (copy_to_user(arg, &p->RIONoMessage, sizeof(p->RIONoMessage))) { 1221 if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) {
1214 rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); 1222 rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
1215 p->RIOError.Error = COPYOUT_FAILED; 1223 p->RIOError.Error = COPYOUT_FAILED;
1216 return -EFAULT; 1224 return -EFAULT;
@@ -1218,7 +1226,7 @@ int su;
1218 return 0; 1226 return 0;
1219 1227
1220 case RIO_MEM_DUMP: 1228 case RIO_MEM_DUMP:
1221 if (copy_from_user(&SubCmd, arg, sizeof(struct SubCmdStruct))) { 1229 if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
1222 p->RIOError.Error = COPYIN_FAILED; 1230 p->RIOError.Error = COPYIN_FAILED;
1223 return -EFAULT; 1231 return -EFAULT;
1224 } 1232 }
@@ -1248,7 +1256,7 @@ int su;
1248 PortP->State |= RIO_BUSY; 1256 PortP->State |= RIO_BUSY;
1249 1257
1250 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 1258 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1251 if (copy_to_user(arg, p->RIOMemDump, MEMDUMP_SIZE)) { 1259 if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) {
1252 rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); 1260 rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
1253 p->RIOError.Error = COPYOUT_FAILED; 1261 p->RIOError.Error = COPYOUT_FAILED;
1254 return -EFAULT; 1262 return -EFAULT;
@@ -1256,30 +1264,30 @@ int su;
1256 return 0; 1264 return 0;
1257 1265
1258 case RIO_TICK: 1266 case RIO_TICK:
1259 if ((unsigned long) arg >= p->RIONumHosts) 1267 if (arg >= p->RIONumHosts)
1260 return -EINVAL; 1268 return -EINVAL;
1261 rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", (unsigned long) arg); 1269 rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg);
1262 writeb(0xFF, &p->RIOHosts[(unsigned long) arg].SetInt); 1270 writeb(0xFF, &p->RIOHosts[arg].SetInt);
1263 return 0; 1271 return 0;
1264 1272
1265 case RIO_TOCK: 1273 case RIO_TOCK:
1266 if ((unsigned long) arg >= p->RIONumHosts) 1274 if (arg >= p->RIONumHosts)
1267 return -EINVAL; 1275 return -EINVAL;
1268 rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", (unsigned long) arg); 1276 rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg);
1269 writeb(0xFF, &p->RIOHosts[(unsigned long) arg].ResetInt); 1277 writeb(0xFF, &p->RIOHosts[arg].ResetInt);
1270 return 0; 1278 return 0;
1271 1279
1272 case RIO_READ_CHECK: 1280 case RIO_READ_CHECK:
1273 /* Check reads for pkts with data[0] the same */ 1281 /* Check reads for pkts with data[0] the same */
1274 p->RIOReadCheck = !p->RIOReadCheck; 1282 p->RIOReadCheck = !p->RIOReadCheck;
1275 if (copy_to_user(arg, &p->RIOReadCheck, sizeof(unsigned int))) { 1283 if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) {
1276 p->RIOError.Error = COPYOUT_FAILED; 1284 p->RIOError.Error = COPYOUT_FAILED;
1277 return -EFAULT; 1285 return -EFAULT;
1278 } 1286 }
1279 return 0; 1287 return 0;
1280 1288
1281 case RIO_READ_REGISTER: 1289 case RIO_READ_REGISTER:
1282 if (copy_from_user(&SubCmd, arg, sizeof(struct SubCmdStruct))) { 1290 if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
1283 p->RIOError.Error = COPYIN_FAILED; 1291 p->RIOError.Error = COPYIN_FAILED;
1284 return -EFAULT; 1292 return -EFAULT;
1285 } 1293 }
@@ -1314,7 +1322,7 @@ int su;
1314 PortP->State |= RIO_BUSY; 1322 PortP->State |= RIO_BUSY;
1315 1323
1316 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 1324 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1317 if (copy_to_user(arg, &p->CdRegister, sizeof(unsigned int))) { 1325 if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) {
1318 rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); 1326 rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
1319 p->RIOError.Error = COPYOUT_FAILED; 1327 p->RIOError.Error = COPYOUT_FAILED;
1320 return -EFAULT; 1328 return -EFAULT;
@@ -1327,10 +1335,10 @@ int su;
1327 */ 1335 */
1328 case RIO_MAKE_DEV: 1336 case RIO_MAKE_DEV:
1329 { 1337 {
1330 unsigned int port = (unsigned long) arg & RIO_MODEM_MASK; 1338 unsigned int port = arg & RIO_MODEM_MASK;
1331 unsigned int ret; 1339 unsigned int ret;
1332 1340
1333 switch ((unsigned long) arg & RIO_DEV_MASK) { 1341 switch (arg & RIO_DEV_MASK) {
1334 case RIO_DEV_DIRECT: 1342 case RIO_DEV_DIRECT:
1335 ret = drv_makedev(MAJOR(dev), port); 1343 ret = drv_makedev(MAJOR(dev), port);
1336 rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret); 1344 rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret);
@@ -1358,7 +1366,7 @@ int su;
1358 int mino; 1366 int mino;
1359 unsigned long ret; 1367 unsigned long ret;
1360 1368
1361 dv = (dev_t) ((unsigned long) arg); 1369 dv = (dev_t) (arg);
1362 mino = RIO_UNMODEM(dv); 1370 mino = RIO_UNMODEM(dv);
1363 1371
1364 if (RIO_ISMODEM(dv)) { 1372 if (RIO_ISMODEM(dv)) {
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index 24d2992154cc..12e34bc3f7ce 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -79,7 +79,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
79 79
80int RIOPCIinit(struct rio_info *p, int Mode); 80int RIOPCIinit(struct rio_info *p, int Mode);
81 81
82static int RIOScrub(int, u8 *, int); 82static int RIOScrub(int, u8 __iomem *, int);
83 83
84 84
85/** 85/**
@@ -92,10 +92,10 @@ static int RIOScrub(int, u8 *, int);
92** bits > 0 indicates 16 bit operation. 92** bits > 0 indicates 16 bit operation.
93*/ 93*/
94 94
95int RIOAssignAT(struct rio_info *p, int Base, caddr_t virtAddr, int mode) 95int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode)
96{ 96{
97 int bits; 97 int bits;
98 struct DpRam *cardp = (struct DpRam *)virtAddr; 98 struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr;
99 99
100 if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) 100 if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE))
101 bits = BYTE_OPERATION; 101 bits = BYTE_OPERATION;
@@ -107,7 +107,7 @@ int RIOAssignAT(struct rio_info *p, int Base, caddr_t virtAddr, int mode)
107 ** transient stuff. 107 ** transient stuff.
108 */ 108 */
109 p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; 109 p->RIOHosts[p->RIONumHosts].Caddr = virtAddr;
110 p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)virtAddr; 110 p->RIOHosts[p->RIONumHosts].CardP = virtAddr;
111 111
112 /* 112 /*
113 ** Revision 01 AT host cards don't support WORD operations, 113 ** Revision 01 AT host cards don't support WORD operations,
@@ -151,10 +151,10 @@ static u8 val[] = {
151** RAM test a board. 151** RAM test a board.
152** Nothing too complicated, just enough to check it out. 152** Nothing too complicated, just enough to check it out.
153*/ 153*/
154int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slot) 154int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot)
155{ 155{
156 struct DpRam *DpRam = (struct DpRam *)caddr; 156 struct DpRam __iomem *DpRam = caddr;
157 char *ram[4]; 157 void __iomem *ram[4];
158 int size[4]; 158 int size[4];
159 int op, bank; 159 int op, bank;
160 int nbanks; 160 int nbanks;
@@ -179,12 +179,12 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
179 size[2] = DP_SRAM3_SIZE; 179 size[2] = DP_SRAM3_SIZE;
180 size[3] = DP_SCRATCH_SIZE; 180 size[3] = DP_SCRATCH_SIZE;
181 181
182 ram[0] = (char *)&DpRam->DpSram1[0]; 182 ram[0] = DpRam->DpSram1;
183 ram[1] = (char *)&DpRam->DpSram2[0]; 183 ram[1] = DpRam->DpSram2;
184 ram[2] = (char *)&DpRam->DpSram3[0]; 184 ram[2] = DpRam->DpSram3;
185 nbanks = (type == RIO_PCI) ? 3 : 4; 185 nbanks = (type == RIO_PCI) ? 3 : 4;
186 if (nbanks == 4) 186 if (nbanks == 4)
187 ram[3] = (char *)&DpRam->DpScratch[0]; 187 ram[3] = DpRam->DpScratch;
188 188
189 189
190 if (nbanks == 3) { 190 if (nbanks == 3) {
@@ -202,7 +202,7 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
202 */ 202 */
203 for (op=0; op<TEST_END; op++) { 203 for (op=0; op<TEST_END; op++) {
204 for (bank=0; bank<nbanks; bank++) { 204 for (bank=0; bank<nbanks; bank++) {
205 if (RIOScrub(op, (u8 *)ram[bank], size[bank]) == RIO_FAIL) { 205 if (RIOScrub(op, ram[bank], size[bank]) == RIO_FAIL) {
206 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", 206 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n",
207 bank, op); 207 bank, op);
208 return RIO_FAIL; 208 return RIO_FAIL;
@@ -227,7 +227,7 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
227** to check that the data from the previous phase was retained. 227** to check that the data from the previous phase was retained.
228*/ 228*/
229 229
230static int RIOScrub(int op, u8 *ram, int size) 230static int RIOScrub(int op, u8 __iomem *ram, int size)
231{ 231{
232 int off; 232 int off;
233 unsigned char oldbyte; 233 unsigned char oldbyte;
@@ -393,7 +393,7 @@ struct rioVersion *RIOVersid(void)
393 return &stVersion; 393 return &stVersion;
394} 394}
395 395
396void RIOHostReset(unsigned int Type, struct DpRam *DpRamP, unsigned int Slot) 396void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot)
397{ 397{
398 /* 398 /*
399 ** Reset the Tpu 399 ** Reset the Tpu
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index 97f0fa550652..eec1fea0cb92 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -102,7 +102,7 @@ void RIOTxEnable(char *en)
102 struct rio_info *p; 102 struct rio_info *p;
103 struct tty_struct *tty; 103 struct tty_struct *tty;
104 int c; 104 int c;
105 struct PKT *PacketP; 105 struct PKT __iomem *PacketP;
106 unsigned long flags; 106 unsigned long flags;
107 107
108 PortP = (struct Port *) en; 108 PortP = (struct Port *) en;
@@ -144,7 +144,7 @@ void RIOTxEnable(char *en)
144 if (c == 0) 144 if (c == 0)
145 break; 145 break;
146 146
147 rio_memcpy_toio(PortP->HostP->Caddr, (caddr_t) PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); 147 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
148 /* udelay (1); */ 148 /* udelay (1); */
149 149
150 writeb(c, &(PacketP->len)); 150 writeb(c, &(PacketP->len));
@@ -219,7 +219,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
219 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { 219 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
220 struct Port *PortP = p->RIOPortp[port]; 220 struct Port *PortP = p->RIOPortp[port];
221 struct tty_struct *ttyP; 221 struct tty_struct *ttyP;
222 struct PKT *PacketP; 222 struct PKT __iomem *PacketP;
223 223
224 /* 224 /*
225 ** not mapped in - most of the RIOPortp[] information 225 ** not mapped in - most of the RIOPortp[] information
@@ -298,7 +298,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
298 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { 298 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
299 struct Port *PortP = p->RIOPortp[port]; 299 struct Port *PortP = p->RIOPortp[port];
300 struct tty_struct *ttyP; 300 struct tty_struct *ttyP;
301 struct PKT *PacketP; 301 struct PKT __iomem *PacketP;
302 302
303 /* 303 /*
304 ** not mapped in - most of the RIOPortp[] information 304 ** not mapped in - most of the RIOPortp[] information
@@ -427,13 +427,13 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
427 427
428 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { 428 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
429 int p; 429 int p;
430 struct PktCmd *PktCmdP; 430 struct PktCmd __iomem *PktCmdP;
431 431
432 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); 432 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
433 /* 433 /*
434 ** make it look just like a WFLUSH command 434 ** make it look just like a WFLUSH command
435 */ 435 */
436 PktCmdP = (struct PktCmd *) &PacketP->data[0]; 436 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
437 437
438 writeb(WFLUSH, &PktCmdP->Command); 438 writeb(WFLUSH, &PktCmdP->Command);
439 439
@@ -525,9 +525,9 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
525{ 525{
526 struct tty_struct *TtyP; 526 struct tty_struct *TtyP;
527 unsigned short transCount; 527 unsigned short transCount;
528 struct PKT *PacketP; 528 struct PKT __iomem *PacketP;
529 register unsigned int DataCnt; 529 register unsigned int DataCnt;
530 unsigned char *ptr; 530 unsigned char __iomem *ptr;
531 unsigned char *buf; 531 unsigned char *buf;
532 int copied = 0; 532 int copied = 0;
533 533
@@ -585,19 +585,19 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
585 /* 585 /*
586 ** check that it is not a command! 586 ** check that it is not a command!
587 */ 587 */
588 if (PacketP->len & PKT_CMD_BIT) { 588 if (readb(&PacketP->len) & PKT_CMD_BIT) {
589 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); 589 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
590 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ 590 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
591 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit); 591 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
592 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port); 592 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
593 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit); 593 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
594 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port); 594 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
595 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", PacketP->len); 595 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
596 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", PacketP->control); 596 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
597 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum); 597 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
598 rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); 598 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
599 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) 599 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
600 rio_dprintk(RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]); 600 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
601 remove_receive(PortP); 601 remove_receive(PortP);
602 put_free_end(PortP->HostP, PacketP); 602 put_free_end(PortP->HostP, PacketP);
603 continue; /* with next packet */ 603 continue; /* with next packet */
@@ -618,24 +618,24 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
618 ** and available space. 618 ** and available space.
619 */ 619 */
620 620
621 transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); 621 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
622 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); 622 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
623 /* 623 /*
624 ** To use the following 'kkprintfs' for debugging - change the '#undef' 624 ** To use the following 'kkprintfs' for debugging - change the '#undef'
625 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the 625 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
626 ** driver). 626 ** driver).
627 */ 627 */
628 ptr = (unsigned char *) PacketP->data + PortP->RxDataStart; 628 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
629 629
630 tty_prepare_flip_string(TtyP, &buf, transCount); 630 tty_prepare_flip_string(TtyP, &buf, transCount);
631 rio_memcpy_fromio(buf, ptr, transCount); 631 rio_memcpy_fromio(buf, ptr, transCount);
632 PortP->RxDataStart += transCount; 632 PortP->RxDataStart += transCount;
633 PacketP->len -= transCount; 633 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
634 copied += transCount; 634 copied += transCount;
635 635
636 636
637 637
638 if (PacketP->len == 0) { 638 if (readb(&PacketP->len) == 0) {
639 /* 639 /*
640 ** If we have emptied the packet, then we can 640 ** If we have emptied the packet, then we can
641 ** free it, and reset the start pointer for 641 ** free it, and reset the start pointer for
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index d2e8092cdb29..1066d9760704 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -154,8 +154,8 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
154{ 154{
155 struct tty_struct *TtyP; 155 struct tty_struct *TtyP;
156 int retval; 156 int retval;
157 struct phb_param *phb_param_ptr; 157 struct phb_param __iomem *phb_param_ptr;
158 struct PKT *PacketP; 158 struct PKT __iomem *PacketP;
159 int res; 159 int res;
160 u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; 160 u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0;
161 u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; 161 u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0;
@@ -235,7 +235,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
235 rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); 235 rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res);
236 rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); 236 rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP);
237 237
238 phb_param_ptr = (struct phb_param *) PacketP->data; 238 phb_param_ptr = (struct phb_param __iomem *) PacketP->data;
239 239
240 240
241 switch (TtyP->termios->c_cflag & CSIZE) { 241 switch (TtyP->termios->c_cflag & CSIZE) {
@@ -580,11 +580,11 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
580** We can add another packet to a transmit queue if the packet pointer pointed 580** We can add another packet to a transmit queue if the packet pointer pointed
581** to by the TxAdd pointer has PKT_IN_USE clear in its address. 581** to by the TxAdd pointer has PKT_IN_USE clear in its address.
582*/ 582*/
583int can_add_transmit(struct PKT **PktP, struct Port *PortP) 583int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP)
584{ 584{
585 struct PKT *tp; 585 struct PKT __iomem *tp;
586 586
587 *PktP = tp = (struct PKT *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd)); 587 *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd));
588 588
589 return !((unsigned long) tp & PKT_IN_USE); 589 return !((unsigned long) tp & PKT_IN_USE);
590} 590}
@@ -608,9 +608,9 @@ void add_transmit(struct Port *PortP)
608 * Put a packet onto the end of the 608 * Put a packet onto the end of the
609 * free list 609 * free list
610 ****************************************/ 610 ****************************************/
611void put_free_end(struct Host *HostP, struct PKT *PktP) 611void put_free_end(struct Host *HostP, struct PKT __iomem *PktP)
612{ 612{
613 struct rio_free_list *tmp_pointer; 613 struct rio_free_list __iomem *tmp_pointer;
614 unsigned short old_end, new_end; 614 unsigned short old_end, new_end;
615 unsigned long flags; 615 unsigned long flags;
616 616
@@ -625,15 +625,15 @@ void put_free_end(struct Host *HostP, struct PKT *PktP)
625 625
626 if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) { 626 if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) {
627 new_end = RIO_OFF(HostP->Caddr, PktP); 627 new_end = RIO_OFF(HostP->Caddr, PktP);
628 tmp_pointer = (struct rio_free_list *) RIO_PTR(HostP->Caddr, old_end); 628 tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end);
629 writew(new_end, &tmp_pointer->next); 629 writew(new_end, &tmp_pointer->next);
630 writew(old_end, &((struct rio_free_list *) PktP)->prev); 630 writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev);
631 writew(TPNULL, &((struct rio_free_list *) PktP)->next); 631 writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next);
632 writew(new_end, &HostP->ParmMapP->free_list_end); 632 writew(new_end, &HostP->ParmMapP->free_list_end);
633 } else { /* First packet on the free list this should never happen! */ 633 } else { /* First packet on the free list this should never happen! */
634 rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); 634 rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
635 writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end); 635 writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end);
636 tmp_pointer = (struct rio_free_list *) PktP; 636 tmp_pointer = (struct rio_free_list __iomem *) PktP;
637 writew(TPNULL, &tmp_pointer->prev); 637 writew(TPNULL, &tmp_pointer->prev);
638 writew(TPNULL, &tmp_pointer->next); 638 writew(TPNULL, &tmp_pointer->next);
639 } 639 }
@@ -647,10 +647,10 @@ void put_free_end(struct Host *HostP, struct PKT *PktP)
647** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, 647** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
648** then can_remove_receive() returns 0. 648** then can_remove_receive() returns 0.
649*/ 649*/
650int can_remove_receive(struct PKT **PktP, struct Port *PortP) 650int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP)
651{ 651{
652 if (readw(PortP->RxRemove) & PKT_IN_USE) { 652 if (readw(PortP->RxRemove) & PKT_IN_USE) {
653 *PktP = (struct PKT *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE); 653 *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE);
654 return 1; 654 return 1;
655 } 655 }
656 return 0; 656 return 0;
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index 357085337942..a99f3d9d7d65 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -86,9 +86,9 @@ static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned i
86** Incoming on the ROUTE_RUP 86** Incoming on the ROUTE_RUP
87** I wrote this while I was tired. Forgive me. 87** I wrote this while I was tired. Forgive me.
88*/ 88*/
89int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT * PacketP) 89int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP)
90{ 90{
91 struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data; 91 struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data;
92 struct PktCmd_M *PktReplyP; 92 struct PktCmd_M *PktReplyP;
93 struct CmdBlk *CmdBlkP; 93 struct CmdBlk *CmdBlkP;
94 struct Port *PortP; 94 struct Port *PortP;
@@ -307,7 +307,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
307 if (!RIOBootOk(p, HostP, RtaUniq)) { 307 if (!RIOBootOk(p, HostP, RtaUniq)) {
308 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); 308 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq);
309 PktReplyP->Command = ROUTE_FOAD; 309 PktReplyP->Command = ROUTE_FOAD;
310 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7); 310 memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
311 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 311 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
312 return 1; 312 return 1;
313 } 313 }
@@ -341,7 +341,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
341 HostP->Mapping[ThisUnit].Flags |= MSG_DONE; 341 HostP->Mapping[ThisUnit].Flags |= MSG_DONE;
342 } 342 }
343 PktReplyP->Command = ROUTE_FOAD; 343 PktReplyP->Command = ROUTE_FOAD;
344 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7); 344 memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
345 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 345 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
346 return 1; 346 return 1;
347 } 347 }
@@ -367,7 +367,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
367 PktReplyP->IDNum2 = ROUTE_NO_ID; 367 PktReplyP->IDNum2 = ROUTE_NO_ID;
368 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); 368 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum);
369 } 369 }
370 HostP->Copy("RT_ALLOCAT", PktReplyP->CommandText, 10); 370 memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10);
371 371
372 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 372 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
373 373
@@ -469,7 +469,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
469 } 469 }
470 470
471 PktReplyP->Command = ROUTE_FOAD; 471 PktReplyP->Command = ROUTE_FOAD;
472 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7); 472 memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
473 } else { 473 } else {
474 /* 474 /*
475 ** we did boot it (as an extra), and there may now be a table 475 ** we did boot it (as an extra), and there may now be a table
@@ -489,7 +489,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
489 } 489 }
490 } 490 }
491 PktReplyP->Command = ROUTE_USED; 491 PktReplyP->Command = ROUTE_USED;
492 HostP->Copy("RT_USED", PktReplyP->CommandText, 7); 492 memcpy(PktReplyP->CommandText, "RT_USED", 7);
493 } 493 }
494 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 494 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
495 return 1; 495 return 1;
@@ -517,8 +517,8 @@ void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit)
517 517
518 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { 518 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {
519 unsigned short dest_port = port + 8; 519 unsigned short dest_port = port + 8;
520 u16 *TxPktP; 520 u16 __iomem *TxPktP;
521 struct PKT *Pkt; 521 struct PKT __iomem *Pkt;
522 522
523 PortP = p->RIOPortp[PortN]; 523 PortP = p->RIOPortp[PortN];
524 524
@@ -555,12 +555,12 @@ void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit)
555 ** card. This needs to be translated into a 32 bit pointer 555 ** card. This needs to be translated into a 32 bit pointer
556 ** so it can be accessed from the driver. 556 ** so it can be accessed from the driver.
557 */ 557 */
558 Pkt = (struct PKT *) RIO_PTR(HostP->Caddr, readw(TxPktP)); 558 Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP));
559 559
560 /* 560 /*
561 ** If the packet is used, reset it. 561 ** If the packet is used, reset it.
562 */ 562 */
563 Pkt = (struct PKT *) ((unsigned long) Pkt & ~PKT_IN_USE); 563 Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE);
564 writeb(dest_unit, &Pkt->dest_unit); 564 writeb(dest_unit, &Pkt->dest_unit);
565 writeb(dest_port, &Pkt->dest_port); 565 writeb(dest_port, &Pkt->dest_port);
566 } 566 }
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index d3abe0d37d64..7e988357326e 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -534,8 +534,8 @@ int RIODeleteRta(struct rio_info *p, struct Map *MapP)
534 if (PortP->SecondBlock) { 534 if (PortP->SecondBlock) {
535 u16 dest_unit = HostMapP->ID; 535 u16 dest_unit = HostMapP->ID;
536 u16 dest_port = port - SysPort; 536 u16 dest_port = port - SysPort;
537 u16 *TxPktP; 537 u16 __iomem *TxPktP;
538 struct PKT *Pkt; 538 struct PKT __iomem *Pkt;
539 539
540 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { 540 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
541 /* 541 /*
@@ -545,12 +545,12 @@ int RIODeleteRta(struct rio_info *p, struct Map *MapP)
545 ** a 32 bit pointer so it can be 545 ** a 32 bit pointer so it can be
546 ** accessed from the driver. 546 ** accessed from the driver.
547 */ 547 */
548 Pkt = (struct PKT *) RIO_PTR(HostP->Caddr, readw(&*TxPktP)); 548 Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP));
549 rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", *TxPktP, Pkt->dest_unit, Pkt->dest_port, dest_unit, dest_port); 549 rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port);
550 writew(dest_unit, &Pkt->dest_unit); 550 writew(dest_unit, &Pkt->dest_unit);
551 writew(dest_port, &Pkt->dest_port); 551 writew(dest_port, &Pkt->dest_port);
552 } 552 }
553 rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, PortP->PhbP->destination & 0xff, (PortP->PhbP->destination >> 8) & 0xff, dest_unit, dest_port); 553 rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port);
554 writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); 554 writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination);
555 } 555 }
556 rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); 556 rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
@@ -781,13 +781,13 @@ int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
781 ** unless the host has been booted 781 ** unless the host has been booted
782 */ 782 */
783 if ((HostP->Flags & RUN_STATE) == RC_RUNNING) { 783 if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
784 struct PHB *PhbP = PortP->PhbP = &HostP->PhbP[HostPort]; 784 struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
785 PortP->TxAdd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add)); 785 PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add));
786 PortP->TxStart = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start)); 786 PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start));
787 PortP->TxEnd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end)); 787 PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end));
788 PortP->RxRemove = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove)); 788 PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove));
789 PortP->RxStart = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start)); 789 PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start));
790 PortP->RxEnd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end)); 790 PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end));
791 } else 791 } else
792 PortP->PhbP = NULL; 792 PortP->PhbP = NULL;
793 793
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index 204267613c9c..a4f0b1e3e7fa 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -576,7 +576,7 @@ static void RIOClearUp(struct Port *PortP)
576*/ 576*/
577int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) 577int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg)
578{ 578{
579 struct PKT *PacketP; 579 struct PKT __iomem *PacketP;
580 int retries = 20; /* at 10 per second -> 2 seconds */ 580 int retries = 20; /* at 10 per second -> 2 seconds */
581 unsigned long flags; 581 unsigned long flags;
582 582
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h
index 4306e01dbf01..46bd532f7746 100644
--- a/drivers/char/rio/unixrup.h
+++ b/drivers/char/rio/unixrup.h
@@ -44,7 +44,7 @@ static char *_unixrup_h_sccs_ = "@(#)unixrup.h 1.2";
44struct UnixRup { 44struct UnixRup {
45 struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */ 45 struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */
46 struct CmdBlk *CmdPendingP; /* The command currently being sent */ 46 struct CmdBlk *CmdPendingP; /* The command currently being sent */
47 struct RUP *RupP; /* the Rup to send it to */ 47 struct RUP __iomem *RupP; /* the Rup to send it to */
48 unsigned int Id; /* Id number */ 48 unsigned int Id; /* Id number */
49 unsigned int BaseSysPort; /* SysPort of first tty on this RTA */ 49 unsigned int BaseSysPort; /* SysPort of first tty on this RTA */
50 unsigned int ModTypes; /* Modules on this RTA */ 50 unsigned int ModTypes; /* Modules on this RTA */
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index b0053280ff2d..6bfcdbc7491e 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -1073,7 +1073,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1073 tasklet_init(&host->finish_tasklet, 1073 tasklet_init(&host->finish_tasklet,
1074 sdhci_tasklet_finish, (unsigned long)host); 1074 sdhci_tasklet_finish, (unsigned long)host);
1075 1075
1076 setup_timer(&host->timer, sdhci_timeout_timer, (int)host); 1076 setup_timer(&host->timer, sdhci_timeout_timer, (long)host);
1077 1077
1078 ret = request_irq(host->irq, sdhci_irq, SA_SHIRQ, 1078 ret = request_irq(host->irq, sdhci_irq, SA_SHIRQ,
1079 host->slot_descr, host); 1079 host->slot_descr, host);
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index f6b775e63ac8..5ac265dde423 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -78,7 +78,7 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
78 option. 78 option.
79 79
80 The option specifies which Flash sectors holds the RedBoot 80 The option specifies which Flash sectors holds the RedBoot
81 partition table. A zero or positive value gives an absolete 81 partition table. A zero or positive value gives an absolute
82 erase block number. A negative value specifies a number of 82 erase block number. A negative value specifies a number of
83 sectors before the end of the device. 83 sectors before the end of the device.
84 84
@@ -103,7 +103,7 @@ config MTD_CMDLINE_PARTS
103 bool "Command line partition table parsing" 103 bool "Command line partition table parsing"
104 depends on MTD_PARTITIONS = "y" 104 depends on MTD_PARTITIONS = "y"
105 ---help--- 105 ---help---
106 Allow generic configuration of the MTD paritition tables via the kernel 106 Allow generic configuration of the MTD partition tables via the kernel
107 command line. Multiple flash resources are supported for hardware where 107 command line. Multiple flash resources are supported for hardware where
108 different kinds of flash memory are available. 108 different kinds of flash memory are available.
109 109
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index a7ec5954caf5..6d8f30deb868 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -30,7 +30,6 @@ config MTD_JEDECPROBE
30 30
31config MTD_GEN_PROBE 31config MTD_GEN_PROBE
32 tristate 32 tristate
33 select OBSOLETE_INTERMODULE
34 33
35config MTD_CFI_ADV_OPTIONS 34config MTD_CFI_ADV_OPTIONS
36 bool "Flash chip driver advanced configuration options" 35 bool "Flash chip driver advanced configuration options"
diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile
index 8afe3092c4e3..75bc1c2a0f43 100644
--- a/drivers/mtd/chips/Makefile
+++ b/drivers/mtd/chips/Makefile
@@ -3,13 +3,6 @@
3# 3#
4# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $ 4# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
5 5
6# *** BIG UGLY NOTE ***
7#
8# The removal of get_module_symbol() and replacement with
9# inter_module_register() et al has introduced a link order dependency
10# here where previously there was none. We now have to ensure that
11# the CFI command set drivers are linked before gen_probe.o
12
13obj-$(CONFIG_MTD) += chipreg.o 6obj-$(CONFIG_MTD) += chipreg.o
14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o 7obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
15obj-$(CONFIG_MTD_CFI) += cfi_probe.o 8obj-$(CONFIG_MTD_CFI) += cfi_probe.o
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 57115618c496..16eaca69fb5a 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -97,7 +97,6 @@ struct amd_flash_private {
97 int interleave; 97 int interleave;
98 int numchips; 98 int numchips;
99 unsigned long chipshift; 99 unsigned long chipshift;
100// const char *im_name;
101 struct flchip chips[0]; 100 struct flchip chips[0];
102}; 101};
103 102
@@ -131,12 +130,6 @@ static struct mtd_chip_driver amd_flash_chipdrv = {
131 .module = THIS_MODULE 130 .module = THIS_MODULE
132}; 131};
133 132
134
135
136static const char im_name[] = "amd_flash";
137
138
139
140static inline __u32 wide_read(struct map_info *map, __u32 addr) 133static inline __u32 wide_read(struct map_info *map, __u32 addr)
141{ 134{
142 if (map->buswidth == 1) { 135 if (map->buswidth == 1) {
@@ -737,6 +730,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
737 offset += dev_size; 730 offset += dev_size;
738 } 731 }
739 mtd->type = MTD_NORFLASH; 732 mtd->type = MTD_NORFLASH;
733 mtd->writesize = 1;
740 mtd->flags = MTD_CAP_NORFLASH; 734 mtd->flags = MTD_CAP_NORFLASH;
741 mtd->name = map->name; 735 mtd->name = map->name;
742 mtd->erase = amd_flash_erase; 736 mtd->erase = amd_flash_erase;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 1c074d63ff3a..0d435814aaa1 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -331,13 +331,6 @@ read_pri_intelext(struct map_info *map, __u16 adr)
331 return extp; 331 return extp;
332} 332}
333 333
334/* This routine is made available to other mtd code via
335 * inter_module_register. It must only be accessed through
336 * inter_module_get which will bump the use count of this module. The
337 * addresses passed back in cfi are valid as long as the use count of
338 * this module is non-zero, i.e. between inter_module_get and
339 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
340 */
341struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) 334struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
342{ 335{
343 struct cfi_private *cfi = map->fldrv_priv; 336 struct cfi_private *cfi = map->fldrv_priv;
@@ -406,7 +399,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
406 for (i=0; i< cfi->numchips; i++) { 399 for (i=0; i< cfi->numchips; i++) {
407 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 400 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
408 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 401 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
409 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 402 cfi->chips[i].erase_time = 1000<<cfi->cfiq->BlockEraseTimeoutTyp;
410 cfi->chips[i].ref_point_counter = 0; 403 cfi->chips[i].ref_point_counter = 0;
411 init_waitqueue_head(&(cfi->chips[i].wq)); 404 init_waitqueue_head(&(cfi->chips[i].wq));
412 } 405 }
@@ -415,6 +408,11 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
415 408
416 return cfi_intelext_setup(mtd); 409 return cfi_intelext_setup(mtd);
417} 410}
411struct mtd_info *cfi_cmdset_0003(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001")));
412struct mtd_info *cfi_cmdset_0200(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001")));
413EXPORT_SYMBOL_GPL(cfi_cmdset_0001);
414EXPORT_SYMBOL_GPL(cfi_cmdset_0003);
415EXPORT_SYMBOL_GPL(cfi_cmdset_0200);
418 416
419static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) 417static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
420{ 418{
@@ -547,12 +545,12 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
547 if (extp->MinorVersion >= '4') { 545 if (extp->MinorVersion >= '4') {
548 struct cfi_intelext_programming_regioninfo *prinfo; 546 struct cfi_intelext_programming_regioninfo *prinfo;
549 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; 547 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
550 MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift; 548 mtd->writesize = cfi->interleave << prinfo->ProgRegShift;
551 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid; 549 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
552 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid; 550 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
553 mtd->flags |= MTD_PROGRAM_REGIONS; 551 mtd->flags &= ~MTD_BIT_WRITEABLE;
554 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n", 552 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
555 map->name, MTD_PROGREGION_SIZE(mtd), 553 map->name, mtd->writesize,
556 MTD_PROGREGION_CTRLMODE_VALID(mtd), 554 MTD_PROGREGION_CTRLMODE_VALID(mtd),
557 MTD_PROGREGION_CTRLMODE_INVALID(mtd)); 555 MTD_PROGREGION_CTRLMODE_INVALID(mtd));
558 } 556 }
@@ -896,26 +894,33 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
896 894
897/* 895/*
898 * When a delay is required for the flash operation to complete, the 896 * When a delay is required for the flash operation to complete, the
899 * xip_udelay() function is polling for both the given timeout and pending 897 * xip_wait_for_operation() function is polling for both the given timeout
900 * (but still masked) hardware interrupts. Whenever there is an interrupt 898 * and pending (but still masked) hardware interrupts. Whenever there is an
901 * pending then the flash erase or write operation is suspended, array mode 899 * interrupt pending then the flash erase or write operation is suspended,
902 * restored and interrupts unmasked. Task scheduling might also happen at that 900 * array mode restored and interrupts unmasked. Task scheduling might also
903 * point. The CPU eventually returns from the interrupt or the call to 901 * happen at that point. The CPU eventually returns from the interrupt or
904 * schedule() and the suspended flash operation is resumed for the remaining 902 * the call to schedule() and the suspended flash operation is resumed for
905 * of the delay period. 903 * the remaining of the delay period.
906 * 904 *
907 * Warning: this function _will_ fool interrupt latency tracing tools. 905 * Warning: this function _will_ fool interrupt latency tracing tools.
908 */ 906 */
909 907
910static void __xipram xip_udelay(struct map_info *map, struct flchip *chip, 908static int __xipram xip_wait_for_operation(
911 unsigned long adr, int usec) 909 struct map_info *map, struct flchip *chip,
910 unsigned long adr, int *chip_op_time )
912{ 911{
913 struct cfi_private *cfi = map->fldrv_priv; 912 struct cfi_private *cfi = map->fldrv_priv;
914 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; 913 struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
915 map_word status, OK = CMD(0x80); 914 map_word status, OK = CMD(0x80);
916 unsigned long suspended, start = xip_currtime(); 915 unsigned long usec, suspended, start, done;
917 flstate_t oldstate, newstate; 916 flstate_t oldstate, newstate;
918 917
918 start = xip_currtime();
919 usec = *chip_op_time * 8;
920 if (usec == 0)
921 usec = 500000;
922 done = 0;
923
919 do { 924 do {
920 cpu_relax(); 925 cpu_relax();
921 if (xip_irqpending() && cfip && 926 if (xip_irqpending() && cfip &&
@@ -932,9 +937,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
932 * we resume the whole thing at once). Yes, it 937 * we resume the whole thing at once). Yes, it
933 * can happen! 938 * can happen!
934 */ 939 */
940 usec -= done;
935 map_write(map, CMD(0xb0), adr); 941 map_write(map, CMD(0xb0), adr);
936 map_write(map, CMD(0x70), adr); 942 map_write(map, CMD(0x70), adr);
937 usec -= xip_elapsed_since(start);
938 suspended = xip_currtime(); 943 suspended = xip_currtime();
939 do { 944 do {
940 if (xip_elapsed_since(suspended) > 100000) { 945 if (xip_elapsed_since(suspended) > 100000) {
@@ -944,7 +949,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
944 * This is a critical error but there 949 * This is a critical error but there
945 * is not much we can do here. 950 * is not much we can do here.
946 */ 951 */
947 return; 952 return -EIO;
948 } 953 }
949 status = map_read(map, adr); 954 status = map_read(map, adr);
950 } while (!map_word_andequal(map, status, OK, OK)); 955 } while (!map_word_andequal(map, status, OK, OK));
@@ -1004,65 +1009,107 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
1004 xip_cpu_idle(); 1009 xip_cpu_idle();
1005 } 1010 }
1006 status = map_read(map, adr); 1011 status = map_read(map, adr);
1012 done = xip_elapsed_since(start);
1007 } while (!map_word_andequal(map, status, OK, OK) 1013 } while (!map_word_andequal(map, status, OK, OK)
1008 && xip_elapsed_since(start) < usec); 1014 && done < usec);
1009}
1010 1015
1011#define UDELAY(map, chip, adr, usec) xip_udelay(map, chip, adr, usec) 1016 return (done >= usec) ? -ETIME : 0;
1017}
1012 1018
1013/* 1019/*
1014 * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while 1020 * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
1015 * the flash is actively programming or erasing since we have to poll for 1021 * the flash is actively programming or erasing since we have to poll for
1016 * the operation to complete anyway. We can't do that in a generic way with 1022 * the operation to complete anyway. We can't do that in a generic way with
1017 * a XIP setup so do it before the actual flash operation in this case 1023 * a XIP setup so do it before the actual flash operation in this case
1018 * and stub it out from INVALIDATE_CACHE_UDELAY. 1024 * and stub it out from INVAL_CACHE_AND_WAIT.
1019 */ 1025 */
1020#define XIP_INVAL_CACHED_RANGE(map, from, size) \ 1026#define XIP_INVAL_CACHED_RANGE(map, from, size) \
1021 INVALIDATE_CACHED_RANGE(map, from, size) 1027 INVALIDATE_CACHED_RANGE(map, from, size)
1022 1028
1023#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \ 1029#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
1024 UDELAY(map, chip, cmd_adr, usec) 1030 xip_wait_for_operation(map, chip, cmd_adr, p_usec)
1025
1026/*
1027 * Extra notes:
1028 *
1029 * Activating this XIP support changes the way the code works a bit. For
1030 * example the code to suspend the current process when concurrent access
1031 * happens is never executed because xip_udelay() will always return with the
1032 * same chip state as it was entered with. This is why there is no care for
1033 * the presence of add_wait_queue() or schedule() calls from within a couple
1034 * xip_disable()'d areas of code, like in do_erase_oneblock for example.
1035 * The queueing and scheduling are always happening within xip_udelay().
1036 *
1037 * Similarly, get_chip() and put_chip() just happen to always be executed
1038 * with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
1039 * is in array mode, therefore never executing many cases therein and not
1040 * causing any problem with XIP.
1041 */
1042 1031
1043#else 1032#else
1044 1033
1045#define xip_disable(map, chip, adr) 1034#define xip_disable(map, chip, adr)
1046#define xip_enable(map, chip, adr) 1035#define xip_enable(map, chip, adr)
1047#define XIP_INVAL_CACHED_RANGE(x...) 1036#define XIP_INVAL_CACHED_RANGE(x...)
1037#define INVAL_CACHE_AND_WAIT inval_cache_and_wait_for_operation
1038
1039static int inval_cache_and_wait_for_operation(
1040 struct map_info *map, struct flchip *chip,
1041 unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
1042 int *chip_op_time )
1043{
1044 struct cfi_private *cfi = map->fldrv_priv;
1045 map_word status, status_OK = CMD(0x80);
1046 int z, chip_state = chip->state;
1047 unsigned long timeo;
1048
1049 spin_unlock(chip->mutex);
1050 if (inval_len)
1051 INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
1052 if (*chip_op_time)
1053 cfi_udelay(*chip_op_time);
1054 spin_lock(chip->mutex);
1055
1056 timeo = *chip_op_time * 8 * HZ / 1000000;
1057 if (timeo < HZ/2)
1058 timeo = HZ/2;
1059 timeo += jiffies;
1060
1061 z = 0;
1062 for (;;) {
1063 if (chip->state != chip_state) {
1064 /* Someone's suspended the operation: sleep */
1065 DECLARE_WAITQUEUE(wait, current);
1066
1067 set_current_state(TASK_UNINTERRUPTIBLE);
1068 add_wait_queue(&chip->wq, &wait);
1069 spin_unlock(chip->mutex);
1070 schedule();
1071 remove_wait_queue(&chip->wq, &wait);
1072 timeo = jiffies + (HZ / 2); /* FIXME */
1073 spin_lock(chip->mutex);
1074 continue;
1075 }
1048 1076
1049#define UDELAY(map, chip, adr, usec) \ 1077 status = map_read(map, cmd_adr);
1050do { \ 1078 if (map_word_andequal(map, status, status_OK, status_OK))
1051 spin_unlock(chip->mutex); \ 1079 break;
1052 cfi_udelay(usec); \ 1080
1053 spin_lock(chip->mutex); \ 1081 /* OK Still waiting */
1054} while (0) 1082 if (time_after(jiffies, timeo)) {
1055 1083 map_write(map, CMD(0x70), cmd_adr);
1056#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \ 1084 chip->state = FL_STATUS;
1057do { \ 1085 return -ETIME;
1058 spin_unlock(chip->mutex); \ 1086 }
1059 INVALIDATE_CACHED_RANGE(map, adr, len); \ 1087
1060 cfi_udelay(usec); \ 1088 /* Latency issues. Drop the lock, wait a while and retry */
1061 spin_lock(chip->mutex); \ 1089 z++;
1062} while (0) 1090 spin_unlock(chip->mutex);
1091 cfi_udelay(1);
1092 spin_lock(chip->mutex);
1093 }
1094
1095 if (!z) {
1096 if (!--(*chip_op_time))
1097 *chip_op_time = 1;
1098 } else if (z > 1)
1099 ++(*chip_op_time);
1100
1101 /* Done and happy. */
1102 chip->state = FL_STATUS;
1103 return 0;
1104}
1063 1105
1064#endif 1106#endif
1065 1107
1108#define WAIT_TIMEOUT(map, chip, adr, udelay) \
1109 ({ int __udelay = (udelay); \
1110 INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
1111
1112
1066static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) 1113static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
1067{ 1114{
1068 unsigned long cmd_addr; 1115 unsigned long cmd_addr;
@@ -1252,14 +1299,11 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1252 unsigned long adr, map_word datum, int mode) 1299 unsigned long adr, map_word datum, int mode)
1253{ 1300{
1254 struct cfi_private *cfi = map->fldrv_priv; 1301 struct cfi_private *cfi = map->fldrv_priv;
1255 map_word status, status_OK, write_cmd; 1302 map_word status, write_cmd;
1256 unsigned long timeo; 1303 int ret=0;
1257 int z, ret=0;
1258 1304
1259 adr += chip->start; 1305 adr += chip->start;
1260 1306
1261 /* Let's determine those according to the interleave only once */
1262 status_OK = CMD(0x80);
1263 switch (mode) { 1307 switch (mode) {
1264 case FL_WRITING: 1308 case FL_WRITING:
1265 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41); 1309 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
@@ -1285,57 +1329,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1285 map_write(map, datum, adr); 1329 map_write(map, datum, adr);
1286 chip->state = mode; 1330 chip->state = mode;
1287 1331
1288 INVALIDATE_CACHE_UDELAY(map, chip, adr, 1332 ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
1289 adr, map_bankwidth(map), 1333 adr, map_bankwidth(map),
1290 chip->word_write_time); 1334 &chip->word_write_time);
1291 1335 if (ret) {
1292 timeo = jiffies + (HZ/2); 1336 xip_enable(map, chip, adr);
1293 z = 0; 1337 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
1294 for (;;) { 1338 goto out;
1295 if (chip->state != mode) {
1296 /* Someone's suspended the write. Sleep */
1297 DECLARE_WAITQUEUE(wait, current);
1298
1299 set_current_state(TASK_UNINTERRUPTIBLE);
1300 add_wait_queue(&chip->wq, &wait);
1301 spin_unlock(chip->mutex);
1302 schedule();
1303 remove_wait_queue(&chip->wq, &wait);
1304 timeo = jiffies + (HZ / 2); /* FIXME */
1305 spin_lock(chip->mutex);
1306 continue;
1307 }
1308
1309 status = map_read(map, adr);
1310 if (map_word_andequal(map, status, status_OK, status_OK))
1311 break;
1312
1313 /* OK Still waiting */
1314 if (time_after(jiffies, timeo)) {
1315 map_write(map, CMD(0x70), adr);
1316 chip->state = FL_STATUS;
1317 xip_enable(map, chip, adr);
1318 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
1319 ret = -EIO;
1320 goto out;
1321 }
1322
1323 /* Latency issues. Drop the lock, wait a while and retry */
1324 z++;
1325 UDELAY(map, chip, adr, 1);
1326 }
1327 if (!z) {
1328 chip->word_write_time--;
1329 if (!chip->word_write_time)
1330 chip->word_write_time = 1;
1331 } 1339 }
1332 if (z > 1)
1333 chip->word_write_time++;
1334
1335 /* Done and happy. */
1336 chip->state = FL_STATUS;
1337 1340
1338 /* check for errors */ 1341 /* check for errors */
1342 status = map_read(map, adr);
1339 if (map_word_bitsset(map, status, CMD(0x1a))) { 1343 if (map_word_bitsset(map, status, CMD(0x1a))) {
1340 unsigned long chipstatus = MERGESTATUS(status); 1344 unsigned long chipstatus = MERGESTATUS(status);
1341 1345
@@ -1452,9 +1456,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1452 unsigned long *pvec_seek, int len) 1456 unsigned long *pvec_seek, int len)
1453{ 1457{
1454 struct cfi_private *cfi = map->fldrv_priv; 1458 struct cfi_private *cfi = map->fldrv_priv;
1455 map_word status, status_OK, write_cmd, datum; 1459 map_word status, write_cmd, datum;
1456 unsigned long cmd_adr, timeo; 1460 unsigned long cmd_adr;
1457 int wbufsize, z, ret=0, word_gap, words; 1461 int ret, wbufsize, word_gap, words;
1458 const struct kvec *vec; 1462 const struct kvec *vec;
1459 unsigned long vec_seek; 1463 unsigned long vec_seek;
1460 1464
@@ -1463,7 +1467,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1463 cmd_adr = adr & ~(wbufsize-1); 1467 cmd_adr = adr & ~(wbufsize-1);
1464 1468
1465 /* Let's determine this according to the interleave only once */ 1469 /* Let's determine this according to the interleave only once */
1466 status_OK = CMD(0x80);
1467 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9); 1470 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
1468 1471
1469 spin_lock(chip->mutex); 1472 spin_lock(chip->mutex);
@@ -1477,12 +1480,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1477 ENABLE_VPP(map); 1480 ENABLE_VPP(map);
1478 xip_disable(map, chip, cmd_adr); 1481 xip_disable(map, chip, cmd_adr);
1479 1482
1480 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set 1483 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
1481 [...], the device will not accept any more Write to Buffer commands". 1484 [...], the device will not accept any more Write to Buffer commands".
1482 So we must check here and reset those bits if they're set. Otherwise 1485 So we must check here and reset those bits if they're set. Otherwise
1483 we're just pissing in the wind */ 1486 we're just pissing in the wind */
1484 if (chip->state != FL_STATUS) 1487 if (chip->state != FL_STATUS) {
1485 map_write(map, CMD(0x70), cmd_adr); 1488 map_write(map, CMD(0x70), cmd_adr);
1489 chip->state = FL_STATUS;
1490 }
1486 status = map_read(map, cmd_adr); 1491 status = map_read(map, cmd_adr);
1487 if (map_word_bitsset(map, status, CMD(0x30))) { 1492 if (map_word_bitsset(map, status, CMD(0x30))) {
1488 xip_enable(map, chip, cmd_adr); 1493 xip_enable(map, chip, cmd_adr);
@@ -1493,32 +1498,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1493 } 1498 }
1494 1499
1495 chip->state = FL_WRITING_TO_BUFFER; 1500 chip->state = FL_WRITING_TO_BUFFER;
1496 1501 map_write(map, write_cmd, cmd_adr);
1497 z = 0; 1502 ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
1498 for (;;) { 1503 if (ret) {
1499 map_write(map, write_cmd, cmd_adr); 1504 /* Argh. Not ready for write to buffer */
1500 1505 map_word Xstatus = map_read(map, cmd_adr);
1506 map_write(map, CMD(0x70), cmd_adr);
1507 chip->state = FL_STATUS;
1501 status = map_read(map, cmd_adr); 1508 status = map_read(map, cmd_adr);
1502 if (map_word_andequal(map, status, status_OK, status_OK)) 1509 map_write(map, CMD(0x50), cmd_adr);
1503 break; 1510 map_write(map, CMD(0x70), cmd_adr);
1504 1511 xip_enable(map, chip, cmd_adr);
1505 UDELAY(map, chip, cmd_adr, 1); 1512 printk(KERN_ERR "%s: Chip not ready for buffer write. Xstatus = %lx, status = %lx\n",
1506 1513 map->name, Xstatus.x[0], status.x[0]);
1507 if (++z > 20) { 1514 goto out;
1508 /* Argh. Not ready for write to buffer */
1509 map_word Xstatus;
1510 map_write(map, CMD(0x70), cmd_adr);
1511 chip->state = FL_STATUS;
1512 Xstatus = map_read(map, cmd_adr);
1513 /* Odd. Clear status bits */
1514 map_write(map, CMD(0x50), cmd_adr);
1515 map_write(map, CMD(0x70), cmd_adr);
1516 xip_enable(map, chip, cmd_adr);
1517 printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
1518 map->name, status.x[0], Xstatus.x[0]);
1519 ret = -EIO;
1520 goto out;
1521 }
1522 } 1515 }
1523 1516
1524 /* Figure out the number of words to write */ 1517 /* Figure out the number of words to write */
@@ -1573,56 +1566,19 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1573 map_write(map, CMD(0xd0), cmd_adr); 1566 map_write(map, CMD(0xd0), cmd_adr);
1574 chip->state = FL_WRITING; 1567 chip->state = FL_WRITING;
1575 1568
1576 INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, 1569 ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
1577 adr, len, 1570 adr, len,
1578 chip->buffer_write_time); 1571 &chip->buffer_write_time);
1579 1572 if (ret) {
1580 timeo = jiffies + (HZ/2); 1573 map_write(map, CMD(0x70), cmd_adr);
1581 z = 0; 1574 chip->state = FL_STATUS;
1582 for (;;) { 1575 xip_enable(map, chip, cmd_adr);
1583 if (chip->state != FL_WRITING) { 1576 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
1584 /* Someone's suspended the write. Sleep */ 1577 goto out;
1585 DECLARE_WAITQUEUE(wait, current);
1586 set_current_state(TASK_UNINTERRUPTIBLE);
1587 add_wait_queue(&chip->wq, &wait);
1588 spin_unlock(chip->mutex);
1589 schedule();
1590 remove_wait_queue(&chip->wq, &wait);
1591 timeo = jiffies + (HZ / 2); /* FIXME */
1592 spin_lock(chip->mutex);
1593 continue;
1594 }
1595
1596 status = map_read(map, cmd_adr);
1597 if (map_word_andequal(map, status, status_OK, status_OK))
1598 break;
1599
1600 /* OK Still waiting */
1601 if (time_after(jiffies, timeo)) {
1602 map_write(map, CMD(0x70), cmd_adr);
1603 chip->state = FL_STATUS;
1604 xip_enable(map, chip, cmd_adr);
1605 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
1606 ret = -EIO;
1607 goto out;
1608 }
1609
1610 /* Latency issues. Drop the lock, wait a while and retry */
1611 z++;
1612 UDELAY(map, chip, cmd_adr, 1);
1613 }
1614 if (!z) {
1615 chip->buffer_write_time--;
1616 if (!chip->buffer_write_time)
1617 chip->buffer_write_time = 1;
1618 } 1578 }
1619 if (z > 1)
1620 chip->buffer_write_time++;
1621
1622 /* Done and happy. */
1623 chip->state = FL_STATUS;
1624 1579
1625 /* check for errors */ 1580 /* check for errors */
1581 status = map_read(map, cmd_adr);
1626 if (map_word_bitsset(map, status, CMD(0x1a))) { 1582 if (map_word_bitsset(map, status, CMD(0x1a))) {
1627 unsigned long chipstatus = MERGESTATUS(status); 1583 unsigned long chipstatus = MERGESTATUS(status);
1628 1584
@@ -1693,6 +1649,11 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
1693 if (chipnum == cfi->numchips) 1649 if (chipnum == cfi->numchips)
1694 return 0; 1650 return 0;
1695 } 1651 }
1652
1653 /* Be nice and reschedule with the chip in a usable state for other
1654 processes. */
1655 cond_resched();
1656
1696 } while (len); 1657 } while (len);
1697 1658
1698 return 0; 1659 return 0;
@@ -1713,17 +1674,12 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1713 unsigned long adr, int len, void *thunk) 1674 unsigned long adr, int len, void *thunk)
1714{ 1675{
1715 struct cfi_private *cfi = map->fldrv_priv; 1676 struct cfi_private *cfi = map->fldrv_priv;
1716 map_word status, status_OK; 1677 map_word status;
1717 unsigned long timeo;
1718 int retries = 3; 1678 int retries = 3;
1719 DECLARE_WAITQUEUE(wait, current); 1679 int ret;
1720 int ret = 0;
1721 1680
1722 adr += chip->start; 1681 adr += chip->start;
1723 1682
1724 /* Let's determine this according to the interleave only once */
1725 status_OK = CMD(0x80);
1726
1727 retry: 1683 retry:
1728 spin_lock(chip->mutex); 1684 spin_lock(chip->mutex);
1729 ret = get_chip(map, chip, adr, FL_ERASING); 1685 ret = get_chip(map, chip, adr, FL_ERASING);
@@ -1745,48 +1701,15 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1745 chip->state = FL_ERASING; 1701 chip->state = FL_ERASING;
1746 chip->erase_suspended = 0; 1702 chip->erase_suspended = 0;
1747 1703
1748 INVALIDATE_CACHE_UDELAY(map, chip, adr, 1704 ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
1749 adr, len, 1705 adr, len,
1750 chip->erase_time*1000/2); 1706 &chip->erase_time);
1751 1707 if (ret) {
1752 /* FIXME. Use a timer to check this, and return immediately. */ 1708 map_write(map, CMD(0x70), adr);
1753 /* Once the state machine's known to be working I'll do that */ 1709 chip->state = FL_STATUS;
1754 1710 xip_enable(map, chip, adr);
1755 timeo = jiffies + (HZ*20); 1711 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
1756 for (;;) { 1712 goto out;
1757 if (chip->state != FL_ERASING) {
1758 /* Someone's suspended the erase. Sleep */
1759 set_current_state(TASK_UNINTERRUPTIBLE);
1760 add_wait_queue(&chip->wq, &wait);
1761 spin_unlock(chip->mutex);
1762 schedule();
1763 remove_wait_queue(&chip->wq, &wait);
1764 spin_lock(chip->mutex);
1765 continue;
1766 }
1767 if (chip->erase_suspended) {
1768 /* This erase was suspended and resumed.
1769 Adjust the timeout */
1770 timeo = jiffies + (HZ*20); /* FIXME */
1771 chip->erase_suspended = 0;
1772 }
1773
1774 status = map_read(map, adr);
1775 if (map_word_andequal(map, status, status_OK, status_OK))
1776 break;
1777
1778 /* OK Still waiting */
1779 if (time_after(jiffies, timeo)) {
1780 map_write(map, CMD(0x70), adr);
1781 chip->state = FL_STATUS;
1782 xip_enable(map, chip, adr);
1783 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
1784 ret = -EIO;
1785 goto out;
1786 }
1787
1788 /* Latency issues. Drop the lock, wait a while and retry */
1789 UDELAY(map, chip, adr, 1000000/HZ);
1790 } 1713 }
1791 1714
1792 /* We've broken this before. It doesn't hurt to be safe */ 1715 /* We've broken this before. It doesn't hurt to be safe */
@@ -1815,7 +1738,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1815 ret = -EIO; 1738 ret = -EIO;
1816 } else if (chipstatus & 0x20 && retries--) { 1739 } else if (chipstatus & 0x20 && retries--) {
1817 printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); 1740 printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
1818 timeo = jiffies + HZ;
1819 put_chip(map, chip, adr); 1741 put_chip(map, chip, adr);
1820 spin_unlock(chip->mutex); 1742 spin_unlock(chip->mutex);
1821 goto retry; 1743 goto retry;
@@ -1921,15 +1843,11 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1921{ 1843{
1922 struct cfi_private *cfi = map->fldrv_priv; 1844 struct cfi_private *cfi = map->fldrv_priv;
1923 struct cfi_pri_intelext *extp = cfi->cmdset_priv; 1845 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
1924 map_word status, status_OK; 1846 int udelay;
1925 unsigned long timeo = jiffies + HZ;
1926 int ret; 1847 int ret;
1927 1848
1928 adr += chip->start; 1849 adr += chip->start;
1929 1850
1930 /* Let's determine this according to the interleave only once */
1931 status_OK = CMD(0x80);
1932
1933 spin_lock(chip->mutex); 1851 spin_lock(chip->mutex);
1934 ret = get_chip(map, chip, adr, FL_LOCKING); 1852 ret = get_chip(map, chip, adr, FL_LOCKING);
1935 if (ret) { 1853 if (ret) {
@@ -1954,41 +1872,21 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1954 * If Instant Individual Block Locking supported then no need 1872 * If Instant Individual Block Locking supported then no need
1955 * to delay. 1873 * to delay.
1956 */ 1874 */
1875 udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
1957 1876
1958 if (!extp || !(extp->FeatureSupport & (1 << 5))) 1877 ret = WAIT_TIMEOUT(map, chip, adr, udelay);
1959 UDELAY(map, chip, adr, 1000000/HZ); 1878 if (ret) {
1960 1879 map_write(map, CMD(0x70), adr);
1961 /* FIXME. Use a timer to check this, and return immediately. */ 1880 chip->state = FL_STATUS;
1962 /* Once the state machine's known to be working I'll do that */ 1881 xip_enable(map, chip, adr);
1963 1882 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
1964 timeo = jiffies + (HZ*20); 1883 goto out;
1965 for (;;) {
1966
1967 status = map_read(map, adr);
1968 if (map_word_andequal(map, status, status_OK, status_OK))
1969 break;
1970
1971 /* OK Still waiting */
1972 if (time_after(jiffies, timeo)) {
1973 map_write(map, CMD(0x70), adr);
1974 chip->state = FL_STATUS;
1975 xip_enable(map, chip, adr);
1976 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
1977 put_chip(map, chip, adr);
1978 spin_unlock(chip->mutex);
1979 return -EIO;
1980 }
1981
1982 /* Latency issues. Drop the lock, wait a while and retry */
1983 UDELAY(map, chip, adr, 1);
1984 } 1884 }
1985 1885
1986 /* Done and happy. */
1987 chip->state = FL_STATUS;
1988 xip_enable(map, chip, adr); 1886 xip_enable(map, chip, adr);
1989 put_chip(map, chip, adr); 1887out: put_chip(map, chip, adr);
1990 spin_unlock(chip->mutex); 1888 spin_unlock(chip->mutex);
1991 return 0; 1889 return ret;
1992} 1890}
1993 1891
1994static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len) 1892static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
@@ -2445,28 +2343,8 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
2445 kfree(mtd->eraseregions); 2343 kfree(mtd->eraseregions);
2446} 2344}
2447 2345
2448static char im_name_0001[] = "cfi_cmdset_0001";
2449static char im_name_0003[] = "cfi_cmdset_0003";
2450static char im_name_0200[] = "cfi_cmdset_0200";
2451
2452static int __init cfi_intelext_init(void)
2453{
2454 inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
2455 inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
2456 inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
2457 return 0;
2458}
2459
2460static void __exit cfi_intelext_exit(void)
2461{
2462 inter_module_unregister(im_name_0001);
2463 inter_module_unregister(im_name_0003);
2464 inter_module_unregister(im_name_0200);
2465}
2466
2467module_init(cfi_intelext_init);
2468module_exit(cfi_intelext_exit);
2469
2470MODULE_LICENSE("GPL"); 2346MODULE_LICENSE("GPL");
2471MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); 2347MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
2472MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips"); 2348MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");
2349MODULE_ALIAS("cfi_cmdset_0003");
2350MODULE_ALIAS("cfi_cmdset_0200");
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index aed10bd5c3c3..1e01ad38b26e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -236,6 +236,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
236 mtd->resume = cfi_amdstd_resume; 236 mtd->resume = cfi_amdstd_resume;
237 mtd->flags = MTD_CAP_NORFLASH; 237 mtd->flags = MTD_CAP_NORFLASH;
238 mtd->name = map->name; 238 mtd->name = map->name;
239 mtd->writesize = 1;
239 240
240 if (cfi->cfi_mode==CFI_MODE_CFI){ 241 if (cfi->cfi_mode==CFI_MODE_CFI){
241 unsigned char bootloc; 242 unsigned char bootloc;
@@ -326,7 +327,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
326 327
327 return cfi_amdstd_setup(mtd); 328 return cfi_amdstd_setup(mtd);
328} 329}
329 330EXPORT_SYMBOL_GPL(cfi_cmdset_0002);
330 331
331static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) 332static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
332{ 333{
@@ -1758,25 +1759,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
1758 kfree(mtd->eraseregions); 1759 kfree(mtd->eraseregions);
1759} 1760}
1760 1761
1761static char im_name[]="cfi_cmdset_0002";
1762
1763
1764static int __init cfi_amdstd_init(void)
1765{
1766 inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
1767 return 0;
1768}
1769
1770
1771static void __exit cfi_amdstd_exit(void)
1772{
1773 inter_module_unregister(im_name);
1774}
1775
1776
1777module_init(cfi_amdstd_init);
1778module_exit(cfi_amdstd_exit);
1779
1780MODULE_LICENSE("GPL"); 1762MODULE_LICENSE("GPL");
1781MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al."); 1763MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
1782MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips"); 1764MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 0807c1c91e55..fae70a5db540 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -162,6 +162,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
162 162
163 return cfi_staa_setup(map); 163 return cfi_staa_setup(map);
164} 164}
165EXPORT_SYMBOL_GPL(cfi_cmdset_0020);
165 166
166static struct mtd_info *cfi_staa_setup(struct map_info *map) 167static struct mtd_info *cfi_staa_setup(struct map_info *map)
167{ 168{
@@ -237,9 +238,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
237 mtd->unlock = cfi_staa_unlock; 238 mtd->unlock = cfi_staa_unlock;
238 mtd->suspend = cfi_staa_suspend; 239 mtd->suspend = cfi_staa_suspend;
239 mtd->resume = cfi_staa_resume; 240 mtd->resume = cfi_staa_resume;
240 mtd->flags = MTD_CAP_NORFLASH; 241 mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
241 mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */ 242 mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
242 mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
243 map->fldrv = &cfi_staa_chipdrv; 243 map->fldrv = &cfi_staa_chipdrv;
244 __module_get(THIS_MODULE); 244 __module_get(THIS_MODULE);
245 mtd->name = map->name; 245 mtd->name = map->name;
@@ -1410,20 +1410,4 @@ static void cfi_staa_destroy(struct mtd_info *mtd)
1410 kfree(cfi); 1410 kfree(cfi);
1411} 1411}
1412 1412
1413static char im_name[]="cfi_cmdset_0020";
1414
1415static int __init cfi_staa_init(void)
1416{
1417 inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020);
1418 return 0;
1419}
1420
1421static void __exit cfi_staa_exit(void)
1422{
1423 inter_module_unregister(im_name);
1424}
1425
1426module_init(cfi_staa_init);
1427module_exit(cfi_staa_exit);
1428
1429MODULE_LICENSE("GPL"); 1413MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index e636aa86bc24..4bf9f8cac0dd 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -349,12 +349,12 @@ static void print_cfi_ident(struct cfi_ident *cfip)
349 else 349 else
350 printk("No Vpp line\n"); 350 printk("No Vpp line\n");
351 351
352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); 352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); 353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
354 354
355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { 355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); 356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); 357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
358 } 358 }
359 else 359 else
360 printk("Full buffer write not supported\n"); 360 printk("Full buffer write not supported\n");
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index 41bd59d20d85..cdb0f590b40c 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -37,8 +37,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
37 if (!mtd) 37 if (!mtd)
38 mtd = check_cmd_set(map, 0); /* Then the secondary */ 38 mtd = check_cmd_set(map, 0); /* Then the secondary */
39 39
40 if (mtd) 40 if (mtd) {
41 if (mtd->size > map->size) {
42 printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
43 (unsigned long)mtd->size >> 10,
44 (unsigned long)map->size >> 10);
45 mtd->size = map->size;
46 }
41 return mtd; 47 return mtd;
48 }
42 49
43 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); 50 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
44 51
@@ -100,7 +107,12 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
100 * Align bitmap storage size to full byte. 107 * Align bitmap storage size to full byte.
101 */ 108 */
102 max_chips = map->size >> cfi.chipshift; 109 max_chips = map->size >> cfi.chipshift;
103 mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); 110 if (!max_chips) {
111 printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
112 max_chips = 1;
113 }
114
115 mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG;
104 chip_map = kmalloc(mapsize, GFP_KERNEL); 116 chip_map = kmalloc(mapsize, GFP_KERNEL);
105 if (!chip_map) { 117 if (!chip_map) {
106 printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); 118 printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
@@ -194,25 +206,28 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
194{ 206{
195 struct cfi_private *cfi = map->fldrv_priv; 207 struct cfi_private *cfi = map->fldrv_priv;
196 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; 208 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
197#if defined(CONFIG_MODULES) && defined(HAVE_INTER_MODULE) 209#ifdef CONFIG_MODULES
198 char probename[32]; 210 char probename[16+sizeof(MODULE_SYMBOL_PREFIX)];
199 cfi_cmdset_fn_t *probe_function; 211 cfi_cmdset_fn_t *probe_function;
200 212
201 sprintf(probename, "cfi_cmdset_%4.4X", type); 213 sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type);
202 214
203 probe_function = inter_module_get_request(probename, probename); 215 probe_function = __symbol_get(probename);
216 if (!probe_function) {
217 request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1);
218 probe_function = __symbol_get(probename);
219 }
204 220
205 if (probe_function) { 221 if (probe_function) {
206 struct mtd_info *mtd; 222 struct mtd_info *mtd;
207 223
208 mtd = (*probe_function)(map, primary); 224 mtd = (*probe_function)(map, primary);
209 /* If it was happy, it'll have increased its own use count */ 225 /* If it was happy, it'll have increased its own use count */
210 inter_module_put(probename); 226 symbol_put_addr(probe_function);
211 return mtd; 227 return mtd;
212 } 228 }
213#endif 229#endif
214 printk(KERN_NOTICE "Support for command set %04X not present\n", 230 printk(KERN_NOTICE "Support for command set %04X not present\n", type);
215 type);
216 231
217 return NULL; 232 return NULL;
218} 233}
@@ -226,12 +241,8 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
226 return NULL; 241 return NULL;
227 242
228 switch(type){ 243 switch(type){
229 /* Urgh. Ifdefs. The version with weak symbols was 244 /* We need these for the !CONFIG_MODULES case,
230 * _much_ nicer. Shame it didn't seem to work on 245 because symbol_get() doesn't work there */
231 * anything but x86, really.
232 * But we can't rely in inter_module_get() because
233 * that'd mean we depend on link order.
234 */
235#ifdef CONFIG_MTD_CFI_INTELEXT 246#ifdef CONFIG_MTD_CFI_INTELEXT
236 case 0x0001: 247 case 0x0001:
237 case 0x0003: 248 case 0x0003:
@@ -246,9 +257,9 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
246 case 0x0020: 257 case 0x0020:
247 return cfi_cmdset_0020(map, primary); 258 return cfi_cmdset_0020(map, primary);
248#endif 259#endif
260 default:
261 return cfi_cmdset_unknown(map, primary);
249 } 262 }
250
251 return cfi_cmdset_unknown(map, primary);
252} 263}
253 264
254MODULE_LICENSE("GPL"); 265MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index bd2e876a814b..763925747db6 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -70,7 +70,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
70 mtd->read = mapram_read; 70 mtd->read = mapram_read;
71 mtd->write = mapram_write; 71 mtd->write = mapram_write;
72 mtd->sync = mapram_nop; 72 mtd->sync = mapram_nop;
73 mtd->flags = MTD_CAP_RAM | MTD_VOLATILE; 73 mtd->flags = MTD_CAP_RAM;
74 74
75 mtd->erasesize = PAGE_SIZE; 75 mtd->erasesize = PAGE_SIZE;
76 while(mtd->size & (mtd->erasesize - 1)) 76 while(mtd->size & (mtd->erasesize - 1))
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index 624c12c232c8..bc6ee9ef8a31 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -46,9 +46,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
46 mtd->write = maprom_write; 46 mtd->write = maprom_write;
47 mtd->sync = maprom_nop; 47 mtd->sync = maprom_nop;
48 mtd->flags = MTD_CAP_ROM; 48 mtd->flags = MTD_CAP_ROM;
49 mtd->erasesize = 131072; 49 mtd->erasesize = map->size;
50 while(mtd->size & (mtd->erasesize - 1))
51 mtd->erasesize >>= 1;
52 50
53 __module_get(THIS_MODULE); 51 __module_get(THIS_MODULE);
54 return mtd; 52 return mtd;
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index 3cc0b23c5865..967abbecdff9 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -140,6 +140,7 @@ static struct mtd_info *sharp_probe(struct map_info *map)
140 mtd->suspend = sharp_suspend; 140 mtd->suspend = sharp_suspend;
141 mtd->resume = sharp_resume; 141 mtd->resume = sharp_resume;
142 mtd->flags = MTD_CAP_NORFLASH; 142 mtd->flags = MTD_CAP_NORFLASH;
143 mtd->writesize = 1;
143 mtd->name = map->name; 144 mtd->name = map->name;
144 145
145 memset(sharp, 0, sizeof(*sharp)); 146 memset(sharp, 0, sizeof(*sharp));
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 7fac438b5c32..16c02b5ccf7e 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -47,6 +47,11 @@ config MTD_MS02NV
47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a 47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a
48 DECsystem 5900 equipped with such a module. 48 DECsystem 5900 equipped with such a module.
49 49
50 If you want to compile this driver as a module ( = code which can be
51 inserted in and removed from the running kernel whenever you want),
52 say M here and read <file:Documentation/modules.txt>. The module will
53 be called ms02-nv.o.
54
50config MTD_DATAFLASH 55config MTD_DATAFLASH
51 tristate "Support for AT45xxx DataFlash" 56 tristate "Support for AT45xxx DataFlash"
52 depends on MTD && SPI_MASTER && EXPERIMENTAL 57 depends on MTD && SPI_MASTER && EXPERIMENTAL
@@ -209,7 +214,6 @@ config MTD_DOC2001PLUS
209config MTD_DOCPROBE 214config MTD_DOCPROBE
210 tristate 215 tristate
211 select MTD_DOCECC 216 select MTD_DOCECC
212 select OBSOLETE_INTERMODULE
213 217
214config MTD_DOCECC 218config MTD_DOCECC
215 tristate 219 tristate
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index b6573670316f..0f788d5c4bf8 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -3,13 +3,6 @@
3# 3#
4# $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $ 4# $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $
5 5
6# *** BIG UGLY NOTE ***
7#
8# The removal of get_module_symbol() and replacement with
9# inter_module_register() et al has introduced a link order dependency
10# here where previously there was none. We now have to ensure that
11# doc200[01].o are linked before docprobe.o
12
13obj-$(CONFIG_MTD_DOC2000) += doc2000.o 6obj-$(CONFIG_MTD_DOC2000) += doc2000.o
14obj-$(CONFIG_MTD_DOC2001) += doc2001.o 7obj-$(CONFIG_MTD_DOC2001) += doc2001.o
15obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o 8obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4160b8334c53..0d98c223c5fc 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -4,7 +4,7 @@
4 * block2mtd.c - create an mtd from a block device 4 * block2mtd.c - create an mtd from a block device
5 * 5 *
6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> 6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk>
7 * Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de> 7 * Copyright (C) 2004-2006 Jörn Engel <joern@wh.fh-wedel.de>
8 * 8 *
9 * Licence: GPL 9 * Licence: GPL
10 */ 10 */
@@ -331,7 +331,6 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
331 dev->mtd.writev = default_mtd_writev; 331 dev->mtd.writev = default_mtd_writev;
332 dev->mtd.sync = block2mtd_sync; 332 dev->mtd.sync = block2mtd_sync;
333 dev->mtd.read = block2mtd_read; 333 dev->mtd.read = block2mtd_read;
334 dev->mtd.readv = default_mtd_readv;
335 dev->mtd.priv = dev; 334 dev->mtd.priv = dev;
336 dev->mtd.owner = THIS_MODULE; 335 dev->mtd.owner = THIS_MODULE;
337 336
@@ -351,6 +350,12 @@ devinit_err:
351} 350}
352 351
353 352
353/* This function works similar to reguler strtoul. In addition, it
354 * allows some suffixes for a more human-readable number format:
355 * ki, Ki, kiB, KiB - multiply result with 1024
356 * Mi, MiB - multiply result with 1024^2
357 * Gi, GiB - multiply result with 1024^3
358 */
354static int ustrtoul(const char *cp, char **endp, unsigned int base) 359static int ustrtoul(const char *cp, char **endp, unsigned int base)
355{ 360{
356 unsigned long result = simple_strtoul(cp, endp, base); 361 unsigned long result = simple_strtoul(cp, endp, base);
@@ -359,11 +364,16 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
359 result *= 1024; 364 result *= 1024;
360 case 'M': 365 case 'M':
361 result *= 1024; 366 result *= 1024;
367 case 'K':
362 case 'k': 368 case 'k':
363 result *= 1024; 369 result *= 1024;
364 /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ 370 /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
365 if ((*endp)[1] == 'i') 371 if ((*endp)[1] == 'i') {
366 (*endp) += 2; 372 if ((*endp)[2] == 'B')
373 (*endp) += 3;
374 else
375 (*endp) += 2;
376 }
367 } 377 }
368 return result; 378 return result;
369} 379}
@@ -418,7 +428,8 @@ static inline void kill_final_newline(char *str)
418 428
419static int block2mtd_setup(const char *val, struct kernel_param *kp) 429static int block2mtd_setup(const char *val, struct kernel_param *kp)
420{ 430{
421 char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */ 431 char buf[80+12]; /* 80 for device, 12 for erase size */
432 char *str = buf;
422 char *token[2]; 433 char *token[2];
423 char *name; 434 char *name;
424 size_t erase_size = PAGE_SIZE; 435 size_t erase_size = PAGE_SIZE;
@@ -430,7 +441,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
430 strcpy(str, val); 441 strcpy(str, val);
431 kill_final_newline(str); 442 kill_final_newline(str);
432 443
433 for (i=0; i<2; i++) 444 for (i = 0; i < 2; i++)
434 token[i] = strsep(&str, ","); 445 token[i] = strsep(&str, ",");
435 446
436 if (str) 447 if (str)
@@ -449,8 +460,10 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
449 460
450 if (token[1]) { 461 if (token[1]) {
451 ret = parse_num(&erase_size, token[1]); 462 ret = parse_num(&erase_size, token[1]);
452 if (ret) 463 if (ret) {
464 kfree(name);
453 parse_err("illegal erase size"); 465 parse_err("illegal erase size");
466 }
454 } 467 }
455 468
456 add_device(name, erase_size); 469 add_device(name, erase_size);
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 23e7a5c7d2c1..c54e40464d82 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -59,13 +59,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
62static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 62static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
63 unsigned long count, loff_t to, size_t *retlen, 63 struct mtd_oob_ops *ops);
64 u_char *eccbuf, struct nand_oobinfo *oobsel); 64static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
65static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 65 struct mtd_oob_ops *ops);
66 size_t *retlen, u_char *buf);
67static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
68 size_t *retlen, const u_char *buf);
69static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len, 66static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
70 size_t *retlen, const u_char *buf); 67 size_t *retlen, const u_char *buf);
71static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); 68static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
@@ -517,16 +514,9 @@ static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
517 return retval; 514 return retval;
518} 515}
519 516
520static const char im_name[] = "DoC2k_init"; 517/* This routine is found from the docprobe code by symbol_get(),
521 518 * which will bump the use count of this module. */
522/* This routine is made available to other mtd code via 519void DoC2k_init(struct mtd_info *mtd)
523 * inter_module_register. It must only be accessed through
524 * inter_module_get which will bump the use count of this module. The
525 * addresses passed back in mtd are valid as long as the use count of
526 * this module is non-zero, i.e. between inter_module_get and
527 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
528 */
529static void DoC2k_init(struct mtd_info *mtd)
530{ 520{
531 struct DiskOnChip *this = mtd->priv; 521 struct DiskOnChip *this = mtd->priv;
532 struct DiskOnChip *old = NULL; 522 struct DiskOnChip *old = NULL;
@@ -586,7 +576,7 @@ static void DoC2k_init(struct mtd_info *mtd)
586 mtd->ecctype = MTD_ECC_RS_DiskOnChip; 576 mtd->ecctype = MTD_ECC_RS_DiskOnChip;
587 mtd->size = 0; 577 mtd->size = 0;
588 mtd->erasesize = 0; 578 mtd->erasesize = 0;
589 mtd->oobblock = 512; 579 mtd->writesize = 512;
590 mtd->oobsize = 16; 580 mtd->oobsize = 16;
591 mtd->owner = THIS_MODULE; 581 mtd->owner = THIS_MODULE;
592 mtd->erase = doc_erase; 582 mtd->erase = doc_erase;
@@ -594,9 +584,6 @@ static void DoC2k_init(struct mtd_info *mtd)
594 mtd->unpoint = NULL; 584 mtd->unpoint = NULL;
595 mtd->read = doc_read; 585 mtd->read = doc_read;
596 mtd->write = doc_write; 586 mtd->write = doc_write;
597 mtd->read_ecc = doc_read_ecc;
598 mtd->write_ecc = doc_write_ecc;
599 mtd->writev_ecc = doc_writev_ecc;
600 mtd->read_oob = doc_read_oob; 587 mtd->read_oob = doc_read_oob;
601 mtd->write_oob = doc_write_oob; 588 mtd->write_oob = doc_write_oob;
602 mtd->sync = NULL; 589 mtd->sync = NULL;
@@ -623,6 +610,7 @@ static void DoC2k_init(struct mtd_info *mtd)
623 return; 610 return;
624 } 611 }
625} 612}
613EXPORT_SYMBOL_GPL(DoC2k_init);
626 614
627static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, 615static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
628 size_t * retlen, u_char * buf) 616 size_t * retlen, u_char * buf)
@@ -971,72 +959,18 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
971 return 0; 959 return 0;
972} 960}
973 961
974static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 962static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
975 unsigned long count, loff_t to, size_t *retlen, 963 struct mtd_oob_ops *ops)
976 u_char *eccbuf, struct nand_oobinfo *oobsel)
977{
978 static char static_buf[512];
979 static DEFINE_MUTEX(writev_buf_mutex);
980
981 size_t totretlen = 0;
982 size_t thisvecofs = 0;
983 int ret= 0;
984
985 mutex_lock(&writev_buf_mutex);
986
987 while(count) {
988 size_t thislen, thisretlen;
989 unsigned char *buf;
990
991 buf = vecs->iov_base + thisvecofs;
992 thislen = vecs->iov_len - thisvecofs;
993
994
995 if (thislen >= 512) {
996 thislen = thislen & ~(512-1);
997 thisvecofs += thislen;
998 } else {
999 /* Not enough to fill a page. Copy into buf */
1000 memcpy(static_buf, buf, thislen);
1001 buf = &static_buf[thislen];
1002
1003 while(count && thislen < 512) {
1004 vecs++;
1005 count--;
1006 thisvecofs = min((512-thislen), vecs->iov_len);
1007 memcpy(buf, vecs->iov_base, thisvecofs);
1008 thislen += thisvecofs;
1009 buf += thisvecofs;
1010 }
1011 buf = static_buf;
1012 }
1013 if (count && thisvecofs == vecs->iov_len) {
1014 thisvecofs = 0;
1015 vecs++;
1016 count--;
1017 }
1018 ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
1019
1020 totretlen += thisretlen;
1021
1022 if (ret || thisretlen != thislen)
1023 break;
1024
1025 to += thislen;
1026 }
1027
1028 mutex_unlock(&writev_buf_mutex);
1029 *retlen = totretlen;
1030 return ret;
1031}
1032
1033
1034static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1035 size_t * retlen, u_char * buf)
1036{ 964{
1037 struct DiskOnChip *this = mtd->priv; 965 struct DiskOnChip *this = mtd->priv;
1038 int len256 = 0, ret; 966 int len256 = 0, ret;
1039 struct Nand *mychip; 967 struct Nand *mychip;
968 uint8_t *buf = ops->oobbuf;
969 size_t len = ops->len;
970
971 BUG_ON(ops->mode != MTD_OOB_PLACE);
972
973 ofs += ops->ooboffs;
1040 974
1041 mutex_lock(&this->lock); 975 mutex_lock(&this->lock);
1042 976
@@ -1077,7 +1011,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1077 1011
1078 DoC_ReadBuf(this, &buf[len256], len - len256); 1012 DoC_ReadBuf(this, &buf[len256], len - len256);
1079 1013
1080 *retlen = len; 1014 ops->retlen = len;
1081 /* Reading the full OOB data drops us off of the end of the page, 1015 /* Reading the full OOB data drops us off of the end of the page,
1082 * causing the flash device to go into busy mode, so we need 1016 * causing the flash device to go into busy mode, so we need
1083 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ 1017 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
@@ -1192,17 +1126,20 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
1192 1126
1193} 1127}
1194 1128
1195static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 1129static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1196 size_t * retlen, const u_char * buf) 1130 struct mtd_oob_ops *ops)
1197{ 1131{
1198 struct DiskOnChip *this = mtd->priv; 1132 struct DiskOnChip *this = mtd->priv;
1199 int ret; 1133 int ret;
1200 1134
1201 mutex_lock(&this->lock); 1135 BUG_ON(ops->mode != MTD_OOB_PLACE);
1202 ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); 1136
1137 mutex_lock(&this->lock);
1138 ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,
1139 &ops->retlen, ops->oobbuf);
1203 1140
1204 mutex_unlock(&this->lock); 1141 mutex_unlock(&this->lock);
1205 return ret; 1142 return ret;
1206} 1143}
1207 1144
1208static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) 1145static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
@@ -1277,12 +1214,6 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1277 * 1214 *
1278 ****************************************************************************/ 1215 ****************************************************************************/
1279 1216
1280static int __init init_doc2000(void)
1281{
1282 inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
1283 return 0;
1284}
1285
1286static void __exit cleanup_doc2000(void) 1217static void __exit cleanup_doc2000(void)
1287{ 1218{
1288 struct mtd_info *mtd; 1219 struct mtd_info *mtd;
@@ -1298,11 +1229,9 @@ static void __exit cleanup_doc2000(void)
1298 kfree(this->chips); 1229 kfree(this->chips);
1299 kfree(mtd); 1230 kfree(mtd);
1300 } 1231 }
1301 inter_module_unregister(im_name);
1302} 1232}
1303 1233
1304module_exit(cleanup_doc2000); 1234module_exit(cleanup_doc2000);
1305module_init(init_doc2000);
1306 1235
1307MODULE_LICENSE("GPL"); 1236MODULE_LICENSE("GPL");
1308MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); 1237MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 681a9c73a2a3..0cf022a69e65 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -43,10 +43,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
43static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 43static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
44 size_t *retlen, const u_char *buf, u_char *eccbuf, 44 size_t *retlen, const u_char *buf, u_char *eccbuf,
45 struct nand_oobinfo *oobsel); 45 struct nand_oobinfo *oobsel);
46static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 46static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
47 size_t *retlen, u_char *buf); 47 struct mtd_oob_ops *ops);
48static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 48static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
49 size_t *retlen, const u_char *buf); 49 struct mtd_oob_ops *ops);
50static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); 50static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
51 51
52static struct mtd_info *docmillist = NULL; 52static struct mtd_info *docmillist = NULL;
@@ -324,16 +324,9 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
324 return retval; 324 return retval;
325} 325}
326 326
327static const char im_name[] = "DoCMil_init"; 327/* This routine is found from the docprobe code by symbol_get(),
328 328 * which will bump the use count of this module. */
329/* This routine is made available to other mtd code via 329void DoCMil_init(struct mtd_info *mtd)
330 * inter_module_register. It must only be accessed through
331 * inter_module_get which will bump the use count of this module. The
332 * addresses passed back in mtd are valid as long as the use count of
333 * this module is non-zero, i.e. between inter_module_get and
334 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
335 */
336static void DoCMil_init(struct mtd_info *mtd)
337{ 330{
338 struct DiskOnChip *this = mtd->priv; 331 struct DiskOnChip *this = mtd->priv;
339 struct DiskOnChip *old = NULL; 332 struct DiskOnChip *old = NULL;
@@ -368,7 +361,7 @@ static void DoCMil_init(struct mtd_info *mtd)
368 /* FIXME: erase size is not always 8KiB */ 361 /* FIXME: erase size is not always 8KiB */
369 mtd->erasesize = 0x2000; 362 mtd->erasesize = 0x2000;
370 363
371 mtd->oobblock = 512; 364 mtd->writesize = 512;
372 mtd->oobsize = 16; 365 mtd->oobsize = 16;
373 mtd->owner = THIS_MODULE; 366 mtd->owner = THIS_MODULE;
374 mtd->erase = doc_erase; 367 mtd->erase = doc_erase;
@@ -376,8 +369,6 @@ static void DoCMil_init(struct mtd_info *mtd)
376 mtd->unpoint = NULL; 369 mtd->unpoint = NULL;
377 mtd->read = doc_read; 370 mtd->read = doc_read;
378 mtd->write = doc_write; 371 mtd->write = doc_write;
379 mtd->read_ecc = doc_read_ecc;
380 mtd->write_ecc = doc_write_ecc;
381 mtd->read_oob = doc_read_oob; 372 mtd->read_oob = doc_read_oob;
382 mtd->write_oob = doc_write_oob; 373 mtd->write_oob = doc_write_oob;
383 mtd->sync = NULL; 374 mtd->sync = NULL;
@@ -401,6 +392,7 @@ static void DoCMil_init(struct mtd_info *mtd)
401 return; 392 return;
402 } 393 }
403} 394}
395EXPORT_SYMBOL_GPL(DoCMil_init);
404 396
405static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, 397static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
406 size_t *retlen, u_char *buf) 398 size_t *retlen, u_char *buf)
@@ -670,8 +662,8 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
670 return ret; 662 return ret;
671} 663}
672 664
673static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 665static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
674 size_t *retlen, u_char *buf) 666 struct mtd_oob_ops *ops)
675{ 667{
676#ifndef USE_MEMCPY 668#ifndef USE_MEMCPY
677 int i; 669 int i;
@@ -680,6 +672,12 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
680 struct DiskOnChip *this = mtd->priv; 672 struct DiskOnChip *this = mtd->priv;
681 void __iomem *docptr = this->virtadr; 673 void __iomem *docptr = this->virtadr;
682 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 674 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
675 uint8_t *buf = ops->oobbuf;
676 size_t len = ops->len;
677
678 BUG_ON(ops->mode != MTD_OOB_PLACE);
679
680 ofs += ops->ooboffs;
683 681
684 /* Find the chip which is to be used and select it */ 682 /* Find the chip which is to be used and select it */
685 if (this->curfloor != mychip->floor) { 683 if (this->curfloor != mychip->floor) {
@@ -716,13 +714,13 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
716#endif 714#endif
717 buf[len - 1] = ReadDOC(docptr, LastDataRead); 715 buf[len - 1] = ReadDOC(docptr, LastDataRead);
718 716
719 *retlen = len; 717 ops->retlen = len;
720 718
721 return 0; 719 return 0;
722} 720}
723 721
724static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 722static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
725 size_t *retlen, const u_char *buf) 723 struct mtd_oob_ops *ops)
726{ 724{
727#ifndef USE_MEMCPY 725#ifndef USE_MEMCPY
728 int i; 726 int i;
@@ -732,6 +730,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
732 struct DiskOnChip *this = mtd->priv; 730 struct DiskOnChip *this = mtd->priv;
733 void __iomem *docptr = this->virtadr; 731 void __iomem *docptr = this->virtadr;
734 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 732 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
733 uint8_t *buf = ops->oobbuf;
734 size_t len = ops->len;
735
736 BUG_ON(ops->mode != MTD_OOB_PLACE);
737
738 ofs += ops->ooboffs;
735 739
736 /* Find the chip which is to be used and select it */ 740 /* Find the chip which is to be used and select it */
737 if (this->curfloor != mychip->floor) { 741 if (this->curfloor != mychip->floor) {
@@ -783,12 +787,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
783 if (ReadDOC(docptr, Mil_CDSN_IO) & 1) { 787 if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
784 printk("Error programming oob data\n"); 788 printk("Error programming oob data\n");
785 /* FIXME: implement Bad Block Replacement (in nftl.c ??) */ 789 /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
786 *retlen = 0; 790 ops->retlen = 0;
787 ret = -EIO; 791 ret = -EIO;
788 } 792 }
789 dummy = ReadDOC(docptr, LastDataRead); 793 dummy = ReadDOC(docptr, LastDataRead);
790 794
791 *retlen = len; 795 ops->retlen = len;
792 796
793 return ret; 797 return ret;
794} 798}
@@ -856,12 +860,6 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
856 * 860 *
857 ****************************************************************************/ 861 ****************************************************************************/
858 862
859static int __init init_doc2001(void)
860{
861 inter_module_register(im_name, THIS_MODULE, &DoCMil_init);
862 return 0;
863}
864
865static void __exit cleanup_doc2001(void) 863static void __exit cleanup_doc2001(void)
866{ 864{
867 struct mtd_info *mtd; 865 struct mtd_info *mtd;
@@ -877,11 +875,9 @@ static void __exit cleanup_doc2001(void)
877 kfree(this->chips); 875 kfree(this->chips);
878 kfree(mtd); 876 kfree(mtd);
879 } 877 }
880 inter_module_unregister(im_name);
881} 878}
882 879
883module_exit(cleanup_doc2001); 880module_exit(cleanup_doc2001);
884module_init(init_doc2001);
885 881
886MODULE_LICENSE("GPL"); 882MODULE_LICENSE("GPL");
887MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); 883MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 5f57f29efee4..66cb1e50469a 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -47,10 +47,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
47static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 47static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
48 size_t *retlen, const u_char *buf, u_char *eccbuf, 48 size_t *retlen, const u_char *buf, u_char *eccbuf,
49 struct nand_oobinfo *oobsel); 49 struct nand_oobinfo *oobsel);
50static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 50static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
51 size_t *retlen, u_char *buf); 51 struct mtd_oob_ops *ops);
52static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 52static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
53 size_t *retlen, const u_char *buf); 53 struct mtd_oob_ops *ops);
54static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); 54static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
55 55
56static struct mtd_info *docmilpluslist = NULL; 56static struct mtd_info *docmilpluslist = NULL;
@@ -447,16 +447,9 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
447 return retval; 447 return retval;
448} 448}
449 449
450static const char im_name[] = "DoCMilPlus_init"; 450/* This routine is found from the docprobe code by symbol_get(),
451 451 * which will bump the use count of this module. */
452/* This routine is made available to other mtd code via 452void DoCMilPlus_init(struct mtd_info *mtd)
453 * inter_module_register. It must only be accessed through
454 * inter_module_get which will bump the use count of this module. The
455 * addresses passed back in mtd are valid as long as the use count of
456 * this module is non-zero, i.e. between inter_module_get and
457 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
458 */
459static void DoCMilPlus_init(struct mtd_info *mtd)
460{ 453{
461 struct DiskOnChip *this = mtd->priv; 454 struct DiskOnChip *this = mtd->priv;
462 struct DiskOnChip *old = NULL; 455 struct DiskOnChip *old = NULL;
@@ -490,7 +483,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
490 mtd->size = 0; 483 mtd->size = 0;
491 484
492 mtd->erasesize = 0; 485 mtd->erasesize = 0;
493 mtd->oobblock = 512; 486 mtd->writesize = 512;
494 mtd->oobsize = 16; 487 mtd->oobsize = 16;
495 mtd->owner = THIS_MODULE; 488 mtd->owner = THIS_MODULE;
496 mtd->erase = doc_erase; 489 mtd->erase = doc_erase;
@@ -498,8 +491,6 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
498 mtd->unpoint = NULL; 491 mtd->unpoint = NULL;
499 mtd->read = doc_read; 492 mtd->read = doc_read;
500 mtd->write = doc_write; 493 mtd->write = doc_write;
501 mtd->read_ecc = doc_read_ecc;
502 mtd->write_ecc = doc_write_ecc;
503 mtd->read_oob = doc_read_oob; 494 mtd->read_oob = doc_read_oob;
504 mtd->write_oob = doc_write_oob; 495 mtd->write_oob = doc_write_oob;
505 mtd->sync = NULL; 496 mtd->sync = NULL;
@@ -524,6 +515,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
524 return; 515 return;
525 } 516 }
526} 517}
518EXPORT_SYMBOL_GPL(DoCMilPlus_init);
527 519
528#if 0 520#if 0
529static int doc_dumpblk(struct mtd_info *mtd, loff_t from) 521static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
@@ -876,14 +868,20 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
876 return ret; 868 return ret;
877} 869}
878 870
879static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 871static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
880 size_t *retlen, u_char *buf) 872 struct mtd_oob_ops *ops)
881{ 873{
882 loff_t fofs, base; 874 loff_t fofs, base;
883 struct DiskOnChip *this = mtd->priv; 875 struct DiskOnChip *this = mtd->priv;
884 void __iomem * docptr = this->virtadr; 876 void __iomem * docptr = this->virtadr;
885 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 877 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
886 size_t i, size, got, want; 878 size_t i, size, got, want;
879 uint8_t *buf = ops->oobbuf;
880 size_t len = ops->len;
881
882 BUG_ON(ops->mode != MTD_OOB_PLACE);
883
884 ofs += ops->ooboffs;
887 885
888 DoC_CheckASIC(docptr); 886 DoC_CheckASIC(docptr);
889 887
@@ -949,12 +947,12 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
949 /* Disable flash internally */ 947 /* Disable flash internally */
950 WriteDOC(0, docptr, Mplus_FlashSelect); 948 WriteDOC(0, docptr, Mplus_FlashSelect);
951 949
952 *retlen = len; 950 ops->retlen = len;
953 return 0; 951 return 0;
954} 952}
955 953
956static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 954static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
957 size_t *retlen, const u_char *buf) 955 struct mtd_oob_ops *ops)
958{ 956{
959 volatile char dummy; 957 volatile char dummy;
960 loff_t fofs, base; 958 loff_t fofs, base;
@@ -963,6 +961,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
963 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 961 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
964 size_t i, size, got, want; 962 size_t i, size, got, want;
965 int ret = 0; 963 int ret = 0;
964 uint8_t *buf = ops->oobbuf;
965 size_t len = ops->len;
966
967 BUG_ON(ops->mode != MTD_OOB_PLACE);
968
969 ofs += ops->ooboffs;
966 970
967 DoC_CheckASIC(docptr); 971 DoC_CheckASIC(docptr);
968 972
@@ -1038,7 +1042,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1038 printk("MTD: Error 0x%x programming oob at 0x%x\n", 1042 printk("MTD: Error 0x%x programming oob at 0x%x\n",
1039 dummy, (int)ofs); 1043 dummy, (int)ofs);
1040 /* FIXME: implement Bad Block Replacement */ 1044 /* FIXME: implement Bad Block Replacement */
1041 *retlen = 0; 1045 ops->retlen = 0;
1042 ret = -EIO; 1046 ret = -EIO;
1043 } 1047 }
1044 dummy = ReadDOC(docptr, Mplus_LastDataRead); 1048 dummy = ReadDOC(docptr, Mplus_LastDataRead);
@@ -1051,7 +1055,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1051 /* Disable flash internally */ 1055 /* Disable flash internally */
1052 WriteDOC(0, docptr, Mplus_FlashSelect); 1056 WriteDOC(0, docptr, Mplus_FlashSelect);
1053 1057
1054 *retlen = len; 1058 ops->retlen = len;
1055 return ret; 1059 return ret;
1056} 1060}
1057 1061
@@ -1122,12 +1126,6 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1122 * 1126 *
1123 ****************************************************************************/ 1127 ****************************************************************************/
1124 1128
1125static int __init init_doc2001plus(void)
1126{
1127 inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);
1128 return 0;
1129}
1130
1131static void __exit cleanup_doc2001plus(void) 1129static void __exit cleanup_doc2001plus(void)
1132{ 1130{
1133 struct mtd_info *mtd; 1131 struct mtd_info *mtd;
@@ -1143,11 +1141,9 @@ static void __exit cleanup_doc2001plus(void)
1143 kfree(this->chips); 1141 kfree(this->chips);
1144 kfree(mtd); 1142 kfree(mtd);
1145 } 1143 }
1146 inter_module_unregister(im_name);
1147} 1144}
1148 1145
1149module_exit(cleanup_doc2001plus); 1146module_exit(cleanup_doc2001plus);
1150module_init(init_doc2001plus);
1151 1147
1152MODULE_LICENSE("GPL"); 1148MODULE_LICENSE("GPL");
1153MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al."); 1149MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 13178b9dd00a..593bb033a3fa 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -231,6 +231,10 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
231 231
232static int docfound; 232static int docfound;
233 233
234extern void DoC2k_init(struct mtd_info *);
235extern void DoCMil_init(struct mtd_info *);
236extern void DoCMilPlus_init(struct mtd_info *);
237
234static void __init DoC_Probe(unsigned long physadr) 238static void __init DoC_Probe(unsigned long physadr)
235{ 239{
236 void __iomem *docptr; 240 void __iomem *docptr;
@@ -239,8 +243,6 @@ static void __init DoC_Probe(unsigned long physadr)
239 int ChipID; 243 int ChipID;
240 char namebuf[15]; 244 char namebuf[15];
241 char *name = namebuf; 245 char *name = namebuf;
242 char *im_funcname = NULL;
243 char *im_modname = NULL;
244 void (*initroutine)(struct mtd_info *) = NULL; 246 void (*initroutine)(struct mtd_info *) = NULL;
245 247
246 docptr = ioremap(physadr, DOC_IOREMAP_LEN); 248 docptr = ioremap(physadr, DOC_IOREMAP_LEN);
@@ -278,41 +280,33 @@ static void __init DoC_Probe(unsigned long physadr)
278 switch(ChipID) { 280 switch(ChipID) {
279 case DOC_ChipID_Doc2kTSOP: 281 case DOC_ChipID_Doc2kTSOP:
280 name="2000 TSOP"; 282 name="2000 TSOP";
281 im_funcname = "DoC2k_init"; 283 initroutine = symbol_request(DoC2k_init);
282 im_modname = "doc2000";
283 break; 284 break;
284 285
285 case DOC_ChipID_Doc2k: 286 case DOC_ChipID_Doc2k:
286 name="2000"; 287 name="2000";
287 im_funcname = "DoC2k_init"; 288 initroutine = symbol_request(DoC2k_init);
288 im_modname = "doc2000";
289 break; 289 break;
290 290
291 case DOC_ChipID_DocMil: 291 case DOC_ChipID_DocMil:
292 name="Millennium"; 292 name="Millennium";
293#ifdef DOC_SINGLE_DRIVER 293#ifdef DOC_SINGLE_DRIVER
294 im_funcname = "DoC2k_init"; 294 initroutine = symbol_request(DoC2k_init);
295 im_modname = "doc2000";
296#else 295#else
297 im_funcname = "DoCMil_init"; 296 initroutine = symbol_request(DoCMil_init);
298 im_modname = "doc2001";
299#endif /* DOC_SINGLE_DRIVER */ 297#endif /* DOC_SINGLE_DRIVER */
300 break; 298 break;
301 299
302 case DOC_ChipID_DocMilPlus16: 300 case DOC_ChipID_DocMilPlus16:
303 case DOC_ChipID_DocMilPlus32: 301 case DOC_ChipID_DocMilPlus32:
304 name="MillenniumPlus"; 302 name="MillenniumPlus";
305 im_funcname = "DoCMilPlus_init"; 303 initroutine = symbol_request(DoCMilPlus_init);
306 im_modname = "doc2001plus";
307 break; 304 break;
308 } 305 }
309 306
310 if (im_funcname)
311 initroutine = inter_module_get_request(im_funcname, im_modname);
312
313 if (initroutine) { 307 if (initroutine) {
314 (*initroutine)(mtd); 308 (*initroutine)(mtd);
315 inter_module_put(im_funcname); 309 symbol_put_addr(initroutine);
316 return; 310 return;
317 } 311 }
318 printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr); 312 printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 29b0ddaa324e..4ea50a1dda85 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -635,6 +635,7 @@ int __init lart_flash_init (void)
635 printk ("%s: This looks like a LART board to me.\n",module_name); 635 printk ("%s: This looks like a LART board to me.\n",module_name);
636 mtd.name = module_name; 636 mtd.name = module_name;
637 mtd.type = MTD_NORFLASH; 637 mtd.type = MTD_NORFLASH;
638 mtd.writesize = 1;
638 mtd.flags = MTD_CAP_NORFLASH; 639 mtd.flags = MTD_CAP_NORFLASH;
639 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; 640 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
640 mtd.erasesize = FLASH_BLOCKSIZE_MAIN; 641 mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 04e65d5dae00..a8466141e914 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -465,6 +465,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
465 flash->mtd.name = spi->dev.bus_id; 465 flash->mtd.name = spi->dev.bus_id;
466 466
467 flash->mtd.type = MTD_NORFLASH; 467 flash->mtd.type = MTD_NORFLASH;
468 flash->mtd.writesize = 1;
468 flash->mtd.flags = MTD_CAP_NORFLASH; 469 flash->mtd.flags = MTD_CAP_NORFLASH;
469 flash->mtd.size = info->sector_size * info->n_sectors; 470 flash->mtd.size = info->sector_size * info->n_sectors;
470 flash->mtd.erasesize = info->sector_size; 471 flash->mtd.erasesize = info->sector_size;
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 485f663493d2..4ab7670770e4 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -219,7 +219,7 @@ static int __init ms02nv_init_one(ulong addr)
219 mp->uaddr = phys_to_virt(fixaddr); 219 mp->uaddr = phys_to_virt(fixaddr);
220 220
221 mtd->type = MTD_RAM; 221 mtd->type = MTD_RAM;
222 mtd->flags = MTD_CAP_RAM | MTD_XIP; 222 mtd->flags = MTD_CAP_RAM;
223 mtd->size = fixsize; 223 mtd->size = fixsize;
224 mtd->name = (char *)ms02nv_name; 224 mtd->name = (char *)ms02nv_name;
225 mtd->owner = THIS_MODULE; 225 mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 1443117fd8f4..b4438eacfd80 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -106,6 +106,7 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
106 mtd->type = MTD_RAM; 106 mtd->type = MTD_RAM;
107 mtd->flags = MTD_CAP_RAM; 107 mtd->flags = MTD_CAP_RAM;
108 mtd->size = size; 108 mtd->size = size;
109 mtd->writesize = 1;
109 mtd->erasesize = MTDRAM_ERASE_SIZE; 110 mtd->erasesize = MTDRAM_ERASE_SIZE;
110 mtd->priv = mapped_address; 111 mtd->priv = mapped_address;
111 112
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index e8685ee6c1e4..e09e416667d3 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,8 +1,8 @@
1/** 1/**
2 * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $ 2 * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> 5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
6 * 6 *
7 * Usage: 7 * Usage:
8 * 8 *
@@ -142,7 +142,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
142 142
143 new->mtd.name = name; 143 new->mtd.name = name;
144 new->mtd.size = len; 144 new->mtd.size = len;
145 new->mtd.flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE; 145 new->mtd.flags = MTD_CAP_RAM;
146 new->mtd.erase = phram_erase; 146 new->mtd.erase = phram_erase;
147 new->mtd.point = phram_point; 147 new->mtd.point = phram_point;
148 new->mtd.unpoint = phram_unpoint; 148 new->mtd.unpoint = phram_unpoint;
@@ -266,12 +266,16 @@ static int phram_setup(const char *val, struct kernel_param *kp)
266 return 0; 266 return 0;
267 267
268 ret = parse_num32(&start, token[1]); 268 ret = parse_num32(&start, token[1]);
269 if (ret) 269 if (ret) {
270 kfree(name);
270 parse_err("illegal start address\n"); 271 parse_err("illegal start address\n");
272 }
271 273
272 ret = parse_num32(&len, token[2]); 274 ret = parse_num32(&len, token[2]);
273 if (ret) 275 if (ret) {
276 kfree(name);
274 parse_err("illegal device length\n"); 277 parse_err("illegal device length\n");
278 }
275 279
276 register_device(name, start, len); 280 register_device(name, start, len);
277 281
@@ -296,5 +300,5 @@ module_init(init_phram);
296module_exit(cleanup_phram); 300module_exit(cleanup_phram);
297 301
298MODULE_LICENSE("GPL"); 302MODULE_LICENSE("GPL");
299MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>"); 303MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>");
300MODULE_DESCRIPTION("MTD driver for physical RAM"); 304MODULE_DESCRIPTION("MTD driver for physical RAM");
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 6faee6c6958c..b3f665e3c38b 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -200,8 +200,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
200 200
201 (*curmtd)->mtdinfo->name = name; 201 (*curmtd)->mtdinfo->name = name;
202 (*curmtd)->mtdinfo->size = length; 202 (*curmtd)->mtdinfo->size = length;
203 (*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS | 203 (*curmtd)->mtdinfo->flags = MTD_CAP_RAM;
204 MTD_WRITEB_WRITEABLE | MTD_VOLATILE | MTD_CAP_RAM;
205 (*curmtd)->mtdinfo->erase = slram_erase; 204 (*curmtd)->mtdinfo->erase = slram_erase;
206 (*curmtd)->mtdinfo->point = slram_point; 205 (*curmtd)->mtdinfo->point = slram_point;
207 (*curmtd)->mtdinfo->unpoint = slram_unpoint; 206 (*curmtd)->mtdinfo->unpoint = slram_unpoint;
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index a3b92479719d..1e21a2c3dd29 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -36,6 +36,7 @@
36#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
37#include <linux/mtd/nftl.h> 37#include <linux/mtd/nftl.h>
38#include <linux/mtd/inftl.h> 38#include <linux/mtd/inftl.h>
39#include <linux/mtd/nand.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/errno.h> 41#include <asm/errno.h>
41#include <asm/io.h> 42#include <asm/io.h>
@@ -79,14 +80,12 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
79 inftl->mbd.devnum = -1; 80 inftl->mbd.devnum = -1;
80 inftl->mbd.blksize = 512; 81 inftl->mbd.blksize = 512;
81 inftl->mbd.tr = tr; 82 inftl->mbd.tr = tr;
82 memcpy(&inftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));
83 inftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;
84 83
85 if (INFTL_mount(inftl) < 0) { 84 if (INFTL_mount(inftl) < 0) {
86 printk(KERN_WARNING "INFTL: could not mount device\n"); 85 printk(KERN_WARNING "INFTL: could not mount device\n");
87 kfree(inftl); 86 kfree(inftl);
88 return; 87 return;
89 } 88 }
90 89
91 /* OK, it's a new one. Set up all the data structures. */ 90 /* OK, it's a new one. Set up all the data structures. */
92 91
@@ -152,6 +151,69 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
152 */ 151 */
153 152
154/* 153/*
154 * Read oob data from flash
155 */
156int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
157 size_t *retlen, uint8_t *buf)
158{
159 struct mtd_oob_ops ops;
160 int res;
161
162 ops.mode = MTD_OOB_PLACE;
163 ops.ooboffs = offs & (mtd->writesize - 1);
164 ops.ooblen = len;
165 ops.oobbuf = buf;
166 ops.datbuf = NULL;
167 ops.len = len;
168
169 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
170 *retlen = ops.retlen;
171 return res;
172}
173
174/*
175 * Write oob data to flash
176 */
177int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
178 size_t *retlen, uint8_t *buf)
179{
180 struct mtd_oob_ops ops;
181 int res;
182
183 ops.mode = MTD_OOB_PLACE;
184 ops.ooboffs = offs & (mtd->writesize - 1);
185 ops.ooblen = len;
186 ops.oobbuf = buf;
187 ops.datbuf = NULL;
188 ops.len = len;
189
190 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
191 *retlen = ops.retlen;
192 return res;
193}
194
195/*
196 * Write data and oob to flash
197 */
198static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
199 size_t *retlen, uint8_t *buf, uint8_t *oob)
200{
201 struct mtd_oob_ops ops;
202 int res;
203
204 ops.mode = MTD_OOB_PLACE;
205 ops.ooboffs = offs;
206 ops.ooblen = mtd->oobsize;
207 ops.oobbuf = oob;
208 ops.datbuf = buf;
209 ops.len = len;
210
211 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
212 *retlen = ops.retlen;
213 return res;
214}
215
216/*
155 * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition. 217 * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition.
156 * This function is used when the give Virtual Unit Chain. 218 * This function is used when the give Virtual Unit Chain.
157 */ 219 */
@@ -198,10 +260,11 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
198 u16 BlockMap[MAX_SECTORS_PER_UNIT]; 260 u16 BlockMap[MAX_SECTORS_PER_UNIT];
199 unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT]; 261 unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
200 unsigned int thisEUN, prevEUN, status; 262 unsigned int thisEUN, prevEUN, status;
263 struct mtd_info *mtd = inftl->mbd.mtd;
201 int block, silly; 264 int block, silly;
202 unsigned int targetEUN; 265 unsigned int targetEUN;
203 struct inftl_oob oob; 266 struct inftl_oob oob;
204 size_t retlen; 267 size_t retlen;
205 268
206 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d," 269 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,"
207 "pending=%d)\n", inftl, thisVUC, pendingblock); 270 "pending=%d)\n", inftl, thisVUC, pendingblock);
@@ -221,18 +284,18 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
221 * Scan to find the Erase Unit which holds the actual data for each 284 * Scan to find the Erase Unit which holds the actual data for each
222 * 512-byte block within the Chain. 285 * 512-byte block within the Chain.
223 */ 286 */
224 silly = MAX_LOOPS; 287 silly = MAX_LOOPS;
225 while (thisEUN < inftl->nb_blocks) { 288 while (thisEUN < inftl->nb_blocks) {
226 for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { 289 for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) {
227 if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) 290 if ((BlockMap[block] != 0xffff) || BlockDeleted[block])
228 continue; 291 continue;
229 292
230 if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) 293 if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize)
231 + (block * SECTORSIZE), 16 , &retlen, 294 + (block * SECTORSIZE), 16, &retlen,
232 (char *)&oob) < 0) 295 (char *)&oob) < 0)
233 status = SECTOR_IGNORE; 296 status = SECTOR_IGNORE;
234 else 297 else
235 status = oob.b.Status | oob.b.Status1; 298 status = oob.b.Status | oob.b.Status1;
236 299
237 switch(status) { 300 switch(status) {
238 case SECTOR_FREE: 301 case SECTOR_FREE:
@@ -282,29 +345,31 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
282 continue; 345 continue;
283 } 346 }
284 347
285 /* 348 /*
286 * Copy only in non free block (free blocks can only 349 * Copy only in non free block (free blocks can only
287 * happen in case of media errors or deleted blocks). 350 * happen in case of media errors or deleted blocks).
288 */ 351 */
289 if (BlockMap[block] == BLOCK_NIL) 352 if (BlockMap[block] == BLOCK_NIL)
290 continue; 353 continue;
291 354
292 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 355 ret = mtd->read(mtd, (inftl->EraseSize * BlockMap[block]) +
293 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 356 (block * SECTORSIZE), SECTORSIZE, &retlen,
294 &retlen, movebuf); 357 movebuf);
295 if (ret < 0) { 358 if (ret < 0 && ret != -EUCLEAN) {
296 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 359 ret = mtd->read(mtd,
297 BlockMap[block]) + (block * SECTORSIZE), 360 (inftl->EraseSize * BlockMap[block]) +
298 SECTORSIZE, &retlen, movebuf); 361 (block * SECTORSIZE), SECTORSIZE,
362 &retlen, movebuf);
299 if (ret != -EIO) 363 if (ret != -EIO)
300 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 364 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
301 "away on retry?\n"); 365 "away on retry?\n");
302 } 366 }
303 memset(&oob, 0xff, sizeof(struct inftl_oob)); 367 memset(&oob, 0xff, sizeof(struct inftl_oob));
304 oob.b.Status = oob.b.Status1 = SECTOR_USED; 368 oob.b.Status = oob.b.Status1 = SECTOR_USED;
305 MTD_WRITEECC(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) + 369
306 (block * SECTORSIZE), SECTORSIZE, &retlen, 370 inftl_write(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) +
307 movebuf, (char *)&oob, &inftl->oobinfo); 371 (block * SECTORSIZE), SECTORSIZE, &retlen,
372 movebuf, (char *)&oob);
308 } 373 }
309 374
310 /* 375 /*
@@ -329,17 +394,17 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
329 if (thisEUN == targetEUN) 394 if (thisEUN == targetEUN)
330 break; 395 break;
331 396
332 if (INFTL_formatblock(inftl, thisEUN) < 0) { 397 if (INFTL_formatblock(inftl, thisEUN) < 0) {
333 /* 398 /*
334 * Could not erase : mark block as reserved. 399 * Could not erase : mark block as reserved.
335 */ 400 */
336 inftl->PUtable[thisEUN] = BLOCK_RESERVED; 401 inftl->PUtable[thisEUN] = BLOCK_RESERVED;
337 } else { 402 } else {
338 /* Correctly erased : mark it as free */ 403 /* Correctly erased : mark it as free */
339 inftl->PUtable[thisEUN] = BLOCK_FREE; 404 inftl->PUtable[thisEUN] = BLOCK_FREE;
340 inftl->PUtable[prevEUN] = BLOCK_NIL; 405 inftl->PUtable[prevEUN] = BLOCK_NIL;
341 inftl->numfreeEUNs++; 406 inftl->numfreeEUNs++;
342 } 407 }
343 } 408 }
344 409
345 return targetEUN; 410 return targetEUN;
@@ -415,6 +480,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
415 unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE); 480 unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE);
416 unsigned int thisEUN, writeEUN, prev_block, status; 481 unsigned int thisEUN, writeEUN, prev_block, status;
417 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1); 482 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1);
483 struct mtd_info *mtd = inftl->mbd.mtd;
418 struct inftl_oob oob; 484 struct inftl_oob oob;
419 struct inftl_bci bci; 485 struct inftl_bci bci;
420 unsigned char anac, nacs, parity; 486 unsigned char anac, nacs, parity;
@@ -434,10 +500,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
434 silly = MAX_LOOPS; 500 silly = MAX_LOOPS;
435 501
436 while (thisEUN <= inftl->lastEUN) { 502 while (thisEUN <= inftl->lastEUN) {
437 MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + 503 inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) +
438 blockofs, 8, &retlen, (char *)&bci); 504 blockofs, 8, &retlen, (char *)&bci);
439 505
440 status = bci.Status | bci.Status1; 506 status = bci.Status | bci.Status1;
441 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in " 507 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
442 "EUN %d is %x\n", block , writeEUN, status); 508 "EUN %d is %x\n", block , writeEUN, status);
443 509
@@ -522,8 +588,8 @@ hitused:
522 nacs = 0; 588 nacs = 0;
523 thisEUN = inftl->VUtable[thisVUC]; 589 thisEUN = inftl->VUtable[thisVUC];
524 if (thisEUN != BLOCK_NIL) { 590 if (thisEUN != BLOCK_NIL) {
525 MTD_READOOB(inftl->mbd.mtd, thisEUN * inftl->EraseSize 591 inftl_read_oob(mtd, thisEUN * inftl->EraseSize
526 + 8, 8, &retlen, (char *)&oob.u); 592 + 8, 8, &retlen, (char *)&oob.u);
527 anac = oob.u.a.ANAC + 1; 593 anac = oob.u.a.ANAC + 1;
528 nacs = oob.u.a.NACs + 1; 594 nacs = oob.u.a.NACs + 1;
529 } 595 }
@@ -544,8 +610,8 @@ hitused:
544 oob.u.a.parityPerField = parity; 610 oob.u.a.parityPerField = parity;
545 oob.u.a.discarded = 0xaa; 611 oob.u.a.discarded = 0xaa;
546 612
547 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 8, 8, 613 inftl_write_oob(mtd, writeEUN * inftl->EraseSize + 8, 8,
548 &retlen, (char *)&oob.u); 614 &retlen, (char *)&oob.u);
549 615
550 /* Also back up header... */ 616 /* Also back up header... */
551 oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC); 617 oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC);
@@ -555,8 +621,8 @@ hitused:
555 oob.u.b.parityPerField = parity; 621 oob.u.b.parityPerField = parity;
556 oob.u.b.discarded = 0xaa; 622 oob.u.b.discarded = 0xaa;
557 623
558 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 624 inftl_write_oob(mtd, writeEUN * inftl->EraseSize +
559 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); 625 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
560 626
561 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; 627 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
562 inftl->VUtable[thisVUC] = writeEUN; 628 inftl->VUtable[thisVUC] = writeEUN;
@@ -576,6 +642,7 @@ hitused:
576 */ 642 */
577static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC) 643static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
578{ 644{
645 struct mtd_info *mtd = inftl->mbd.mtd;
579 unsigned char BlockUsed[MAX_SECTORS_PER_UNIT]; 646 unsigned char BlockUsed[MAX_SECTORS_PER_UNIT];
580 unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT]; 647 unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
581 unsigned int thisEUN, status; 648 unsigned int thisEUN, status;
@@ -606,9 +673,9 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
606 if (BlockUsed[block] || BlockDeleted[block]) 673 if (BlockUsed[block] || BlockDeleted[block])
607 continue; 674 continue;
608 675
609 if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) 676 if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize)
610 + (block * SECTORSIZE), 8 , &retlen, 677 + (block * SECTORSIZE), 8 , &retlen,
611 (char *)&bci) < 0) 678 (char *)&bci) < 0)
612 status = SECTOR_IGNORE; 679 status = SECTOR_IGNORE;
613 else 680 else
614 status = bci.Status | bci.Status1; 681 status = bci.Status | bci.Status1;
@@ -670,12 +737,12 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
670 DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n", 737 DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
671 thisEUN, thisVUC); 738 thisEUN, thisVUC);
672 739
673 if (INFTL_formatblock(inftl, thisEUN) < 0) { 740 if (INFTL_formatblock(inftl, thisEUN) < 0) {
674 /* 741 /*
675 * Could not erase : mark block as reserved. 742 * Could not erase : mark block as reserved.
676 */ 743 */
677 inftl->PUtable[thisEUN] = BLOCK_RESERVED; 744 inftl->PUtable[thisEUN] = BLOCK_RESERVED;
678 } else { 745 } else {
679 /* Correctly erased : mark it as free */ 746 /* Correctly erased : mark it as free */
680 inftl->PUtable[thisEUN] = BLOCK_FREE; 747 inftl->PUtable[thisEUN] = BLOCK_FREE;
681 inftl->numfreeEUNs++; 748 inftl->numfreeEUNs++;
@@ -697,6 +764,7 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
697{ 764{
698 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)]; 765 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
699 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); 766 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
767 struct mtd_info *mtd = inftl->mbd.mtd;
700 unsigned int status; 768 unsigned int status;
701 int silly = MAX_LOOPS; 769 int silly = MAX_LOOPS;
702 size_t retlen; 770 size_t retlen;
@@ -706,8 +774,8 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
706 "block=%d)\n", inftl, block); 774 "block=%d)\n", inftl, block);
707 775
708 while (thisEUN < inftl->nb_blocks) { 776 while (thisEUN < inftl->nb_blocks) {
709 if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + 777 if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) +
710 blockofs, 8, &retlen, (char *)&bci) < 0) 778 blockofs, 8, &retlen, (char *)&bci) < 0)
711 status = SECTOR_IGNORE; 779 status = SECTOR_IGNORE;
712 else 780 else
713 status = bci.Status | bci.Status1; 781 status = bci.Status | bci.Status1;
@@ -741,10 +809,10 @@ foundit:
741 if (thisEUN != BLOCK_NIL) { 809 if (thisEUN != BLOCK_NIL) {
742 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs; 810 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
743 811
744 if (MTD_READOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0) 812 if (inftl_read_oob(mtd, ptr, 8, &retlen, (char *)&bci) < 0)
745 return -EIO; 813 return -EIO;
746 bci.Status = bci.Status1 = SECTOR_DELETED; 814 bci.Status = bci.Status1 = SECTOR_DELETED;
747 if (MTD_WRITEOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0) 815 if (inftl_write_oob(mtd, ptr, 8, &retlen, (char *)&bci) < 0)
748 return -EIO; 816 return -EIO;
749 INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE)); 817 INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE));
750 } 818 }
@@ -784,9 +852,10 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
784 852
785 memset(&oob, 0xff, sizeof(struct inftl_oob)); 853 memset(&oob, 0xff, sizeof(struct inftl_oob));
786 oob.b.Status = oob.b.Status1 = SECTOR_USED; 854 oob.b.Status = oob.b.Status1 = SECTOR_USED;
787 MTD_WRITEECC(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) + 855
788 blockofs, SECTORSIZE, &retlen, (char *)buffer, 856 inftl_write(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) +
789 (char *)&oob, &inftl->oobinfo); 857 blockofs, SECTORSIZE, &retlen, (char *)buffer,
858 (char *)&oob);
790 /* 859 /*
791 * need to write SECTOR_USED flags since they are not written 860 * need to write SECTOR_USED flags since they are not written
792 * in mtd_writeecc 861 * in mtd_writeecc
@@ -804,17 +873,18 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
804 struct INFTLrecord *inftl = (void *)mbd; 873 struct INFTLrecord *inftl = (void *)mbd;
805 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)]; 874 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
806 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); 875 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
807 unsigned int status; 876 struct mtd_info *mtd = inftl->mbd.mtd;
877 unsigned int status;
808 int silly = MAX_LOOPS; 878 int silly = MAX_LOOPS;
809 struct inftl_bci bci; 879 struct inftl_bci bci;
810 size_t retlen; 880 size_t retlen;
811 881
812 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld," 882 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld,"
813 "buffer=%p)\n", inftl, block, buffer); 883 "buffer=%p)\n", inftl, block, buffer);
814 884
815 while (thisEUN < inftl->nb_blocks) { 885 while (thisEUN < inftl->nb_blocks) {
816 if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + 886 if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) +
817 blockofs, 8, &retlen, (char *)&bci) < 0) 887 blockofs, 8, &retlen, (char *)&bci) < 0)
818 status = SECTOR_IGNORE; 888 status = SECTOR_IGNORE;
819 else 889 else
820 status = bci.Status | bci.Status1; 890 status = bci.Status | bci.Status1;
@@ -850,10 +920,12 @@ foundit:
850 /* The requested block is not on the media, return all 0x00 */ 920 /* The requested block is not on the media, return all 0x00 */
851 memset(buffer, 0, SECTORSIZE); 921 memset(buffer, 0, SECTORSIZE);
852 } else { 922 } else {
853 size_t retlen; 923 size_t retlen;
854 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs; 924 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
855 if (MTD_READ(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen, 925 int ret = mtd->read(mtd, ptr, SECTORSIZE, &retlen, buffer);
856 buffer)) 926
927 /* Handle corrected bit flips gracefully */
928 if (ret < 0 && ret != -EUCLEAN)
857 return -EIO; 929 return -EIO;
858 } 930 }
859 return 0; 931 return 0;
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 43fdc9433882..8f6006f1a519 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -43,6 +43,11 @@
43 43
44char inftlmountrev[]="$Revision: 1.18 $"; 44char inftlmountrev[]="$Revision: 1.18 $";
45 45
46extern int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
47 size_t *retlen, uint8_t *buf);
48extern int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
49 size_t *retlen, uint8_t *buf);
50
46/* 51/*
47 * find_boot_record: Find the INFTL Media Header and its Spare copy which 52 * find_boot_record: Find the INFTL Media Header and its Spare copy which
48 * contains the various device information of the INFTL partition and 53 * contains the various device information of the INFTL partition and
@@ -57,6 +62,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
57 unsigned int i, block; 62 unsigned int i, block;
58 u8 buf[SECTORSIZE]; 63 u8 buf[SECTORSIZE];
59 struct INFTLMediaHeader *mh = &inftl->MediaHdr; 64 struct INFTLMediaHeader *mh = &inftl->MediaHdr;
65 struct mtd_info *mtd = inftl->mbd.mtd;
60 struct INFTLPartition *ip; 66 struct INFTLPartition *ip;
61 size_t retlen; 67 size_t retlen;
62 68
@@ -80,8 +86,8 @@ static int find_boot_record(struct INFTLrecord *inftl)
80 * Check for BNAND header first. Then whinge if it's found 86 * Check for BNAND header first. Then whinge if it's found
81 * but later checks fail. 87 * but later checks fail.
82 */ 88 */
83 ret = MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize, 89 ret = mtd->read(mtd, block * inftl->EraseSize,
84 SECTORSIZE, &retlen, buf); 90 SECTORSIZE, &retlen, buf);
85 /* We ignore ret in case the ECC of the MediaHeader is invalid 91 /* We ignore ret in case the ECC of the MediaHeader is invalid
86 (which is apparently acceptable) */ 92 (which is apparently acceptable) */
87 if (retlen != SECTORSIZE) { 93 if (retlen != SECTORSIZE) {
@@ -106,8 +112,9 @@ static int find_boot_record(struct INFTLrecord *inftl)
106 } 112 }
107 113
108 /* To be safer with BIOS, also use erase mark as discriminant */ 114 /* To be safer with BIOS, also use erase mark as discriminant */
109 if ((ret = MTD_READOOB(inftl->mbd.mtd, block * inftl->EraseSize + 115 if ((ret = inftl_read_oob(mtd, block * inftl->EraseSize +
110 SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) { 116 SECTORSIZE + 8, 8, &retlen,
117 (char *)&h1) < 0)) {
111 printk(KERN_WARNING "INFTL: ANAND header found at " 118 printk(KERN_WARNING "INFTL: ANAND header found at "
112 "0x%x in mtd%d, but OOB data read failed " 119 "0x%x in mtd%d, but OOB data read failed "
113 "(err %d)\n", block * inftl->EraseSize, 120 "(err %d)\n", block * inftl->EraseSize,
@@ -123,8 +130,8 @@ static int find_boot_record(struct INFTLrecord *inftl)
123 memcpy(mh, buf, sizeof(struct INFTLMediaHeader)); 130 memcpy(mh, buf, sizeof(struct INFTLMediaHeader));
124 131
125 /* Read the spare media header at offset 4096 */ 132 /* Read the spare media header at offset 4096 */
126 MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize + 4096, 133 mtd->read(mtd, block * inftl->EraseSize + 4096,
127 SECTORSIZE, &retlen, buf); 134 SECTORSIZE, &retlen, buf);
128 if (retlen != SECTORSIZE) { 135 if (retlen != SECTORSIZE) {
129 printk(KERN_WARNING "INFTL: Unable to read spare " 136 printk(KERN_WARNING "INFTL: Unable to read spare "
130 "Media Header\n"); 137 "Media Header\n");
@@ -233,7 +240,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
233 */ 240 */
234 instr->addr = ip->Reserved0 * inftl->EraseSize; 241 instr->addr = ip->Reserved0 * inftl->EraseSize;
235 instr->len = inftl->EraseSize; 242 instr->len = inftl->EraseSize;
236 MTD_ERASE(inftl->mbd.mtd, instr); 243 mtd->erase(mtd, instr);
237 } 244 }
238 if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { 245 if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
239 printk(KERN_WARNING "INFTL: Media Header " 246 printk(KERN_WARNING "INFTL: Media Header "
@@ -350,21 +357,21 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
350 int len, int check_oob) 357 int len, int check_oob)
351{ 358{
352 u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize]; 359 u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize];
360 struct mtd_info *mtd = inftl->mbd.mtd;
353 size_t retlen; 361 size_t retlen;
354 int i; 362 int i;
355 363
356 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=%p,"
357 "address=0x%x,len=%d,check_oob=%d)\n", inftl,
358 address, len, check_oob);
359
360 for (i = 0; i < len; i += SECTORSIZE) { 364 for (i = 0; i < len; i += SECTORSIZE) {
361 if (MTD_READECC(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &inftl->oobinfo) < 0) 365 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
362 return -1; 366 return -1;
363 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 367 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
364 return -1; 368 return -1;
365 369
366 if (check_oob) { 370 if (check_oob) {
367 if (memcmpb(buf + SECTORSIZE, 0xff, inftl->mbd.mtd->oobsize) != 0) 371 if(inftl_read_oob(mtd, address, mtd->oobsize,
372 &retlen, &buf[SECTORSIZE]) < 0)
373 return -1;
374 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
368 return -1; 375 return -1;
369 } 376 }
370 address += SECTORSIZE; 377 address += SECTORSIZE;
@@ -387,6 +394,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
387 size_t retlen; 394 size_t retlen;
388 struct inftl_unittail uci; 395 struct inftl_unittail uci;
389 struct erase_info *instr = &inftl->instr; 396 struct erase_info *instr = &inftl->instr;
397 struct mtd_info *mtd = inftl->mbd.mtd;
390 int physblock; 398 int physblock;
391 399
392 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p," 400 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
@@ -404,8 +412,9 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
404 /* Erase one physical eraseblock at a time, even though the NAND api 412 /* Erase one physical eraseblock at a time, even though the NAND api
405 allows us to group them. This way we if we have a failure, we can 413 allows us to group them. This way we if we have a failure, we can
406 mark only the failed block in the bbt. */ 414 mark only the failed block in the bbt. */
407 for (physblock = 0; physblock < inftl->EraseSize; physblock += instr->len, instr->addr += instr->len) { 415 for (physblock = 0; physblock < inftl->EraseSize;
408 MTD_ERASE(inftl->mbd.mtd, instr); 416 physblock += instr->len, instr->addr += instr->len) {
417 mtd->erase(inftl->mbd.mtd, instr);
409 418
410 if (instr->state == MTD_ERASE_FAILED) { 419 if (instr->state == MTD_ERASE_FAILED) {
411 printk(KERN_WARNING "INFTL: error while formatting block %d\n", 420 printk(KERN_WARNING "INFTL: error while formatting block %d\n",
@@ -414,10 +423,10 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
414 } 423 }
415 424
416 /* 425 /*
417 * Check the "freeness" of Erase Unit before updating metadata. 426 * Check the "freeness" of Erase Unit before updating metadata.
418 * FixMe: is this check really necessary? Since we have check the 427 * FixMe: is this check really necessary? Since we have check
419 * return code after the erase operation. 428 * the return code after the erase operation.
420 */ 429 */
421 if (check_free_sectors(inftl, instr->addr, instr->len, 1) != 0) 430 if (check_free_sectors(inftl, instr->addr, instr->len, 1) != 0)
422 goto fail; 431 goto fail;
423 } 432 }
@@ -429,8 +438,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
429 uci.Reserved[2] = 0; 438 uci.Reserved[2] = 0;
430 uci.Reserved[3] = 0; 439 uci.Reserved[3] = 0;
431 instr->addr = block * inftl->EraseSize + SECTORSIZE * 2; 440 instr->addr = block * inftl->EraseSize + SECTORSIZE * 2;
432 if (MTD_WRITEOOB(inftl->mbd.mtd, instr->addr + 441 if (inftl_write_oob(mtd, instr->addr + 8, 8, &retlen, (char *)&uci) < 0)
433 8, 8, &retlen, (char *)&uci) < 0)
434 goto fail; 442 goto fail;
435 return 0; 443 return 0;
436fail: 444fail:
@@ -549,6 +557,7 @@ void INFTL_dumpVUchains(struct INFTLrecord *s)
549 557
550int INFTL_mount(struct INFTLrecord *s) 558int INFTL_mount(struct INFTLrecord *s)
551{ 559{
560 struct mtd_info *mtd = s->mbd.mtd;
552 unsigned int block, first_block, prev_block, last_block; 561 unsigned int block, first_block, prev_block, last_block;
553 unsigned int first_logical_block, logical_block, erase_mark; 562 unsigned int first_logical_block, logical_block, erase_mark;
554 int chain_length, do_format_chain; 563 int chain_length, do_format_chain;
@@ -607,10 +616,11 @@ int INFTL_mount(struct INFTLrecord *s)
607 break; 616 break;
608 } 617 }
609 618
610 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 619 if (inftl_read_oob(mtd, block * s->EraseSize + 8,
611 8, &retlen, (char *)&h0) < 0 || 620 8, &retlen, (char *)&h0) < 0 ||
612 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 621 inftl_read_oob(mtd, block * s->EraseSize +
613 2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) { 622 2 * SECTORSIZE + 8, 8, &retlen,
623 (char *)&h1) < 0) {
614 /* Should never happen? */ 624 /* Should never happen? */
615 do_format_chain++; 625 do_format_chain++;
616 break; 626 break;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 7abd7fee0dda..6bdaacc6d6f9 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -37,7 +37,7 @@ config MTD_PHYSMAP_START
37config MTD_PHYSMAP_LEN 37config MTD_PHYSMAP_LEN
38 hex "Physical length of flash mapping" 38 hex "Physical length of flash mapping"
39 depends on MTD_PHYSMAP 39 depends on MTD_PHYSMAP
40 default "0x4000000" 40 default "0"
41 help 41 help
42 This is the total length of the mapping of the flash chips on 42 This is the total length of the mapping of the flash chips on
43 your particular board. If there is space, or aliases, in the 43 your particular board. If there is space, or aliases, in the
@@ -78,7 +78,7 @@ config MTD_PNC2000
78 78
79config MTD_SC520CDP 79config MTD_SC520CDP
80 tristate "CFI Flash device mapped on AMD SC520 CDP" 80 tristate "CFI Flash device mapped on AMD SC520 CDP"
81 depends on X86 && MTD_CFI 81 depends on X86 && MTD_CFI && MTD_CONCAT
82 help 82 help
83 The SC520 CDP board has two banks of CFI-compliant chips and one 83 The SC520 CDP board has two banks of CFI-compliant chips and one
84 Dual-in-line JEDEC chip. This 'mapping' driver supports that 84 Dual-in-line JEDEC chip. This 'mapping' driver supports that
@@ -109,7 +109,7 @@ config MTD_TS5500
109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL. 109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
110 110
111 Note that jumper 3 ("Write Enable Drive A") must be set 111 Note that jumper 3 ("Write Enable Drive A") must be set
112 otherwise detection won't succeeed. 112 otherwise detection won't succeed.
113 113
114config MTD_SBC_GXX 114config MTD_SBC_GXX
115 tristate "CFI Flash device mapped on Arcom SBC-GXx boards" 115 tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
@@ -200,8 +200,8 @@ config MTD_TSUNAMI
200 Support for the flash chip on Tsunami TIG bus. 200 Support for the flash chip on Tsunami TIG bus.
201 201
202config MTD_LASAT 202config MTD_LASAT
203 tristate "Flash chips on LASAT board" 203 tristate "LASAT flash device"
204 depends on LASAT 204 depends on LASAT && MTD_CFI
205 help 205 help
206 Support for the flash chips on the Lasat 100 and 200 boards. 206 Support for the flash chips on the Lasat 100 and 200 boards.
207 207
@@ -561,7 +561,6 @@ config MTD_PCMCIA
561config MTD_PCMCIA_ANONYMOUS 561config MTD_PCMCIA_ANONYMOUS
562 bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards" 562 bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards"
563 depends on MTD_PCMCIA 563 depends on MTD_PCMCIA
564 default N
565 help 564 help
566 If this option is enabled, PCMCIA cards which do not report 565 If this option is enabled, PCMCIA cards which do not report
567 anything about themselves are assumed to be MTD cards. 566 anything about themselves are assumed to be MTD cards.
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index fd0f0d3187de..92b5d883d7b0 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is> 2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
3 * 3 *
4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $ 4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
@@ -135,5 +135,5 @@ module_exit(cleanup_flagadm);
135 135
136 136
137MODULE_LICENSE("GPL"); 137MODULE_LICENSE("GPL");
138MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>"); 138MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
139MODULE_DESCRIPTION("MTD map driver for Flaga digital module"); 139MODULE_DESCRIPTION("MTD map driver for Flaga digital module");
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index 652813cd6c2d..85c2a9e22b1e 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -122,5 +122,5 @@ module_exit(cleanup_dbox2_flash);
122 122
123 123
124MODULE_LICENSE("GPL"); 124MODULE_LICENSE("GPL");
125MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>"); 125MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
126MODULE_DESCRIPTION("MTD map driver for D-Box 2 board"); 126MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
index d1e66e186746..5c25d4e552c6 100644
--- a/drivers/mtd/maps/mtx-1_flash.c
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -4,7 +4,7 @@
4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $ 4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
5 * 5 *
6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz> 6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de> 7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
8 * 8 *
9 */ 9 */
10 10
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 54a3102ab19a..0994b5b2e331 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -20,6 +20,8 @@
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/mtd/cfi.h> 21#include <linux/mtd/cfi.h>
22#include <linux/reboot.h> 22#include <linux/reboot.h>
23#include <linux/kdev_t.h>
24#include <linux/root_dev.h>
23#include <asm/io.h> 25#include <asm/io.h>
24 26
25/****************************************************************************/ 27/****************************************************************************/
@@ -188,7 +190,7 @@ int nettel_eraseconfig(void)
188 set_current_state(TASK_INTERRUPTIBLE); 190 set_current_state(TASK_INTERRUPTIBLE);
189 add_wait_queue(&wait_q, &wait); 191 add_wait_queue(&wait_q, &wait);
190 192
191 ret = MTD_ERASE(mtd, &nettel_erase); 193 ret = mtd->erase(mtd, &nettel_erase);
192 if (ret) { 194 if (ret) {
193 set_current_state(TASK_RUNNING); 195 set_current_state(TASK_RUNNING);
194 remove_wait_queue(&wait_q, &wait); 196 remove_wait_queue(&wait_q, &wait);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index d27f4129afd3..c861134cbc48 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -713,6 +713,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
713 713
714 if(dev->mtd_info) { 714 if(dev->mtd_info) {
715 del_mtd_device(dev->mtd_info); 715 del_mtd_device(dev->mtd_info);
716 map_destroy(dev->mtd_info);
716 info("mtd%d: Removed", dev->mtd_info->index); 717 info("mtd%d: Removed", dev->mtd_info->index);
717 } 718 }
718 719
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index f49ebc3c4606..433c3cac3ca9 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -14,112 +14,229 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <asm/io.h> 17#include <linux/device.h>
18#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h> 20#include <linux/mtd/map.h>
20#include <linux/config.h> 21#include <linux/config.h>
21#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
22#include <linux/mtd/physmap.h> 23#include <linux/mtd/physmap.h>
24#include <asm/io.h>
23 25
24static struct mtd_info *mymtd; 26struct physmap_flash_info {
25 27 struct mtd_info *mtd;
26struct map_info physmap_map = { 28 struct map_info map;
27 .name = "phys_mapped_flash", 29 struct resource *res;
28 .phys = CONFIG_MTD_PHYSMAP_START, 30#ifdef CONFIG_MTD_PARTITIONS
29 .size = CONFIG_MTD_PHYSMAP_LEN, 31 int nr_parts;
30 .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH, 32 struct mtd_partition *parts;
33#endif
31}; 34};
32 35
36
37static int physmap_flash_remove(struct platform_device *dev)
38{
39 struct physmap_flash_info *info;
40 struct physmap_flash_data *physmap_data;
41
42 info = platform_get_drvdata(dev);
43 if (info == NULL)
44 return 0;
45 platform_set_drvdata(dev, NULL);
46
47 physmap_data = dev->dev.platform_data;
48
49 if (info->mtd != NULL) {
33#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
34static struct mtd_partition *mtd_parts; 51 if (info->nr_parts) {
35static int mtd_parts_nb; 52 del_mtd_partitions(info->mtd);
53 kfree(info->parts);
54 } else if (physmap_data->nr_parts) {
55 del_mtd_partitions(info->mtd);
56 } else {
57 del_mtd_device(info->mtd);
58 }
59#else
60 del_mtd_device(info->mtd);
61#endif
62 map_destroy(info->mtd);
63 }
36 64
37static int num_physmap_partitions; 65 if (info->map.virt != NULL)
38static struct mtd_partition *physmap_partitions; 66 iounmap((void *)info->map.virt);
39 67
40static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; 68 if (info->res != NULL) {
69 release_resource(info->res);
70 kfree(info->res);
71 }
41 72
42void physmap_set_partitions(struct mtd_partition *parts, int num_parts) 73 return 0;
43{
44 physmap_partitions=parts;
45 num_physmap_partitions=num_parts;
46} 74}
47#endif /* CONFIG_MTD_PARTITIONS */
48 75
49static int __init init_physmap(void) 76static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
77#ifdef CONFIG_MTD_PARTITIONS
78static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
79#endif
80
81static int physmap_flash_probe(struct platform_device *dev)
50{ 82{
51 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; 83 struct physmap_flash_data *physmap_data;
52 const char **type; 84 struct physmap_flash_info *info;
85 const char **probe_type;
86 int err;
87
88 physmap_data = dev->dev.platform_data;
89 if (physmap_data == NULL)
90 return -ENODEV;
91
92 printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
93 (unsigned long long)dev->resource->end - dev->resource->start + 1,
94 (unsigned long long)dev->resource->start);
95
96 info = kmalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
97 if (info == NULL) {
98 err = -ENOMEM;
99 goto err_out;
100 }
101 memset(info, 0, sizeof(*info));
53 102
54 printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); 103 platform_set_drvdata(dev, info);
55 physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size);
56 104
57 if (!physmap_map.virt) { 105 info->res = request_mem_region(dev->resource->start,
58 printk("Failed to ioremap\n"); 106 dev->resource->end - dev->resource->start + 1,
59 return -EIO; 107 dev->dev.bus_id);
108 if (info->res == NULL) {
109 dev_err(&dev->dev, "Could not reserve memory region\n");
110 err = -ENOMEM;
111 goto err_out;
60 } 112 }
61 113
62 simple_map_init(&physmap_map); 114 info->map.name = dev->dev.bus_id;
115 info->map.phys = dev->resource->start;
116 info->map.size = dev->resource->end - dev->resource->start + 1;
117 info->map.bankwidth = physmap_data->width;
118 info->map.set_vpp = physmap_data->set_vpp;
119
120 info->map.virt = ioremap(info->map.phys, info->map.size);
121 if (info->map.virt == NULL) {
122 dev_err(&dev->dev, "Failed to ioremap flash region\n");
123 err = EIO;
124 goto err_out;
125 }
63 126
64 mymtd = NULL; 127 simple_map_init(&info->map);
65 type = rom_probe_types; 128
66 for(; !mymtd && *type; type++) { 129 probe_type = rom_probe_types;
67 mymtd = do_map_probe(*type, &physmap_map); 130 for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
131 info->mtd = do_map_probe(*probe_type, &info->map);
132 if (info->mtd == NULL) {
133 dev_err(&dev->dev, "map_probe failed\n");
134 err = -ENXIO;
135 goto err_out;
68 } 136 }
69 if (mymtd) { 137 info->mtd->owner = THIS_MODULE;
70 mymtd->owner = THIS_MODULE;
71 138
72#ifdef CONFIG_MTD_PARTITIONS 139#ifdef CONFIG_MTD_PARTITIONS
73 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 140 err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
74 &mtd_parts, 0); 141 if (err > 0) {
142 add_mtd_partitions(info->mtd, info->parts, err);
143 return 0;
144 }
75 145
76 if (mtd_parts_nb > 0) 146 if (physmap_data->nr_parts) {
77 { 147 printk(KERN_NOTICE "Using physmap partition information\n");
78 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); 148 add_mtd_partitions(info->mtd, physmap_data->parts,
79 return 0; 149 physmap_data->nr_parts);
80 } 150 return 0;
151 }
152#endif
153
154 add_mtd_device(info->mtd);
155 return 0;
156
157err_out:
158 physmap_flash_remove(dev);
159 return err;
160}
161
162static struct platform_driver physmap_flash_driver = {
163 .probe = physmap_flash_probe,
164 .remove = physmap_flash_remove,
165 .driver = {
166 .name = "physmap-flash",
167 },
168};
81 169
82 if (num_physmap_partitions != 0)
83 {
84 printk(KERN_NOTICE
85 "Using physmap partition definition\n");
86 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
87 return 0;
88 }
89 170
171#ifdef CONFIG_MTD_PHYSMAP_LEN
172#if CONFIG_MTD_PHYSMAP_LEN != 0
173#warning using PHYSMAP compat code
174#define PHYSMAP_COMPAT
175#endif
90#endif 176#endif
91 add_mtd_device(mymtd);
92 177
93 return 0; 178#ifdef PHYSMAP_COMPAT
94 } 179static struct physmap_flash_data physmap_flash_data = {
180 .width = CONFIG_MTD_PHYSMAP_BANKWIDTH,
181};
95 182
96 iounmap(physmap_map.virt); 183static struct resource physmap_flash_resource = {
97 return -ENXIO; 184 .start = CONFIG_MTD_PHYSMAP_START,
98} 185 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN,
186 .flags = IORESOURCE_MEM,
187};
99 188
100static void __exit cleanup_physmap(void) 189static struct platform_device physmap_flash = {
190 .name = "physmap-flash",
191 .id = 0,
192 .dev = {
193 .platform_data = &physmap_flash_data,
194 },
195 .num_resources = 1,
196 .resource = &physmap_flash_resource,
197};
198
199void physmap_configure(unsigned long addr, unsigned long size,
200 int bankwidth, void (*set_vpp)(struct map_info *, int))
101{ 201{
202 physmap_flash_resource.start = addr;
203 physmap_flash_resource.end = addr + size - 1;
204 physmap_flash_data.width = bankwidth;
205 physmap_flash_data.set_vpp = set_vpp;
206}
207
102#ifdef CONFIG_MTD_PARTITIONS 208#ifdef CONFIG_MTD_PARTITIONS
103 if (mtd_parts_nb) { 209void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
104 del_mtd_partitions(mymtd); 210{
105 kfree(mtd_parts); 211 physmap_flash_data.nr_parts = num_parts;
106 } else if (num_physmap_partitions) { 212 physmap_flash_data.parts = parts;
107 del_mtd_partitions(mymtd); 213}
108 } else { 214#endif
109 del_mtd_device(mymtd);
110 }
111#else
112 del_mtd_device(mymtd);
113#endif 215#endif
114 map_destroy(mymtd);
115 216
116 iounmap(physmap_map.virt); 217static int __init physmap_init(void)
117 physmap_map.virt = NULL; 218{
219 int err;
220
221 err = platform_driver_register(&physmap_flash_driver);
222#ifdef PHYSMAP_COMPAT
223 if (err == 0)
224 platform_device_register(&physmap_flash);
225#endif
226
227 return err;
118} 228}
119 229
120module_init(init_physmap); 230static void __exit physmap_exit(void)
121module_exit(cleanup_physmap); 231{
232#ifdef PHYSMAP_COMPAT
233 platform_device_unregister(&physmap_flash);
234#endif
235 platform_driver_unregister(&physmap_flash_driver);
236}
122 237
238module_init(physmap_init);
239module_exit(physmap_exit);
123 240
124MODULE_LICENSE("GPL"); 241MODULE_LICENSE("GPL");
125MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 242MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 2cef280e388c..e5c78463ebfd 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -71,7 +71,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
71 set_current_state(TASK_INTERRUPTIBLE); 71 set_current_state(TASK_INTERRUPTIBLE);
72 add_wait_queue(&wait_q, &wait); 72 add_wait_queue(&wait_q, &wait);
73 73
74 ret = MTD_ERASE(mtd, &erase); 74 ret = mtd->erase(mtd, &erase);
75 if (ret) { 75 if (ret) {
76 set_current_state(TASK_RUNNING); 76 set_current_state(TASK_RUNNING);
77 remove_wait_queue(&wait_q, &wait); 77 remove_wait_queue(&wait_q, &wait);
@@ -88,7 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
88 * Next, writhe data to flash. 88 * Next, writhe data to flash.
89 */ 89 */
90 90
91 ret = MTD_WRITE (mtd, pos, len, &retlen, buf); 91 ret = mtd->write(mtd, pos, len, &retlen, buf);
92 if (ret) 92 if (ret)
93 return ret; 93 return ret;
94 if (retlen != len) 94 if (retlen != len)
@@ -138,7 +138,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
138 mtd->name, pos, len); 138 mtd->name, pos, len);
139 139
140 if (!sect_size) 140 if (!sect_size)
141 return MTD_WRITE (mtd, pos, len, &retlen, buf); 141 return mtd->write(mtd, pos, len, &retlen, buf);
142 142
143 while (len > 0) { 143 while (len > 0) {
144 unsigned long sect_start = (pos/sect_size)*sect_size; 144 unsigned long sect_start = (pos/sect_size)*sect_size;
@@ -170,7 +170,8 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
170 mtdblk->cache_offset != sect_start) { 170 mtdblk->cache_offset != sect_start) {
171 /* fill the cache with the current sector */ 171 /* fill the cache with the current sector */
172 mtdblk->cache_state = STATE_EMPTY; 172 mtdblk->cache_state = STATE_EMPTY;
173 ret = MTD_READ(mtd, sect_start, sect_size, &retlen, mtdblk->cache_data); 173 ret = mtd->read(mtd, sect_start, sect_size,
174 &retlen, mtdblk->cache_data);
174 if (ret) 175 if (ret)
175 return ret; 176 return ret;
176 if (retlen != sect_size) 177 if (retlen != sect_size)
@@ -207,7 +208,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
207 mtd->name, pos, len); 208 mtd->name, pos, len);
208 209
209 if (!sect_size) 210 if (!sect_size)
210 return MTD_READ (mtd, pos, len, &retlen, buf); 211 return mtd->read(mtd, pos, len, &retlen, buf);
211 212
212 while (len > 0) { 213 while (len > 0) {
213 unsigned long sect_start = (pos/sect_size)*sect_size; 214 unsigned long sect_start = (pos/sect_size)*sect_size;
@@ -226,7 +227,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
226 mtdblk->cache_offset == sect_start) { 227 mtdblk->cache_offset == sect_start) {
227 memcpy (buf, mtdblk->cache_data + offset, size); 228 memcpy (buf, mtdblk->cache_data + offset, size);
228 } else { 229 } else {
229 ret = MTD_READ (mtd, pos, size, &retlen, buf); 230 ret = mtd->read(mtd, pos, size, &retlen, buf);
230 if (ret) 231 if (ret)
231 return ret; 232 return ret;
232 if (retlen != size) 233 if (retlen != size)
@@ -288,8 +289,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
288 289
289 mutex_init(&mtdblk->cache_mutex); 290 mutex_init(&mtdblk->cache_mutex);
290 mtdblk->cache_state = STATE_EMPTY; 291 mtdblk->cache_state = STATE_EMPTY;
291 if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && 292 if ( !(mtdblk->mtd->flags & MTD_NO_ERASE) && mtdblk->mtd->erasesize) {
292 mtdblk->mtd->erasesize) {
293 mtdblk->cache_size = mtdblk->mtd->erasesize; 293 mtdblk->cache_size = mtdblk->mtd->erasesize;
294 mtdblk->cache_data = NULL; 294 mtdblk->cache_data = NULL;
295 } 295 }
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index 0c830ba41ef0..29563ed258a4 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -45,9 +45,7 @@ static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
45 dev->blksize = 512; 45 dev->blksize = 512;
46 dev->size = mtd->size >> 9; 46 dev->size = mtd->size >> 9;
47 dev->tr = tr; 47 dev->tr = tr;
48 if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) != 48 dev->readonly = 1;
49 (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE))
50 dev->readonly = 1;
51 49
52 add_mtd_blktrans_dev(dev); 50 add_mtd_blktrans_dev(dev);
53} 51}
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6f044584bdc6..aa18d45b264b 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -49,24 +49,18 @@ static struct mtd_notifier notifier = {
49}; 49};
50 50
51/* 51/*
52 * We use file->private_data to store a pointer to the MTDdevice. 52 * Data structure to hold the pointer to the mtd device as well
53 * Since alighment is at least 32 bits, we have 2 bits free for OTP 53 * as mode information ofr various use cases.
54 * modes as well.
55 */ 54 */
56 55struct mtd_file_info {
57#define TO_MTD(file) (struct mtd_info *)((long)((file)->private_data) & ~3L) 56 struct mtd_info *mtd;
58 57 enum mtd_file_modes mode;
59#define MTD_MODE_OTP_FACT 1 58};
60#define MTD_MODE_OTP_USER 2
61#define MTD_MODE(file) ((long)((file)->private_data) & 3)
62
63#define SET_MTD_MODE(file, mode) \
64 do { long __p = (long)((file)->private_data); \
65 (file)->private_data = (void *)((__p & ~3L) | mode); } while (0)
66 59
67static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) 60static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
68{ 61{
69 struct mtd_info *mtd = TO_MTD(file); 62 struct mtd_file_info *mfi = file->private_data;
63 struct mtd_info *mtd = mfi->mtd;
70 64
71 switch (orig) { 65 switch (orig) {
72 case 0: 66 case 0:
@@ -97,6 +91,7 @@ static int mtd_open(struct inode *inode, struct file *file)
97 int minor = iminor(inode); 91 int minor = iminor(inode);
98 int devnum = minor >> 1; 92 int devnum = minor >> 1;
99 struct mtd_info *mtd; 93 struct mtd_info *mtd;
94 struct mtd_file_info *mfi;
100 95
101 DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n"); 96 DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n");
102 97
@@ -117,14 +112,20 @@ static int mtd_open(struct inode *inode, struct file *file)
117 return -ENODEV; 112 return -ENODEV;
118 } 113 }
119 114
120 file->private_data = mtd;
121
122 /* You can't open it RW if it's not a writeable device */ 115 /* You can't open it RW if it's not a writeable device */
123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { 116 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
124 put_mtd_device(mtd); 117 put_mtd_device(mtd);
125 return -EACCES; 118 return -EACCES;
126 } 119 }
127 120
121 mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
122 if (!mfi) {
123 put_mtd_device(mtd);
124 return -ENOMEM;
125 }
126 mfi->mtd = mtd;
127 file->private_data = mfi;
128
128 return 0; 129 return 0;
129} /* mtd_open */ 130} /* mtd_open */
130 131
@@ -132,16 +133,17 @@ static int mtd_open(struct inode *inode, struct file *file)
132 133
133static int mtd_close(struct inode *inode, struct file *file) 134static int mtd_close(struct inode *inode, struct file *file)
134{ 135{
135 struct mtd_info *mtd; 136 struct mtd_file_info *mfi = file->private_data;
137 struct mtd_info *mtd = mfi->mtd;
136 138
137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 139 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
138 140
139 mtd = TO_MTD(file);
140
141 if (mtd->sync) 141 if (mtd->sync)
142 mtd->sync(mtd); 142 mtd->sync(mtd);
143 143
144 put_mtd_device(mtd); 144 put_mtd_device(mtd);
145 file->private_data = NULL;
146 kfree(mfi);
145 147
146 return 0; 148 return 0;
147} /* mtd_close */ 149} /* mtd_close */
@@ -153,7 +155,8 @@ static int mtd_close(struct inode *inode, struct file *file)
153 155
154static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) 156static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
155{ 157{
156 struct mtd_info *mtd = TO_MTD(file); 158 struct mtd_file_info *mfi = file->private_data;
159 struct mtd_info *mtd = mfi->mtd;
157 size_t retlen=0; 160 size_t retlen=0;
158 size_t total_retlen=0; 161 size_t total_retlen=0;
159 int ret=0; 162 int ret=0;
@@ -170,36 +173,58 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
170 173
171 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers 174 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers
172 and pass them directly to the MTD functions */ 175 and pass them directly to the MTD functions */
176
177 if (count > MAX_KMALLOC_SIZE)
178 kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
179 else
180 kbuf=kmalloc(count, GFP_KERNEL);
181
182 if (!kbuf)
183 return -ENOMEM;
184
173 while (count) { 185 while (count) {
186
174 if (count > MAX_KMALLOC_SIZE) 187 if (count > MAX_KMALLOC_SIZE)
175 len = MAX_KMALLOC_SIZE; 188 len = MAX_KMALLOC_SIZE;
176 else 189 else
177 len = count; 190 len = count;
178 191
179 kbuf=kmalloc(len,GFP_KERNEL); 192 switch (mfi->mode) {
180 if (!kbuf) 193 case MTD_MODE_OTP_FACTORY:
181 return -ENOMEM;
182
183 switch (MTD_MODE(file)) {
184 case MTD_MODE_OTP_FACT:
185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 194 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
186 break; 195 break;
187 case MTD_MODE_OTP_USER: 196 case MTD_MODE_OTP_USER:
188 ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf); 197 ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
189 break; 198 break;
199 case MTD_MODE_RAW:
200 {
201 struct mtd_oob_ops ops;
202
203 ops.mode = MTD_OOB_RAW;
204 ops.datbuf = kbuf;
205 ops.oobbuf = NULL;
206 ops.len = len;
207
208 ret = mtd->read_oob(mtd, *ppos, &ops);
209 retlen = ops.retlen;
210 break;
211 }
190 default: 212 default:
191 ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); 213 ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);
192 } 214 }
193 /* Nand returns -EBADMSG on ecc errors, but it returns 215 /* Nand returns -EBADMSG on ecc errors, but it returns
194 * the data. For our userspace tools it is important 216 * the data. For our userspace tools it is important
195 * to dump areas with ecc errors ! 217 * to dump areas with ecc errors !
218 * For kernel internal usage it also might return -EUCLEAN
219 * to signal the caller that a bitflip has occured and has
220 * been corrected by the ECC algorithm.
196 * Userspace software which accesses NAND this way 221 * Userspace software which accesses NAND this way
197 * must be aware of the fact that it deals with NAND 222 * must be aware of the fact that it deals with NAND
198 */ 223 */
199 if (!ret || (ret == -EBADMSG)) { 224 if (!ret || (ret == -EUCLEAN) || (ret == -EBADMSG)) {
200 *ppos += retlen; 225 *ppos += retlen;
201 if (copy_to_user(buf, kbuf, retlen)) { 226 if (copy_to_user(buf, kbuf, retlen)) {
202 kfree(kbuf); 227 kfree(kbuf);
203 return -EFAULT; 228 return -EFAULT;
204 } 229 }
205 else 230 else
@@ -215,15 +240,16 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
215 return ret; 240 return ret;
216 } 241 }
217 242
218 kfree(kbuf);
219 } 243 }
220 244
245 kfree(kbuf);
221 return total_retlen; 246 return total_retlen;
222} /* mtd_read */ 247} /* mtd_read */
223 248
224static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) 249static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
225{ 250{
226 struct mtd_info *mtd = TO_MTD(file); 251 struct mtd_file_info *mfi = file->private_data;
252 struct mtd_info *mtd = mfi->mtd;
227 char *kbuf; 253 char *kbuf;
228 size_t retlen; 254 size_t retlen;
229 size_t total_retlen=0; 255 size_t total_retlen=0;
@@ -241,25 +267,28 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
241 if (!count) 267 if (!count)
242 return 0; 268 return 0;
243 269
270 if (count > MAX_KMALLOC_SIZE)
271 kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
272 else
273 kbuf=kmalloc(count, GFP_KERNEL);
274
275 if (!kbuf)
276 return -ENOMEM;
277
244 while (count) { 278 while (count) {
279
245 if (count > MAX_KMALLOC_SIZE) 280 if (count > MAX_KMALLOC_SIZE)
246 len = MAX_KMALLOC_SIZE; 281 len = MAX_KMALLOC_SIZE;
247 else 282 else
248 len = count; 283 len = count;
249 284
250 kbuf=kmalloc(len,GFP_KERNEL);
251 if (!kbuf) {
252 printk("kmalloc is null\n");
253 return -ENOMEM;
254 }
255
256 if (copy_from_user(kbuf, buf, len)) { 285 if (copy_from_user(kbuf, buf, len)) {
257 kfree(kbuf); 286 kfree(kbuf);
258 return -EFAULT; 287 return -EFAULT;
259 } 288 }
260 289
261 switch (MTD_MODE(file)) { 290 switch (mfi->mode) {
262 case MTD_MODE_OTP_FACT: 291 case MTD_MODE_OTP_FACTORY:
263 ret = -EROFS; 292 ret = -EROFS;
264 break; 293 break;
265 case MTD_MODE_OTP_USER: 294 case MTD_MODE_OTP_USER:
@@ -269,6 +298,21 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
269 } 298 }
270 ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf); 299 ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
271 break; 300 break;
301
302 case MTD_MODE_RAW:
303 {
304 struct mtd_oob_ops ops;
305
306 ops.mode = MTD_OOB_RAW;
307 ops.datbuf = kbuf;
308 ops.oobbuf = NULL;
309 ops.len = len;
310
311 ret = mtd->write_oob(mtd, *ppos, &ops);
312 retlen = ops.retlen;
313 break;
314 }
315
272 default: 316 default:
273 ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf); 317 ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
274 } 318 }
@@ -282,10 +326,9 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
282 kfree(kbuf); 326 kfree(kbuf);
283 return ret; 327 return ret;
284 } 328 }
285
286 kfree(kbuf);
287 } 329 }
288 330
331 kfree(kbuf);
289 return total_retlen; 332 return total_retlen;
290} /* mtd_write */ 333} /* mtd_write */
291 334
@@ -299,13 +342,45 @@ static void mtdchar_erase_callback (struct erase_info *instr)
299 wake_up((wait_queue_head_t *)instr->priv); 342 wake_up((wait_queue_head_t *)instr->priv);
300} 343}
301 344
345#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP)
346static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
347{
348 struct mtd_info *mtd = mfi->mtd;
349 int ret = 0;
350
351 switch (mode) {
352 case MTD_OTP_FACTORY:
353 if (!mtd->read_fact_prot_reg)
354 ret = -EOPNOTSUPP;
355 else
356 mfi->mode = MTD_MODE_OTP_FACTORY;
357 break;
358 case MTD_OTP_USER:
359 if (!mtd->read_fact_prot_reg)
360 ret = -EOPNOTSUPP;
361 else
362 mfi->mode = MTD_MODE_OTP_USER;
363 break;
364 default:
365 ret = -EINVAL;
366 case MTD_OTP_OFF:
367 break;
368 }
369 return ret;
370}
371#else
372# define otp_select_filemode(f,m) -EOPNOTSUPP
373#endif
374
302static int mtd_ioctl(struct inode *inode, struct file *file, 375static int mtd_ioctl(struct inode *inode, struct file *file,
303 u_int cmd, u_long arg) 376 u_int cmd, u_long arg)
304{ 377{
305 struct mtd_info *mtd = TO_MTD(file); 378 struct mtd_file_info *mfi = file->private_data;
379 struct mtd_info *mtd = mfi->mtd;
306 void __user *argp = (void __user *)arg; 380 void __user *argp = (void __user *)arg;
307 int ret = 0; 381 int ret = 0;
308 u_long size; 382 u_long size;
383 struct mtd_info_user info;
309 384
310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 385 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
311 386
@@ -341,7 +416,15 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
341 } 416 }
342 417
343 case MEMGETINFO: 418 case MEMGETINFO:
344 if (copy_to_user(argp, mtd, sizeof(struct mtd_info_user))) 419 info.type = mtd->type;
420 info.flags = mtd->flags;
421 info.size = mtd->size;
422 info.erasesize = mtd->erasesize;
423 info.writesize = mtd->writesize;
424 info.oobsize = mtd->oobsize;
425 info.ecctype = mtd->ecctype;
426 info.eccsize = mtd->eccsize;
427 if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
345 return -EFAULT; 428 return -EFAULT;
346 break; 429 break;
347 430
@@ -400,8 +483,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
400 case MEMWRITEOOB: 483 case MEMWRITEOOB:
401 { 484 {
402 struct mtd_oob_buf buf; 485 struct mtd_oob_buf buf;
403 void *databuf; 486 struct mtd_oob_ops ops;
404 ssize_t retlen;
405 487
406 if(!(file->f_mode & 2)) 488 if(!(file->f_mode & 2))
407 return -EPERM; 489 return -EPERM;
@@ -409,7 +491,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 491 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
410 return -EFAULT; 492 return -EFAULT;
411 493
412 if (buf.length > 0x4096) 494 if (buf.length > 4096)
413 return -EINVAL; 495 return -EINVAL;
414 496
415 if (!mtd->write_oob) 497 if (!mtd->write_oob)
@@ -421,21 +503,32 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
421 if (ret) 503 if (ret)
422 return ret; 504 return ret;
423 505
424 databuf = kmalloc(buf.length, GFP_KERNEL); 506 ops.len = buf.length;
425 if (!databuf) 507 ops.ooblen = buf.length;
508 ops.ooboffs = buf.start & (mtd->oobsize - 1);
509 ops.datbuf = NULL;
510 ops.mode = MTD_OOB_PLACE;
511
512 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
513 return -EINVAL;
514
515 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
516 if (!ops.oobbuf)
426 return -ENOMEM; 517 return -ENOMEM;
427 518
428 if (copy_from_user(databuf, buf.ptr, buf.length)) { 519 if (copy_from_user(ops.oobbuf, buf.ptr, buf.length)) {
429 kfree(databuf); 520 kfree(ops.oobbuf);
430 return -EFAULT; 521 return -EFAULT;
431 } 522 }
432 523
433 ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf); 524 buf.start &= ~(mtd->oobsize - 1);
525 ret = mtd->write_oob(mtd, buf.start, &ops);
434 526
435 if (copy_to_user(argp + sizeof(uint32_t), &retlen, sizeof(uint32_t))) 527 if (copy_to_user(argp + sizeof(uint32_t), &ops.retlen,
528 sizeof(uint32_t)))
436 ret = -EFAULT; 529 ret = -EFAULT;
437 530
438 kfree(databuf); 531 kfree(ops.oobbuf);
439 break; 532 break;
440 533
441 } 534 }
@@ -443,13 +536,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
443 case MEMREADOOB: 536 case MEMREADOOB:
444 { 537 {
445 struct mtd_oob_buf buf; 538 struct mtd_oob_buf buf;
446 void *databuf; 539 struct mtd_oob_ops ops;
447 ssize_t retlen;
448 540
449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 541 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
450 return -EFAULT; 542 return -EFAULT;
451 543
452 if (buf.length > 0x4096) 544 if (buf.length > 4096)
453 return -EINVAL; 545 return -EINVAL;
454 546
455 if (!mtd->read_oob) 547 if (!mtd->read_oob)
@@ -457,22 +549,32 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
457 else 549 else
458 ret = access_ok(VERIFY_WRITE, buf.ptr, 550 ret = access_ok(VERIFY_WRITE, buf.ptr,
459 buf.length) ? 0 : -EFAULT; 551 buf.length) ? 0 : -EFAULT;
460
461 if (ret) 552 if (ret)
462 return ret; 553 return ret;
463 554
464 databuf = kmalloc(buf.length, GFP_KERNEL); 555 ops.len = buf.length;
465 if (!databuf) 556 ops.ooblen = buf.length;
557 ops.ooboffs = buf.start & (mtd->oobsize - 1);
558 ops.datbuf = NULL;
559 ops.mode = MTD_OOB_PLACE;
560
561 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
562 return -EINVAL;
563
564 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
565 if (!ops.oobbuf)
466 return -ENOMEM; 566 return -ENOMEM;
467 567
468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); 568 buf.start &= ~(mtd->oobsize - 1);
569 ret = mtd->read_oob(mtd, buf.start, &ops);
469 570
470 if (put_user(retlen, (uint32_t __user *)argp)) 571 if (put_user(ops.retlen, (uint32_t __user *)argp))
471 ret = -EFAULT; 572 ret = -EFAULT;
472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) 573 else if (ops.retlen && copy_to_user(buf.ptr, ops.oobbuf,
574 ops.retlen))
473 ret = -EFAULT; 575 ret = -EFAULT;
474 576
475 kfree(databuf); 577 kfree(ops.oobbuf);
476 break; 578 break;
477 } 579 }
478 580
@@ -504,16 +606,22 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
504 break; 606 break;
505 } 607 }
506 608
507 case MEMSETOOBSEL: 609 /* Legacy interface */
508 {
509 if (copy_from_user(&mtd->oobinfo, argp, sizeof(struct nand_oobinfo)))
510 return -EFAULT;
511 break;
512 }
513
514 case MEMGETOOBSEL: 610 case MEMGETOOBSEL:
515 { 611 {
516 if (copy_to_user(argp, &(mtd->oobinfo), sizeof(struct nand_oobinfo))) 612 struct nand_oobinfo oi;
613
614 if (!mtd->ecclayout)
615 return -EOPNOTSUPP;
616 if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
617 return -EINVAL;
618
619 oi.useecc = MTD_NANDECC_AUTOPLACE;
620 memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
621 memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
622 sizeof(oi.oobfree));
623
624 if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
517 return -EFAULT; 625 return -EFAULT;
518 break; 626 break;
519 } 627 }
@@ -544,31 +652,17 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
544 break; 652 break;
545 } 653 }
546 654
547#ifdef CONFIG_MTD_OTP 655#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP)
548 case OTPSELECT: 656 case OTPSELECT:
549 { 657 {
550 int mode; 658 int mode;
551 if (copy_from_user(&mode, argp, sizeof(int))) 659 if (copy_from_user(&mode, argp, sizeof(int)))
552 return -EFAULT; 660 return -EFAULT;
553 SET_MTD_MODE(file, 0); 661
554 switch (mode) { 662 mfi->mode = MTD_MODE_NORMAL;
555 case MTD_OTP_FACTORY: 663
556 if (!mtd->read_fact_prot_reg) 664 ret = otp_select_filemode(mfi, mode);
557 ret = -EOPNOTSUPP; 665
558 else
559 SET_MTD_MODE(file, MTD_MODE_OTP_FACT);
560 break;
561 case MTD_OTP_USER:
562 if (!mtd->read_fact_prot_reg)
563 ret = -EOPNOTSUPP;
564 else
565 SET_MTD_MODE(file, MTD_MODE_OTP_USER);
566 break;
567 default:
568 ret = -EINVAL;
569 case MTD_OTP_OFF:
570 break;
571 }
572 file->f_pos = 0; 666 file->f_pos = 0;
573 break; 667 break;
574 } 668 }
@@ -580,8 +674,8 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
580 if (!buf) 674 if (!buf)
581 return -ENOMEM; 675 return -ENOMEM;
582 ret = -EOPNOTSUPP; 676 ret = -EOPNOTSUPP;
583 switch (MTD_MODE(file)) { 677 switch (mfi->mode) {
584 case MTD_MODE_OTP_FACT: 678 case MTD_MODE_OTP_FACTORY:
585 if (mtd->get_fact_prot_info) 679 if (mtd->get_fact_prot_info)
586 ret = mtd->get_fact_prot_info(mtd, buf, 4096); 680 ret = mtd->get_fact_prot_info(mtd, buf, 4096);
587 break; 681 break;
@@ -589,6 +683,8 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
589 if (mtd->get_user_prot_info) 683 if (mtd->get_user_prot_info)
590 ret = mtd->get_user_prot_info(mtd, buf, 4096); 684 ret = mtd->get_user_prot_info(mtd, buf, 4096);
591 break; 685 break;
686 default:
687 break;
592 } 688 }
593 if (ret >= 0) { 689 if (ret >= 0) {
594 if (cmd == OTPGETREGIONCOUNT) { 690 if (cmd == OTPGETREGIONCOUNT) {
@@ -607,7 +703,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
607 { 703 {
608 struct otp_info info; 704 struct otp_info info;
609 705
610 if (MTD_MODE(file) != MTD_MODE_OTP_USER) 706 if (mfi->mode != MTD_MODE_OTP_USER)
611 return -EINVAL; 707 return -EINVAL;
612 if (copy_from_user(&info, argp, sizeof(info))) 708 if (copy_from_user(&info, argp, sizeof(info)))
613 return -EFAULT; 709 return -EFAULT;
@@ -618,6 +714,49 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
618 } 714 }
619#endif 715#endif
620 716
717 case ECCGETLAYOUT:
718 {
719 if (!mtd->ecclayout)
720 return -EOPNOTSUPP;
721
722 if (copy_to_user(argp, &mtd->ecclayout,
723 sizeof(struct nand_ecclayout)))
724 return -EFAULT;
725 break;
726 }
727
728 case ECCGETSTATS:
729 {
730 if (copy_to_user(argp, &mtd->ecc_stats,
731 sizeof(struct mtd_ecc_stats)))
732 return -EFAULT;
733 break;
734 }
735
736 case MTDFILEMODE:
737 {
738 mfi->mode = 0;
739
740 switch(arg) {
741 case MTD_MODE_OTP_FACTORY:
742 case MTD_MODE_OTP_USER:
743 ret = otp_select_filemode(mfi, arg);
744 break;
745
746 case MTD_MODE_RAW:
747 if (!mtd->read_oob || !mtd->write_oob)
748 return -EOPNOTSUPP;
749 mfi->mode = arg;
750
751 case MTD_MODE_NORMAL:
752 break;
753 default:
754 ret = -EINVAL;
755 }
756 file->f_pos = 0;
757 break;
758 }
759
621 default: 760 default:
622 ret = -ENOTTY; 761 ret = -ENOTTY;
623 } 762 }
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 9af840364a74..1fea631b5852 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -19,6 +19,8 @@
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/mtd/concat.h> 20#include <linux/mtd/concat.h>
21 21
22#include <asm/div64.h>
23
22/* 24/*
23 * Our storage structure: 25 * Our storage structure:
24 * Subdev points to an array of pointers to struct mtd_info objects 26 * Subdev points to an array of pointers to struct mtd_info objects
@@ -54,7 +56,7 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
54 size_t * retlen, u_char * buf) 56 size_t * retlen, u_char * buf)
55{ 57{
56 struct mtd_concat *concat = CONCAT(mtd); 58 struct mtd_concat *concat = CONCAT(mtd);
57 int err = -EINVAL; 59 int ret = 0, err;
58 int i; 60 int i;
59 61
60 *retlen = 0; 62 *retlen = 0;
@@ -78,19 +80,29 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
78 80
79 err = subdev->read(subdev, from, size, &retsize, buf); 81 err = subdev->read(subdev, from, size, &retsize, buf);
80 82
81 if (err) 83 /* Save information about bitflips! */
82 break; 84 if (unlikely(err)) {
85 if (err == -EBADMSG) {
86 mtd->ecc_stats.failed++;
87 ret = err;
88 } else if (err == -EUCLEAN) {
89 mtd->ecc_stats.corrected++;
90 /* Do not overwrite -EBADMSG !! */
91 if (!ret)
92 ret = err;
93 } else
94 return err;
95 }
83 96
84 *retlen += retsize; 97 *retlen += retsize;
85 len -= size; 98 len -= size;
86 if (len == 0) 99 if (len == 0)
87 break; 100 return ret;
88 101
89 err = -EINVAL;
90 buf += size; 102 buf += size;
91 from = 0; 103 from = 0;
92 } 104 }
93 return err; 105 return -EINVAL;
94} 106}
95 107
96static int 108static int
@@ -141,211 +153,185 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
141} 153}
142 154
143static int 155static int
144concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 156concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
145 size_t * retlen, u_char * buf, u_char * eccbuf, 157 unsigned long count, loff_t to, size_t * retlen)
146 struct nand_oobinfo *oobsel)
147{ 158{
148 struct mtd_concat *concat = CONCAT(mtd); 159 struct mtd_concat *concat = CONCAT(mtd);
149 int err = -EINVAL; 160 struct kvec *vecs_copy;
161 unsigned long entry_low, entry_high;
162 size_t total_len = 0;
150 int i; 163 int i;
164 int err = -EINVAL;
151 165
152 *retlen = 0; 166 if (!(mtd->flags & MTD_WRITEABLE))
153 167 return -EROFS;
154 for (i = 0; i < concat->num_subdev; i++) {
155 struct mtd_info *subdev = concat->subdev[i];
156 size_t size, retsize;
157
158 if (from >= subdev->size) {
159 /* Not destined for this subdev */
160 size = 0;
161 from -= subdev->size;
162 continue;
163 }
164
165 if (from + len > subdev->size)
166 /* First part goes into this subdev */
167 size = subdev->size - from;
168 else
169 /* Entire transaction goes into this subdev */
170 size = len;
171 168
172 if (subdev->read_ecc) 169 *retlen = 0;
173 err = subdev->read_ecc(subdev, from, size,
174 &retsize, buf, eccbuf, oobsel);
175 else
176 err = -EINVAL;
177 170
178 if (err) 171 /* Calculate total length of data */
179 break; 172 for (i = 0; i < count; i++)
173 total_len += vecs[i].iov_len;
180 174
181 *retlen += retsize; 175 /* Do not allow write past end of device */
182 len -= size; 176 if ((to + total_len) > mtd->size)
183 if (len == 0) 177 return -EINVAL;
184 break;
185 178
186 err = -EINVAL; 179 /* Check alignment */
187 buf += size; 180 if (mtd->writesize > 1) {
188 if (eccbuf) { 181 loff_t __to = to;
189 eccbuf += subdev->oobsize; 182 if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize))
190 /* in nand.c at least, eccbufs are 183 return -EINVAL;
191 tagged with 2 (int)eccstatus'; we
192 must account for these */
193 eccbuf += 2 * (sizeof (int));
194 }
195 from = 0;
196 } 184 }
197 return err;
198}
199 185
200static int 186 /* make a copy of vecs */
201concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 187 vecs_copy = kmalloc(sizeof(struct kvec) * count, GFP_KERNEL);
202 size_t * retlen, const u_char * buf, u_char * eccbuf, 188 if (!vecs_copy)
203 struct nand_oobinfo *oobsel) 189 return -ENOMEM;
204{ 190 memcpy(vecs_copy, vecs, sizeof(struct kvec) * count);
205 struct mtd_concat *concat = CONCAT(mtd);
206 int err = -EINVAL;
207 int i;
208
209 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS;
211
212 *retlen = 0;
213 191
192 entry_low = 0;
214 for (i = 0; i < concat->num_subdev; i++) { 193 for (i = 0; i < concat->num_subdev; i++) {
215 struct mtd_info *subdev = concat->subdev[i]; 194 struct mtd_info *subdev = concat->subdev[i];
216 size_t size, retsize; 195 size_t size, wsize, retsize, old_iov_len;
217 196
218 if (to >= subdev->size) { 197 if (to >= subdev->size) {
219 size = 0;
220 to -= subdev->size; 198 to -= subdev->size;
221 continue; 199 continue;
222 } 200 }
223 if (to + len > subdev->size) 201
224 size = subdev->size - to; 202 size = min(total_len, (size_t)(subdev->size - to));
225 else 203 wsize = size; /* store for future use */
226 size = len; 204
205 entry_high = entry_low;
206 while (entry_high < count) {
207 if (size <= vecs_copy[entry_high].iov_len)
208 break;
209 size -= vecs_copy[entry_high++].iov_len;
210 }
211
212 old_iov_len = vecs_copy[entry_high].iov_len;
213 vecs_copy[entry_high].iov_len = size;
227 214
228 if (!(subdev->flags & MTD_WRITEABLE)) 215 if (!(subdev->flags & MTD_WRITEABLE))
229 err = -EROFS; 216 err = -EROFS;
230 else if (subdev->write_ecc)
231 err = subdev->write_ecc(subdev, to, size,
232 &retsize, buf, eccbuf, oobsel);
233 else 217 else
234 err = -EINVAL; 218 err = subdev->writev(subdev, &vecs_copy[entry_low],
219 entry_high - entry_low + 1, to, &retsize);
220
221 vecs_copy[entry_high].iov_len = old_iov_len - size;
222 vecs_copy[entry_high].iov_base += size;
223
224 entry_low = entry_high;
235 225
236 if (err) 226 if (err)
237 break; 227 break;
238 228
239 *retlen += retsize; 229 *retlen += retsize;
240 len -= size; 230 total_len -= wsize;
241 if (len == 0) 231
232 if (total_len == 0)
242 break; 233 break;
243 234
244 err = -EINVAL; 235 err = -EINVAL;
245 buf += size;
246 if (eccbuf)
247 eccbuf += subdev->oobsize;
248 to = 0; 236 to = 0;
249 } 237 }
238
239 kfree(vecs_copy);
250 return err; 240 return err;
251} 241}
252 242
253static int 243static int
254concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 244concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
255 size_t * retlen, u_char * buf)
256{ 245{
257 struct mtd_concat *concat = CONCAT(mtd); 246 struct mtd_concat *concat = CONCAT(mtd);
258 int err = -EINVAL; 247 struct mtd_oob_ops devops = *ops;
259 int i; 248 int i, err, ret = 0;
260 249
261 *retlen = 0; 250 ops->retlen = 0;
262 251
263 for (i = 0; i < concat->num_subdev; i++) { 252 for (i = 0; i < concat->num_subdev; i++) {
264 struct mtd_info *subdev = concat->subdev[i]; 253 struct mtd_info *subdev = concat->subdev[i];
265 size_t size, retsize;
266 254
267 if (from >= subdev->size) { 255 if (from >= subdev->size) {
268 /* Not destined for this subdev */
269 size = 0;
270 from -= subdev->size; 256 from -= subdev->size;
271 continue; 257 continue;
272 } 258 }
273 if (from + len > subdev->size)
274 /* First part goes into this subdev */
275 size = subdev->size - from;
276 else
277 /* Entire transaction goes into this subdev */
278 size = len;
279 259
280 if (subdev->read_oob) 260 /* partial read ? */
281 err = subdev->read_oob(subdev, from, size, 261 if (from + devops.len > subdev->size)
282 &retsize, buf); 262 devops.len = subdev->size - from;
283 else 263
284 err = -EINVAL; 264 err = subdev->read_oob(subdev, from, &devops);
265 ops->retlen += devops.retlen;
266
267 /* Save information about bitflips! */
268 if (unlikely(err)) {
269 if (err == -EBADMSG) {
270 mtd->ecc_stats.failed++;
271 ret = err;
272 } else if (err == -EUCLEAN) {
273 mtd->ecc_stats.corrected++;
274 /* Do not overwrite -EBADMSG !! */
275 if (!ret)
276 ret = err;
277 } else
278 return err;
279 }
285 280
286 if (err) 281 devops.len = ops->len - ops->retlen;
287 break; 282 if (!devops.len)
283 return ret;
288 284
289 *retlen += retsize; 285 if (devops.datbuf)
290 len -= size; 286 devops.datbuf += devops.retlen;
291 if (len == 0) 287 if (devops.oobbuf)
292 break; 288 devops.oobbuf += devops.ooblen;
293 289
294 err = -EINVAL;
295 buf += size;
296 from = 0; 290 from = 0;
297 } 291 }
298 return err; 292 return -EINVAL;
299} 293}
300 294
301static int 295static int
302concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 296concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
303 size_t * retlen, const u_char * buf)
304{ 297{
305 struct mtd_concat *concat = CONCAT(mtd); 298 struct mtd_concat *concat = CONCAT(mtd);
306 int err = -EINVAL; 299 struct mtd_oob_ops devops = *ops;
307 int i; 300 int i, err;
308 301
309 if (!(mtd->flags & MTD_WRITEABLE)) 302 if (!(mtd->flags & MTD_WRITEABLE))
310 return -EROFS; 303 return -EROFS;
311 304
312 *retlen = 0; 305 ops->retlen = 0;
313 306
314 for (i = 0; i < concat->num_subdev; i++) { 307 for (i = 0; i < concat->num_subdev; i++) {
315 struct mtd_info *subdev = concat->subdev[i]; 308 struct mtd_info *subdev = concat->subdev[i];
316 size_t size, retsize;
317 309
318 if (to >= subdev->size) { 310 if (to >= subdev->size) {
319 size = 0;
320 to -= subdev->size; 311 to -= subdev->size;
321 continue; 312 continue;
322 } 313 }
323 if (to + len > subdev->size)
324 size = subdev->size - to;
325 else
326 size = len;
327 314
328 if (!(subdev->flags & MTD_WRITEABLE)) 315 /* partial write ? */
329 err = -EROFS; 316 if (to + devops.len > subdev->size)
330 else if (subdev->write_oob) 317 devops.len = subdev->size - to;
331 err = subdev->write_oob(subdev, to, size, &retsize,
332 buf);
333 else
334 err = -EINVAL;
335 318
319 err = subdev->write_oob(subdev, to, &devops);
320 ops->retlen += devops.retlen;
336 if (err) 321 if (err)
337 break; 322 return err;
338 323
339 *retlen += retsize; 324 devops.len = ops->len - ops->retlen;
340 len -= size; 325 if (!devops.len)
341 if (len == 0) 326 return 0;
342 break;
343 327
344 err = -EINVAL; 328 if (devops.datbuf)
345 buf += size; 329 devops.datbuf += devops.retlen;
330 if (devops.oobbuf)
331 devops.oobbuf += devops.ooblen;
346 to = 0; 332 to = 0;
347 } 333 }
348 return err; 334 return -EINVAL;
349} 335}
350 336
351static void concat_erase_callback(struct erase_info *instr) 337static void concat_erase_callback(struct erase_info *instr)
@@ -636,6 +622,60 @@ static void concat_resume(struct mtd_info *mtd)
636 } 622 }
637} 623}
638 624
625static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
626{
627 struct mtd_concat *concat = CONCAT(mtd);
628 int i, res = 0;
629
630 if (!concat->subdev[0]->block_isbad)
631 return res;
632
633 if (ofs > mtd->size)
634 return -EINVAL;
635
636 for (i = 0; i < concat->num_subdev; i++) {
637 struct mtd_info *subdev = concat->subdev[i];
638
639 if (ofs >= subdev->size) {
640 ofs -= subdev->size;
641 continue;
642 }
643
644 res = subdev->block_isbad(subdev, ofs);
645 break;
646 }
647
648 return res;
649}
650
651static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
652{
653 struct mtd_concat *concat = CONCAT(mtd);
654 int i, err = -EINVAL;
655
656 if (!concat->subdev[0]->block_markbad)
657 return 0;
658
659 if (ofs > mtd->size)
660 return -EINVAL;
661
662 for (i = 0; i < concat->num_subdev; i++) {
663 struct mtd_info *subdev = concat->subdev[i];
664
665 if (ofs >= subdev->size) {
666 ofs -= subdev->size;
667 continue;
668 }
669
670 err = subdev->block_markbad(subdev, ofs);
671 if (!err)
672 mtd->ecc_stats.badblocks++;
673 break;
674 }
675
676 return err;
677}
678
639/* 679/*
640 * This function constructs a virtual MTD device by concatenating 680 * This function constructs a virtual MTD device by concatenating
641 * num_devs MTD devices. A pointer to the new device object is 681 * num_devs MTD devices. A pointer to the new device object is
@@ -677,18 +717,22 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
677 concat->mtd.flags = subdev[0]->flags; 717 concat->mtd.flags = subdev[0]->flags;
678 concat->mtd.size = subdev[0]->size; 718 concat->mtd.size = subdev[0]->size;
679 concat->mtd.erasesize = subdev[0]->erasesize; 719 concat->mtd.erasesize = subdev[0]->erasesize;
680 concat->mtd.oobblock = subdev[0]->oobblock; 720 concat->mtd.writesize = subdev[0]->writesize;
681 concat->mtd.oobsize = subdev[0]->oobsize; 721 concat->mtd.oobsize = subdev[0]->oobsize;
682 concat->mtd.ecctype = subdev[0]->ecctype; 722 concat->mtd.ecctype = subdev[0]->ecctype;
683 concat->mtd.eccsize = subdev[0]->eccsize; 723 concat->mtd.eccsize = subdev[0]->eccsize;
684 if (subdev[0]->read_ecc) 724 if (subdev[0]->writev)
685 concat->mtd.read_ecc = concat_read_ecc; 725 concat->mtd.writev = concat_writev;
686 if (subdev[0]->write_ecc)
687 concat->mtd.write_ecc = concat_write_ecc;
688 if (subdev[0]->read_oob) 726 if (subdev[0]->read_oob)
689 concat->mtd.read_oob = concat_read_oob; 727 concat->mtd.read_oob = concat_read_oob;
690 if (subdev[0]->write_oob) 728 if (subdev[0]->write_oob)
691 concat->mtd.write_oob = concat_write_oob; 729 concat->mtd.write_oob = concat_write_oob;
730 if (subdev[0]->block_isbad)
731 concat->mtd.block_isbad = concat_block_isbad;
732 if (subdev[0]->block_markbad)
733 concat->mtd.block_markbad = concat_block_markbad;
734
735 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
692 736
693 concat->subdev[0] = subdev[0]; 737 concat->subdev[0] = subdev[0];
694 738
@@ -717,12 +761,12 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
717 subdev[i]->flags & MTD_WRITEABLE; 761 subdev[i]->flags & MTD_WRITEABLE;
718 } 762 }
719 concat->mtd.size += subdev[i]->size; 763 concat->mtd.size += subdev[i]->size;
720 if (concat->mtd.oobblock != subdev[i]->oobblock || 764 concat->mtd.ecc_stats.badblocks +=
765 subdev[i]->ecc_stats.badblocks;
766 if (concat->mtd.writesize != subdev[i]->writesize ||
721 concat->mtd.oobsize != subdev[i]->oobsize || 767 concat->mtd.oobsize != subdev[i]->oobsize ||
722 concat->mtd.ecctype != subdev[i]->ecctype || 768 concat->mtd.ecctype != subdev[i]->ecctype ||
723 concat->mtd.eccsize != subdev[i]->eccsize || 769 concat->mtd.eccsize != subdev[i]->eccsize ||
724 !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
725 !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
726 !concat->mtd.read_oob != !subdev[i]->read_oob || 770 !concat->mtd.read_oob != !subdev[i]->read_oob ||
727 !concat->mtd.write_oob != !subdev[i]->write_oob) { 771 !concat->mtd.write_oob != !subdev[i]->write_oob) {
728 kfree(concat); 772 kfree(concat);
@@ -734,14 +778,11 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
734 778
735 } 779 }
736 780
781 concat->mtd.ecclayout = subdev[0]->ecclayout;
782
737 concat->num_subdev = num_devs; 783 concat->num_subdev = num_devs;
738 concat->mtd.name = name; 784 concat->mtd.name = name;
739 785
740 /*
741 * NOTE: for now, we do not provide any readv()/writev() methods
742 * because they are messy to implement and they are not
743 * used to a great extent anyway.
744 */
745 concat->mtd.erase = concat_erase; 786 concat->mtd.erase = concat_erase;
746 concat->mtd.read = concat_read; 787 concat->mtd.read = concat_read;
747 concat->mtd.write = concat_write; 788 concat->mtd.write = concat_write;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9905870f56e5..16a952dd486a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -47,6 +47,7 @@ int add_mtd_device(struct mtd_info *mtd)
47{ 47{
48 int i; 48 int i;
49 49
50 BUG_ON(mtd->writesize == 0);
50 mutex_lock(&mtd_table_mutex); 51 mutex_lock(&mtd_table_mutex);
51 52
52 for (i=0; i < MAX_MTD_DEVICES; i++) 53 for (i=0; i < MAX_MTD_DEVICES; i++)
@@ -254,37 +255,6 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
254 return ret; 255 return ret;
255} 256}
256 257
257
258/* default_mtd_readv - default mtd readv method for MTD devices that dont
259 * implement their own
260 */
261
262int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
263 unsigned long count, loff_t from, size_t *retlen)
264{
265 unsigned long i;
266 size_t totlen = 0, thislen;
267 int ret = 0;
268
269 if(!mtd->read) {
270 ret = -EIO;
271 } else {
272 for (i=0; i<count; i++) {
273 if (!vecs[i].iov_len)
274 continue;
275 ret = mtd->read(mtd, from, vecs[i].iov_len, &thislen, vecs[i].iov_base);
276 totlen += thislen;
277 if (ret || thislen != vecs[i].iov_len)
278 break;
279 from += vecs[i].iov_len;
280 }
281 }
282 if (retlen)
283 *retlen = totlen;
284 return ret;
285}
286
287
288EXPORT_SYMBOL(add_mtd_device); 258EXPORT_SYMBOL(add_mtd_device);
289EXPORT_SYMBOL(del_mtd_device); 259EXPORT_SYMBOL(del_mtd_device);
290EXPORT_SYMBOL(get_mtd_device); 260EXPORT_SYMBOL(get_mtd_device);
@@ -292,7 +262,6 @@ EXPORT_SYMBOL(put_mtd_device);
292EXPORT_SYMBOL(register_mtd_user); 262EXPORT_SYMBOL(register_mtd_user);
293EXPORT_SYMBOL(unregister_mtd_user); 263EXPORT_SYMBOL(unregister_mtd_user);
294EXPORT_SYMBOL(default_mtd_writev); 264EXPORT_SYMBOL(default_mtd_writev);
295EXPORT_SYMBOL(default_mtd_readv);
296 265
297#ifdef CONFIG_PROC_FS 266#ifdef CONFIG_PROC_FS
298 267
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 99395911d26f..77a7123a5c56 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -51,16 +51,21 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
51 size_t *retlen, u_char *buf) 51 size_t *retlen, u_char *buf)
52{ 52{
53 struct mtd_part *part = PART(mtd); 53 struct mtd_part *part = PART(mtd);
54 int res;
55
54 if (from >= mtd->size) 56 if (from >= mtd->size)
55 len = 0; 57 len = 0;
56 else if (from + len > mtd->size) 58 else if (from + len > mtd->size)
57 len = mtd->size - from; 59 len = mtd->size - from;
58 if (part->master->read_ecc == NULL) 60 res = part->master->read (part->master, from + part->offset,
59 return part->master->read (part->master, from + part->offset, 61 len, retlen, buf);
60 len, retlen, buf); 62 if (unlikely(res)) {
61 else 63 if (res == -EUCLEAN)
62 return part->master->read_ecc (part->master, from + part->offset, 64 mtd->ecc_stats.corrected++;
63 len, retlen, buf, NULL, &mtd->oobinfo); 65 if (res == -EBADMSG)
66 mtd->ecc_stats.failed++;
67 }
68 return res;
64} 69}
65 70
66static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 71static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
@@ -74,6 +79,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
74 return part->master->point (part->master, from + part->offset, 79 return part->master->point (part->master, from + part->offset,
75 len, retlen, buf); 80 len, retlen, buf);
76} 81}
82
77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 83static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
78{ 84{
79 struct mtd_part *part = PART(mtd); 85 struct mtd_part *part = PART(mtd);
@@ -81,31 +87,25 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
81 part->master->unpoint (part->master, addr, from + part->offset, len); 87 part->master->unpoint (part->master, addr, from + part->offset, len);
82} 88}
83 89
84 90static int part_read_oob(struct mtd_info *mtd, loff_t from,
85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 91 struct mtd_oob_ops *ops)
86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
87{ 92{
88 struct mtd_part *part = PART(mtd); 93 struct mtd_part *part = PART(mtd);
89 if (oobsel == NULL) 94 int res;
90 oobsel = &mtd->oobinfo;
91 if (from >= mtd->size)
92 len = 0;
93 else if (from + len > mtd->size)
94 len = mtd->size - from;
95 return part->master->read_ecc (part->master, from + part->offset,
96 len, retlen, buf, eccbuf, oobsel);
97}
98 95
99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
100 size_t *retlen, u_char *buf)
101{
102 struct mtd_part *part = PART(mtd);
103 if (from >= mtd->size) 96 if (from >= mtd->size)
104 len = 0; 97 return -EINVAL;
105 else if (from + len > mtd->size) 98 if (from + ops->len > mtd->size)
106 len = mtd->size - from; 99 return -EINVAL;
107 return part->master->read_oob (part->master, from + part->offset, 100 res = part->master->read_oob(part->master, from + part->offset, ops);
108 len, retlen, buf); 101
102 if (unlikely(res)) {
103 if (res == -EUCLEAN)
104 mtd->ecc_stats.corrected++;
105 if (res == -EBADMSG)
106 mtd->ecc_stats.failed++;
107 }
108 return res;
109} 109}
110 110
111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
@@ -148,44 +148,23 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
148 len = 0; 148 len = 0;
149 else if (to + len > mtd->size) 149 else if (to + len > mtd->size)
150 len = mtd->size - to; 150 len = mtd->size - to;
151 if (part->master->write_ecc == NULL) 151 return part->master->write (part->master, to + part->offset,
152 return part->master->write (part->master, to + part->offset, 152 len, retlen, buf);
153 len, retlen, buf);
154 else
155 return part->master->write_ecc (part->master, to + part->offset,
156 len, retlen, buf, NULL, &mtd->oobinfo);
157
158} 153}
159 154
160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, 155static int part_write_oob(struct mtd_info *mtd, loff_t to,
161 size_t *retlen, const u_char *buf, 156 struct mtd_oob_ops *ops)
162 u_char *eccbuf, struct nand_oobinfo *oobsel)
163{ 157{
164 struct mtd_part *part = PART(mtd); 158 struct mtd_part *part = PART(mtd);
165 if (!(mtd->flags & MTD_WRITEABLE))
166 return -EROFS;
167 if (oobsel == NULL)
168 oobsel = &mtd->oobinfo;
169 if (to >= mtd->size)
170 len = 0;
171 else if (to + len > mtd->size)
172 len = mtd->size - to;
173 return part->master->write_ecc (part->master, to + part->offset,
174 len, retlen, buf, eccbuf, oobsel);
175}
176 159
177static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
178 size_t *retlen, const u_char *buf)
179{
180 struct mtd_part *part = PART(mtd);
181 if (!(mtd->flags & MTD_WRITEABLE)) 160 if (!(mtd->flags & MTD_WRITEABLE))
182 return -EROFS; 161 return -EROFS;
162
183 if (to >= mtd->size) 163 if (to >= mtd->size)
184 len = 0; 164 return -EINVAL;
185 else if (to + len > mtd->size) 165 if (to + ops->len > mtd->size)
186 len = mtd->size - to; 166 return -EINVAL;
187 return part->master->write_oob (part->master, to + part->offset, 167 return part->master->write_oob(part->master, to + part->offset, ops);
188 len, retlen, buf);
189} 168}
190 169
191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 170static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
@@ -208,52 +187,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 187 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 188 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 189 return -EROFS;
211 if (part->master->writev_ecc == NULL) 190 return part->master->writev (part->master, vecs, count,
212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 191 to + part->offset, retlen);
214 else
215 return part->master->writev_ecc (part->master, vecs, count,
216 to + part->offset, retlen,
217 NULL, &mtd->oobinfo);
218}
219
220static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
221 unsigned long count, loff_t from, size_t *retlen)
222{
223 struct mtd_part *part = PART(mtd);
224 if (part->master->readv_ecc == NULL)
225 return part->master->readv (part->master, vecs, count,
226 from + part->offset, retlen);
227 else
228 return part->master->readv_ecc (part->master, vecs, count,
229 from + part->offset, retlen,
230 NULL, &mtd->oobinfo);
231}
232
233static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
234 unsigned long count, loff_t to, size_t *retlen,
235 u_char *eccbuf, struct nand_oobinfo *oobsel)
236{
237 struct mtd_part *part = PART(mtd);
238 if (!(mtd->flags & MTD_WRITEABLE))
239 return -EROFS;
240 if (oobsel == NULL)
241 oobsel = &mtd->oobinfo;
242 return part->master->writev_ecc (part->master, vecs, count,
243 to + part->offset, retlen,
244 eccbuf, oobsel);
245}
246
247static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
248 unsigned long count, loff_t from, size_t *retlen,
249 u_char *eccbuf, struct nand_oobinfo *oobsel)
250{
251 struct mtd_part *part = PART(mtd);
252 if (oobsel == NULL)
253 oobsel = &mtd->oobinfo;
254 return part->master->readv_ecc (part->master, vecs, count,
255 from + part->offset, retlen,
256 eccbuf, oobsel);
257} 192}
258 193
259static int part_erase (struct mtd_info *mtd, struct erase_info *instr) 194static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
@@ -329,12 +264,17 @@ static int part_block_isbad (struct mtd_info *mtd, loff_t ofs)
329static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) 264static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
330{ 265{
331 struct mtd_part *part = PART(mtd); 266 struct mtd_part *part = PART(mtd);
267 int res;
268
332 if (!(mtd->flags & MTD_WRITEABLE)) 269 if (!(mtd->flags & MTD_WRITEABLE))
333 return -EROFS; 270 return -EROFS;
334 if (ofs >= mtd->size) 271 if (ofs >= mtd->size)
335 return -EINVAL; 272 return -EINVAL;
336 ofs += part->offset; 273 ofs += part->offset;
337 return part->master->block_markbad(part->master, ofs); 274 res = part->master->block_markbad(part->master, ofs);
275 if (!res)
276 mtd->ecc_stats.badblocks++;
277 return res;
338} 278}
339 279
340/* 280/*
@@ -398,7 +338,7 @@ int add_mtd_partitions(struct mtd_info *master,
398 slave->mtd.type = master->type; 338 slave->mtd.type = master->type;
399 slave->mtd.flags = master->flags & ~parts[i].mask_flags; 339 slave->mtd.flags = master->flags & ~parts[i].mask_flags;
400 slave->mtd.size = parts[i].size; 340 slave->mtd.size = parts[i].size;
401 slave->mtd.oobblock = master->oobblock; 341 slave->mtd.writesize = master->writesize;
402 slave->mtd.oobsize = master->oobsize; 342 slave->mtd.oobsize = master->oobsize;
403 slave->mtd.ecctype = master->ecctype; 343 slave->mtd.ecctype = master->ecctype;
404 slave->mtd.eccsize = master->eccsize; 344 slave->mtd.eccsize = master->eccsize;
@@ -415,10 +355,6 @@ int add_mtd_partitions(struct mtd_info *master,
415 slave->mtd.unpoint = part_unpoint; 355 slave->mtd.unpoint = part_unpoint;
416 } 356 }
417 357
418 if (master->read_ecc)
419 slave->mtd.read_ecc = part_read_ecc;
420 if (master->write_ecc)
421 slave->mtd.write_ecc = part_write_ecc;
422 if (master->read_oob) 358 if (master->read_oob)
423 slave->mtd.read_oob = part_read_oob; 359 slave->mtd.read_oob = part_read_oob;
424 if (master->write_oob) 360 if (master->write_oob)
@@ -443,12 +379,6 @@ int add_mtd_partitions(struct mtd_info *master,
443 } 379 }
444 if (master->writev) 380 if (master->writev)
445 slave->mtd.writev = part_writev; 381 slave->mtd.writev = part_writev;
446 if (master->readv)
447 slave->mtd.readv = part_readv;
448 if (master->writev_ecc)
449 slave->mtd.writev_ecc = part_writev_ecc;
450 if (master->readv_ecc)
451 slave->mtd.readv_ecc = part_readv_ecc;
452 if (master->lock) 382 if (master->lock)
453 slave->mtd.lock = part_lock; 383 slave->mtd.lock = part_lock;
454 if (master->unlock) 384 if (master->unlock)
@@ -528,8 +458,17 @@ int add_mtd_partitions(struct mtd_info *master,
528 parts[i].name); 458 parts[i].name);
529 } 459 }
530 460
531 /* copy oobinfo from master */ 461 slave->mtd.ecclayout = master->ecclayout;
532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); 462 if (master->block_isbad) {
463 uint32_t offs = 0;
464
465 while(offs < slave->mtd.size) {
466 if (master->block_isbad(master,
467 offs + slave->offset))
468 slave->mtd.ecc_stats.badblocks++;
469 offs += slave->mtd.erasesize;
470 }
471 }
533 472
534 if(parts[i].mtdp) 473 if(parts[i].mtdp)
535 { /* store the object pointer (caller may or may not register it */ 474 { /* store the object pointer (caller may or may not register it */
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index cfe288a6e853..3db77eec0ed2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -23,6 +23,14 @@ config MTD_NAND_VERIFY_WRITE
23 device thinks the write was successful, a bit could have been 23 device thinks the write was successful, a bit could have been
24 flipped accidentaly due to device wear or something else. 24 flipped accidentaly due to device wear or something else.
25 25
26config MTD_NAND_ECC_SMC
27 bool "NAND ECC Smart Media byte order"
28 depends on MTD_NAND
29 default n
30 help
31 Software ECC according to the Smart Media Specification.
32 The original Linux implementation had byte 0 and 1 swapped.
33
26config MTD_NAND_AUTCPU12 34config MTD_NAND_AUTCPU12
27 tristate "SmartMediaCard on autronix autcpu12 board" 35 tristate "SmartMediaCard on autronix autcpu12 board"
28 depends on MTD_NAND && ARCH_AUTCPU12 36 depends on MTD_NAND && ARCH_AUTCPU12
@@ -49,12 +57,24 @@ config MTD_NAND_SPIA
49 help 57 help
50 If you had to ask, you don't have one. Say 'N'. 58 If you had to ask, you don't have one. Say 'N'.
51 59
60config MTD_NAND_AMS_DELTA
61 tristate "NAND Flash device on Amstrad E3"
62 depends on MACH_AMS_DELTA && MTD_NAND
63 help
64 Support for NAND flash on Amstrad E3 (Delta).
65
52config MTD_NAND_TOTO 66config MTD_NAND_TOTO
53 tristate "NAND Flash device on TOTO board" 67 tristate "NAND Flash device on TOTO board"
54 depends on ARCH_OMAP && MTD_NAND 68 depends on ARCH_OMAP && MTD_NAND && BROKEN
55 help 69 help
56 Support for NAND flash on Texas Instruments Toto platform. 70 Support for NAND flash on Texas Instruments Toto platform.
57 71
72config MTD_NAND_TS7250
73 tristate "NAND Flash device on TS-7250 board"
74 depends on MACH_TS72XX && MTD_NAND
75 help
76 Support for NAND flash on Technologic Systems TS-7250 platform.
77
58config MTD_NAND_IDS 78config MTD_NAND_IDS
59 tristate 79 tristate
60 80
@@ -76,7 +96,7 @@ config MTD_NAND_RTC_FROM4
76 96
77config MTD_NAND_PPCHAMELEONEVB 97config MTD_NAND_PPCHAMELEONEVB
78 tristate "NAND Flash device on PPChameleonEVB board" 98 tristate "NAND Flash device on PPChameleonEVB board"
79 depends on PPCHAMELEONEVB && MTD_NAND 99 depends on PPCHAMELEONEVB && MTD_NAND && BROKEN
80 help 100 help
81 This enables the NAND flash driver on the PPChameleon EVB Board. 101 This enables the NAND flash driver on the PPChameleon EVB Board.
82 102
@@ -87,7 +107,7 @@ config MTD_NAND_S3C2410
87 This enables the NAND flash controller on the S3C2410 and S3C2440 107 This enables the NAND flash controller on the S3C2410 and S3C2440
88 SoCs 108 SoCs
89 109
90 No board specfic support is done by this driver, each board 110 No board specific support is done by this driver, each board
91 must advertise a platform_device for the driver to attach. 111 must advertise a platform_device for the driver to attach.
92 112
93config MTD_NAND_S3C2410_DEBUG 113config MTD_NAND_S3C2410_DEBUG
@@ -109,6 +129,22 @@ config MTD_NAND_S3C2410_HWECC
109 currently not be able to switch to software, as there is no 129 currently not be able to switch to software, as there is no
110 implementation for ECC method used by the S3C2410 130 implementation for ECC method used by the S3C2410
111 131
132config MTD_NAND_NDFC
133 tristate "NDFC NanD Flash Controller"
134 depends on MTD_NAND && 44x
135 help
136 NDFC Nand Flash Controllers are integrated in EP44x SoCs
137
138config MTD_NAND_S3C2410_CLKSTOP
139 bool "S3C2410 NAND IDLE clock stop"
140 depends on MTD_NAND_S3C2410
141 default n
142 help
143 Stop the clock to the NAND controller when there is no chip
144 selected to save power. This will mean there is a small delay
145 when the is NAND chip selected or released, but will save
146 approximately 5mA of power when there is nothing happening.
147
112config MTD_NAND_DISKONCHIP 148config MTD_NAND_DISKONCHIP
113 tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)" 149 tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
114 depends on MTD_NAND && EXPERIMENTAL 150 depends on MTD_NAND && EXPERIMENTAL
@@ -183,11 +219,24 @@ config MTD_NAND_SHARPSL
183 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" 219 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA 220 depends on MTD_NAND && ARCH_PXA
185 221
222config MTD_NAND_CS553X
223 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
224 depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)
225 help
226 The CS553x companion chips for the AMD Geode processor
227 include NAND flash controllers with built-in hardware ECC
228 capabilities; enabling this option will allow you to use
229 these. The driver will check the MSRs to verify that the
230 controller is enabled for NAND, and currently requires that
231 the controller be in MMIO mode.
232
233 If you say "m", the module will be called "cs553x_nand.ko".
234
186config MTD_NAND_NANDSIM 235config MTD_NAND_NANDSIM
187 tristate "Support for NAND Flash Simulator" 236 tristate "Support for NAND Flash Simulator"
188 depends on MTD_NAND && MTD_PARTITIONS 237 depends on MTD_NAND && MTD_PARTITIONS
189 help 238 help
190 The simulator may simulate verious NAND flash chips for the 239 The simulator may simulate various NAND flash chips for the
191 MTD nand layer. 240 MTD nand layer.
192 241
193endmenu 242endmenu
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 41742026a52e..f74759351c91 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
7obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o 7obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
8 8
9obj-$(CONFIG_MTD_NAND_SPIA) += spia.o 9obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
10obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
10obj-$(CONFIG_MTD_NAND_TOTO) += toto.o 11obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o 12obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o 13obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
@@ -17,6 +18,9 @@ obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
17obj-$(CONFIG_MTD_NAND_H1900) += h1910.o 18obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
18obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o 19obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
19obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o 20obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
21obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o
20obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o 22obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
23obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
24obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
21 25
22nand-objs = nand_base.o nand_bbt.o 26nand-objs = nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
new file mode 100644
index 000000000000..d7897dc6b3c8
--- /dev/null
+++ b/drivers/mtd/nand/ams-delta.c
@@ -0,0 +1,237 @@
1/*
2 * drivers/mtd/nand/ams-delta.c
3 *
4 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
5 *
6 * Derived from drivers/mtd/toto.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Overview:
13 * This is a device driver for the NAND flash device found on the
14 * Amstrad E3 (Delta).
15 */
16
17#include <linux/slab.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/nand.h>
23#include <linux/mtd/partitions.h>
24#include <asm/io.h>
25#include <asm/arch/hardware.h>
26#include <asm/sizes.h>
27#include <asm/arch/gpio.h>
28#include <asm/arch/board-ams-delta.h>
29
30/*
31 * MTD structure for E3 (Delta)
32 */
33static struct mtd_info *ams_delta_mtd = NULL;
34
35#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
36
37/*
38 * Define partitions for flash devices
39 */
40
41static struct mtd_partition partition_info[] = {
42 { .name = "Kernel",
43 .offset = 0,
44 .size = 3 * SZ_1M + SZ_512K },
45 { .name = "u-boot",
46 .offset = 3 * SZ_1M + SZ_512K,
47 .size = SZ_256K },
48 { .name = "u-boot params",
49 .offset = 3 * SZ_1M + SZ_512K + SZ_256K,
50 .size = SZ_256K },
51 { .name = "Amstrad LDR",
52 .offset = 4 * SZ_1M,
53 .size = SZ_256K },
54 { .name = "File system",
55 .offset = 4 * SZ_1M + 1 * SZ_256K,
56 .size = 27 * SZ_1M },
57 { .name = "PBL reserved",
58 .offset = 32 * SZ_1M - 3 * SZ_256K,
59 .size = 3 * SZ_256K },
60};
61
62static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
63{
64 struct nand_chip *this = mtd->priv;
65
66 omap_writew(0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
67 omap_writew(byte, this->IO_ADDR_W);
68 ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0);
69 ndelay(40);
70 ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE,
71 AMS_DELTA_LATCH2_NAND_NWE);
72}
73
74static u_char ams_delta_read_byte(struct mtd_info *mtd)
75{
76 u_char res;
77 struct nand_chip *this = mtd->priv;
78
79 ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0);
80 ndelay(40);
81 omap_writew(~0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
82 res = omap_readw(this->IO_ADDR_R);
83 ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE,
84 AMS_DELTA_LATCH2_NAND_NRE);
85
86 return res;
87}
88
89static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf,
90 int len)
91{
92 int i;
93
94 for (i=0; i<len; i++)
95 ams_delta_write_byte(mtd, buf[i]);
96}
97
98static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
99{
100 int i;
101
102 for (i=0; i<len; i++)
103 buf[i] = ams_delta_read_byte(mtd);
104}
105
106static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
107 int len)
108{
109 int i;
110
111 for (i=0; i<len; i++)
112 if (buf[i] != ams_delta_read_byte(mtd))
113 return -EFAULT;
114
115 return 0;
116}
117
118/*
119 * Command control function
120 *
121 * ctrl:
122 * NAND_NCE: bit 0 -> bit 2
123 * NAND_CLE: bit 1 -> bit 7
124 * NAND_ALE: bit 2 -> bit 6
125 */
126static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
127 unsigned int ctrl)
128{
129
130 if (ctrl & NAND_CTRL_CHANGE) {
131 unsigned long bits;
132
133 bits = (~ctrl & NAND_NCE) << 2;
134 bits |= (ctrl & NAND_CLE) << 7;
135 bits |= (ctrl & NAND_ALE) << 6;
136
137 ams_delta_latch2_write(0xC2, bits);
138 }
139
140 if (cmd != NAND_CMD_NONE)
141 ams_delta_write_byte(mtd, cmd);
142}
143
144static int ams_delta_nand_ready(struct mtd_info *mtd)
145{
146 return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
147}
148
149/*
150 * Main initialization routine
151 */
152static int __init ams_delta_init(void)
153{
154 struct nand_chip *this;
155 int err = 0;
156
157 /* Allocate memory for MTD device structure and private data */
158 ams_delta_mtd = kmalloc(sizeof(struct mtd_info) +
159 sizeof(struct nand_chip), GFP_KERNEL);
160 if (!ams_delta_mtd) {
161 printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n");
162 err = -ENOMEM;
163 goto out;
164 }
165
166 ams_delta_mtd->owner = THIS_MODULE;
167
168 /* Get pointer to private data */
169 this = (struct nand_chip *) (&ams_delta_mtd[1]);
170
171 /* Initialize structures */
172 memset(ams_delta_mtd, 0, sizeof(struct mtd_info));
173 memset(this, 0, sizeof(struct nand_chip));
174
175 /* Link the private data with the MTD structure */
176 ams_delta_mtd->priv = this;
177
178 /* Set address of NAND IO lines */
179 this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
180 this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
181 this->read_byte = ams_delta_read_byte;
182 this->write_buf = ams_delta_write_buf;
183 this->read_buf = ams_delta_read_buf;
184 this->verify_buf = ams_delta_verify_buf;
185 this->cmd_ctrl = ams_delta_hwcontrol;
186 if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
187 this->dev_ready = ams_delta_nand_ready;
188 } else {
189 this->dev_ready = NULL;
190 printk(KERN_NOTICE "Couldn't request gpio for Delta NAND ready.\n");
191 }
192 /* 25 us command delay time */
193 this->chip_delay = 30;
194 this->ecc.mode = NAND_ECC_SOFT;
195
196 /* Set chip enabled, but */
197 ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE |
198 AMS_DELTA_LATCH2_NAND_NWE |
199 AMS_DELTA_LATCH2_NAND_NCE |
200 AMS_DELTA_LATCH2_NAND_NWP);
201
202 /* Scan to find existance of the device */
203 if (nand_scan(ams_delta_mtd, 1)) {
204 err = -ENXIO;
205 goto out_mtd;
206 }
207
208 /* Register the partitions */
209 add_mtd_partitions(ams_delta_mtd, partition_info,
210 ARRAY_SIZE(partition_info));
211
212 goto out;
213
214 out_mtd:
215 kfree(ams_delta_mtd);
216 out:
217 return err;
218}
219
220module_init(ams_delta_init);
221
222/*
223 * Clean up routine
224 */
225static void __exit ams_delta_cleanup(void)
226{
227 /* Release resources, unregister device */
228 nand_release(ams_delta_mtd);
229
230 /* Free the MTD device structure */
231 kfree(ams_delta_mtd);
232}
233module_exit(ams_delta_cleanup);
234
235MODULE_LICENSE("GPL");
236MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
237MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index bde3550910a2..31228334da12 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/interrupt.h>
17#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 19#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
@@ -38,22 +39,21 @@
38 */ 39 */
39static struct mtd_info *au1550_mtd = NULL; 40static struct mtd_info *au1550_mtd = NULL;
40static void __iomem *p_nand; 41static void __iomem *p_nand;
41static int nand_width = 1; /* default x8*/ 42static int nand_width = 1; /* default x8 */
43static void (*au1550_write_byte)(struct mtd_info *, u_char);
42 44
43/* 45/*
44 * Define partitions for flash device 46 * Define partitions for flash device
45 */ 47 */
46static const struct mtd_partition partition_info[] = { 48static const struct mtd_partition partition_info[] = {
47 { 49 {
48 .name = "NAND FS 0", 50 .name = "NAND FS 0",
49 .offset = 0, 51 .offset = 0,
50 .size = 8*1024*1024 52 .size = 8 * 1024 * 1024},
51 },
52 { 53 {
53 .name = "NAND FS 1", 54 .name = "NAND FS 1",
54 .offset = MTDPART_OFS_APPEND, 55 .offset = MTDPART_OFS_APPEND,
55 .size = MTDPART_SIZ_FULL 56 .size = MTDPART_SIZ_FULL}
56 }
57}; 57};
58 58
59/** 59/**
@@ -130,21 +130,6 @@ static u16 au_read_word(struct mtd_info *mtd)
130} 130}
131 131
132/** 132/**
133 * au_write_word - write one word to the chip
134 * @mtd: MTD device structure
135 * @word: data word to write
136 *
137 * write function for 16bit buswith without
138 * endianess conversion
139 */
140static void au_write_word(struct mtd_info *mtd, u16 word)
141{
142 struct nand_chip *this = mtd->priv;
143 writew(word, this->IO_ADDR_W);
144 au_sync();
145}
146
147/**
148 * au_write_buf - write buffer to chip 133 * au_write_buf - write buffer to chip
149 * @mtd: MTD device structure 134 * @mtd: MTD device structure
150 * @buf: data buffer 135 * @buf: data buffer
@@ -157,7 +142,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
157 int i; 142 int i;
158 struct nand_chip *this = mtd->priv; 143 struct nand_chip *this = mtd->priv;
159 144
160 for (i=0; i<len; i++) { 145 for (i = 0; i < len; i++) {
161 writeb(buf[i], this->IO_ADDR_W); 146 writeb(buf[i], this->IO_ADDR_W);
162 au_sync(); 147 au_sync();
163 } 148 }
@@ -176,7 +161,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
176 int i; 161 int i;
177 struct nand_chip *this = mtd->priv; 162 struct nand_chip *this = mtd->priv;
178 163
179 for (i=0; i<len; i++) { 164 for (i = 0; i < len; i++) {
180 buf[i] = readb(this->IO_ADDR_R); 165 buf[i] = readb(this->IO_ADDR_R);
181 au_sync(); 166 au_sync();
182 } 167 }
@@ -195,7 +180,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
195 int i; 180 int i;
196 struct nand_chip *this = mtd->priv; 181 struct nand_chip *this = mtd->priv;
197 182
198 for (i=0; i<len; i++) { 183 for (i = 0; i < len; i++) {
199 if (buf[i] != readb(this->IO_ADDR_R)) 184 if (buf[i] != readb(this->IO_ADDR_R))
200 return -EFAULT; 185 return -EFAULT;
201 au_sync(); 186 au_sync();
@@ -219,7 +204,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
219 u16 *p = (u16 *) buf; 204 u16 *p = (u16 *) buf;
220 len >>= 1; 205 len >>= 1;
221 206
222 for (i=0; i<len; i++) { 207 for (i = 0; i < len; i++) {
223 writew(p[i], this->IO_ADDR_W); 208 writew(p[i], this->IO_ADDR_W);
224 au_sync(); 209 au_sync();
225 } 210 }
@@ -241,7 +226,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
241 u16 *p = (u16 *) buf; 226 u16 *p = (u16 *) buf;
242 len >>= 1; 227 len >>= 1;
243 228
244 for (i=0; i<len; i++) { 229 for (i = 0; i < len; i++) {
245 p[i] = readw(this->IO_ADDR_R); 230 p[i] = readw(this->IO_ADDR_R);
246 au_sync(); 231 au_sync();
247 } 232 }
@@ -262,7 +247,7 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
262 u16 *p = (u16 *) buf; 247 u16 *p = (u16 *) buf;
263 len >>= 1; 248 len >>= 1;
264 249
265 for (i=0; i<len; i++) { 250 for (i = 0; i < len; i++) {
266 if (p[i] != readw(this->IO_ADDR_R)) 251 if (p[i] != readw(this->IO_ADDR_R))
267 return -EFAULT; 252 return -EFAULT;
268 au_sync(); 253 au_sync();
@@ -270,32 +255,52 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
270 return 0; 255 return 0;
271} 256}
272 257
258/* Select the chip by setting nCE to low */
259#define NAND_CTL_SETNCE 1
260/* Deselect the chip by setting nCE to high */
261#define NAND_CTL_CLRNCE 2
262/* Select the command latch by setting CLE to high */
263#define NAND_CTL_SETCLE 3
264/* Deselect the command latch by setting CLE to low */
265#define NAND_CTL_CLRCLE 4
266/* Select the address latch by setting ALE to high */
267#define NAND_CTL_SETALE 5
268/* Deselect the address latch by setting ALE to low */
269#define NAND_CTL_CLRALE 6
273 270
274static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) 271static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
275{ 272{
276 register struct nand_chip *this = mtd->priv; 273 register struct nand_chip *this = mtd->priv;
277 274
278 switch(cmd){ 275 switch (cmd) {
279 276
280 case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break; 277 case NAND_CTL_SETCLE:
281 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; 278 this->IO_ADDR_W = p_nand + MEM_STNAND_CMD;
279 break;
280
281 case NAND_CTL_CLRCLE:
282 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
283 break;
284
285 case NAND_CTL_SETALE:
286 this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR;
287 break;
282 288
283 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
284 case NAND_CTL_CLRALE: 289 case NAND_CTL_CLRALE:
285 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; 290 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
286 /* FIXME: Nobody knows why this is neccecary, 291 /* FIXME: Nobody knows why this is necessary,
287 * but it works only that way */ 292 * but it works only that way */
288 udelay(1); 293 udelay(1);
289 break; 294 break;
290 295
291 case NAND_CTL_SETNCE: 296 case NAND_CTL_SETNCE:
292 /* assert (force assert) chip enable */ 297 /* assert (force assert) chip enable */
293 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; 298 au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL);
294 break; 299 break;
295 300
296 case NAND_CTL_CLRNCE: 301 case NAND_CTL_CLRNCE:
297 /* deassert chip enable */ 302 /* deassert chip enable */
298 au_writel(0, MEM_STNDCTL); break; 303 au_writel(0, MEM_STNDCTL);
299 break; 304 break;
300 } 305 }
301 306
@@ -312,69 +317,200 @@ int au1550_device_ready(struct mtd_info *mtd)
312 return ret; 317 return ret;
313} 318}
314 319
320/**
321 * au1550_select_chip - control -CE line
322 * Forbid driving -CE manually permitting the NAND controller to do this.
323 * Keeping -CE asserted during the whole sector reads interferes with the
324 * NOR flash and PCMCIA drivers as it causes contention on the static bus.
325 * We only have to hold -CE low for the NAND read commands since the flash
326 * chip needs it to be asserted during chip not ready time but the NAND
327 * controller keeps it released.
328 *
329 * @mtd: MTD device structure
330 * @chip: chipnumber to select, -1 for deselect
331 */
332static void au1550_select_chip(struct mtd_info *mtd, int chip)
333{
334}
335
336/**
337 * au1550_command - Send command to NAND device
338 * @mtd: MTD device structure
339 * @command: the command to be sent
340 * @column: the column address for this command, -1 if none
341 * @page_addr: the page address for this command, -1 if none
342 */
343static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
344{
345 register struct nand_chip *this = mtd->priv;
346 int ce_override = 0, i;
347 ulong flags;
348
349 /* Begin command latch cycle */
350 au1550_hwcontrol(mtd, NAND_CTL_SETCLE);
351 /*
352 * Write out the command to the device.
353 */
354 if (command == NAND_CMD_SEQIN) {
355 int readcmd;
356
357 if (column >= mtd->writesize) {
358 /* OOB area */
359 column -= mtd->writesize;
360 readcmd = NAND_CMD_READOOB;
361 } else if (column < 256) {
362 /* First 256 bytes --> READ0 */
363 readcmd = NAND_CMD_READ0;
364 } else {
365 column -= 256;
366 readcmd = NAND_CMD_READ1;
367 }
368 au1550_write_byte(mtd, readcmd);
369 }
370 au1550_write_byte(mtd, command);
371
372 /* Set ALE and clear CLE to start address cycle */
373 au1550_hwcontrol(mtd, NAND_CTL_CLRCLE);
374
375 if (column != -1 || page_addr != -1) {
376 au1550_hwcontrol(mtd, NAND_CTL_SETALE);
377
378 /* Serially input address */
379 if (column != -1) {
380 /* Adjust columns for 16 bit buswidth */
381 if (this->options & NAND_BUSWIDTH_16)
382 column >>= 1;
383 au1550_write_byte(mtd, column);
384 }
385 if (page_addr != -1) {
386 au1550_write_byte(mtd, (u8)(page_addr & 0xff));
387
388 if (command == NAND_CMD_READ0 ||
389 command == NAND_CMD_READ1 ||
390 command == NAND_CMD_READOOB) {
391 /*
392 * NAND controller will release -CE after
393 * the last address byte is written, so we'll
394 * have to forcibly assert it. No interrupts
395 * are allowed while we do this as we don't
396 * want the NOR flash or PCMCIA drivers to
397 * steal our precious bytes of data...
398 */
399 ce_override = 1;
400 local_irq_save(flags);
401 au1550_hwcontrol(mtd, NAND_CTL_SETNCE);
402 }
403
404 au1550_write_byte(mtd, (u8)(page_addr >> 8));
405
406 /* One more address cycle for devices > 32MiB */
407 if (this->chipsize > (32 << 20))
408 au1550_write_byte(mtd, (u8)((page_addr >> 16) & 0x0f));
409 }
410 /* Latch in address */
411 au1550_hwcontrol(mtd, NAND_CTL_CLRALE);
412 }
413
414 /*
415 * Program and erase have their own busy handlers.
416 * Status and sequential in need no delay.
417 */
418 switch (command) {
419
420 case NAND_CMD_PAGEPROG:
421 case NAND_CMD_ERASE1:
422 case NAND_CMD_ERASE2:
423 case NAND_CMD_SEQIN:
424 case NAND_CMD_STATUS:
425 return;
426
427 case NAND_CMD_RESET:
428 break;
429
430 case NAND_CMD_READ0:
431 case NAND_CMD_READ1:
432 case NAND_CMD_READOOB:
433 /* Check if we're really driving -CE low (just in case) */
434 if (unlikely(!ce_override))
435 break;
436
437 /* Apply a short delay always to ensure that we do wait tWB. */
438 ndelay(100);
439 /* Wait for a chip to become ready... */
440 for (i = this->chip_delay; !this->dev_ready(mtd) && i > 0; --i)
441 udelay(1);
442
443 /* Release -CE and re-enable interrupts. */
444 au1550_hwcontrol(mtd, NAND_CTL_CLRNCE);
445 local_irq_restore(flags);
446 return;
447 }
448 /* Apply this short delay always to ensure that we do wait tWB. */
449 ndelay(100);
450
451 while(!this->dev_ready(mtd));
452}
453
454
315/* 455/*
316 * Main initialization routine 456 * Main initialization routine
317 */ 457 */
318int __init au1xxx_nand_init (void) 458static int __init au1xxx_nand_init(void)
319{ 459{
320 struct nand_chip *this; 460 struct nand_chip *this;
321 u16 boot_swapboot = 0; /* default value */ 461 u16 boot_swapboot = 0; /* default value */
322 int retval; 462 int retval;
323 u32 mem_staddr; 463 u32 mem_staddr;
324 u32 nand_phys; 464 u32 nand_phys;
325 465
326 /* Allocate memory for MTD device structure and private data */ 466 /* Allocate memory for MTD device structure and private data */
327 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 467 au1550_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
328 sizeof (struct nand_chip), GFP_KERNEL);
329 if (!au1550_mtd) { 468 if (!au1550_mtd) {
330 printk ("Unable to allocate NAND MTD dev structure.\n"); 469 printk("Unable to allocate NAND MTD dev structure.\n");
331 return -ENOMEM; 470 return -ENOMEM;
332 } 471 }
333 472
334 /* Get pointer to private data */ 473 /* Get pointer to private data */
335 this = (struct nand_chip *) (&au1550_mtd[1]); 474 this = (struct nand_chip *)(&au1550_mtd[1]);
336 475
337 /* Initialize structures */ 476 /* Initialize structures */
338 memset((char *) au1550_mtd, 0, sizeof(struct mtd_info)); 477 memset(au1550_mtd, 0, sizeof(struct mtd_info));
339 memset((char *) this, 0, sizeof(struct nand_chip)); 478 memset(this, 0, sizeof(struct nand_chip));
340 479
341 /* Link the private data with the MTD structure */ 480 /* Link the private data with the MTD structure */
342 au1550_mtd->priv = this; 481 au1550_mtd->priv = this;
482 au1550_mtd->owner = THIS_MODULE;
343 483
344 484
345 /* disable interrupts */ 485 /* MEM_STNDCTL: disable ints, disable nand boot */
346 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); 486 au_writel(0, MEM_STNDCTL);
347
348 /* disable NAND boot */
349 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
350 487
351#ifdef CONFIG_MIPS_PB1550 488#ifdef CONFIG_MIPS_PB1550
352 /* set gpio206 high */ 489 /* set gpio206 high */
353 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); 490 au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
354 491
355 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 492 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
356 ((bcsr->status >> 6) & 0x1);
357 switch (boot_swapboot) { 493 switch (boot_swapboot) {
358 case 0: 494 case 0:
359 case 2: 495 case 2:
360 case 8: 496 case 8:
361 case 0xC: 497 case 0xC:
362 case 0xD: 498 case 0xD:
363 /* x16 NAND Flash */ 499 /* x16 NAND Flash */
364 nand_width = 0; 500 nand_width = 0;
365 break; 501 break;
366 case 1: 502 case 1:
367 case 9: 503 case 9:
368 case 3: 504 case 3:
369 case 0xE: 505 case 0xE:
370 case 0xF: 506 case 0xF:
371 /* x8 NAND Flash */ 507 /* x8 NAND Flash */
372 nand_width = 1; 508 nand_width = 1;
373 break; 509 break;
374 default: 510 default:
375 printk("Pb1550 NAND: bad boot:swap\n"); 511 printk("Pb1550 NAND: bad boot:swap\n");
376 retval = -EINVAL; 512 retval = -EINVAL;
377 goto outmem; 513 goto outmem;
378 } 514 }
379#endif 515#endif
380 516
@@ -424,21 +560,22 @@ int __init au1xxx_nand_init (void)
424 560
425 /* make controller and MTD agree */ 561 /* make controller and MTD agree */
426 if (NAND_CS == 0) 562 if (NAND_CS == 0)
427 nand_width = au_readl(MEM_STCFG0) & (1<<22); 563 nand_width = au_readl(MEM_STCFG0) & (1 << 22);
428 if (NAND_CS == 1) 564 if (NAND_CS == 1)
429 nand_width = au_readl(MEM_STCFG1) & (1<<22); 565 nand_width = au_readl(MEM_STCFG1) & (1 << 22);
430 if (NAND_CS == 2) 566 if (NAND_CS == 2)
431 nand_width = au_readl(MEM_STCFG2) & (1<<22); 567 nand_width = au_readl(MEM_STCFG2) & (1 << 22);
432 if (NAND_CS == 3) 568 if (NAND_CS == 3)
433 nand_width = au_readl(MEM_STCFG3) & (1<<22); 569 nand_width = au_readl(MEM_STCFG3) & (1 << 22);
434
435 570
436 /* Set address of hardware control function */ 571 /* Set address of hardware control function */
437 this->hwcontrol = au1550_hwcontrol;
438 this->dev_ready = au1550_device_ready; 572 this->dev_ready = au1550_device_ready;
573 this->select_chip = au1550_select_chip;
574 this->cmdfunc = au1550_command;
575
439 /* 30 us command delay time */ 576 /* 30 us command delay time */
440 this->chip_delay = 30; 577 this->chip_delay = 30;
441 this->eccmode = NAND_ECC_SOFT; 578 this->ecc.mode = NAND_ECC_SOFT;
442 579
443 this->options = NAND_NO_AUTOINCR; 580 this->options = NAND_NO_AUTOINCR;
444 581
@@ -446,15 +583,14 @@ int __init au1xxx_nand_init (void)
446 this->options |= NAND_BUSWIDTH_16; 583 this->options |= NAND_BUSWIDTH_16;
447 584
448 this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte; 585 this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte;
449 this->write_byte = (!nand_width) ? au_write_byte16 : au_write_byte; 586 au1550_write_byte = (!nand_width) ? au_write_byte16 : au_write_byte;
450 this->write_word = au_write_word;
451 this->read_word = au_read_word; 587 this->read_word = au_read_word;
452 this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf; 588 this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf;
453 this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf; 589 this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf;
454 this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf; 590 this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
455 591
456 /* Scan to find existence of the device */ 592 /* Scan to find existence of the device */
457 if (nand_scan (au1550_mtd, 1)) { 593 if (nand_scan(au1550_mtd, 1)) {
458 retval = -ENXIO; 594 retval = -ENXIO;
459 goto outio; 595 goto outio;
460 } 596 }
@@ -465,10 +601,10 @@ int __init au1xxx_nand_init (void)
465 return 0; 601 return 0;
466 602
467 outio: 603 outio:
468 iounmap ((void *)p_nand); 604 iounmap((void *)p_nand);
469 605
470 outmem: 606 outmem:
471 kfree (au1550_mtd); 607 kfree(au1550_mtd);
472 return retval; 608 return retval;
473} 609}
474 610
@@ -477,22 +613,21 @@ module_init(au1xxx_nand_init);
477/* 613/*
478 * Clean up routine 614 * Clean up routine
479 */ 615 */
480#ifdef MODULE 616static void __exit au1550_cleanup(void)
481static void __exit au1550_cleanup (void)
482{ 617{
483 struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1]; 618 struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1];
484 619
485 /* Release resources, unregister device */ 620 /* Release resources, unregister device */
486 nand_release (au1550_mtd); 621 nand_release(au1550_mtd);
487 622
488 /* Free the MTD device structure */ 623 /* Free the MTD device structure */
489 kfree (au1550_mtd); 624 kfree(au1550_mtd);
490 625
491 /* Unmap */ 626 /* Unmap */
492 iounmap ((void *)p_nand); 627 iounmap((void *)p_nand);
493} 628}
629
494module_exit(au1550_cleanup); 630module_exit(au1550_cleanup);
495#endif
496 631
497MODULE_LICENSE("GPL"); 632MODULE_LICENSE("GPL");
498MODULE_AUTHOR("Embedded Edge, LLC"); 633MODULE_AUTHOR("Embedded Edge, LLC");
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index a3c7fea404d0..fe94ae9ae1f2 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -4,7 +4,7 @@
4 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> 4 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
5 * 5 *
6 * Derived from drivers/mtd/spia.c 6 * Derived from drivers/mtd/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ 9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
@@ -42,12 +42,7 @@
42 * MTD structure for AUTCPU12 board 42 * MTD structure for AUTCPU12 board
43 */ 43 */
44static struct mtd_info *autcpu12_mtd = NULL; 44static struct mtd_info *autcpu12_mtd = NULL;
45 45static void __iomem *autcpu12_fio_base;
46static int autcpu12_io_base = CS89712_VIRT_BASE;
47static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC;
48static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET;
49static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET;
50static void __iomem * autcpu12_fio_base;
51 46
52/* 47/*
53 * Define partitions for flash devices 48 * Define partitions for flash devices
@@ -94,108 +89,131 @@ static struct mtd_partition partition_info128k[] = {
94#define NUM_PARTITIONS128K 2 89#define NUM_PARTITIONS128K 2
95/* 90/*
96 * hardware specific access to control-lines 91 * hardware specific access to control-lines
97*/ 92 *
98static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) 93 * ALE bit 4 autcpu12_pedr
94 * CLE bit 5 autcpu12_pedr
95 * NCE bit 0 fio_ctrl
96 *
97 */
98static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int ctrl)
99{ 100{
101 struct nand_chip *chip = mtd->priv;
100 102
101 switch(cmd){ 103 if (ctrl & NAND_CTRL_CHANGE) {
102 104 void __iomem *addr
103 case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_CLE; break; 105 unsigned char bits;
104 case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break;
105 106
106 case NAND_CTL_SETALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_ALE; break; 107 addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
107 case NAND_CTL_CLRALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_ALE; break; 108 bits = (ctrl & NAND_CLE) << 4;
109 bits |= (ctrl & NAND_ALE) << 2;
110 writeb((readb(addr) & ~0x30) | bits, addr);
108 111
109 case NAND_CTL_SETNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x01; break; 112 addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET;
110 case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x00; break; 113 writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr);
111 } 114 }
115
116 if (cmd != NAND_CMD_NONE)
117 writeb(cmd, chip->IO_ADDR_W);
112} 118}
113 119
114/* 120/*
115* read device ready pin 121 * read device ready pin
116*/ 122 */
117int autcpu12_device_ready(struct mtd_info *mtd) 123int autcpu12_device_ready(struct mtd_info *mtd)
118{ 124{
125 void __iomem *addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
119 126
120 return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; 127 return readb(addr) & AUTCPU12_SMC_RDY;
121
122} 128}
123 129
124/* 130/*
125 * Main initialization routine 131 * Main initialization routine
126 */ 132 */
127int __init autcpu12_init (void) 133static int __init autcpu12_init(void)
128{ 134{
129 struct nand_chip *this; 135 struct nand_chip *this;
130 int err = 0; 136 int err = 0;
131 137
132 /* Allocate memory for MTD device structure and private data */ 138 /* Allocate memory for MTD device structure and private data */
133 autcpu12_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), 139 autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
134 GFP_KERNEL); 140 GFP_KERNEL);
135 if (!autcpu12_mtd) { 141 if (!autcpu12_mtd) {
136 printk ("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); 142 printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
137 err = -ENOMEM; 143 err = -ENOMEM;
138 goto out; 144 goto out;
139 } 145 }
140 146
141 /* map physical adress */ 147 /* map physical adress */
142 autcpu12_fio_base = ioremap(autcpu12_fio_pbase,SZ_1K); 148 autcpu12_fio_base = ioremap(AUTCPU12_PHYS_SMC, SZ_1K);
143 if(!autcpu12_fio_base){ 149 if (!autcpu12_fio_base) {
144 printk("Ioremap autcpu12 SmartMedia Card failed\n"); 150 printk("Ioremap autcpu12 SmartMedia Card failed\n");
145 err = -EIO; 151 err = -EIO;
146 goto out_mtd; 152 goto out_mtd;
147 } 153 }
148 154
149 /* Get pointer to private data */ 155 /* Get pointer to private data */
150 this = (struct nand_chip *) (&autcpu12_mtd[1]); 156 this = (struct nand_chip *)(&autcpu12_mtd[1]);
151 157
152 /* Initialize structures */ 158 /* Initialize structures */
153 memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info)); 159 memset(autcpu12_mtd, 0, sizeof(struct mtd_info));
154 memset((char *) this, 0, sizeof(struct nand_chip)); 160 memset(this, 0, sizeof(struct nand_chip));
155 161
156 /* Link the private data with the MTD structure */ 162 /* Link the private data with the MTD structure */
157 autcpu12_mtd->priv = this; 163 autcpu12_mtd->priv = this;
164 autcpu12_mtd->owner = THIS_MODULE;
158 165
159 /* Set address of NAND IO lines */ 166 /* Set address of NAND IO lines */
160 this->IO_ADDR_R = autcpu12_fio_base; 167 this->IO_ADDR_R = autcpu12_fio_base;
161 this->IO_ADDR_W = autcpu12_fio_base; 168 this->IO_ADDR_W = autcpu12_fio_base;
162 this->hwcontrol = autcpu12_hwcontrol; 169 this->cmd_ctrl = autcpu12_hwcontrol;
163 this->dev_ready = autcpu12_device_ready; 170 this->dev_ready = autcpu12_device_ready;
164 /* 20 us command delay time */ 171 /* 20 us command delay time */
165 this->chip_delay = 20; 172 this->chip_delay = 20;
166 this->eccmode = NAND_ECC_SOFT; 173 this->ecc.mode = NAND_ECC_SOFT;
167 174
168 /* Enable the following for a flash based bad block table */ 175 /* Enable the following for a flash based bad block table */
169 /* 176 /*
170 this->options = NAND_USE_FLASH_BBT; 177 this->options = NAND_USE_FLASH_BBT;
171 */ 178 */
172 this->options = NAND_USE_FLASH_BBT; 179 this->options = NAND_USE_FLASH_BBT;
173 180
174 /* Scan to find existance of the device */ 181 /* Scan to find existance of the device */
175 if (nand_scan (autcpu12_mtd, 1)) { 182 if (nand_scan(autcpu12_mtd, 1)) {
176 err = -ENXIO; 183 err = -ENXIO;
177 goto out_ior; 184 goto out_ior;
178 } 185 }
179 186
180 /* Register the partitions */ 187 /* Register the partitions */
181 switch(autcpu12_mtd->size){ 188 switch (autcpu12_mtd->size) {
182 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; 189 case SZ_16M:
183 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; 190 add_mtd_partitions(autcpu12_mtd, partition_info16k,
184 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 191 NUM_PARTITIONS16K);
185 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 192 break;
186 default: { 193 case SZ_32M:
187 printk ("Unsupported SmartMedia device\n"); 194 add_mtd_partitions(autcpu12_mtd, partition_info32k,
195 NUM_PARTITIONS32K);
196 break;
197 case SZ_64M:
198 add_mtd_partitions(autcpu12_mtd, partition_info64k,
199 NUM_PARTITIONS64K);
200 break;
201 case SZ_128M:
202 add_mtd_partitions(autcpu12_mtd, partition_info128k,
203 NUM_PARTITIONS128K);
204 break;
205 default:
206 printk("Unsupported SmartMedia device\n");
188 err = -ENXIO; 207 err = -ENXIO;
189 goto out_ior; 208 goto out_ior;
190 }
191 } 209 }
192 goto out; 210 goto out;
193 211
194out_ior: 212 out_ior:
195 iounmap((void *)autcpu12_fio_base); 213 iounmap(autcpu12_fio_base);
196out_mtd: 214 out_mtd:
197 kfree (autcpu12_mtd); 215 kfree(autcpu12_mtd);
198out: 216 out:
199 return err; 217 return err;
200} 218}
201 219
@@ -204,20 +222,19 @@ module_init(autcpu12_init);
204/* 222/*
205 * Clean up routine 223 * Clean up routine
206 */ 224 */
207#ifdef MODULE 225static void __exit autcpu12_cleanup(void)
208static void __exit autcpu12_cleanup (void)
209{ 226{
210 /* Release resources, unregister device */ 227 /* Release resources, unregister device */
211 nand_release (autcpu12_mtd); 228 nand_release(autcpu12_mtd);
212 229
213 /* unmap physical adress */ 230 /* unmap physical adress */
214 iounmap((void *)autcpu12_fio_base); 231 iounmap(autcpu12_fio_base);
215 232
216 /* Free the MTD device structure */ 233 /* Free the MTD device structure */
217 kfree (autcpu12_mtd); 234 kfree(autcpu12_mtd);
218} 235}
236
219module_exit(autcpu12_cleanup); 237module_exit(autcpu12_cleanup);
220#endif
221 238
222MODULE_LICENSE("GPL"); 239MODULE_LICENSE("GPL");
223MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); 240MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c
new file mode 100644
index 000000000000..e0a1d386e581
--- /dev/null
+++ b/drivers/mtd/nand/cs553x_nand.c
@@ -0,0 +1,353 @@
1/*
2 * drivers/mtd/nand/cs553x_nand.c
3 *
4 * (C) 2005, 2006 Red Hat Inc.
5 *
6 * Author: David Woodhouse <dwmw2@infradead.org>
7 * Tom Sylla <tom.sylla@amd.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Overview:
14 * This is a device driver for the NAND flash controller found on
15 * the AMD CS5535/CS5536 companion chipsets for the Geode processor.
16 *
17 */
18
19#include <linux/slab.h>
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/pci.h>
24#include <linux/mtd/mtd.h>
25#include <linux/mtd/nand.h>
26#include <linux/mtd/nand_ecc.h>
27#include <linux/mtd/partitions.h>
28
29#include <asm/msr.h>
30#include <asm/io.h>
31
32#define NR_CS553X_CONTROLLERS 4
33
34#define MSR_DIVIL_GLD_CAP 0x51400000 /* DIVIL capabilitiies */
35#define CAP_CS5535 0x2df000ULL
36#define CAP_CS5536 0x5df500ULL
37
38/* NAND Timing MSRs */
39#define MSR_NANDF_DATA 0x5140001b /* NAND Flash Data Timing MSR */
40#define MSR_NANDF_CTL 0x5140001c /* NAND Flash Control Timing */
41#define MSR_NANDF_RSVD 0x5140001d /* Reserved */
42
43/* NAND BAR MSRs */
44#define MSR_DIVIL_LBAR_FLSH0 0x51400010 /* Flash Chip Select 0 */
45#define MSR_DIVIL_LBAR_FLSH1 0x51400011 /* Flash Chip Select 1 */
46#define MSR_DIVIL_LBAR_FLSH2 0x51400012 /* Flash Chip Select 2 */
47#define MSR_DIVIL_LBAR_FLSH3 0x51400013 /* Flash Chip Select 3 */
48 /* Each made up of... */
49#define FLSH_LBAR_EN (1ULL<<32)
50#define FLSH_NOR_NAND (1ULL<<33) /* 1 for NAND */
51#define FLSH_MEM_IO (1ULL<<34) /* 1 for MMIO */
52 /* I/O BARs have BASE_ADDR in bits 15:4, IO_MASK in 47:36 */
53 /* MMIO BARs have BASE_ADDR in bits 31:12, MEM_MASK in 63:44 */
54
55/* Pin function selection MSR (IDE vs. flash on the IDE pins) */
56#define MSR_DIVIL_BALL_OPTS 0x51400015
57#define PIN_OPT_IDE (1<<0) /* 0 for flash, 1 for IDE */
58
59/* Registers within the NAND flash controller BAR -- memory mapped */
60#define MM_NAND_DATA 0x00 /* 0 to 0x7ff, in fact */
61#define MM_NAND_CTL 0x800 /* Any even address 0x800-0x80e */
62#define MM_NAND_IO 0x801 /* Any odd address 0x801-0x80f */
63#define MM_NAND_STS 0x810
64#define MM_NAND_ECC_LSB 0x811
65#define MM_NAND_ECC_MSB 0x812
66#define MM_NAND_ECC_COL 0x813
67#define MM_NAND_LAC 0x814
68#define MM_NAND_ECC_CTL 0x815
69
70/* Registers within the NAND flash controller BAR -- I/O mapped */
71#define IO_NAND_DATA 0x00 /* 0 to 3, in fact */
72#define IO_NAND_CTL 0x04
73#define IO_NAND_IO 0x05
74#define IO_NAND_STS 0x06
75#define IO_NAND_ECC_CTL 0x08
76#define IO_NAND_ECC_LSB 0x09
77#define IO_NAND_ECC_MSB 0x0a
78#define IO_NAND_ECC_COL 0x0b
79#define IO_NAND_LAC 0x0c
80
81#define CS_NAND_CTL_DIST_EN (1<<4) /* Enable NAND Distract interrupt */
82#define CS_NAND_CTL_RDY_INT_MASK (1<<3) /* Enable RDY/BUSY# interrupt */
83#define CS_NAND_CTL_ALE (1<<2)
84#define CS_NAND_CTL_CLE (1<<1)
85#define CS_NAND_CTL_CE (1<<0) /* Keep low; 1 to reset */
86
87#define CS_NAND_STS_FLASH_RDY (1<<3)
88#define CS_NAND_CTLR_BUSY (1<<2)
89#define CS_NAND_CMD_COMP (1<<1)
90#define CS_NAND_DIST_ST (1<<0)
91
92#define CS_NAND_ECC_PARITY (1<<2)
93#define CS_NAND_ECC_CLRECC (1<<1)
94#define CS_NAND_ECC_ENECC (1<<0)
95
96static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len)
97{
98 struct nand_chip *this = mtd->priv;
99
100 while (unlikely(len > 0x800)) {
101 memcpy_fromio(buf, this->IO_ADDR_R, 0x800);
102 buf += 0x800;
103 len -= 0x800;
104 }
105 memcpy_fromio(buf, this->IO_ADDR_R, len);
106}
107
108static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
109{
110 struct nand_chip *this = mtd->priv;
111
112 while (unlikely(len > 0x800)) {
113 memcpy_toio(this->IO_ADDR_R, buf, 0x800);
114 buf += 0x800;
115 len -= 0x800;
116 }
117 memcpy_toio(this->IO_ADDR_R, buf, len);
118}
119
120static unsigned char cs553x_read_byte(struct mtd_info *mtd)
121{
122 struct nand_chip *this = mtd->priv;
123 return readb(this->IO_ADDR_R);
124}
125
126static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
127{
128 struct nand_chip *this = mtd->priv;
129 int i = 100000;
130
131 while (i && readb(this->IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) {
132 udelay(1);
133 i--;
134 }
135 writeb(byte, this->IO_ADDR_W + 0x801);
136}
137
138static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd,
139 unsigned int ctrl)
140{
141 struct nand_chip *this = mtd->priv;
142 void __iomem *mmio_base = this->IO_ADDR_R;
143 if (ctrl & NAND_CTRL_CHANGE) {
144 unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01;
145 writeb(ctl, mmio_base + MM_NAND_CTL);
146 }
147 if (cmd != NAND_CMD_NONE)
148 cs553x_write_byte(mtd, cmd);
149}
150
151static int cs553x_device_ready(struct mtd_info *mtd)
152{
153 struct nand_chip *this = mtd->priv;
154 void __iomem *mmio_base = this->IO_ADDR_R;
155 unsigned char foo = readb(mmio_base + MM_NAND_STS);
156
157 return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
158}
159
160static void cs_enable_hwecc(struct mtd_info *mtd, int mode)
161{
162 struct nand_chip *this = mtd->priv;
163 void __iomem *mmio_base = this->IO_ADDR_R;
164
165 writeb(0x07, mmio_base + MM_NAND_ECC_CTL);
166}
167
168static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
169{
170 uint32_t ecc;
171 struct nand_chip *this = mtd->priv;
172 void __iomem *mmio_base = this->IO_ADDR_R;
173
174 ecc = readl(mmio_base + MM_NAND_STS);
175
176 ecc_code[1] = ecc >> 8;
177 ecc_code[0] = ecc >> 16;
178 ecc_code[2] = ecc >> 24;
179 return 0;
180}
181
182static struct mtd_info *cs553x_mtd[4];
183
184static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
185{
186 int err = 0;
187 struct nand_chip *this;
188 struct mtd_info *new_mtd;
189
190 printk(KERN_NOTICE "Probing CS553x NAND controller CS#%d at %sIO 0x%08lx\n", cs, mmio?"MM":"P", adr);
191
192 if (!mmio) {
193 printk(KERN_NOTICE "PIO mode not yet implemented for CS553X NAND controller\n");
194 return -ENXIO;
195 }
196
197 /* Allocate memory for MTD device structure and private data */
198 new_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
199 if (!new_mtd) {
200 printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n");
201 err = -ENOMEM;
202 goto out;
203 }
204
205 /* Get pointer to private data */
206 this = (struct nand_chip *)(&new_mtd[1]);
207
208 /* Initialize structures */
209 memset(new_mtd, 0, sizeof(struct mtd_info));
210 memset(this, 0, sizeof(struct nand_chip));
211
212 /* Link the private data with the MTD structure */
213 new_mtd->priv = this;
214 new_mtd->owner = THIS_MODULE;
215
216 /* map physical address */
217 this->IO_ADDR_R = this->IO_ADDR_W = ioremap(adr, 4096);
218 if (!this->IO_ADDR_R) {
219 printk(KERN_WARNING "ioremap cs553x NAND @0x%08lx failed\n", adr);
220 err = -EIO;
221 goto out_mtd;
222 }
223
224 this->cmd_ctrl = cs553x_hwcontrol;
225 this->dev_ready = cs553x_device_ready;
226 this->read_byte = cs553x_read_byte;
227 this->read_buf = cs553x_read_buf;
228 this->write_buf = cs553x_write_buf;
229
230 this->chip_delay = 0;
231
232 this->ecc.mode = NAND_ECC_HW;
233 this->ecc.size = 256;
234 this->ecc.bytes = 3;
235 this->ecc.hwctl = cs_enable_hwecc;
236 this->ecc.calculate = cs_calculate_ecc;
237 this->ecc.correct = nand_correct_data;
238
239 /* Enable the following for a flash based bad block table */
240 this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
241
242 /* Scan to find existance of the device */
243 if (nand_scan(new_mtd, 1)) {
244 err = -ENXIO;
245 goto out_ior;
246 }
247
248 cs553x_mtd[cs] = new_mtd;
249 goto out;
250
251out_ior:
252 iounmap((void *)this->IO_ADDR_R);
253out_mtd:
254 kfree(new_mtd);
255out:
256 return err;
257}
258
259static int is_geode(void)
260{
261 /* These are the CPUs which will have a CS553[56] companion chip */
262 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
263 boot_cpu_data.x86 == 5 &&
264 boot_cpu_data.x86_model == 10)
265 return 1; /* Geode LX */
266
267 if ((boot_cpu_data.x86_vendor == X86_VENDOR_NSC ||
268 boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX) &&
269 boot_cpu_data.x86 == 5 &&
270 boot_cpu_data.x86_model == 5)
271 return 1; /* Geode GX (née GX2) */
272
273 return 0;
274}
275
276static int __init cs553x_init(void)
277{
278 int err = -ENXIO;
279 int i;
280 uint64_t val;
281
282 /* If the CPU isn't a Geode GX or LX, abort */
283 if (!is_geode())
284 return -ENXIO;
285
286 /* If it doesn't have the CS553[56], abort */
287 rdmsrl(MSR_DIVIL_GLD_CAP, val);
288 val &= ~0xFFULL;
289 if (val != CAP_CS5535 && val != CAP_CS5536)
290 return -ENXIO;
291
292 /* If it doesn't have the NAND controller enabled, abort */
293 rdmsrl(MSR_DIVIL_BALL_OPTS, val);
294 if (val & 1) {
295 printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
296 return -ENXIO;
297 }
298
299 for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
300 rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);
301
302 if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
303 err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
304 }
305
306 /* Register all devices together here. This means we can easily hack it to
307 do mtdconcat etc. if we want to. */
308 for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
309 if (cs553x_mtd[i]) {
310 add_mtd_device(cs553x_mtd[i]);
311
312 /* If any devices registered, return success. Else the last error. */
313 err = 0;
314 }
315 }
316
317 return err;
318}
319
320module_init(cs553x_init);
321
322static void __exit cs553x_cleanup(void)
323{
324 int i;
325
326 for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
327 struct mtd_info *mtd = cs553x_mtd[i];
328 struct nand_chip *this;
329 void __iomem *mmio_base;
330
331 if (!mtd)
332 break;
333
334 this = cs553x_mtd[i]->priv;
335 mmio_base = this->IO_ADDR_R;
336
337 /* Release resources, unregister device */
338 nand_release(cs553x_mtd[i]);
339 cs553x_mtd[i] = NULL;
340
341 /* unmap physical adress */
342 iounmap(mmio_base);
343
344 /* Free the MTD device structure */
345 kfree(mtd);
346 }
347}
348
349module_exit(cs553x_cleanup);
350
351MODULE_LICENSE("GPL");
352MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
353MODULE_DESCRIPTION("NAND controller driver for AMD CS5535/CS5536 companion chip");
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index ec5e45e4e4ef..6107f532855b 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -58,10 +58,10 @@ static unsigned long __initdata doc_locations[] = {
58 0xe4000000, 58 0xe4000000,
59#elif defined(CONFIG_MOMENCO_OCELOT) 59#elif defined(CONFIG_MOMENCO_OCELOT)
60 0x2f000000, 60 0x2f000000,
61 0xff000000, 61 0xff000000,
62#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) 62#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
63 0xff000000, 63 0xff000000,
64##else 64#else
65#warning Unknown architecture for DiskOnChip. No default probe locations defined 65#warning Unknown architecture for DiskOnChip. No default probe locations defined
66#endif 66#endif
67 0xffffffff }; 67 0xffffffff };
@@ -73,7 +73,7 @@ struct doc_priv {
73 unsigned long physadr; 73 unsigned long physadr;
74 u_char ChipID; 74 u_char ChipID;
75 u_char CDSNControl; 75 u_char CDSNControl;
76 int chips_per_floor; /* The number of chips detected on each floor */ 76 int chips_per_floor; /* The number of chips detected on each floor */
77 int curfloor; 77 int curfloor;
78 int curchip; 78 int curchip;
79 int mh0_page; 79 int mh0_page;
@@ -84,6 +84,7 @@ struct doc_priv {
84/* This is the syndrome computed by the HW ecc generator upon reading an empty 84/* This is the syndrome computed by the HW ecc generator upon reading an empty
85 page, one with all 0xff for data and stored ecc code. */ 85 page, one with all 0xff for data and stored ecc code. */
86static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; 86static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
87
87/* This is the ecc value computed by the HW ecc generator upon writing an empty 88/* This is the ecc value computed by the HW ecc generator upon writing an empty
88 page, one with all 0xff for data. */ 89 page, one with all 0xff for data. */
89static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; 90static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
@@ -94,28 +95,29 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
94#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) 95#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
95#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) 96#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
96 97
97static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); 98static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int bitmask);
98static void doc200x_select_chip(struct mtd_info *mtd, int chip); 100static void doc200x_select_chip(struct mtd_info *mtd, int chip);
99 101
100static int debug=0; 102static int debug = 0;
101module_param(debug, int, 0); 103module_param(debug, int, 0);
102 104
103static int try_dword=1; 105static int try_dword = 1;
104module_param(try_dword, int, 0); 106module_param(try_dword, int, 0);
105 107
106static int no_ecc_failures=0; 108static int no_ecc_failures = 0;
107module_param(no_ecc_failures, int, 0); 109module_param(no_ecc_failures, int, 0);
108 110
109static int no_autopart=0; 111static int no_autopart = 0;
110module_param(no_autopart, int, 0); 112module_param(no_autopart, int, 0);
111 113
112static int show_firmware_partition=0; 114static int show_firmware_partition = 0;
113module_param(show_firmware_partition, int, 0); 115module_param(show_firmware_partition, int, 0);
114 116
115#ifdef MTD_NAND_DISKONCHIP_BBTWRITE 117#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
116static int inftl_bbt_write=1; 118static int inftl_bbt_write = 1;
117#else 119#else
118static int inftl_bbt_write=0; 120static int inftl_bbt_write = 0;
119#endif 121#endif
120module_param(inftl_bbt_write, int, 0); 122module_param(inftl_bbt_write, int, 0);
121 123
@@ -123,7 +125,6 @@ static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDR
123module_param(doc_config_location, ulong, 0); 125module_param(doc_config_location, ulong, 0);
124MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip"); 126MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
125 127
126
127/* Sector size for HW ECC */ 128/* Sector size for HW ECC */
128#define SECTOR_SIZE 512 129#define SECTOR_SIZE 512
129/* The sector bytes are packed into NB_DATA 10 bit words */ 130/* The sector bytes are packed into NB_DATA 10 bit words */
@@ -147,7 +148,7 @@ static struct rs_control *rs_decoder;
147 * some comments, improved a minor bit and converted it to make use 148 * some comments, improved a minor bit and converted it to make use
148 * of the generic Reed-Solomon libary. tglx 149 * of the generic Reed-Solomon libary. tglx
149 */ 150 */
150static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) 151static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
151{ 152{
152 int i, j, nerr, errpos[8]; 153 int i, j, nerr, errpos[8];
153 uint8_t parity; 154 uint8_t parity;
@@ -168,18 +169,18 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] 169 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
169 * where x = alpha^(FCR + i) 170 * where x = alpha^(FCR + i)
170 */ 171 */
171 for(j = 1; j < NROOTS; j++) { 172 for (j = 1; j < NROOTS; j++) {
172 if(ds[j] == 0) 173 if (ds[j] == 0)
173 continue; 174 continue;
174 tmp = rs->index_of[ds[j]]; 175 tmp = rs->index_of[ds[j]];
175 for(i = 0; i < NROOTS; i++) 176 for (i = 0; i < NROOTS; i++)
176 s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)]; 177 s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
177 } 178 }
178 179
179 /* Calc s[i] = s[i] / alpha^(v + i) */ 180 /* Calc s[i] = s[i] / alpha^(v + i) */
180 for (i = 0; i < NROOTS; i++) { 181 for (i = 0; i < NROOTS; i++) {
181 if (syn[i]) 182 if (syn[i])
182 syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i)); 183 syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
183 } 184 }
184 /* Call the decoder library */ 185 /* Call the decoder library */
185 nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval); 186 nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval);
@@ -193,7 +194,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
193 * but they are given by the design of the de/encoder circuit 194 * but they are given by the design of the de/encoder circuit
194 * in the DoC ASIC's. 195 * in the DoC ASIC's.
195 */ 196 */
196 for(i = 0;i < nerr; i++) { 197 for (i = 0; i < nerr; i++) {
197 int index, bitpos, pos = 1015 - errpos[i]; 198 int index, bitpos, pos = 1015 - errpos[i];
198 uint8_t val; 199 uint8_t val;
199 if (pos >= NB_DATA && pos < 1019) 200 if (pos >= NB_DATA && pos < 1019)
@@ -205,8 +206,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
205 can be modified since pos is even */ 206 can be modified since pos is even */
206 index = (pos >> 3) ^ 1; 207 index = (pos >> 3) ^ 1;
207 bitpos = pos & 7; 208 bitpos = pos & 7;
208 if ((index >= 0 && index < SECTOR_SIZE) || 209 if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) {
209 index == (SECTOR_SIZE + 1)) {
210 val = (uint8_t) (errval[i] >> (2 + bitpos)); 210 val = (uint8_t) (errval[i] >> (2 + bitpos));
211 parity ^= val; 211 parity ^= val;
212 if (index < SECTOR_SIZE) 212 if (index < SECTOR_SIZE)
@@ -216,9 +216,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
216 bitpos = (bitpos + 10) & 7; 216 bitpos = (bitpos + 10) & 7;
217 if (bitpos == 0) 217 if (bitpos == 0)
218 bitpos = 8; 218 bitpos = 8;
219 if ((index >= 0 && index < SECTOR_SIZE) || 219 if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) {
220 index == (SECTOR_SIZE + 1)) { 220 val = (uint8_t) (errval[i] << (8 - bitpos));
221 val = (uint8_t)(errval[i] << (8 - bitpos));
222 parity ^= val; 221 parity ^= val;
223 if (index < SECTOR_SIZE) 222 if (index < SECTOR_SIZE)
224 data[index] ^= val; 223 data[index] ^= val;
@@ -250,10 +249,11 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
250/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ 249/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
251static int _DoC_WaitReady(struct doc_priv *doc) 250static int _DoC_WaitReady(struct doc_priv *doc)
252{ 251{
253 void __iomem *docptr = doc->virtadr; 252 void __iomem *docptr = doc->virtadr;
254 unsigned long timeo = jiffies + (HZ * 10); 253 unsigned long timeo = jiffies + (HZ * 10);
255 254
256 if(debug) printk("_DoC_WaitReady...\n"); 255 if (debug)
256 printk("_DoC_WaitReady...\n");
257 /* Out-of-line routine to wait for chip response */ 257 /* Out-of-line routine to wait for chip response */
258 if (DoC_is_MillenniumPlus(doc)) { 258 if (DoC_is_MillenniumPlus(doc)) {
259 while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { 259 while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
@@ -280,7 +280,7 @@ static int _DoC_WaitReady(struct doc_priv *doc)
280 280
281static inline int DoC_WaitReady(struct doc_priv *doc) 281static inline int DoC_WaitReady(struct doc_priv *doc)
282{ 282{
283 void __iomem *docptr = doc->virtadr; 283 void __iomem *docptr = doc->virtadr;
284 int ret = 0; 284 int ret = 0;
285 285
286 if (DoC_is_MillenniumPlus(doc)) { 286 if (DoC_is_MillenniumPlus(doc)) {
@@ -298,7 +298,8 @@ static inline int DoC_WaitReady(struct doc_priv *doc)
298 DoC_Delay(doc, 2); 298 DoC_Delay(doc, 2);
299 } 299 }
300 300
301 if(debug) printk("DoC_WaitReady OK\n"); 301 if (debug)
302 printk("DoC_WaitReady OK\n");
302 return ret; 303 return ret;
303} 304}
304 305
@@ -306,9 +307,10 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
306{ 307{
307 struct nand_chip *this = mtd->priv; 308 struct nand_chip *this = mtd->priv;
308 struct doc_priv *doc = this->priv; 309 struct doc_priv *doc = this->priv;
309 void __iomem *docptr = doc->virtadr; 310 void __iomem *docptr = doc->virtadr;
310 311
311 if(debug)printk("write_byte %02x\n", datum); 312 if (debug)
313 printk("write_byte %02x\n", datum);
312 WriteDOC(datum, docptr, CDSNSlowIO); 314 WriteDOC(datum, docptr, CDSNSlowIO);
313 WriteDOC(datum, docptr, 2k_CDSN_IO); 315 WriteDOC(datum, docptr, 2k_CDSN_IO);
314} 316}
@@ -317,77 +319,78 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
317{ 319{
318 struct nand_chip *this = mtd->priv; 320 struct nand_chip *this = mtd->priv;
319 struct doc_priv *doc = this->priv; 321 struct doc_priv *doc = this->priv;
320 void __iomem *docptr = doc->virtadr; 322 void __iomem *docptr = doc->virtadr;
321 u_char ret; 323 u_char ret;
322 324
323 ReadDOC(docptr, CDSNSlowIO); 325 ReadDOC(docptr, CDSNSlowIO);
324 DoC_Delay(doc, 2); 326 DoC_Delay(doc, 2);
325 ret = ReadDOC(docptr, 2k_CDSN_IO); 327 ret = ReadDOC(docptr, 2k_CDSN_IO);
326 if (debug) printk("read_byte returns %02x\n", ret); 328 if (debug)
329 printk("read_byte returns %02x\n", ret);
327 return ret; 330 return ret;
328} 331}
329 332
330static void doc2000_writebuf(struct mtd_info *mtd, 333static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
331 const u_char *buf, int len)
332{ 334{
333 struct nand_chip *this = mtd->priv; 335 struct nand_chip *this = mtd->priv;
334 struct doc_priv *doc = this->priv; 336 struct doc_priv *doc = this->priv;
335 void __iomem *docptr = doc->virtadr; 337 void __iomem *docptr = doc->virtadr;
336 int i; 338 int i;
337 if (debug)printk("writebuf of %d bytes: ", len); 339 if (debug)
338 for (i=0; i < len; i++) { 340 printk("writebuf of %d bytes: ", len);
341 for (i = 0; i < len; i++) {
339 WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i); 342 WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
340 if (debug && i < 16) 343 if (debug && i < 16)
341 printk("%02x ", buf[i]); 344 printk("%02x ", buf[i]);
342 } 345 }
343 if (debug) printk("\n"); 346 if (debug)
347 printk("\n");
344} 348}
345 349
346static void doc2000_readbuf(struct mtd_info *mtd, 350static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len)
347 u_char *buf, int len)
348{ 351{
349 struct nand_chip *this = mtd->priv; 352 struct nand_chip *this = mtd->priv;
350 struct doc_priv *doc = this->priv; 353 struct doc_priv *doc = this->priv;
351 void __iomem *docptr = doc->virtadr; 354 void __iomem *docptr = doc->virtadr;
352 int i; 355 int i;
353 356
354 if (debug)printk("readbuf of %d bytes: ", len); 357 if (debug)
358 printk("readbuf of %d bytes: ", len);
355 359
356 for (i=0; i < len; i++) { 360 for (i = 0; i < len; i++) {
357 buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i); 361 buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
358 } 362 }
359} 363}
360 364
361static void doc2000_readbuf_dword(struct mtd_info *mtd, 365static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len)
362 u_char *buf, int len)
363{ 366{
364 struct nand_chip *this = mtd->priv; 367 struct nand_chip *this = mtd->priv;
365 struct doc_priv *doc = this->priv; 368 struct doc_priv *doc = this->priv;
366 void __iomem *docptr = doc->virtadr; 369 void __iomem *docptr = doc->virtadr;
367 int i; 370 int i;
368 371
369 if (debug) printk("readbuf_dword of %d bytes: ", len); 372 if (debug)
373 printk("readbuf_dword of %d bytes: ", len);
370 374
371 if (unlikely((((unsigned long)buf)|len) & 3)) { 375 if (unlikely((((unsigned long)buf) | len) & 3)) {
372 for (i=0; i < len; i++) { 376 for (i = 0; i < len; i++) {
373 *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); 377 *(uint8_t *) (&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
374 } 378 }
375 } else { 379 } else {
376 for (i=0; i < len; i+=4) { 380 for (i = 0; i < len; i += 4) {
377 *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); 381 *(uint32_t *) (&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
378 } 382 }
379 } 383 }
380} 384}
381 385
382static int doc2000_verifybuf(struct mtd_info *mtd, 386static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
383 const u_char *buf, int len)
384{ 387{
385 struct nand_chip *this = mtd->priv; 388 struct nand_chip *this = mtd->priv;
386 struct doc_priv *doc = this->priv; 389 struct doc_priv *doc = this->priv;
387 void __iomem *docptr = doc->virtadr; 390 void __iomem *docptr = doc->virtadr;
388 int i; 391 int i;
389 392
390 for (i=0; i < len; i++) 393 for (i = 0; i < len; i++)
391 if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO)) 394 if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
392 return -EFAULT; 395 return -EFAULT;
393 return 0; 396 return 0;
@@ -400,12 +403,10 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
400 uint16_t ret; 403 uint16_t ret;
401 404
402 doc200x_select_chip(mtd, nr); 405 doc200x_select_chip(mtd, nr);
403 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 406 doc200x_hwcontrol(mtd, NAND_CMD_READID,
404 this->write_byte(mtd, NAND_CMD_READID); 407 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
405 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 408 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 409 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
407 this->write_byte(mtd, 0);
408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
409 410
410 /* We cant' use dev_ready here, but at least we wait for the 411 /* We cant' use dev_ready here, but at least we wait for the
411 * command to complete 412 * command to complete
@@ -423,12 +424,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
423 } ident; 424 } ident;
424 void __iomem *docptr = doc->virtadr; 425 void __iomem *docptr = doc->virtadr;
425 426
426 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 427 doc200x_hwcontrol(mtd, NAND_CMD_READID,
427 doc2000_write_byte(mtd, NAND_CMD_READID); 428 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
428 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 429 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
429 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 430 doc200x_hwcontrol(mtd, NAND_CMD_NONE,
430 doc2000_write_byte(mtd, 0); 431 NAND_NCE | NAND_CTRL_CHANGE);
431 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
432 432
433 udelay(50); 433 udelay(50);
434 434
@@ -464,7 +464,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)
464 printk(KERN_DEBUG "Detected %d chips per floor.\n", i); 464 printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
465} 465}
466 466
467static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) 467static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)
468{ 468{
469 struct doc_priv *doc = this->priv; 469 struct doc_priv *doc = this->priv;
470 470
@@ -482,7 +482,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
482{ 482{
483 struct nand_chip *this = mtd->priv; 483 struct nand_chip *this = mtd->priv;
484 struct doc_priv *doc = this->priv; 484 struct doc_priv *doc = this->priv;
485 void __iomem *docptr = doc->virtadr; 485 void __iomem *docptr = doc->virtadr;
486 486
487 WriteDOC(datum, docptr, CDSNSlowIO); 487 WriteDOC(datum, docptr, CDSNSlowIO);
488 WriteDOC(datum, docptr, Mil_CDSN_IO); 488 WriteDOC(datum, docptr, Mil_CDSN_IO);
@@ -493,7 +493,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
493{ 493{
494 struct nand_chip *this = mtd->priv; 494 struct nand_chip *this = mtd->priv;
495 struct doc_priv *doc = this->priv; 495 struct doc_priv *doc = this->priv;
496 void __iomem *docptr = doc->virtadr; 496 void __iomem *docptr = doc->virtadr;
497 497
498 //ReadDOC(docptr, CDSNSlowIO); 498 //ReadDOC(docptr, CDSNSlowIO);
499 /* 11.4.5 -- delay twice to allow extended length cycle */ 499 /* 11.4.5 -- delay twice to allow extended length cycle */
@@ -503,50 +503,47 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
503 return ReadDOC(docptr, LastDataRead); 503 return ReadDOC(docptr, LastDataRead);
504} 504}
505 505
506static void doc2001_writebuf(struct mtd_info *mtd, 506static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
507 const u_char *buf, int len)
508{ 507{
509 struct nand_chip *this = mtd->priv; 508 struct nand_chip *this = mtd->priv;
510 struct doc_priv *doc = this->priv; 509 struct doc_priv *doc = this->priv;
511 void __iomem *docptr = doc->virtadr; 510 void __iomem *docptr = doc->virtadr;
512 int i; 511 int i;
513 512
514 for (i=0; i < len; i++) 513 for (i = 0; i < len; i++)
515 WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); 514 WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
516 /* Terminate write pipeline */ 515 /* Terminate write pipeline */
517 WriteDOC(0x00, docptr, WritePipeTerm); 516 WriteDOC(0x00, docptr, WritePipeTerm);
518} 517}
519 518
520static void doc2001_readbuf(struct mtd_info *mtd, 519static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len)
521 u_char *buf, int len)
522{ 520{
523 struct nand_chip *this = mtd->priv; 521 struct nand_chip *this = mtd->priv;
524 struct doc_priv *doc = this->priv; 522 struct doc_priv *doc = this->priv;
525 void __iomem *docptr = doc->virtadr; 523 void __iomem *docptr = doc->virtadr;
526 int i; 524 int i;
527 525
528 /* Start read pipeline */ 526 /* Start read pipeline */
529 ReadDOC(docptr, ReadPipeInit); 527 ReadDOC(docptr, ReadPipeInit);
530 528
531 for (i=0; i < len-1; i++) 529 for (i = 0; i < len - 1; i++)
532 buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff)); 530 buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
533 531
534 /* Terminate read pipeline */ 532 /* Terminate read pipeline */
535 buf[i] = ReadDOC(docptr, LastDataRead); 533 buf[i] = ReadDOC(docptr, LastDataRead);
536} 534}
537 535
538static int doc2001_verifybuf(struct mtd_info *mtd, 536static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
539 const u_char *buf, int len)
540{ 537{
541 struct nand_chip *this = mtd->priv; 538 struct nand_chip *this = mtd->priv;
542 struct doc_priv *doc = this->priv; 539 struct doc_priv *doc = this->priv;
543 void __iomem *docptr = doc->virtadr; 540 void __iomem *docptr = doc->virtadr;
544 int i; 541 int i;
545 542
546 /* Start read pipeline */ 543 /* Start read pipeline */
547 ReadDOC(docptr, ReadPipeInit); 544 ReadDOC(docptr, ReadPipeInit);
548 545
549 for (i=0; i < len-1; i++) 546 for (i = 0; i < len - 1; i++)
550 if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { 547 if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
551 ReadDOC(docptr, LastDataRead); 548 ReadDOC(docptr, LastDataRead);
552 return i; 549 return i;
@@ -560,87 +557,90 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
560{ 557{
561 struct nand_chip *this = mtd->priv; 558 struct nand_chip *this = mtd->priv;
562 struct doc_priv *doc = this->priv; 559 struct doc_priv *doc = this->priv;
563 void __iomem *docptr = doc->virtadr; 560 void __iomem *docptr = doc->virtadr;
564 u_char ret; 561 u_char ret;
565 562
566 ReadDOC(docptr, Mplus_ReadPipeInit); 563 ReadDOC(docptr, Mplus_ReadPipeInit);
567 ReadDOC(docptr, Mplus_ReadPipeInit); 564 ReadDOC(docptr, Mplus_ReadPipeInit);
568 ret = ReadDOC(docptr, Mplus_LastDataRead); 565 ret = ReadDOC(docptr, Mplus_LastDataRead);
569 if (debug) printk("read_byte returns %02x\n", ret); 566 if (debug)
567 printk("read_byte returns %02x\n", ret);
570 return ret; 568 return ret;
571} 569}
572 570
573static void doc2001plus_writebuf(struct mtd_info *mtd, 571static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
574 const u_char *buf, int len)
575{ 572{
576 struct nand_chip *this = mtd->priv; 573 struct nand_chip *this = mtd->priv;
577 struct doc_priv *doc = this->priv; 574 struct doc_priv *doc = this->priv;
578 void __iomem *docptr = doc->virtadr; 575 void __iomem *docptr = doc->virtadr;
579 int i; 576 int i;
580 577
581 if (debug)printk("writebuf of %d bytes: ", len); 578 if (debug)
582 for (i=0; i < len; i++) { 579 printk("writebuf of %d bytes: ", len);
580 for (i = 0; i < len; i++) {
583 WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); 581 WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
584 if (debug && i < 16) 582 if (debug && i < 16)
585 printk("%02x ", buf[i]); 583 printk("%02x ", buf[i]);
586 } 584 }
587 if (debug) printk("\n"); 585 if (debug)
586 printk("\n");
588} 587}
589 588
590static void doc2001plus_readbuf(struct mtd_info *mtd, 589static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len)
591 u_char *buf, int len)
592{ 590{
593 struct nand_chip *this = mtd->priv; 591 struct nand_chip *this = mtd->priv;
594 struct doc_priv *doc = this->priv; 592 struct doc_priv *doc = this->priv;
595 void __iomem *docptr = doc->virtadr; 593 void __iomem *docptr = doc->virtadr;
596 int i; 594 int i;
597 595
598 if (debug)printk("readbuf of %d bytes: ", len); 596 if (debug)
597 printk("readbuf of %d bytes: ", len);
599 598
600 /* Start read pipeline */ 599 /* Start read pipeline */
601 ReadDOC(docptr, Mplus_ReadPipeInit); 600 ReadDOC(docptr, Mplus_ReadPipeInit);
602 ReadDOC(docptr, Mplus_ReadPipeInit); 601 ReadDOC(docptr, Mplus_ReadPipeInit);
603 602
604 for (i=0; i < len-2; i++) { 603 for (i = 0; i < len - 2; i++) {
605 buf[i] = ReadDOC(docptr, Mil_CDSN_IO); 604 buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
606 if (debug && i < 16) 605 if (debug && i < 16)
607 printk("%02x ", buf[i]); 606 printk("%02x ", buf[i]);
608 } 607 }
609 608
610 /* Terminate read pipeline */ 609 /* Terminate read pipeline */
611 buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); 610 buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);
612 if (debug && i < 16) 611 if (debug && i < 16)
613 printk("%02x ", buf[len-2]); 612 printk("%02x ", buf[len - 2]);
614 buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); 613 buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead);
615 if (debug && i < 16) 614 if (debug && i < 16)
616 printk("%02x ", buf[len-1]); 615 printk("%02x ", buf[len - 1]);
617 if (debug) printk("\n"); 616 if (debug)
617 printk("\n");
618} 618}
619 619
620static int doc2001plus_verifybuf(struct mtd_info *mtd, 620static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
621 const u_char *buf, int len)
622{ 621{
623 struct nand_chip *this = mtd->priv; 622 struct nand_chip *this = mtd->priv;
624 struct doc_priv *doc = this->priv; 623 struct doc_priv *doc = this->priv;
625 void __iomem *docptr = doc->virtadr; 624 void __iomem *docptr = doc->virtadr;
626 int i; 625 int i;
627 626
628 if (debug)printk("verifybuf of %d bytes: ", len); 627 if (debug)
628 printk("verifybuf of %d bytes: ", len);
629 629
630 /* Start read pipeline */ 630 /* Start read pipeline */
631 ReadDOC(docptr, Mplus_ReadPipeInit); 631 ReadDOC(docptr, Mplus_ReadPipeInit);
632 ReadDOC(docptr, Mplus_ReadPipeInit); 632 ReadDOC(docptr, Mplus_ReadPipeInit);
633 633
634 for (i=0; i < len-2; i++) 634 for (i = 0; i < len - 2; i++)
635 if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { 635 if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
636 ReadDOC(docptr, Mplus_LastDataRead); 636 ReadDOC(docptr, Mplus_LastDataRead);
637 ReadDOC(docptr, Mplus_LastDataRead); 637 ReadDOC(docptr, Mplus_LastDataRead);
638 return i; 638 return i;
639 } 639 }
640 if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead)) 640 if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead))
641 return len-2; 641 return len - 2;
642 if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead)) 642 if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead))
643 return len-1; 643 return len - 1;
644 return 0; 644 return 0;
645} 645}
646 646
@@ -648,10 +648,11 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
648{ 648{
649 struct nand_chip *this = mtd->priv; 649 struct nand_chip *this = mtd->priv;
650 struct doc_priv *doc = this->priv; 650 struct doc_priv *doc = this->priv;
651 void __iomem *docptr = doc->virtadr; 651 void __iomem *docptr = doc->virtadr;
652 int floor = 0; 652 int floor = 0;
653 653
654 if(debug)printk("select chip (%d)\n", chip); 654 if (debug)
655 printk("select chip (%d)\n", chip);
655 656
656 if (chip == -1) { 657 if (chip == -1) {
657 /* Disable flash internally */ 658 /* Disable flash internally */
@@ -660,7 +661,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
660 } 661 }
661 662
662 floor = chip / doc->chips_per_floor; 663 floor = chip / doc->chips_per_floor;
663 chip -= (floor * doc->chips_per_floor); 664 chip -= (floor * doc->chips_per_floor);
664 665
665 /* Assert ChipEnable and deassert WriteProtect */ 666 /* Assert ChipEnable and deassert WriteProtect */
666 WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect); 667 WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
@@ -674,72 +675,61 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
674{ 675{
675 struct nand_chip *this = mtd->priv; 676 struct nand_chip *this = mtd->priv;
676 struct doc_priv *doc = this->priv; 677 struct doc_priv *doc = this->priv;
677 void __iomem *docptr = doc->virtadr; 678 void __iomem *docptr = doc->virtadr;
678 int floor = 0; 679 int floor = 0;
679 680
680 if(debug)printk("select chip (%d)\n", chip); 681 if (debug)
682 printk("select chip (%d)\n", chip);
681 683
682 if (chip == -1) 684 if (chip == -1)
683 return; 685 return;
684 686
685 floor = chip / doc->chips_per_floor; 687 floor = chip / doc->chips_per_floor;
686 chip -= (floor * doc->chips_per_floor); 688 chip -= (floor * doc->chips_per_floor);
687 689
688 /* 11.4.4 -- deassert CE before changing chip */ 690 /* 11.4.4 -- deassert CE before changing chip */
689 doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); 691 doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
690 692
691 WriteDOC(floor, docptr, FloorSelect); 693 WriteDOC(floor, docptr, FloorSelect);
692 WriteDOC(chip, docptr, CDSNDeviceSelect); 694 WriteDOC(chip, docptr, CDSNDeviceSelect);
693 695
694 doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); 696 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
695 697
696 doc->curchip = chip; 698 doc->curchip = chip;
697 doc->curfloor = floor; 699 doc->curfloor = floor;
698} 700}
699 701
700static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) 702#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)
703
704static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
705 unsigned int ctrl)
701{ 706{
702 struct nand_chip *this = mtd->priv; 707 struct nand_chip *this = mtd->priv;
703 struct doc_priv *doc = this->priv; 708 struct doc_priv *doc = this->priv;
704 void __iomem *docptr = doc->virtadr; 709 void __iomem *docptr = doc->virtadr;
705 710
706 switch(cmd) { 711 if (ctrl & NAND_CTRL_CHANGE) {
707 case NAND_CTL_SETNCE: 712 doc->CDSNControl &= ~CDSN_CTRL_MSK;
708 doc->CDSNControl |= CDSN_CTRL_CE; 713 doc->CDSNControl |= ctrl & CDSN_CTRL_MSK;
709 break; 714 if (debug)
710 case NAND_CTL_CLRNCE: 715 printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
711 doc->CDSNControl &= ~CDSN_CTRL_CE; 716 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
712 break; 717 /* 11.4.3 -- 4 NOPs after CSDNControl write */
713 case NAND_CTL_SETCLE: 718 DoC_Delay(doc, 4);
714 doc->CDSNControl |= CDSN_CTRL_CLE; 719 }
715 break; 720 if (cmd != NAND_CMD_NONE) {
716 case NAND_CTL_CLRCLE: 721 if (DoC_is_2000(doc))
717 doc->CDSNControl &= ~CDSN_CTRL_CLE; 722 doc2000_write_byte(mtd, cmd);
718 break; 723 else
719 case NAND_CTL_SETALE: 724 doc2001_write_byte(mtd, cmd);
720 doc->CDSNControl |= CDSN_CTRL_ALE;
721 break;
722 case NAND_CTL_CLRALE:
723 doc->CDSNControl &= ~CDSN_CTRL_ALE;
724 break;
725 case NAND_CTL_SETWP:
726 doc->CDSNControl |= CDSN_CTRL_WP;
727 break;
728 case NAND_CTL_CLRWP:
729 doc->CDSNControl &= ~CDSN_CTRL_WP;
730 break;
731 } 725 }
732 if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
733 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
734 /* 11.4.3 -- 4 NOPs after CSDNControl write */
735 DoC_Delay(doc, 4);
736} 726}
737 727
738static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) 728static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
739{ 729{
740 struct nand_chip *this = mtd->priv; 730 struct nand_chip *this = mtd->priv;
741 struct doc_priv *doc = this->priv; 731 struct doc_priv *doc = this->priv;
742 void __iomem *docptr = doc->virtadr; 732 void __iomem *docptr = doc->virtadr;
743 733
744 /* 734 /*
745 * Must terminate write pipeline before sending any commands 735 * Must terminate write pipeline before sending any commands
@@ -756,9 +746,9 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
756 if (command == NAND_CMD_SEQIN) { 746 if (command == NAND_CMD_SEQIN) {
757 int readcmd; 747 int readcmd;
758 748
759 if (column >= mtd->oobblock) { 749 if (column >= mtd->writesize) {
760 /* OOB area */ 750 /* OOB area */
761 column -= mtd->oobblock; 751 column -= mtd->writesize;
762 readcmd = NAND_CMD_READOOB; 752 readcmd = NAND_CMD_READOOB;
763 } else if (column < 256) { 753 } else if (column < 256) {
764 /* First 256 bytes --> READ0 */ 754 /* First 256 bytes --> READ0 */
@@ -782,25 +772,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
782 WriteDOC(column, docptr, Mplus_FlashAddress); 772 WriteDOC(column, docptr, Mplus_FlashAddress);
783 } 773 }
784 if (page_addr != -1) { 774 if (page_addr != -1) {
785 WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress); 775 WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress);
786 WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress); 776 WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
787 /* One more address cycle for higher density devices */ 777 /* One more address cycle for higher density devices */
788 if (this->chipsize & 0x0c000000) { 778 if (this->chipsize & 0x0c000000) {
789 WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress); 779 WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
790 printk("high density\n"); 780 printk("high density\n");
791 } 781 }
792 } 782 }
793 WriteDOC(0, docptr, Mplus_WritePipeTerm); 783 WriteDOC(0, docptr, Mplus_WritePipeTerm);
794 WriteDOC(0, docptr, Mplus_WritePipeTerm); 784 WriteDOC(0, docptr, Mplus_WritePipeTerm);
795 /* deassert ALE */ 785 /* deassert ALE */
796 if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID) 786 if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
787 command == NAND_CMD_READOOB || command == NAND_CMD_READID)
797 WriteDOC(0, docptr, Mplus_FlashControl); 788 WriteDOC(0, docptr, Mplus_FlashControl);
798 } 789 }
799 790
800 /* 791 /*
801 * program and erase have their own busy handlers 792 * program and erase have their own busy handlers
802 * status and sequential in needs no delay 793 * status and sequential in needs no delay
803 */ 794 */
804 switch (command) { 795 switch (command) {
805 796
806 case NAND_CMD_PAGEPROG: 797 case NAND_CMD_PAGEPROG:
@@ -817,55 +808,57 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
817 WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd); 808 WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
818 WriteDOC(0, docptr, Mplus_WritePipeTerm); 809 WriteDOC(0, docptr, Mplus_WritePipeTerm);
819 WriteDOC(0, docptr, Mplus_WritePipeTerm); 810 WriteDOC(0, docptr, Mplus_WritePipeTerm);
820 while ( !(this->read_byte(mtd) & 0x40)); 811 while (!(this->read_byte(mtd) & 0x40)) ;
821 return; 812 return;
822 813
823 /* This applies to read commands */ 814 /* This applies to read commands */
824 default: 815 default:
825 /* 816 /*
826 * If we don't have access to the busy pin, we apply the given 817 * If we don't have access to the busy pin, we apply the given
827 * command delay 818 * command delay
828 */ 819 */
829 if (!this->dev_ready) { 820 if (!this->dev_ready) {
830 udelay (this->chip_delay); 821 udelay(this->chip_delay);
831 return; 822 return;
832 } 823 }
833 } 824 }
834 825
835 /* Apply this short delay always to ensure that we do wait tWB in 826 /* Apply this short delay always to ensure that we do wait tWB in
836 * any case on any machine. */ 827 * any case on any machine. */
837 ndelay (100); 828 ndelay(100);
838 /* wait until command is processed */ 829 /* wait until command is processed */
839 while (!this->dev_ready(mtd)); 830 while (!this->dev_ready(mtd)) ;
840} 831}
841 832
842static int doc200x_dev_ready(struct mtd_info *mtd) 833static int doc200x_dev_ready(struct mtd_info *mtd)
843{ 834{
844 struct nand_chip *this = mtd->priv; 835 struct nand_chip *this = mtd->priv;
845 struct doc_priv *doc = this->priv; 836 struct doc_priv *doc = this->priv;
846 void __iomem *docptr = doc->virtadr; 837 void __iomem *docptr = doc->virtadr;
847 838
848 if (DoC_is_MillenniumPlus(doc)) { 839 if (DoC_is_MillenniumPlus(doc)) {
849 /* 11.4.2 -- must NOP four times before checking FR/B# */ 840 /* 11.4.2 -- must NOP four times before checking FR/B# */
850 DoC_Delay(doc, 4); 841 DoC_Delay(doc, 4);
851 if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { 842 if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
852 if(debug) 843 if (debug)
853 printk("not ready\n"); 844 printk("not ready\n");
854 return 0; 845 return 0;
855 } 846 }
856 if (debug)printk("was ready\n"); 847 if (debug)
848 printk("was ready\n");
857 return 1; 849 return 1;
858 } else { 850 } else {
859 /* 11.4.2 -- must NOP four times before checking FR/B# */ 851 /* 11.4.2 -- must NOP four times before checking FR/B# */
860 DoC_Delay(doc, 4); 852 DoC_Delay(doc, 4);
861 if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { 853 if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
862 if(debug) 854 if (debug)
863 printk("not ready\n"); 855 printk("not ready\n");
864 return 0; 856 return 0;
865 } 857 }
866 /* 11.4.2 -- Must NOP twice if it's ready */ 858 /* 11.4.2 -- Must NOP twice if it's ready */
867 DoC_Delay(doc, 2); 859 DoC_Delay(doc, 2);
868 if (debug)printk("was ready\n"); 860 if (debug)
861 printk("was ready\n");
869 return 1; 862 return 1;
870 } 863 }
871} 864}
@@ -881,10 +874,10 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
881{ 874{
882 struct nand_chip *this = mtd->priv; 875 struct nand_chip *this = mtd->priv;
883 struct doc_priv *doc = this->priv; 876 struct doc_priv *doc = this->priv;
884 void __iomem *docptr = doc->virtadr; 877 void __iomem *docptr = doc->virtadr;
885 878
886 /* Prime the ECC engine */ 879 /* Prime the ECC engine */
887 switch(mode) { 880 switch (mode) {
888 case NAND_ECC_READ: 881 case NAND_ECC_READ:
889 WriteDOC(DOC_ECC_RESET, docptr, ECCConf); 882 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
890 WriteDOC(DOC_ECC_EN, docptr, ECCConf); 883 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
@@ -900,10 +893,10 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
900{ 893{
901 struct nand_chip *this = mtd->priv; 894 struct nand_chip *this = mtd->priv;
902 struct doc_priv *doc = this->priv; 895 struct doc_priv *doc = this->priv;
903 void __iomem *docptr = doc->virtadr; 896 void __iomem *docptr = doc->virtadr;
904 897
905 /* Prime the ECC engine */ 898 /* Prime the ECC engine */
906 switch(mode) { 899 switch (mode) {
907 case NAND_ECC_READ: 900 case NAND_ECC_READ:
908 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); 901 WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
909 WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); 902 WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
@@ -916,12 +909,11 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
916} 909}
917 910
918/* This code is only called on write */ 911/* This code is only called on write */
919static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, 912static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code)
920 unsigned char *ecc_code)
921{ 913{
922 struct nand_chip *this = mtd->priv; 914 struct nand_chip *this = mtd->priv;
923 struct doc_priv *doc = this->priv; 915 struct doc_priv *doc = this->priv;
924 void __iomem *docptr = doc->virtadr; 916 void __iomem *docptr = doc->virtadr;
925 int i; 917 int i;
926 int emptymatch = 1; 918 int emptymatch = 1;
927 919
@@ -961,7 +953,8 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
961 often. It could be optimized away by examining the data in 953 often. It could be optimized away by examining the data in
962 the writebuf routine, and remembering the result. */ 954 the writebuf routine, and remembering the result. */
963 for (i = 0; i < 512; i++) { 955 for (i = 0; i < 512; i++) {
964 if (dat[i] == 0xff) continue; 956 if (dat[i] == 0xff)
957 continue;
965 emptymatch = 0; 958 emptymatch = 0;
966 break; 959 break;
967 } 960 }
@@ -969,17 +962,20 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
969 /* If emptymatch still =1, we do have an all-0xff data buffer. 962 /* If emptymatch still =1, we do have an all-0xff data buffer.
970 Return all-0xff ecc value instead of the computed one, so 963 Return all-0xff ecc value instead of the computed one, so
971 it'll look just like a freshly-erased page. */ 964 it'll look just like a freshly-erased page. */
972 if (emptymatch) memset(ecc_code, 0xff, 6); 965 if (emptymatch)
966 memset(ecc_code, 0xff, 6);
973#endif 967#endif
974 return 0; 968 return 0;
975} 969}
976 970
977static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 971static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
972 u_char *read_ecc, u_char *isnull)
978{ 973{
979 int i, ret = 0; 974 int i, ret = 0;
980 struct nand_chip *this = mtd->priv; 975 struct nand_chip *this = mtd->priv;
981 struct doc_priv *doc = this->priv; 976 struct doc_priv *doc = this->priv;
982 void __iomem *docptr = doc->virtadr; 977 void __iomem *docptr = doc->virtadr;
978 uint8_t calc_ecc[6];
983 volatile u_char dummy; 979 volatile u_char dummy;
984 int emptymatch = 1; 980 int emptymatch = 1;
985 981
@@ -1012,18 +1008,20 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1012 all-0xff data and stored ecc block. Check the stored ecc. */ 1008 all-0xff data and stored ecc block. Check the stored ecc. */
1013 if (emptymatch) { 1009 if (emptymatch) {
1014 for (i = 0; i < 6; i++) { 1010 for (i = 0; i < 6; i++) {
1015 if (read_ecc[i] == 0xff) continue; 1011 if (read_ecc[i] == 0xff)
1012 continue;
1016 emptymatch = 0; 1013 emptymatch = 0;
1017 break; 1014 break;
1018 } 1015 }
1019 } 1016 }
1020 /* If emptymatch still =1, check the data block. */ 1017 /* If emptymatch still =1, check the data block. */
1021 if (emptymatch) { 1018 if (emptymatch) {
1022 /* Note: this somewhat expensive test should not be triggered 1019 /* Note: this somewhat expensive test should not be triggered
1023 often. It could be optimized away by examining the data in 1020 often. It could be optimized away by examining the data in
1024 the readbuf routine, and remembering the result. */ 1021 the readbuf routine, and remembering the result. */
1025 for (i = 0; i < 512; i++) { 1022 for (i = 0; i < 512; i++) {
1026 if (dat[i] == 0xff) continue; 1023 if (dat[i] == 0xff)
1024 continue;
1027 emptymatch = 0; 1025 emptymatch = 0;
1028 break; 1026 break;
1029 } 1027 }
@@ -1032,7 +1030,8 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1032 erased block, in which case the ECC will not come out right. 1030 erased block, in which case the ECC will not come out right.
1033 We'll suppress the error and tell the caller everything's 1031 We'll suppress the error and tell the caller everything's
1034 OK. Because it is. */ 1032 OK. Because it is. */
1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); 1033 if (!emptymatch)
1034 ret = doc_ecc_decode(rs_decoder, dat, calc_ecc);
1036 if (ret > 0) 1035 if (ret > 0)
1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); 1036 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
1038 } 1037 }
@@ -1059,11 +1058,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1059 * safer. The only problem with it is that any code that parses oobfree must 1058 * safer. The only problem with it is that any code that parses oobfree must
1060 * be able to handle out-of-order segments. 1059 * be able to handle out-of-order segments.
1061 */ 1060 */
1062static struct nand_oobinfo doc200x_oobinfo = { 1061static struct nand_ecclayout doc200x_oobinfo = {
1063 .useecc = MTD_NANDECC_AUTOPLACE, 1062 .eccbytes = 6,
1064 .eccbytes = 6, 1063 .eccpos = {0, 1, 2, 3, 4, 5},
1065 .eccpos = {0, 1, 2, 3, 4, 5}, 1064 .oobfree = {{8, 8}, {6, 2}}
1066 .oobfree = { {8, 8}, {6, 2} }
1067}; 1065};
1068 1066
1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header. 1067/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1072,8 +1070,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
1072 either "ANAND" or "BNAND". If findmirror=1, also look for the mirror media 1070 either "ANAND" or "BNAND". If findmirror=1, also look for the mirror media
1073 header. The page #s of the found media headers are placed in mh0_page and 1071 header. The page #s of the found media headers are placed in mh0_page and
1074 mh1_page in the DOC private structure. */ 1072 mh1_page in the DOC private structure. */
1075static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, 1073static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror)
1076 const char *id, int findmirror)
1077{ 1074{
1078 struct nand_chip *this = mtd->priv; 1075 struct nand_chip *this = mtd->priv;
1079 struct doc_priv *doc = this->priv; 1076 struct doc_priv *doc = this->priv;
@@ -1082,17 +1079,19 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
1082 size_t retlen; 1079 size_t retlen;
1083 1080
1084 for (offs = 0; offs < mtd->size; offs += mtd->erasesize) { 1081 for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
1085 ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); 1082 ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
1086 if (retlen != mtd->oobblock) continue; 1083 if (retlen != mtd->writesize)
1084 continue;
1087 if (ret) { 1085 if (ret) {
1088 printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", 1086 printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", offs);
1089 offs);
1090 } 1087 }
1091 if (memcmp(buf, id, 6)) continue; 1088 if (memcmp(buf, id, 6))
1089 continue;
1092 printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs); 1090 printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
1093 if (doc->mh0_page == -1) { 1091 if (doc->mh0_page == -1) {
1094 doc->mh0_page = offs >> this->page_shift; 1092 doc->mh0_page = offs >> this->page_shift;
1095 if (!findmirror) return 1; 1093 if (!findmirror)
1094 return 1;
1096 continue; 1095 continue;
1097 } 1096 }
1098 doc->mh1_page = offs >> this->page_shift; 1097 doc->mh1_page = offs >> this->page_shift;
@@ -1105,8 +1104,8 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
1105 /* Only one mediaheader was found. We want buf to contain a 1104 /* Only one mediaheader was found. We want buf to contain a
1106 mediaheader on return, so we'll have to re-read the one we found. */ 1105 mediaheader on return, so we'll have to re-read the one we found. */
1107 offs = doc->mh0_page << this->page_shift; 1106 offs = doc->mh0_page << this->page_shift;
1108 ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); 1107 ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
1109 if (retlen != mtd->oobblock) { 1108 if (retlen != mtd->writesize) {
1110 /* Insanity. Give up. */ 1109 /* Insanity. Give up. */
1111 printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n"); 1110 printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
1112 return 0; 1111 return 0;
@@ -1114,8 +1113,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
1114 return 1; 1113 return 1;
1115} 1114}
1116 1115
1117static inline int __init nftl_partscan(struct mtd_info *mtd, 1116static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)
1118 struct mtd_partition *parts)
1119{ 1117{
1120 struct nand_chip *this = mtd->priv; 1118 struct nand_chip *this = mtd->priv;
1121 struct doc_priv *doc = this->priv; 1119 struct doc_priv *doc = this->priv;
@@ -1127,13 +1125,14 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1127 unsigned blocks, maxblocks; 1125 unsigned blocks, maxblocks;
1128 int offs, numheaders; 1126 int offs, numheaders;
1129 1127
1130 buf = kmalloc(mtd->oobblock, GFP_KERNEL); 1128 buf = kmalloc(mtd->writesize, GFP_KERNEL);
1131 if (!buf) { 1129 if (!buf) {
1132 printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); 1130 printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
1133 return 0; 1131 return 0;
1134 } 1132 }
1135 if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; 1133 if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1)))
1136 mh = (struct NFTLMediaHeader *) buf; 1134 goto out;
1135 mh = (struct NFTLMediaHeader *)buf;
1137 1136
1138 mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits); 1137 mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits);
1139 mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN); 1138 mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN);
@@ -1155,8 +1154,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1155 /* Auto-determine UnitSizeFactor. The constraints are: 1154 /* Auto-determine UnitSizeFactor. The constraints are:
1156 - There can be at most 32768 virtual blocks. 1155 - There can be at most 32768 virtual blocks.
1157 - There can be at most (virtual block size - page size) 1156 - There can be at most (virtual block size - page size)
1158 virtual blocks (because MediaHeader+BBT must fit in 1). 1157 virtual blocks (because MediaHeader+BBT must fit in 1).
1159 */ 1158 */
1160 mh->UnitSizeFactor = 0xff; 1159 mh->UnitSizeFactor = 0xff;
1161 while (blocks > maxblocks) { 1160 while (blocks > maxblocks) {
1162 blocks >>= 1; 1161 blocks >>= 1;
@@ -1211,14 +1210,13 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1211 } 1210 }
1212 1211
1213 ret = numparts; 1212 ret = numparts;
1214out: 1213 out:
1215 kfree(buf); 1214 kfree(buf);
1216 return ret; 1215 return ret;
1217} 1216}
1218 1217
1219/* This is a stripped-down copy of the code in inftlmount.c */ 1218/* This is a stripped-down copy of the code in inftlmount.c */
1220static inline int __init inftl_partscan(struct mtd_info *mtd, 1219static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)
1221 struct mtd_partition *parts)
1222{ 1220{
1223 struct nand_chip *this = mtd->priv; 1221 struct nand_chip *this = mtd->priv;
1224 struct doc_priv *doc = this->priv; 1222 struct doc_priv *doc = this->priv;
@@ -1235,15 +1233,16 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1235 if (inftl_bbt_write) 1233 if (inftl_bbt_write)
1236 end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift); 1234 end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift);
1237 1235
1238 buf = kmalloc(mtd->oobblock, GFP_KERNEL); 1236 buf = kmalloc(mtd->writesize, GFP_KERNEL);
1239 if (!buf) { 1237 if (!buf) {
1240 printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); 1238 printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
1241 return 0; 1239 return 0;
1242 } 1240 }
1243 1241
1244 if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out; 1242 if (!find_media_headers(mtd, buf, "BNAND", 0))
1243 goto out;
1245 doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift); 1244 doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
1246 mh = (struct INFTLMediaHeader *) buf; 1245 mh = (struct INFTLMediaHeader *)buf;
1247 1246
1248 mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks); 1247 mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
1249 mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions); 1248 mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
@@ -1319,8 +1318,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1319 parts[numparts].offset = ip->firstUnit << vshift; 1318 parts[numparts].offset = ip->firstUnit << vshift;
1320 parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift; 1319 parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift;
1321 numparts++; 1320 numparts++;
1322 if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit; 1321 if (ip->lastUnit > lastvunit)
1323 if (ip->flags & INFTL_LAST) break; 1322 lastvunit = ip->lastUnit;
1323 if (ip->flags & INFTL_LAST)
1324 break;
1324 } 1325 }
1325 lastvunit++; 1326 lastvunit++;
1326 if ((lastvunit << vshift) < end) { 1327 if ((lastvunit << vshift) < end) {
@@ -1330,7 +1331,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1330 numparts++; 1331 numparts++;
1331 } 1332 }
1332 ret = numparts; 1333 ret = numparts;
1333out: 1334 out:
1334 kfree(buf); 1335 kfree(buf);
1335 return ret; 1336 return ret;
1336} 1337}
@@ -1342,11 +1343,12 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd)
1342 struct doc_priv *doc = this->priv; 1343 struct doc_priv *doc = this->priv;
1343 struct mtd_partition parts[2]; 1344 struct mtd_partition parts[2];
1344 1345
1345 memset((char *) parts, 0, sizeof(parts)); 1346 memset((char *)parts, 0, sizeof(parts));
1346 /* On NFTL, we have to find the media headers before we can read the 1347 /* On NFTL, we have to find the media headers before we can read the
1347 BBTs, since they're stored in the media header eraseblocks. */ 1348 BBTs, since they're stored in the media header eraseblocks. */
1348 numparts = nftl_partscan(mtd, parts); 1349 numparts = nftl_partscan(mtd, parts);
1349 if (!numparts) return -EIO; 1350 if (!numparts)
1351 return -EIO;
1350 this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT | 1352 this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
1351 NAND_BBT_SAVECONTENT | NAND_BBT_WRITE | 1353 NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
1352 NAND_BBT_VERSION; 1354 NAND_BBT_VERSION;
@@ -1393,8 +1395,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
1393 this->bbt_td->pages[0] = 2; 1395 this->bbt_td->pages[0] = 2;
1394 this->bbt_md = NULL; 1396 this->bbt_md = NULL;
1395 } else { 1397 } else {
1396 this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | 1398 this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;
1397 NAND_BBT_VERSION;
1398 if (inftl_bbt_write) 1399 if (inftl_bbt_write)
1399 this->bbt_td->options |= NAND_BBT_WRITE; 1400 this->bbt_td->options |= NAND_BBT_WRITE;
1400 this->bbt_td->offs = 8; 1401 this->bbt_td->offs = 8;
@@ -1404,8 +1405,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
1404 this->bbt_td->reserved_block_code = 0x01; 1405 this->bbt_td->reserved_block_code = 0x01;
1405 this->bbt_td->pattern = "MSYS_BBT"; 1406 this->bbt_td->pattern = "MSYS_BBT";
1406 1407
1407 this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | 1408 this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;
1408 NAND_BBT_VERSION;
1409 if (inftl_bbt_write) 1409 if (inftl_bbt_write)
1410 this->bbt_md->options |= NAND_BBT_WRITE; 1410 this->bbt_md->options |= NAND_BBT_WRITE;
1411 this->bbt_md->offs = 8; 1411 this->bbt_md->offs = 8;
@@ -1420,12 +1420,13 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
1420 At least as nand_bbt.c is currently written. */ 1420 At least as nand_bbt.c is currently written. */
1421 if ((ret = nand_scan_bbt(mtd, NULL))) 1421 if ((ret = nand_scan_bbt(mtd, NULL)))
1422 return ret; 1422 return ret;
1423 memset((char *) parts, 0, sizeof(parts)); 1423 memset((char *)parts, 0, sizeof(parts));
1424 numparts = inftl_partscan(mtd, parts); 1424 numparts = inftl_partscan(mtd, parts);
1425 /* At least for now, require the INFTL Media Header. We could probably 1425 /* At least for now, require the INFTL Media Header. We could probably
1426 do without it for non-INFTL use, since all it gives us is 1426 do without it for non-INFTL use, since all it gives us is
1427 autopartitioning, but I want to give it more thought. */ 1427 autopartitioning, but I want to give it more thought. */
1428 if (!numparts) return -EIO; 1428 if (!numparts)
1429 return -EIO;
1429 add_mtd_device(mtd); 1430 add_mtd_device(mtd);
1430#ifdef CONFIG_MTD_PARTITIONS 1431#ifdef CONFIG_MTD_PARTITIONS
1431 if (!no_autopart) 1432 if (!no_autopart)
@@ -1439,7 +1440,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)
1439 struct nand_chip *this = mtd->priv; 1440 struct nand_chip *this = mtd->priv;
1440 struct doc_priv *doc = this->priv; 1441 struct doc_priv *doc = this->priv;
1441 1442
1442 this->write_byte = doc2000_write_byte;
1443 this->read_byte = doc2000_read_byte; 1443 this->read_byte = doc2000_read_byte;
1444 this->write_buf = doc2000_writebuf; 1444 this->write_buf = doc2000_writebuf;
1445 this->read_buf = doc2000_readbuf; 1445 this->read_buf = doc2000_readbuf;
@@ -1457,7 +1457,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
1457 struct nand_chip *this = mtd->priv; 1457 struct nand_chip *this = mtd->priv;
1458 struct doc_priv *doc = this->priv; 1458 struct doc_priv *doc = this->priv;
1459 1459
1460 this->write_byte = doc2001_write_byte;
1461 this->read_byte = doc2001_read_byte; 1460 this->read_byte = doc2001_read_byte;
1462 this->write_buf = doc2001_writebuf; 1461 this->write_buf = doc2001_writebuf;
1463 this->read_buf = doc2001_readbuf; 1462 this->read_buf = doc2001_readbuf;
@@ -1489,16 +1488,15 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
1489 struct nand_chip *this = mtd->priv; 1488 struct nand_chip *this = mtd->priv;
1490 struct doc_priv *doc = this->priv; 1489 struct doc_priv *doc = this->priv;
1491 1490
1492 this->write_byte = NULL;
1493 this->read_byte = doc2001plus_read_byte; 1491 this->read_byte = doc2001plus_read_byte;
1494 this->write_buf = doc2001plus_writebuf; 1492 this->write_buf = doc2001plus_writebuf;
1495 this->read_buf = doc2001plus_readbuf; 1493 this->read_buf = doc2001plus_readbuf;
1496 this->verify_buf = doc2001plus_verifybuf; 1494 this->verify_buf = doc2001plus_verifybuf;
1497 this->scan_bbt = inftl_scan_bbt; 1495 this->scan_bbt = inftl_scan_bbt;
1498 this->hwcontrol = NULL; 1496 this->cmd_ctrl = NULL;
1499 this->select_chip = doc2001plus_select_chip; 1497 this->select_chip = doc2001plus_select_chip;
1500 this->cmdfunc = doc2001plus_command; 1498 this->cmdfunc = doc2001plus_command;
1501 this->enable_hwecc = doc2001plus_enable_hwecc; 1499 this->ecc.hwctl = doc2001plus_enable_hwecc;
1502 1500
1503 doc->chips_per_floor = 1; 1501 doc->chips_per_floor = 1;
1504 mtd->name = "DiskOnChip Millennium Plus"; 1502 mtd->name = "DiskOnChip Millennium Plus";
@@ -1535,20 +1533,16 @@ static int __init doc_probe(unsigned long physadr)
1535 save_control = ReadDOC(virtadr, DOCControl); 1533 save_control = ReadDOC(virtadr, DOCControl);
1536 1534
1537 /* Reset the DiskOnChip ASIC */ 1535 /* Reset the DiskOnChip ASIC */
1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1536 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl);
1539 virtadr, DOCControl); 1537 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl);
1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1541 virtadr, DOCControl);
1542 1538
1543 /* Enable the DiskOnChip ASIC */ 1539 /* Enable the DiskOnChip ASIC */
1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl);
1545 virtadr, DOCControl); 1541 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl);
1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1547 virtadr, DOCControl);
1548 1542
1549 ChipID = ReadDOC(virtadr, ChipID); 1543 ChipID = ReadDOC(virtadr, ChipID);
1550 1544
1551 switch(ChipID) { 1545 switch (ChipID) {
1552 case DOC_ChipID_Doc2k: 1546 case DOC_ChipID_Doc2k:
1553 reg = DoC_2k_ECCStatus; 1547 reg = DoC_2k_ECCStatus;
1554 break; 1548 break;
@@ -1564,15 +1558,13 @@ static int __init doc_probe(unsigned long physadr)
1564 ReadDOC(virtadr, Mplus_Power); 1558 ReadDOC(virtadr, Mplus_Power);
1565 1559
1566 /* Reset the Millennium Plus ASIC */ 1560 /* Reset the Millennium Plus ASIC */
1567 tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | 1561 tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;
1568 DOC_MODE_BDECT;
1569 WriteDOC(tmp, virtadr, Mplus_DOCControl); 1562 WriteDOC(tmp, virtadr, Mplus_DOCControl);
1570 WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); 1563 WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
1571 1564
1572 mdelay(1); 1565 mdelay(1);
1573 /* Enable the Millennium Plus ASIC */ 1566 /* Enable the Millennium Plus ASIC */
1574 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | 1567 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;
1575 DOC_MODE_BDECT;
1576 WriteDOC(tmp, virtadr, Mplus_DOCControl); 1568 WriteDOC(tmp, virtadr, Mplus_DOCControl);
1577 WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); 1569 WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
1578 mdelay(1); 1570 mdelay(1);
@@ -1596,7 +1588,7 @@ static int __init doc_probe(unsigned long physadr)
1596 goto notfound; 1588 goto notfound;
1597 } 1589 }
1598 /* Check the TOGGLE bit in the ECC register */ 1590 /* Check the TOGGLE bit in the ECC register */
1599 tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; 1591 tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
1600 tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; 1592 tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
1601 tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; 1593 tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
1602 if ((tmp == tmpb) || (tmp != tmpc)) { 1594 if ((tmp == tmpb) || (tmp != tmpc)) {
@@ -1626,11 +1618,11 @@ static int __init doc_probe(unsigned long physadr)
1626 if (ChipID == DOC_ChipID_DocMilPlus16) { 1618 if (ChipID == DOC_ChipID_DocMilPlus16) {
1627 WriteDOC(~newval, virtadr, Mplus_AliasResolution); 1619 WriteDOC(~newval, virtadr, Mplus_AliasResolution);
1628 oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); 1620 oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
1629 WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it 1621 WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it
1630 } else { 1622 } else {
1631 WriteDOC(~newval, virtadr, AliasResolution); 1623 WriteDOC(~newval, virtadr, AliasResolution);
1632 oldval = ReadDOC(doc->virtadr, AliasResolution); 1624 oldval = ReadDOC(doc->virtadr, AliasResolution);
1633 WriteDOC(newval, virtadr, AliasResolution); // restore it 1625 WriteDOC(newval, virtadr, AliasResolution); // restore it
1634 } 1626 }
1635 newval = ~newval; 1627 newval = ~newval;
1636 if (oldval == newval) { 1628 if (oldval == newval) {
@@ -1642,10 +1634,8 @@ static int __init doc_probe(unsigned long physadr)
1642 printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); 1634 printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);
1643 1635
1644 len = sizeof(struct mtd_info) + 1636 len = sizeof(struct mtd_info) +
1645 sizeof(struct nand_chip) + 1637 sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr));
1646 sizeof(struct doc_priv) + 1638 mtd = kmalloc(len, GFP_KERNEL);
1647 (2 * sizeof(struct nand_bbt_descr));
1648 mtd = kmalloc(len, GFP_KERNEL);
1649 if (!mtd) { 1639 if (!mtd) {
1650 printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len); 1640 printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);
1651 ret = -ENOMEM; 1641 ret = -ENOMEM;
@@ -1663,17 +1653,19 @@ static int __init doc_probe(unsigned long physadr)
1663 1653
1664 nand->priv = doc; 1654 nand->priv = doc;
1665 nand->select_chip = doc200x_select_chip; 1655 nand->select_chip = doc200x_select_chip;
1666 nand->hwcontrol = doc200x_hwcontrol; 1656 nand->cmd_ctrl = doc200x_hwcontrol;
1667 nand->dev_ready = doc200x_dev_ready; 1657 nand->dev_ready = doc200x_dev_ready;
1668 nand->waitfunc = doc200x_wait; 1658 nand->waitfunc = doc200x_wait;
1669 nand->block_bad = doc200x_block_bad; 1659 nand->block_bad = doc200x_block_bad;
1670 nand->enable_hwecc = doc200x_enable_hwecc; 1660 nand->ecc.hwctl = doc200x_enable_hwecc;
1671 nand->calculate_ecc = doc200x_calculate_ecc; 1661 nand->ecc.calculate = doc200x_calculate_ecc;
1672 nand->correct_data = doc200x_correct_data; 1662 nand->ecc.correct = doc200x_correct_data;
1673 1663
1674 nand->autooob = &doc200x_oobinfo; 1664 nand->ecc.layout = &doc200x_oobinfo;
1675 nand->eccmode = NAND_ECC_HW6_512; 1665 nand->ecc.mode = NAND_ECC_HW_SYNDROME;
1676 nand->options = NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME; 1666 nand->ecc.size = 512;
1667 nand->ecc.bytes = 6;
1668 nand->options = NAND_USE_FLASH_BBT;
1677 1669
1678 doc->physadr = physadr; 1670 doc->physadr = physadr;
1679 doc->virtadr = virtadr; 1671 doc->virtadr = virtadr;
@@ -1707,18 +1699,18 @@ static int __init doc_probe(unsigned long physadr)
1707 doclist = mtd; 1699 doclist = mtd;
1708 return 0; 1700 return 0;
1709 1701
1710notfound: 1702 notfound:
1711 /* Put back the contents of the DOCControl register, in case it's not 1703 /* Put back the contents of the DOCControl register, in case it's not
1712 actually a DiskOnChip. */ 1704 actually a DiskOnChip. */
1713 WriteDOC(save_control, virtadr, DOCControl); 1705 WriteDOC(save_control, virtadr, DOCControl);
1714fail: 1706 fail:
1715 iounmap(virtadr); 1707 iounmap(virtadr);
1716 return ret; 1708 return ret;
1717} 1709}
1718 1710
1719static void release_nanddoc(void) 1711static void release_nanddoc(void)
1720{ 1712{
1721 struct mtd_info *mtd, *nextmtd; 1713 struct mtd_info *mtd, *nextmtd;
1722 struct nand_chip *nand; 1714 struct nand_chip *nand;
1723 struct doc_priv *doc; 1715 struct doc_priv *doc;
1724 1716
@@ -1747,8 +1739,8 @@ static int __init init_nanddoc(void)
1747 * generator polinomial degree = 4 1739 * generator polinomial degree = 4
1748 */ 1740 */
1749 rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS); 1741 rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);
1750 if (!rs_decoder) { 1742 if (!rs_decoder) {
1751 printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n"); 1743 printk(KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
1752 return -ENOMEM; 1744 return -ENOMEM;
1753 } 1745 }
1754 1746
@@ -1758,7 +1750,7 @@ static int __init init_nanddoc(void)
1758 if (ret < 0) 1750 if (ret < 0)
1759 goto outerr; 1751 goto outerr;
1760 } else { 1752 } else {
1761 for (i=0; (doc_locations[i] != 0xffffffff); i++) { 1753 for (i = 0; (doc_locations[i] != 0xffffffff); i++) {
1762 doc_probe(doc_locations[i]); 1754 doc_probe(doc_locations[i]);
1763 } 1755 }
1764 } 1756 }
@@ -1770,7 +1762,7 @@ static int __init init_nanddoc(void)
1770 goto outerr; 1762 goto outerr;
1771 } 1763 }
1772 return 0; 1764 return 0;
1773outerr: 1765 outerr:
1774 free_rs(rs_decoder); 1766 free_rs(rs_decoder);
1775 return ret; 1767 return ret;
1776} 1768}
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 9b1fd2f387fa..516c0e5e564c 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/mtd/nand/edb7312.c 2 * drivers/mtd/nand/edb7312.c
3 * 3 *
4 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) 4 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
5 * 5 *
6 * Derived from drivers/mtd/nand/autcpu12.c 6 * Derived from drivers/mtd/nand/autcpu12.c
7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
@@ -25,7 +25,7 @@
25#include <linux/mtd/nand.h> 25#include <linux/mtd/nand.h>
26#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */ 28#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
29#include <asm/sizes.h> 29#include <asm/sizes.h>
30#include <asm/hardware/clps7111.h> 30#include <asm/hardware/clps7111.h>
31 31
@@ -54,51 +54,45 @@ static struct mtd_info *ep7312_mtd = NULL;
54 */ 54 */
55 55
56static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE; 56static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
57static void __iomem * ep7312_pxdr = (void __iomem *) EP7312_PXDR; 57static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
58static void __iomem * ep7312_pxddr = (void __iomem *) EP7312_PXDDR; 58static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
59 59
60#ifdef CONFIG_MTD_PARTITIONS 60#ifdef CONFIG_MTD_PARTITIONS
61/* 61/*
62 * Define static partitions for flash device 62 * Define static partitions for flash device
63 */ 63 */
64static struct mtd_partition partition_info[] = { 64static struct mtd_partition partition_info[] = {
65 { .name = "EP7312 Nand Flash", 65 {.name = "EP7312 Nand Flash",
66 .offset = 0, 66 .offset = 0,
67 .size = 8*1024*1024 } 67 .size = 8 * 1024 * 1024}
68}; 68};
69
69#define NUM_PARTITIONS 1 70#define NUM_PARTITIONS 1
70 71
71#endif 72#endif
72 73
73
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 *
77 * NAND_NCE: bit 0 -> bit 7
78 * NAND_CLE: bit 1 -> bit 4
79 * NAND_ALE: bit 2 -> bit 5
76 */ 80 */
77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) 81static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
78{ 82{
79 switch(cmd) { 83 struct nand_chip *chip = mtd->priv;
80 84
81 case NAND_CTL_SETCLE: 85 if (ctrl & NAND_CTRL_CHANGE) {
82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); 86 unsigned char bits;
83 break; 87
84 case NAND_CTL_CLRCLE: 88 bits = (ctrl & (NAND_CLE | NAND_ALE)) << 3;
85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); 89 bits = (ctrl & NAND_NCE) << 7;
86 break; 90
87 91 clps_writeb((clps_readb(ep7312_pxdr) & 0xB0) | 0x10,
88 case NAND_CTL_SETALE: 92 ep7312_pxdr);
89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
90 break;
91 case NAND_CTL_CLRALE:
92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
93 break;
94
95 case NAND_CTL_SETNCE:
96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
97 break;
98 case NAND_CTL_CLRNCE:
99 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) | 0x40, ep7312_pxdr);
100 break;
101 } 93 }
94 if (cmd != NAND_CMD_NONE)
95 writeb(cmd, chip->IO_ADDR_W);
102} 96}
103 97
104/* 98/*
@@ -108,6 +102,7 @@ static int ep7312_device_ready(struct mtd_info *mtd)
108{ 102{
109 return 1; 103 return 1;
110} 104}
105
111#ifdef CONFIG_MTD_PARTITIONS 106#ifdef CONFIG_MTD_PARTITIONS
112const char *part_probes[] = { "cmdlinepart", NULL }; 107const char *part_probes[] = { "cmdlinepart", NULL };
113#endif 108#endif
@@ -115,18 +110,16 @@ const char *part_probes[] = { "cmdlinepart", NULL };
115/* 110/*
116 * Main initialization routine 111 * Main initialization routine
117 */ 112 */
118static int __init ep7312_init (void) 113static int __init ep7312_init(void)
119{ 114{
120 struct nand_chip *this; 115 struct nand_chip *this;
121 const char *part_type = 0; 116 const char *part_type = 0;
122 int mtd_parts_nb = 0; 117 int mtd_parts_nb = 0;
123 struct mtd_partition *mtd_parts = 0; 118 struct mtd_partition *mtd_parts = 0;
124 void __iomem * ep7312_fio_base; 119 void __iomem *ep7312_fio_base;
125 120
126 /* Allocate memory for MTD device structure and private data */ 121 /* Allocate memory for MTD device structure and private data */
127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) + 122 ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
128 sizeof(struct nand_chip),
129 GFP_KERNEL);
130 if (!ep7312_mtd) { 123 if (!ep7312_mtd) {
131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); 124 printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
132 return -ENOMEM; 125 return -ENOMEM;
@@ -134,21 +127,22 @@ static int __init ep7312_init (void)
134 127
135 /* map physical adress */ 128 /* map physical adress */
136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); 129 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
137 if(!ep7312_fio_base) { 130 if (!ep7312_fio_base) {
138 printk("ioremap EDB7312 NAND flash failed\n"); 131 printk("ioremap EDB7312 NAND flash failed\n");
139 kfree(ep7312_mtd); 132 kfree(ep7312_mtd);
140 return -EIO; 133 return -EIO;
141 } 134 }
142 135
143 /* Get pointer to private data */ 136 /* Get pointer to private data */
144 this = (struct nand_chip *) (&ep7312_mtd[1]); 137 this = (struct nand_chip *)(&ep7312_mtd[1]);
145 138
146 /* Initialize structures */ 139 /* Initialize structures */
147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); 140 memset(ep7312_mtd, 0, sizeof(struct mtd_info));
148 memset((char *) this, 0, sizeof(struct nand_chip)); 141 memset(this, 0, sizeof(struct nand_chip));
149 142
150 /* Link the private data with the MTD structure */ 143 /* Link the private data with the MTD structure */
151 ep7312_mtd->priv = this; 144 ep7312_mtd->priv = this;
145 ep7312_mtd->owner = THIS_MODULE;
152 146
153 /* 147 /*
154 * Set GPIO Port B control register so that the pins are configured 148 * Set GPIO Port B control register so that the pins are configured
@@ -159,22 +153,20 @@ static int __init ep7312_init (void)
159 /* insert callbacks */ 153 /* insert callbacks */
160 this->IO_ADDR_R = ep7312_fio_base; 154 this->IO_ADDR_R = ep7312_fio_base;
161 this->IO_ADDR_W = ep7312_fio_base; 155 this->IO_ADDR_W = ep7312_fio_base;
162 this->hwcontrol = ep7312_hwcontrol; 156 this->cmd_ctrl = ep7312_hwcontrol;
163 this->dev_ready = ep7312_device_ready; 157 this->dev_ready = ep7312_device_ready;
164 /* 15 us command delay time */ 158 /* 15 us command delay time */
165 this->chip_delay = 15; 159 this->chip_delay = 15;
166 160
167 /* Scan to find existence of the device */ 161 /* Scan to find existence of the device */
168 if (nand_scan (ep7312_mtd, 1)) { 162 if (nand_scan(ep7312_mtd, 1)) {
169 iounmap((void *)ep7312_fio_base); 163 iounmap((void *)ep7312_fio_base);
170 kfree (ep7312_mtd); 164 kfree(ep7312_mtd);
171 return -ENXIO; 165 return -ENXIO;
172 } 166 }
173
174#ifdef CONFIG_MTD_PARTITIONS 167#ifdef CONFIG_MTD_PARTITIONS
175 ep7312_mtd->name = "edb7312-nand"; 168 ep7312_mtd->name = "edb7312-nand";
176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, 169 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
177 &mtd_parts, 0);
178 if (mtd_parts_nb > 0) 170 if (mtd_parts_nb > 0)
179 part_type = "command line"; 171 part_type = "command line";
180 else 172 else
@@ -193,24 +185,23 @@ static int __init ep7312_init (void)
193 /* Return happy */ 185 /* Return happy */
194 return 0; 186 return 0;
195} 187}
188
196module_init(ep7312_init); 189module_init(ep7312_init);
197 190
198/* 191/*
199 * Clean up routine 192 * Clean up routine
200 */ 193 */
201static void __exit ep7312_cleanup (void) 194static void __exit ep7312_cleanup(void)
202{ 195{
203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; 196 struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
204 197
205 /* Release resources, unregister device */ 198 /* Release resources, unregister device */
206 nand_release (ap7312_mtd); 199 nand_release(ap7312_mtd);
207
208 /* Free internal data buffer */
209 kfree (this->data_buf);
210 200
211 /* Free the MTD device structure */ 201 /* Free the MTD device structure */
212 kfree (ep7312_mtd); 202 kfree(ep7312_mtd);
213} 203}
204
214module_exit(ep7312_cleanup); 205module_exit(ep7312_cleanup);
215 206
216MODULE_LICENSE("GPL"); 207MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index f68f7a99a630..2d585d2d090c 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2003 Joshua Wise (joshua@joshuawise.com) 4 * Copyright (C) 2003 Joshua Wise (joshua@joshuawise.com)
5 * 5 *
6 * Derived from drivers/mtd/nand/edb7312.c 6 * Derived from drivers/mtd/nand/edb7312.c
7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) 7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
9 * 9 *
10 * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $ 10 * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
@@ -26,7 +26,7 @@
26#include <linux/mtd/nand.h> 26#include <linux/mtd/nand.h>
27#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */ 29#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
30#include <asm/sizes.h> 30#include <asm/sizes.h>
31#include <asm/arch/h1900-gpio.h> 31#include <asm/arch/h1900-gpio.h>
32#include <asm/arch/ipaq.h> 32#include <asm/arch/ipaq.h>
@@ -45,47 +45,29 @@ static struct mtd_info *h1910_nand_mtd = NULL;
45 * Define static partitions for flash device 45 * Define static partitions for flash device
46 */ 46 */
47static struct mtd_partition partition_info[] = { 47static struct mtd_partition partition_info[] = {
48 { name: "h1910 NAND Flash", 48 {name:"h1910 NAND Flash",
49 offset: 0, 49 offset:0,
50 size: 16*1024*1024 } 50 size:16 * 1024 * 1024}
51}; 51};
52
52#define NUM_PARTITIONS 1 53#define NUM_PARTITIONS 1
53 54
54#endif 55#endif
55 56
56
57/* 57/*
58 * hardware specific access to control-lines 58 * hardware specific access to control-lines
59 *
60 * NAND_NCE: bit 0 - don't care
61 * NAND_CLE: bit 1 - address bit 2
62 * NAND_ALE: bit 2 - address bit 3
59 */ 63 */
60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) 64static void h1910_hwcontrol(struct mtd_info *mtd, int cmd,
65 unsigned int ctrl)
61{ 66{
62 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 67 struct nand_chip *chip = mtd->priv;
63 68
64 switch(cmd) { 69 if (cmd != NAND_CMD_NONE)
65 70 writeb(cmd, chip->IO_ADDR_W | ((ctrl & 0x6) << 1));
66 case NAND_CTL_SETCLE:
67 this->IO_ADDR_R |= (1 << 2);
68 this->IO_ADDR_W |= (1 << 2);
69 break;
70 case NAND_CTL_CLRCLE:
71 this->IO_ADDR_R &= ~(1 << 2);
72 this->IO_ADDR_W &= ~(1 << 2);
73 break;
74
75 case NAND_CTL_SETALE:
76 this->IO_ADDR_R |= (1 << 3);
77 this->IO_ADDR_W |= (1 << 3);
78 break;
79 case NAND_CTL_CLRALE:
80 this->IO_ADDR_R &= ~(1 << 3);
81 this->IO_ADDR_W &= ~(1 << 3);
82 break;
83
84 case NAND_CTL_SETNCE:
85 break;
86 case NAND_CTL_CLRNCE:
87 break;
88 }
89} 71}
90 72
91/* 73/*
@@ -101,7 +83,7 @@ static int h1910_device_ready(struct mtd_info *mtd)
101/* 83/*
102 * Main initialization routine 84 * Main initialization routine
103 */ 85 */
104static int __init h1910_init (void) 86static int __init h1910_init(void)
105{ 87{
106 struct nand_chip *this; 88 struct nand_chip *this;
107 const char *part_type = 0; 89 const char *part_type = 0;
@@ -119,24 +101,23 @@ static int __init h1910_init (void)
119 } 101 }
120 102
121 /* Allocate memory for MTD device structure and private data */ 103 /* Allocate memory for MTD device structure and private data */
122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + 104 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
123 sizeof(struct nand_chip),
124 GFP_KERNEL);
125 if (!h1910_nand_mtd) { 105 if (!h1910_nand_mtd) {
126 printk("Unable to allocate h1910 NAND MTD device structure.\n"); 106 printk("Unable to allocate h1910 NAND MTD device structure.\n");
127 iounmap ((void *) nandaddr); 107 iounmap((void *)nandaddr);
128 return -ENOMEM; 108 return -ENOMEM;
129 } 109 }
130 110
131 /* Get pointer to private data */ 111 /* Get pointer to private data */
132 this = (struct nand_chip *) (&h1910_nand_mtd[1]); 112 this = (struct nand_chip *)(&h1910_nand_mtd[1]);
133 113
134 /* Initialize structures */ 114 /* Initialize structures */
135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); 115 memset(h1910_nand_mtd, 0, sizeof(struct mtd_info));
136 memset((char *) this, 0, sizeof(struct nand_chip)); 116 memset(this, 0, sizeof(struct nand_chip));
137 117
138 /* Link the private data with the MTD structure */ 118 /* Link the private data with the MTD structure */
139 h1910_nand_mtd->priv = this; 119 h1910_nand_mtd->priv = this;
120 h1910_nand_mtd->owner = THIS_MODULE;
140 121
141 /* 122 /*
142 * Enable VPEN 123 * Enable VPEN
@@ -146,31 +127,28 @@ static int __init h1910_init (void)
146 /* insert callbacks */ 127 /* insert callbacks */
147 this->IO_ADDR_R = nandaddr; 128 this->IO_ADDR_R = nandaddr;
148 this->IO_ADDR_W = nandaddr; 129 this->IO_ADDR_W = nandaddr;
149 this->hwcontrol = h1910_hwcontrol; 130 this->cmd_ctrl = h1910_hwcontrol;
150 this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ 131 this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */
151 /* 15 us command delay time */ 132 /* 15 us command delay time */
152 this->chip_delay = 50; 133 this->chip_delay = 50;
153 this->eccmode = NAND_ECC_SOFT; 134 this->ecc.mode = NAND_ECC_SOFT;
154 this->options = NAND_NO_AUTOINCR; 135 this->options = NAND_NO_AUTOINCR;
155 136
156 /* Scan to find existence of the device */ 137 /* Scan to find existence of the device */
157 if (nand_scan (h1910_nand_mtd, 1)) { 138 if (nand_scan(h1910_nand_mtd, 1)) {
158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); 139 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
159 kfree (h1910_nand_mtd); 140 kfree(h1910_nand_mtd);
160 iounmap ((void *) nandaddr); 141 iounmap((void *)nandaddr);
161 return -ENXIO; 142 return -ENXIO;
162 } 143 }
163
164#ifdef CONFIG_MTD_CMDLINE_PARTS 144#ifdef CONFIG_MTD_CMDLINE_PARTS
165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, 145 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand");
166 "h1910-nand");
167 if (mtd_parts_nb > 0) 146 if (mtd_parts_nb > 0)
168 part_type = "command line"; 147 part_type = "command line";
169 else 148 else
170 mtd_parts_nb = 0; 149 mtd_parts_nb = 0;
171#endif 150#endif
172 if (mtd_parts_nb == 0) 151 if (mtd_parts_nb == 0) {
173 {
174 mtd_parts = partition_info; 152 mtd_parts = partition_info;
175 mtd_parts_nb = NUM_PARTITIONS; 153 mtd_parts_nb = NUM_PARTITIONS;
176 part_type = "static"; 154 part_type = "static";
@@ -183,24 +161,26 @@ static int __init h1910_init (void)
183 /* Return happy */ 161 /* Return happy */
184 return 0; 162 return 0;
185} 163}
164
186module_init(h1910_init); 165module_init(h1910_init);
187 166
188/* 167/*
189 * Clean up routine 168 * Clean up routine
190 */ 169 */
191static void __exit h1910_cleanup (void) 170static void __exit h1910_cleanup(void)
192{ 171{
193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; 172 struct nand_chip *this = (struct nand_chip *)&h1910_nand_mtd[1];
194 173
195 /* Release resources, unregister device */ 174 /* Release resources, unregister device */
196 nand_release (h1910_nand_mtd); 175 nand_release(h1910_nand_mtd);
197 176
198 /* Release io resource */ 177 /* Release io resource */
199 iounmap ((void *) this->IO_ADDR_W); 178 iounmap((void *)this->IO_ADDR_W);
200 179
201 /* Free the MTD device structure */ 180 /* Free the MTD device structure */
202 kfree (h1910_nand_mtd); 181 kfree(h1910_nand_mtd);
203} 182}
183
204module_exit(h1910_cleanup); 184module_exit(h1910_cleanup);
205 185
206MODULE_LICENSE("GPL"); 186MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 95e96fa1fceb..27083ed0a017 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -10,67 +10,31 @@
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/tech/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002 Thomas Gleixner (tglx@linutronix.de) 13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
14 * 14 *
15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment 15 * Credits:
16 * pages on read / read_oob
17 *
18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
19 * pointed this out, as he marked an auto increment capable chip
20 * as NOAUTOINCR in the board driver.
21 * Make reads over block boundaries work too
22 *
23 * 04-14-2004 tglx: first working version for 2k page size chips
24 *
25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
26 *
27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
28 * among multiple independend devices. Suggestions and initial patch
29 * from Ben Dooks <ben-mtd@fluff.org>
30 *
31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
32 * Basically, any block not rewritten may lose data when surrounding blocks
33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
35 * do not lose data, force them to be rewritten when some of the surrounding
36 * blocks are erased. Rather than tracking a specific nearby block (which
37 * could itself go bad), use a page address 'mask' to select several blocks
38 * in the same area, and rewrite the BBT when any of them are erased.
39 *
40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
41 * AG-AND chips. If there was a sudden loss of power during an erase operation,
42 * a "device recovery" operation must be performed when power is restored
43 * to ensure correct operation.
44 *
45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
46 * perform extra error status checks on erase and write failures. This required
47 * adding a wrapper function for nand_read_ecc.
48 *
49 * 08-20-2005 vwool: suspend/resume added
50 *
51 * Credits:
52 * David Woodhouse for adding multichip support 16 * David Woodhouse for adding multichip support
53 * 17 *
54 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the 18 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
55 * rework for 2K page size chips 19 * rework for 2K page size chips
56 * 20 *
57 * TODO: 21 * TODO:
58 * Enable cached programming for 2k page size chips 22 * Enable cached programming for 2k page size chips
59 * Check, if mtd->ecctype should be set to MTD_ECC_HW 23 * Check, if mtd->ecctype should be set to MTD_ECC_HW
60 * if we have HW ecc support. 24 * if we have HW ecc support.
61 * The AG-AND chips have nice features for speed improvement, 25 * The AG-AND chips have nice features for speed improvement,
62 * which are not supported yet. Read / program 4 pages in one go. 26 * which are not supported yet. Read / program 4 pages in one go.
63 * 27 *
64 * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
65 *
66 * This program is free software; you can redistribute it and/or modify 28 * This program is free software; you can redistribute it and/or modify
67 * it under the terms of the GNU General Public License version 2 as 29 * it under the terms of the GNU General Public License version 2 as
68 * published by the Free Software Foundation. 30 * published by the Free Software Foundation.
69 * 31 *
70 */ 32 */
71 33
34#include <linux/module.h>
72#include <linux/delay.h> 35#include <linux/delay.h>
73#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/err.h>
74#include <linux/sched.h> 38#include <linux/sched.h>
75#include <linux/slab.h> 39#include <linux/slab.h>
76#include <linux/types.h> 40#include <linux/types.h>
@@ -88,75 +52,46 @@
88#endif 52#endif
89 53
90/* Define default oob placement schemes for large and small page devices */ 54/* Define default oob placement schemes for large and small page devices */
91static struct nand_oobinfo nand_oob_8 = { 55static struct nand_ecclayout nand_oob_8 = {
92 .useecc = MTD_NANDECC_AUTOPLACE,
93 .eccbytes = 3, 56 .eccbytes = 3,
94 .eccpos = {0, 1, 2}, 57 .eccpos = {0, 1, 2},
95 .oobfree = { {3, 2}, {6, 2} } 58 .oobfree = {
59 {.offset = 3,
60 .length = 2},
61 {.offset = 6,
62 .length = 2}}
96}; 63};
97 64
98static struct nand_oobinfo nand_oob_16 = { 65static struct nand_ecclayout nand_oob_16 = {
99 .useecc = MTD_NANDECC_AUTOPLACE,
100 .eccbytes = 6, 66 .eccbytes = 6,
101 .eccpos = {0, 1, 2, 3, 6, 7}, 67 .eccpos = {0, 1, 2, 3, 6, 7},
102 .oobfree = { {8, 8} } 68 .oobfree = {
69 {.offset = 8,
70 . length = 8}}
103}; 71};
104 72
105static struct nand_oobinfo nand_oob_64 = { 73static struct nand_ecclayout nand_oob_64 = {
106 .useecc = MTD_NANDECC_AUTOPLACE,
107 .eccbytes = 24, 74 .eccbytes = 24,
108 .eccpos = { 75 .eccpos = {
109 40, 41, 42, 43, 44, 45, 46, 47, 76 40, 41, 42, 43, 44, 45, 46, 47,
110 48, 49, 50, 51, 52, 53, 54, 55, 77 48, 49, 50, 51, 52, 53, 54, 55,
111 56, 57, 58, 59, 60, 61, 62, 63}, 78 56, 57, 58, 59, 60, 61, 62, 63},
112 .oobfree = { {2, 38} } 79 .oobfree = {
80 {.offset = 2,
81 .length = 38}}
113}; 82};
114 83
115/* This is used for padding purposes in nand_write_oob */ 84static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
116static u_char ffchars[] = { 85 int new_state);
117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 86
118 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 87static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
119 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 88 struct mtd_oob_ops *ops);
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
123 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
124 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
125};
126 89
127/* 90/*
128 * NAND low-level MTD interface functions 91 * For devices which display every fart in the system on a seperate LED. Is
92 * compiled away when LED support is disabled.
129 */ 93 */
130static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); 94DEFINE_LED_TRIGGER(nand_led_trigger);
131static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
132static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
133
134static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
135static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
136 size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
137static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
138static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
139static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
140 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
141static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
142static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
143 unsigned long count, loff_t to, size_t * retlen);
144static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
145 unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
146static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
147static void nand_sync (struct mtd_info *mtd);
148
149/* Some internal functions */
150static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
151 struct nand_oobinfo *oobsel, int mode);
152#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
153static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
154 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
155#else
156#define nand_verify_pages(...) (0)
157#endif
158
159static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
160 95
161/** 96/**
162 * nand_release_device - [GENERIC] release chip 97 * nand_release_device - [GENERIC] release chip
@@ -164,27 +99,19 @@ static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int ne
164 * 99 *
165 * Deselect, release chip lock and wake up anyone waiting on the device 100 * Deselect, release chip lock and wake up anyone waiting on the device
166 */ 101 */
167static void nand_release_device (struct mtd_info *mtd) 102static void nand_release_device(struct mtd_info *mtd)
168{ 103{
169 struct nand_chip *this = mtd->priv; 104 struct nand_chip *chip = mtd->priv;
170 105
171 /* De-select the NAND device */ 106 /* De-select the NAND device */
172 this->select_chip(mtd, -1); 107 chip->select_chip(mtd, -1);
173 108
174 if (this->controller) { 109 /* Release the controller and the chip */
175 /* Release the controller and the chip */ 110 spin_lock(&chip->controller->lock);
176 spin_lock(&this->controller->lock); 111 chip->controller->active = NULL;
177 this->controller->active = NULL; 112 chip->state = FL_READY;
178 this->state = FL_READY; 113 wake_up(&chip->controller->wq);
179 wake_up(&this->controller->wq); 114 spin_unlock(&chip->controller->lock);
180 spin_unlock(&this->controller->lock);
181 } else {
182 /* Release the chip */
183 spin_lock(&this->chip_lock);
184 this->state = FL_READY;
185 wake_up(&this->wq);
186 spin_unlock(&this->chip_lock);
187 }
188} 115}
189 116
190/** 117/**
@@ -193,23 +120,10 @@ static void nand_release_device (struct mtd_info *mtd)
193 * 120 *
194 * Default read function for 8bit buswith 121 * Default read function for 8bit buswith
195 */ 122 */
196static u_char nand_read_byte(struct mtd_info *mtd) 123static uint8_t nand_read_byte(struct mtd_info *mtd)
197{
198 struct nand_chip *this = mtd->priv;
199 return readb(this->IO_ADDR_R);
200}
201
202/**
203 * nand_write_byte - [DEFAULT] write one byte to the chip
204 * @mtd: MTD device structure
205 * @byte: pointer to data byte to write
206 *
207 * Default write function for 8it buswith
208 */
209static void nand_write_byte(struct mtd_info *mtd, u_char byte)
210{ 124{
211 struct nand_chip *this = mtd->priv; 125 struct nand_chip *chip = mtd->priv;
212 writeb(byte, this->IO_ADDR_W); 126 return readb(chip->IO_ADDR_R);
213} 127}
214 128
215/** 129/**
@@ -219,24 +133,10 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
219 * Default read function for 16bit buswith with 133 * Default read function for 16bit buswith with
220 * endianess conversion 134 * endianess conversion
221 */ 135 */
222static u_char nand_read_byte16(struct mtd_info *mtd) 136static uint8_t nand_read_byte16(struct mtd_info *mtd)
223{ 137{
224 struct nand_chip *this = mtd->priv; 138 struct nand_chip *chip = mtd->priv;
225 return (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); 139 return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
226}
227
228/**
229 * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
230 * @mtd: MTD device structure
231 * @byte: pointer to data byte to write
232 *
233 * Default write function for 16bit buswith with
234 * endianess conversion
235 */
236static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
237{
238 struct nand_chip *this = mtd->priv;
239 writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
240} 140}
241 141
242/** 142/**
@@ -248,22 +148,8 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
248 */ 148 */
249static u16 nand_read_word(struct mtd_info *mtd) 149static u16 nand_read_word(struct mtd_info *mtd)
250{ 150{
251 struct nand_chip *this = mtd->priv; 151 struct nand_chip *chip = mtd->priv;
252 return readw(this->IO_ADDR_R); 152 return readw(chip->IO_ADDR_R);
253}
254
255/**
256 * nand_write_word - [DEFAULT] write one word to the chip
257 * @mtd: MTD device structure
258 * @word: data word to write
259 *
260 * Default write function for 16bit buswith without
261 * endianess conversion
262 */
263static void nand_write_word(struct mtd_info *mtd, u16 word)
264{
265 struct nand_chip *this = mtd->priv;
266 writew(word, this->IO_ADDR_W);
267} 153}
268 154
269/** 155/**
@@ -273,15 +159,15 @@ static void nand_write_word(struct mtd_info *mtd, u16 word)
273 * 159 *
274 * Default select function for 1 chip devices. 160 * Default select function for 1 chip devices.
275 */ 161 */
276static void nand_select_chip(struct mtd_info *mtd, int chip) 162static void nand_select_chip(struct mtd_info *mtd, int chipnr)
277{ 163{
278 struct nand_chip *this = mtd->priv; 164 struct nand_chip *chip = mtd->priv;
279 switch(chip) { 165
166 switch (chipnr) {
280 case -1: 167 case -1:
281 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 168 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
282 break; 169 break;
283 case 0: 170 case 0:
284 this->hwcontrol(mtd, NAND_CTL_SETNCE);
285 break; 171 break;
286 172
287 default: 173 default:
@@ -297,13 +183,13 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
297 * 183 *
298 * Default write function for 8bit buswith 184 * Default write function for 8bit buswith
299 */ 185 */
300static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 186static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
301{ 187{
302 int i; 188 int i;
303 struct nand_chip *this = mtd->priv; 189 struct nand_chip *chip = mtd->priv;
304 190
305 for (i=0; i<len; i++) 191 for (i = 0; i < len; i++)
306 writeb(buf[i], this->IO_ADDR_W); 192 writeb(buf[i], chip->IO_ADDR_W);
307} 193}
308 194
309/** 195/**
@@ -314,13 +200,13 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
314 * 200 *
315 * Default read function for 8bit buswith 201 * Default read function for 8bit buswith
316 */ 202 */
317static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 203static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
318{ 204{
319 int i; 205 int i;
320 struct nand_chip *this = mtd->priv; 206 struct nand_chip *chip = mtd->priv;
321 207
322 for (i=0; i<len; i++) 208 for (i = 0; i < len; i++)
323 buf[i] = readb(this->IO_ADDR_R); 209 buf[i] = readb(chip->IO_ADDR_R);
324} 210}
325 211
326/** 212/**
@@ -331,15 +217,14 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
331 * 217 *
332 * Default verify function for 8bit buswith 218 * Default verify function for 8bit buswith
333 */ 219 */
334static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) 220static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
335{ 221{
336 int i; 222 int i;
337 struct nand_chip *this = mtd->priv; 223 struct nand_chip *chip = mtd->priv;
338 224
339 for (i=0; i<len; i++) 225 for (i = 0; i < len; i++)
340 if (buf[i] != readb(this->IO_ADDR_R)) 226 if (buf[i] != readb(chip->IO_ADDR_R))
341 return -EFAULT; 227 return -EFAULT;
342
343 return 0; 228 return 0;
344} 229}
345 230
@@ -351,15 +236,15 @@ static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
351 * 236 *
352 * Default write function for 16bit buswith 237 * Default write function for 16bit buswith
353 */ 238 */
354static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) 239static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
355{ 240{
356 int i; 241 int i;
357 struct nand_chip *this = mtd->priv; 242 struct nand_chip *chip = mtd->priv;
358 u16 *p = (u16 *) buf; 243 u16 *p = (u16 *) buf;
359 len >>= 1; 244 len >>= 1;
360 245
361 for (i=0; i<len; i++) 246 for (i = 0; i < len; i++)
362 writew(p[i], this->IO_ADDR_W); 247 writew(p[i], chip->IO_ADDR_W);
363 248
364} 249}
365 250
@@ -371,15 +256,15 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
371 * 256 *
372 * Default read function for 16bit buswith 257 * Default read function for 16bit buswith
373 */ 258 */
374static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) 259static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
375{ 260{
376 int i; 261 int i;
377 struct nand_chip *this = mtd->priv; 262 struct nand_chip *chip = mtd->priv;
378 u16 *p = (u16 *) buf; 263 u16 *p = (u16 *) buf;
379 len >>= 1; 264 len >>= 1;
380 265
381 for (i=0; i<len; i++) 266 for (i = 0; i < len; i++)
382 p[i] = readw(this->IO_ADDR_R); 267 p[i] = readw(chip->IO_ADDR_R);
383} 268}
384 269
385/** 270/**
@@ -390,15 +275,15 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
390 * 275 *
391 * Default verify function for 16bit buswith 276 * Default verify function for 16bit buswith
392 */ 277 */
393static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) 278static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
394{ 279{
395 int i; 280 int i;
396 struct nand_chip *this = mtd->priv; 281 struct nand_chip *chip = mtd->priv;
397 u16 *p = (u16 *) buf; 282 u16 *p = (u16 *) buf;
398 len >>= 1; 283 len >>= 1;
399 284
400 for (i=0; i<len; i++) 285 for (i = 0; i < len; i++)
401 if (p[i] != readw(this->IO_ADDR_R)) 286 if (p[i] != readw(chip->IO_ADDR_R))
402 return -EFAULT; 287 return -EFAULT;
403 288
404 return 0; 289 return 0;
@@ -415,38 +300,37 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
415static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 300static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
416{ 301{
417 int page, chipnr, res = 0; 302 int page, chipnr, res = 0;
418 struct nand_chip *this = mtd->priv; 303 struct nand_chip *chip = mtd->priv;
419 u16 bad; 304 u16 bad;
420 305
421 if (getchip) { 306 if (getchip) {
422 page = (int)(ofs >> this->page_shift); 307 page = (int)(ofs >> chip->page_shift);
423 chipnr = (int)(ofs >> this->chip_shift); 308 chipnr = (int)(ofs >> chip->chip_shift);
424 309
425 /* Grab the lock and see if the device is available */ 310 nand_get_device(chip, mtd, FL_READING);
426 nand_get_device (this, mtd, FL_READING);
427 311
428 /* Select the NAND device */ 312 /* Select the NAND device */
429 this->select_chip(mtd, chipnr); 313 chip->select_chip(mtd, chipnr);
430 } else 314 } else
431 page = (int) ofs; 315 page = (int)ofs;
432 316
433 if (this->options & NAND_BUSWIDTH_16) { 317 if (chip->options & NAND_BUSWIDTH_16) {
434 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); 318 chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
435 bad = cpu_to_le16(this->read_word(mtd)); 319 page & chip->pagemask);
436 if (this->badblockpos & 0x1) 320 bad = cpu_to_le16(chip->read_word(mtd));
321 if (chip->badblockpos & 0x1)
437 bad >>= 8; 322 bad >>= 8;
438 if ((bad & 0xFF) != 0xff) 323 if ((bad & 0xFF) != 0xff)
439 res = 1; 324 res = 1;
440 } else { 325 } else {
441 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask); 326 chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
442 if (this->read_byte(mtd) != 0xff) 327 page & chip->pagemask);
328 if (chip->read_byte(mtd) != 0xff)
443 res = 1; 329 res = 1;
444 } 330 }
445 331
446 if (getchip) { 332 if (getchip)
447 /* Deselect and wake up anyone waiting on the device */
448 nand_release_device(mtd); 333 nand_release_device(mtd);
449 }
450 334
451 return res; 335 return res;
452} 336}
@@ -461,23 +345,33 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
461*/ 345*/
462static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) 346static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
463{ 347{
464 struct nand_chip *this = mtd->priv; 348 struct nand_chip *chip = mtd->priv;
465 u_char buf[2] = {0, 0}; 349 uint8_t buf[2] = { 0, 0 };
466 size_t retlen; 350 int block, ret;
467 int block;
468 351
469 /* Get block number */ 352 /* Get block number */
470 block = ((int) ofs) >> this->bbt_erase_shift; 353 block = ((int)ofs) >> chip->bbt_erase_shift;
471 if (this->bbt) 354 if (chip->bbt)
472 this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); 355 chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
473 356
474 /* Do we have a flash based bad block table ? */ 357 /* Do we have a flash based bad block table ? */
475 if (this->options & NAND_USE_FLASH_BBT) 358 if (chip->options & NAND_USE_FLASH_BBT)
476 return nand_update_bbt (mtd, ofs); 359 ret = nand_update_bbt(mtd, ofs);
360 else {
361 /* We write two bytes, so we dont have to mess with 16 bit
362 * access
363 */
364 ofs += mtd->oobsize;
365 chip->ops.len = 2;
366 chip->ops.datbuf = NULL;
367 chip->ops.oobbuf = buf;
368 chip->ops.ooboffs = chip->badblockpos & ~0x01;
477 369
478 /* We write two bytes, so we dont have to mess with 16 bit access */ 370 ret = nand_do_write_oob(mtd, ofs, &chip->ops);
479 ofs += mtd->oobsize + (this->badblockpos & ~0x01); 371 }
480 return nand_write_oob (mtd, ofs , 2, &retlen, buf); 372 if (!ret)
373 mtd->ecc_stats.badblocks++;
374 return ret;
481} 375}
482 376
483/** 377/**
@@ -487,12 +381,12 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
487 * 381 *
488 * The function expects, that the device is already selected 382 * The function expects, that the device is already selected
489 */ 383 */
490static int nand_check_wp (struct mtd_info *mtd) 384static int nand_check_wp(struct mtd_info *mtd)
491{ 385{
492 struct nand_chip *this = mtd->priv; 386 struct nand_chip *chip = mtd->priv;
493 /* Check the WP bit */ 387 /* Check the WP bit */
494 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 388 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
495 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; 389 return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
496} 390}
497 391
498/** 392/**
@@ -505,32 +399,31 @@ static int nand_check_wp (struct mtd_info *mtd)
505 * Check, if the block is bad. Either by reading the bad block table or 399 * Check, if the block is bad. Either by reading the bad block table or
506 * calling of the scan function. 400 * calling of the scan function.
507 */ 401 */
508static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) 402static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
403 int allowbbt)
509{ 404{
510 struct nand_chip *this = mtd->priv; 405 struct nand_chip *chip = mtd->priv;
511 406
512 if (!this->bbt) 407 if (!chip->bbt)
513 return this->block_bad(mtd, ofs, getchip); 408 return chip->block_bad(mtd, ofs, getchip);
514 409
515 /* Return info from the table */ 410 /* Return info from the table */
516 return nand_isbad_bbt (mtd, ofs, allowbbt); 411 return nand_isbad_bbt(mtd, ofs, allowbbt);
517} 412}
518 413
519DEFINE_LED_TRIGGER(nand_led_trigger);
520
521/* 414/*
522 * Wait for the ready pin, after a command 415 * Wait for the ready pin, after a command
523 * The timeout is catched later. 416 * The timeout is catched later.
524 */ 417 */
525static void nand_wait_ready(struct mtd_info *mtd) 418static void nand_wait_ready(struct mtd_info *mtd)
526{ 419{
527 struct nand_chip *this = mtd->priv; 420 struct nand_chip *chip = mtd->priv;
528 unsigned long timeo = jiffies + 2; 421 unsigned long timeo = jiffies + 2;
529 422
530 led_trigger_event(nand_led_trigger, LED_FULL); 423 led_trigger_event(nand_led_trigger, LED_FULL);
531 /* wait until command is processed or timeout occures */ 424 /* wait until command is processed or timeout occures */
532 do { 425 do {
533 if (this->dev_ready(mtd)) 426 if (chip->dev_ready(mtd))
534 break; 427 break;
535 touch_softlockup_watchdog(); 428 touch_softlockup_watchdog();
536 } while (time_before(jiffies, timeo)); 429 } while (time_before(jiffies, timeo));
@@ -547,21 +440,21 @@ static void nand_wait_ready(struct mtd_info *mtd)
547 * Send command to NAND device. This function is used for small page 440 * Send command to NAND device. This function is used for small page
548 * devices (256/512 Bytes per page) 441 * devices (256/512 Bytes per page)
549 */ 442 */
550static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) 443static void nand_command(struct mtd_info *mtd, unsigned int command,
444 int column, int page_addr)
551{ 445{
552 register struct nand_chip *this = mtd->priv; 446 register struct nand_chip *chip = mtd->priv;
447 int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
553 448
554 /* Begin command latch cycle */
555 this->hwcontrol(mtd, NAND_CTL_SETCLE);
556 /* 449 /*
557 * Write out the command to the device. 450 * Write out the command to the device.
558 */ 451 */
559 if (command == NAND_CMD_SEQIN) { 452 if (command == NAND_CMD_SEQIN) {
560 int readcmd; 453 int readcmd;
561 454
562 if (column >= mtd->oobblock) { 455 if (column >= mtd->writesize) {
563 /* OOB area */ 456 /* OOB area */
564 column -= mtd->oobblock; 457 column -= mtd->writesize;
565 readcmd = NAND_CMD_READOOB; 458 readcmd = NAND_CMD_READOOB;
566 } else if (column < 256) { 459 } else if (column < 256) {
567 /* First 256 bytes --> READ0 */ 460 /* First 256 bytes --> READ0 */
@@ -570,38 +463,37 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
570 column -= 256; 463 column -= 256;
571 readcmd = NAND_CMD_READ1; 464 readcmd = NAND_CMD_READ1;
572 } 465 }
573 this->write_byte(mtd, readcmd); 466 chip->cmd_ctrl(mtd, readcmd, ctrl);
467 ctrl &= ~NAND_CTRL_CHANGE;
574 } 468 }
575 this->write_byte(mtd, command); 469 chip->cmd_ctrl(mtd, command, ctrl);
576
577 /* Set ALE and clear CLE to start address cycle */
578 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
579 470
580 if (column != -1 || page_addr != -1) { 471 /*
581 this->hwcontrol(mtd, NAND_CTL_SETALE); 472 * Address cycle, when necessary
582 473 */
583 /* Serially input address */ 474 ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
584 if (column != -1) { 475 /* Serially input address */
585 /* Adjust columns for 16 bit buswidth */ 476 if (column != -1) {
586 if (this->options & NAND_BUSWIDTH_16) 477 /* Adjust columns for 16 bit buswidth */
587 column >>= 1; 478 if (chip->options & NAND_BUSWIDTH_16)
588 this->write_byte(mtd, column); 479 column >>= 1;
589 } 480 chip->cmd_ctrl(mtd, column, ctrl);
590 if (page_addr != -1) { 481 ctrl &= ~NAND_CTRL_CHANGE;
591 this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); 482 }
592 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); 483 if (page_addr != -1) {
593 /* One more address cycle for devices > 32MiB */ 484 chip->cmd_ctrl(mtd, page_addr, ctrl);
594 if (this->chipsize > (32 << 20)) 485 ctrl &= ~NAND_CTRL_CHANGE;
595 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); 486 chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
596 } 487 /* One more address cycle for devices > 32MiB */
597 /* Latch in address */ 488 if (chip->chipsize > (32 << 20))
598 this->hwcontrol(mtd, NAND_CTL_CLRALE); 489 chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
599 } 490 }
491 chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
600 492
601 /* 493 /*
602 * program and erase have their own busy handlers 494 * program and erase have their own busy handlers
603 * status and sequential in needs no delay 495 * status and sequential in needs no delay
604 */ 496 */
605 switch (command) { 497 switch (command) {
606 498
607 case NAND_CMD_PAGEPROG: 499 case NAND_CMD_PAGEPROG:
@@ -612,29 +504,30 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
612 return; 504 return;
613 505
614 case NAND_CMD_RESET: 506 case NAND_CMD_RESET:
615 if (this->dev_ready) 507 if (chip->dev_ready)
616 break; 508 break;
617 udelay(this->chip_delay); 509 udelay(chip->chip_delay);
618 this->hwcontrol(mtd, NAND_CTL_SETCLE); 510 chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
619 this->write_byte(mtd, NAND_CMD_STATUS); 511 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
620 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 512 chip->cmd_ctrl(mtd,
621 while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); 513 NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
514 while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
622 return; 515 return;
623 516
624 /* This applies to read commands */ 517 /* This applies to read commands */
625 default: 518 default:
626 /* 519 /*
627 * If we don't have access to the busy pin, we apply the given 520 * If we don't have access to the busy pin, we apply the given
628 * command delay 521 * command delay
629 */ 522 */
630 if (!this->dev_ready) { 523 if (!chip->dev_ready) {
631 udelay (this->chip_delay); 524 udelay(chip->chip_delay);
632 return; 525 return;
633 } 526 }
634 } 527 }
635 /* Apply this short delay always to ensure that we do wait tWB in 528 /* Apply this short delay always to ensure that we do wait tWB in
636 * any case on any machine. */ 529 * any case on any machine. */
637 ndelay (100); 530 ndelay(100);
638 531
639 nand_wait_ready(mtd); 532 nand_wait_ready(mtd);
640} 533}
@@ -646,50 +539,49 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
646 * @column: the column address for this command, -1 if none 539 * @column: the column address for this command, -1 if none
647 * @page_addr: the page address for this command, -1 if none 540 * @page_addr: the page address for this command, -1 if none
648 * 541 *
649 * Send command to NAND device. This is the version for the new large page devices 542 * Send command to NAND device. This is the version for the new large page
650 * We dont have the seperate regions as we have in the small page devices. 543 * devices We dont have the separate regions as we have in the small page
651 * We must emulate NAND_CMD_READOOB to keep the code compatible. 544 * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
652 * 545 *
653 */ 546 */
654static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) 547static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
548 int column, int page_addr)
655{ 549{
656 register struct nand_chip *this = mtd->priv; 550 register struct nand_chip *chip = mtd->priv;
657 551
658 /* Emulate NAND_CMD_READOOB */ 552 /* Emulate NAND_CMD_READOOB */
659 if (command == NAND_CMD_READOOB) { 553 if (command == NAND_CMD_READOOB) {
660 column += mtd->oobblock; 554 column += mtd->writesize;
661 command = NAND_CMD_READ0; 555 command = NAND_CMD_READ0;
662 } 556 }
663 557
664 558 /* Command latch cycle */
665 /* Begin command latch cycle */ 559 chip->cmd_ctrl(mtd, command & 0xff,
666 this->hwcontrol(mtd, NAND_CTL_SETCLE); 560 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
667 /* Write out the command to the device. */
668 this->write_byte(mtd, (command & 0xff));
669 /* End command latch cycle */
670 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
671 561
672 if (column != -1 || page_addr != -1) { 562 if (column != -1 || page_addr != -1) {
673 this->hwcontrol(mtd, NAND_CTL_SETALE); 563 int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
674 564
675 /* Serially input address */ 565 /* Serially input address */
676 if (column != -1) { 566 if (column != -1) {
677 /* Adjust columns for 16 bit buswidth */ 567 /* Adjust columns for 16 bit buswidth */
678 if (this->options & NAND_BUSWIDTH_16) 568 if (chip->options & NAND_BUSWIDTH_16)
679 column >>= 1; 569 column >>= 1;
680 this->write_byte(mtd, column & 0xff); 570 chip->cmd_ctrl(mtd, column, ctrl);
681 this->write_byte(mtd, column >> 8); 571 ctrl &= ~NAND_CTRL_CHANGE;
572 chip->cmd_ctrl(mtd, column >> 8, ctrl);
682 } 573 }
683 if (page_addr != -1) { 574 if (page_addr != -1) {
684 this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); 575 chip->cmd_ctrl(mtd, page_addr, ctrl);
685 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); 576 chip->cmd_ctrl(mtd, page_addr >> 8,
577 NAND_NCE | NAND_ALE);
686 /* One more address cycle for devices > 128MiB */ 578 /* One more address cycle for devices > 128MiB */
687 if (this->chipsize > (128 << 20)) 579 if (chip->chipsize > (128 << 20))
688 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); 580 chip->cmd_ctrl(mtd, page_addr >> 16,
581 NAND_NCE | NAND_ALE);
689 } 582 }
690 /* Latch in address */
691 this->hwcontrol(mtd, NAND_CTL_CLRALE);
692 } 583 }
584 chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
693 585
694 /* 586 /*
695 * program and erase have their own busy handlers 587 * program and erase have their own busy handlers
@@ -702,55 +594,62 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
702 case NAND_CMD_ERASE1: 594 case NAND_CMD_ERASE1:
703 case NAND_CMD_ERASE2: 595 case NAND_CMD_ERASE2:
704 case NAND_CMD_SEQIN: 596 case NAND_CMD_SEQIN:
597 case NAND_CMD_RNDIN:
705 case NAND_CMD_STATUS: 598 case NAND_CMD_STATUS:
706 case NAND_CMD_DEPLETE1: 599 case NAND_CMD_DEPLETE1:
707 return; 600 return;
708 601
709 /* 602 /*
710 * read error status commands require only a short delay 603 * read error status commands require only a short delay
711 */ 604 */
712 case NAND_CMD_STATUS_ERROR: 605 case NAND_CMD_STATUS_ERROR:
713 case NAND_CMD_STATUS_ERROR0: 606 case NAND_CMD_STATUS_ERROR0:
714 case NAND_CMD_STATUS_ERROR1: 607 case NAND_CMD_STATUS_ERROR1:
715 case NAND_CMD_STATUS_ERROR2: 608 case NAND_CMD_STATUS_ERROR2:
716 case NAND_CMD_STATUS_ERROR3: 609 case NAND_CMD_STATUS_ERROR3:
717 udelay(this->chip_delay); 610 udelay(chip->chip_delay);
718 return; 611 return;
719 612
720 case NAND_CMD_RESET: 613 case NAND_CMD_RESET:
721 if (this->dev_ready) 614 if (chip->dev_ready)
722 break; 615 break;
723 udelay(this->chip_delay); 616 udelay(chip->chip_delay);
724 this->hwcontrol(mtd, NAND_CTL_SETCLE); 617 chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
725 this->write_byte(mtd, NAND_CMD_STATUS); 618 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
726 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 619 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
727 while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); 620 NAND_NCE | NAND_CTRL_CHANGE);
621 while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
622 return;
623
624 case NAND_CMD_RNDOUT:
625 /* No ready / busy check necessary */
626 chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
627 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
628 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
629 NAND_NCE | NAND_CTRL_CHANGE);
728 return; 630 return;
729 631
730 case NAND_CMD_READ0: 632 case NAND_CMD_READ0:
731 /* Begin command latch cycle */ 633 chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
732 this->hwcontrol(mtd, NAND_CTL_SETCLE); 634 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
733 /* Write out the start read command */ 635 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
734 this->write_byte(mtd, NAND_CMD_READSTART); 636 NAND_NCE | NAND_CTRL_CHANGE);
735 /* End command latch cycle */ 637
736 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 638 /* This applies to read commands */
737 /* Fall through into ready check */
738
739 /* This applies to read commands */
740 default: 639 default:
741 /* 640 /*
742 * If we don't have access to the busy pin, we apply the given 641 * If we don't have access to the busy pin, we apply the given
743 * command delay 642 * command delay
744 */ 643 */
745 if (!this->dev_ready) { 644 if (!chip->dev_ready) {
746 udelay (this->chip_delay); 645 udelay(chip->chip_delay);
747 return; 646 return;
748 } 647 }
749 } 648 }
750 649
751 /* Apply this short delay always to ensure that we do wait tWB in 650 /* Apply this short delay always to ensure that we do wait tWB in
752 * any case on any machine. */ 651 * any case on any machine. */
753 ndelay (100); 652 ndelay(100);
754 653
755 nand_wait_ready(mtd); 654 nand_wait_ready(mtd);
756} 655}
@@ -763,34 +662,28 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
763 * 662 *
764 * Get the device and lock it for exclusive access 663 * Get the device and lock it for exclusive access
765 */ 664 */
766static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) 665static int
666nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
767{ 667{
768 struct nand_chip *active; 668 spinlock_t *lock = &chip->controller->lock;
769 spinlock_t *lock; 669 wait_queue_head_t *wq = &chip->controller->wq;
770 wait_queue_head_t *wq; 670 DECLARE_WAITQUEUE(wait, current);
771 DECLARE_WAITQUEUE (wait, current); 671 retry:
772
773 lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
774 wq = (this->controller) ? &this->controller->wq : &this->wq;
775retry:
776 active = this;
777 spin_lock(lock); 672 spin_lock(lock);
778 673
779 /* Hardware controller shared among independend devices */ 674 /* Hardware controller shared among independend devices */
780 if (this->controller) { 675 /* Hardware controller shared among independend devices */
781 if (this->controller->active) 676 if (!chip->controller->active)
782 active = this->controller->active; 677 chip->controller->active = chip;
783 else 678
784 this->controller->active = this; 679 if (chip->controller->active == chip && chip->state == FL_READY) {
785 } 680 chip->state = new_state;
786 if (active == this && this->state == FL_READY) {
787 this->state = new_state;
788 spin_unlock(lock); 681 spin_unlock(lock);
789 return 0; 682 return 0;
790 } 683 }
791 if (new_state == FL_PM_SUSPENDED) { 684 if (new_state == FL_PM_SUSPENDED) {
792 spin_unlock(lock); 685 spin_unlock(lock);
793 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; 686 return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
794 } 687 }
795 set_current_state(TASK_UNINTERRUPTIBLE); 688 set_current_state(TASK_UNINTERRUPTIBLE);
796 add_wait_queue(wq, &wait); 689 add_wait_queue(wq, &wait);
@@ -804,540 +697,339 @@ retry:
804 * nand_wait - [DEFAULT] wait until the command is done 697 * nand_wait - [DEFAULT] wait until the command is done
805 * @mtd: MTD device structure 698 * @mtd: MTD device structure
806 * @this: NAND chip structure 699 * @this: NAND chip structure
807 * @state: state to select the max. timeout value
808 * 700 *
809 * Wait for command done. This applies to erase and program only 701 * Wait for command done. This applies to erase and program only
810 * Erase can take up to 400ms and program up to 20ms according to 702 * Erase can take up to 400ms and program up to 20ms according to
811 * general NAND and SmartMedia specs 703 * general NAND and SmartMedia specs
812 * 704 *
813*/ 705*/
814static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) 706static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
815{ 707{
816 708
817 unsigned long timeo = jiffies; 709 unsigned long timeo = jiffies;
818 int status; 710 int status, state = chip->state;
819 711
820 if (state == FL_ERASING) 712 if (state == FL_ERASING)
821 timeo += (HZ * 400) / 1000; 713 timeo += (HZ * 400) / 1000;
822 else 714 else
823 timeo += (HZ * 20) / 1000; 715 timeo += (HZ * 20) / 1000;
824 716
825 led_trigger_event(nand_led_trigger, LED_FULL); 717 led_trigger_event(nand_led_trigger, LED_FULL);
826 718
827 /* Apply this short delay always to ensure that we do wait tWB in 719 /* Apply this short delay always to ensure that we do wait tWB in
828 * any case on any machine. */ 720 * any case on any machine. */
829 ndelay (100); 721 ndelay(100);
830 722
831 if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) 723 if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
832 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); 724 chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
833 else 725 else
834 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 726 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
835 727
836 while (time_before(jiffies, timeo)) { 728 while (time_before(jiffies, timeo)) {
837 /* Check, if we were interrupted */ 729 if (chip->dev_ready) {
838 if (this->state != state) 730 if (chip->dev_ready(mtd))
839 return 0;
840
841 if (this->dev_ready) {
842 if (this->dev_ready(mtd))
843 break; 731 break;
844 } else { 732 } else {
845 if (this->read_byte(mtd) & NAND_STATUS_READY) 733 if (chip->read_byte(mtd) & NAND_STATUS_READY)
846 break; 734 break;
847 } 735 }
848 cond_resched(); 736 cond_resched();
849 } 737 }
850 led_trigger_event(nand_led_trigger, LED_OFF); 738 led_trigger_event(nand_led_trigger, LED_OFF);
851 739
852 status = (int) this->read_byte(mtd); 740 status = (int)chip->read_byte(mtd);
853 return status; 741 return status;
854} 742}
855 743
856/** 744/**
857 * nand_write_page - [GENERIC] write one page 745 * nand_read_page_raw - [Intern] read raw page data without ecc
858 * @mtd: MTD device structure 746 * @mtd: mtd info structure
859 * @this: NAND chip structure 747 * @chip: nand chip info structure
860 * @page: startpage inside the chip, must be called with (page & this->pagemask) 748 * @buf: buffer to store read data
861 * @oob_buf: out of band data buffer
862 * @oobsel: out of band selecttion structre
863 * @cached: 1 = enable cached programming if supported by chip
864 *
865 * Nand_page_program function is used for write and writev !
866 * This function will always program a full page of data
867 * If you call it with a non page aligned buffer, you're lost :)
868 *
869 * Cached programming is not supported yet.
870 */ 749 */
871static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, 750static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
872 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) 751 uint8_t *buf)
873{ 752{
874 int i, status; 753 chip->read_buf(mtd, buf, mtd->writesize);
875 u_char ecc_code[32]; 754 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
876 int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; 755 return 0;
877 int *oob_config = oobsel->eccpos; 756}
878 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
879 int eccbytes = 0;
880
881 /* FIXME: Enable cached programming */
882 cached = 0;
883 757
884 /* Send command to begin auto page programming */ 758/**
885 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); 759 * nand_read_page_swecc - {REPLACABLE] software ecc based page read function
760 * @mtd: mtd info structure
761 * @chip: nand chip info structure
762 * @buf: buffer to store read data
763 */
764static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
765 uint8_t *buf)
766{
767 int i, eccsize = chip->ecc.size;
768 int eccbytes = chip->ecc.bytes;
769 int eccsteps = chip->ecc.steps;
770 uint8_t *p = buf;
771 uint8_t *ecc_calc = chip->buffers.ecccalc;
772 uint8_t *ecc_code = chip->buffers.ecccode;
773 int *eccpos = chip->ecc.layout->eccpos;
886 774
887 /* Write out complete page of data, take care of eccmode */ 775 nand_read_page_raw(mtd, chip, buf);
888 switch (eccmode) {
889 /* No ecc, write all */
890 case NAND_ECC_NONE:
891 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
892 this->write_buf(mtd, this->data_poi, mtd->oobblock);
893 break;
894 776
895 /* Software ecc 3/256, write all */ 777 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
896 case NAND_ECC_SOFT: 778 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
897 for (; eccsteps; eccsteps--) {
898 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
899 for (i = 0; i < 3; i++, eccidx++)
900 oob_buf[oob_config[eccidx]] = ecc_code[i];
901 datidx += this->eccsize;
902 }
903 this->write_buf(mtd, this->data_poi, mtd->oobblock);
904 break;
905 default:
906 eccbytes = this->eccbytes;
907 for (; eccsteps; eccsteps--) {
908 /* enable hardware ecc logic for write */
909 this->enable_hwecc(mtd, NAND_ECC_WRITE);
910 this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
911 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
912 for (i = 0; i < eccbytes; i++, eccidx++)
913 oob_buf[oob_config[eccidx]] = ecc_code[i];
914 /* If the hardware ecc provides syndromes then
915 * the ecc code must be written immidiately after
916 * the data bytes (words) */
917 if (this->options & NAND_HWECC_SYNDROME)
918 this->write_buf(mtd, ecc_code, eccbytes);
919 datidx += this->eccsize;
920 }
921 break;
922 }
923 779
924 /* Write out OOB data */ 780 for (i = 0; i < chip->ecc.total; i++)
925 if (this->options & NAND_HWECC_SYNDROME) 781 ecc_code[i] = chip->oob_poi[eccpos[i]];
926 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
927 else
928 this->write_buf(mtd, oob_buf, mtd->oobsize);
929 782
930 /* Send command to actually program the data */ 783 eccsteps = chip->ecc.steps;
931 this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1); 784 p = buf;
932 785
933 if (!cached) { 786 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
934 /* call wait ready function */ 787 int stat;
935 status = this->waitfunc (mtd, this, FL_WRITING);
936 788
937 /* See if operation failed and additional status checks are available */ 789 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
938 if ((status & NAND_STATUS_FAIL) && (this->errstat)) { 790 if (stat == -1)
939 status = this->errstat(mtd, this, FL_WRITING, status, page); 791 mtd->ecc_stats.failed++;
940 } 792 else
941 793 mtd->ecc_stats.corrected += stat;
942 /* See if device thinks it succeeded */
943 if (status & NAND_STATUS_FAIL) {
944 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
945 return -EIO;
946 }
947 } else {
948 /* FIXME: Implement cached programming ! */
949 /* wait until cache is ready*/
950 // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
951 } 794 }
952 return 0; 795 return 0;
953} 796}
954 797
955#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
956/** 798/**
957 * nand_verify_pages - [GENERIC] verify the chip contents after a write 799 * nand_read_page_hwecc - {REPLACABLE] hardware ecc based page read function
958 * @mtd: MTD device structure 800 * @mtd: mtd info structure
959 * @this: NAND chip structure 801 * @chip: nand chip info structure
960 * @page: startpage inside the chip, must be called with (page & this->pagemask) 802 * @buf: buffer to store read data
961 * @numpages: number of pages to verify
962 * @oob_buf: out of band data buffer
963 * @oobsel: out of band selecttion structre
964 * @chipnr: number of the current chip
965 * @oobmode: 1 = full buffer verify, 0 = ecc only
966 * 803 *
967 * The NAND device assumes that it is always writing to a cleanly erased page. 804 * Not for syndrome calculating ecc controllers which need a special oob layout
968 * Hence, it performs its internal write verification only on bits that
969 * transitioned from 1 to 0. The device does NOT verify the whole page on a
970 * byte by byte basis. It is possible that the page was not completely erased
971 * or the page is becoming unusable due to wear. The read with ECC would catch
972 * the error later when the ECC page check fails, but we would rather catch
973 * it early in the page write stage. Better to write no data than invalid data.
974 */ 805 */
975static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 806static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
976 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) 807 uint8_t *buf)
977{ 808{
978 int i, j, datidx = 0, oobofs = 0, res = -EIO; 809 int i, eccsize = chip->ecc.size;
979 int eccsteps = this->eccsteps; 810 int eccbytes = chip->ecc.bytes;
980 int hweccbytes; 811 int eccsteps = chip->ecc.steps;
981 u_char oobdata[64]; 812 uint8_t *p = buf;
982 813 uint8_t *ecc_calc = chip->buffers.ecccalc;
983 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; 814 uint8_t *ecc_code = chip->buffers.ecccode;
984 815 int *eccpos = chip->ecc.layout->eccpos;
985 /* Send command to read back the first page */ 816
986 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); 817 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
987 818 chip->ecc.hwctl(mtd, NAND_ECC_READ);
988 for(;;) { 819 chip->read_buf(mtd, p, eccsize);
989 for (j = 0; j < eccsteps; j++) { 820 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
990 /* Loop through and verify the data */ 821 }
991 if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) { 822 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
992 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
993 goto out;
994 }
995 datidx += mtd->eccsize;
996 /* Have we a hw generator layout ? */
997 if (!hweccbytes)
998 continue;
999 if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
1000 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
1001 goto out;
1002 }
1003 oobofs += hweccbytes;
1004 }
1005 823
1006 /* check, if we must compare all data or if we just have to 824 for (i = 0; i < chip->ecc.total; i++)
1007 * compare the ecc bytes 825 ecc_code[i] = chip->oob_poi[eccpos[i]];
1008 */
1009 if (oobmode) {
1010 if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
1011 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
1012 goto out;
1013 }
1014 } else {
1015 /* Read always, else autoincrement fails */
1016 this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
1017
1018 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
1019 int ecccnt = oobsel->eccbytes;
1020
1021 for (i = 0; i < ecccnt; i++) {
1022 int idx = oobsel->eccpos[i];
1023 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
1024 DEBUG (MTD_DEBUG_LEVEL0,
1025 "%s: Failed ECC write "
1026 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
1027 goto out;
1028 }
1029 }
1030 }
1031 }
1032 oobofs += mtd->oobsize - hweccbytes * eccsteps;
1033 page++;
1034 numpages--;
1035
1036 /* Apply delay or wait for ready/busy pin
1037 * Do this before the AUTOINCR check, so no problems
1038 * arise if a chip which does auto increment
1039 * is marked as NOAUTOINCR by the board driver.
1040 * Do this also before returning, so the chip is
1041 * ready for the next command.
1042 */
1043 if (!this->dev_ready)
1044 udelay (this->chip_delay);
1045 else
1046 nand_wait_ready(mtd);
1047 826
1048 /* All done, return happy */ 827 eccsteps = chip->ecc.steps;
1049 if (!numpages) 828 p = buf;
1050 return 0;
1051 829
830 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
831 int stat;
1052 832
1053 /* Check, if the chip supports auto page increment */ 833 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
1054 if (!NAND_CANAUTOINCR(this)) 834 if (stat == -1)
1055 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 835 mtd->ecc_stats.failed++;
836 else
837 mtd->ecc_stats.corrected += stat;
1056 } 838 }
1057 /* 839 return 0;
1058 * Terminate the read command. We come here in case of an error
1059 * So we must issue a reset command.
1060 */
1061out:
1062 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
1063 return res;
1064} 840}
1065#endif
1066 841
1067/** 842/**
1068 * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc 843 * nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read
1069 * @mtd: MTD device structure 844 * @mtd: mtd info structure
1070 * @from: offset to read from 845 * @chip: nand chip info structure
1071 * @len: number of bytes to read 846 * @buf: buffer to store read data
1072 * @retlen: pointer to variable to store the number of read bytes
1073 * @buf: the databuffer to put data
1074 * 847 *
1075 * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL 848 * The hw generator calculates the error syndrome automatically. Therefor
1076 * and flags = 0xff 849 * we need a special oob layout and handling.
1077 */ 850 */
1078static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) 851static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
852 uint8_t *buf)
1079{ 853{
1080 return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff); 854 int i, eccsize = chip->ecc.size;
1081} 855 int eccbytes = chip->ecc.bytes;
856 int eccsteps = chip->ecc.steps;
857 uint8_t *p = buf;
858 uint8_t *oob = chip->oob_poi;
859
860 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
861 int stat;
862
863 chip->ecc.hwctl(mtd, NAND_ECC_READ);
864 chip->read_buf(mtd, p, eccsize);
865
866 if (chip->ecc.prepad) {
867 chip->read_buf(mtd, oob, chip->ecc.prepad);
868 oob += chip->ecc.prepad;
869 }
870
871 chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
872 chip->read_buf(mtd, oob, eccbytes);
873 stat = chip->ecc.correct(mtd, p, oob, NULL);
874
875 if (stat == -1)
876 mtd->ecc_stats.failed++;
877 else
878 mtd->ecc_stats.corrected += stat;
879
880 oob += eccbytes;
881
882 if (chip->ecc.postpad) {
883 chip->read_buf(mtd, oob, chip->ecc.postpad);
884 oob += chip->ecc.postpad;
885 }
886 }
887
888 /* Calculate remaining oob bytes */
889 i = mtd->oobsize - (oob - chip->oob_poi);
890 if (i)
891 chip->read_buf(mtd, oob, i);
1082 892
893 return 0;
894}
1083 895
1084/** 896/**
1085 * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc 897 * nand_transfer_oob - [Internal] Transfer oob to client buffer
1086 * @mtd: MTD device structure 898 * @chip: nand chip structure
1087 * @from: offset to read from 899 * @ops: oob ops structure
1088 * @len: number of bytes to read
1089 * @retlen: pointer to variable to store the number of read bytes
1090 * @buf: the databuffer to put data
1091 * @oob_buf: filesystem supplied oob data buffer
1092 * @oobsel: oob selection structure
1093 *
1094 * This function simply calls nand_do_read_ecc with flags = 0xff
1095 */ 900 */
1096static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 901static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
1097 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) 902 struct mtd_oob_ops *ops)
1098{ 903{
1099 /* use userspace supplied oobinfo, if zero */ 904 size_t len = ops->ooblen;
1100 if (oobsel == NULL) 905
1101 oobsel = &mtd->oobinfo; 906 switch(ops->mode) {
1102 return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff); 907
908 case MTD_OOB_PLACE:
909 case MTD_OOB_RAW:
910 memcpy(oob, chip->oob_poi + ops->ooboffs, len);
911 return oob + len;
912
913 case MTD_OOB_AUTO: {
914 struct nand_oobfree *free = chip->ecc.layout->oobfree;
915 uint32_t boffs = 0, roffs = ops->ooboffs;
916 size_t bytes = 0;
917
918 for(; free->length && len; free++, len -= bytes) {
919 /* Read request not from offset 0 ? */
920 if (unlikely(roffs)) {
921 if (roffs >= free->length) {
922 roffs -= free->length;
923 continue;
924 }
925 boffs = free->offset + roffs;
926 bytes = min_t(size_t, len,
927 (free->length - roffs));
928 roffs = 0;
929 } else {
930 bytes = min_t(size_t, len, free->length);
931 boffs = free->offset;
932 }
933 memcpy(oob, chip->oob_poi + boffs, bytes);
934 oob += bytes;
935 }
936 return oob;
937 }
938 default:
939 BUG();
940 }
941 return NULL;
1103} 942}
1104 943
1105
1106/** 944/**
1107 * nand_do_read_ecc - [MTD Interface] Read data with ECC 945 * nand_do_read_ops - [Internal] Read data with ECC
946 *
1108 * @mtd: MTD device structure 947 * @mtd: MTD device structure
1109 * @from: offset to read from 948 * @from: offset to read from
1110 * @len: number of bytes to read
1111 * @retlen: pointer to variable to store the number of read bytes
1112 * @buf: the databuffer to put data
1113 * @oob_buf: filesystem supplied oob data buffer (can be NULL)
1114 * @oobsel: oob selection structure
1115 * @flags: flag to indicate if nand_get_device/nand_release_device should be preformed
1116 * and how many corrected error bits are acceptable:
1117 * bits 0..7 - number of tolerable errors
1118 * bit 8 - 0 == do not get/release chip, 1 == get/release chip
1119 * 949 *
1120 * NAND read with ECC 950 * Internal function. Called with chip held.
1121 */ 951 */
1122int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 952static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1123 size_t * retlen, u_char * buf, u_char * oob_buf, 953 struct mtd_oob_ops *ops)
1124 struct nand_oobinfo *oobsel, int flags)
1125{ 954{
955 int chipnr, page, realpage, col, bytes, aligned;
956 struct nand_chip *chip = mtd->priv;
957 struct mtd_ecc_stats stats;
958 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
959 int sndcmd = 1;
960 int ret = 0;
961 uint32_t readlen = ops->len;
962 uint8_t *bufpoi, *oob, *buf;
1126 963
1127 int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1; 964 stats = mtd->ecc_stats;
1128 int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
1129 struct nand_chip *this = mtd->priv;
1130 u_char *data_poi, *oob_data = oob_buf;
1131 u_char ecc_calc[32];
1132 u_char ecc_code[32];
1133 int eccmode, eccsteps;
1134 int *oob_config, datidx;
1135 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
1136 int eccbytes;
1137 int compareecc = 1;
1138 int oobreadlen;
1139
1140
1141 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
1142
1143 /* Do not allow reads past end of device */
1144 if ((from + len) > mtd->size) {
1145 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
1146 *retlen = 0;
1147 return -EINVAL;
1148 }
1149
1150 /* Grab the lock and see if the device is available */
1151 if (flags & NAND_GET_DEVICE)
1152 nand_get_device (this, mtd, FL_READING);
1153
1154 /* Autoplace of oob data ? Use the default placement scheme */
1155 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
1156 oobsel = this->autooob;
1157
1158 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
1159 oob_config = oobsel->eccpos;
1160
1161 /* Select the NAND device */
1162 chipnr = (int)(from >> this->chip_shift);
1163 this->select_chip(mtd, chipnr);
1164
1165 /* First we calculate the starting page */
1166 realpage = (int) (from >> this->page_shift);
1167 page = realpage & this->pagemask;
1168
1169 /* Get raw starting column */
1170 col = from & (mtd->oobblock - 1);
1171
1172 end = mtd->oobblock;
1173 ecc = this->eccsize;
1174 eccbytes = this->eccbytes;
1175
1176 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
1177 compareecc = 0;
1178
1179 oobreadlen = mtd->oobsize;
1180 if (this->options & NAND_HWECC_SYNDROME)
1181 oobreadlen -= oobsel->eccbytes;
1182 965
1183 /* Loop until all data read */ 966 chipnr = (int)(from >> chip->chip_shift);
1184 while (read < len) { 967 chip->select_chip(mtd, chipnr);
1185 968
1186 int aligned = (!col && (len - read) >= end); 969 realpage = (int)(from >> chip->page_shift);
1187 /* 970 page = realpage & chip->pagemask;
1188 * If the read is not page aligned, we have to read into data buffer
1189 * due to ecc, else we read into return buffer direct
1190 */
1191 if (aligned)
1192 data_poi = &buf[read];
1193 else
1194 data_poi = this->data_buf;
1195 971
1196 /* Check, if we have this page in the buffer 972 col = (int)(from & (mtd->writesize - 1));
1197 * 973 chip->oob_poi = chip->buffers.oobrbuf;
1198 * FIXME: Make it work when we must provide oob data too,
1199 * check the usage of data_buf oob field
1200 */
1201 if (realpage == this->pagebuf && !oob_buf) {
1202 /* aligned read ? */
1203 if (aligned)
1204 memcpy (data_poi, this->data_buf, end);
1205 goto readdata;
1206 }
1207 974
1208 /* Check, if we must send the read command */ 975 buf = ops->datbuf;
1209 if (sndcmd) { 976 oob = ops->oobbuf;
1210 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1211 sndcmd = 0;
1212 }
1213 977
1214 /* get oob area, if we have no oob buffer from fs-driver */ 978 while(1) {
1215 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || 979 bytes = min(mtd->writesize - col, readlen);
1216 oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 980 aligned = (bytes == mtd->writesize);
1217 oob_data = &this->data_buf[end];
1218 981
1219 eccsteps = this->eccsteps; 982 /* Is the current page in the buffer ? */
983 if (realpage != chip->pagebuf || oob) {
984 bufpoi = aligned ? buf : chip->buffers.databuf;
1220 985
1221 switch (eccmode) { 986 if (likely(sndcmd)) {
1222 case NAND_ECC_NONE: { /* No ECC, Read in a page */ 987 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
1223 static unsigned long lastwhinge = 0; 988 sndcmd = 0;
1224 if ((lastwhinge / HZ) != (jiffies / HZ)) {
1225 printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
1226 lastwhinge = jiffies;
1227 } 989 }
1228 this->read_buf(mtd, data_poi, end);
1229 break;
1230 }
1231 990
1232 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ 991 /* Now read the page into the buffer */
1233 this->read_buf(mtd, data_poi, end); 992 ret = chip->ecc.read_page(mtd, chip, bufpoi);
1234 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 993 if (ret < 0)
1235 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 994 break;
1236 break;
1237 995
1238 default: 996 /* Transfer not aligned data */
1239 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { 997 if (!aligned) {
1240 this->enable_hwecc(mtd, NAND_ECC_READ); 998 chip->pagebuf = realpage;
1241 this->read_buf(mtd, &data_poi[datidx], ecc); 999 memcpy(buf, chip->buffers.databuf + col, bytes);
1242
1243 /* HW ecc with syndrome calculation must read the
1244 * syndrome from flash immidiately after the data */
1245 if (!compareecc) {
1246 /* Some hw ecc generators need to know when the
1247 * syndrome is read from flash */
1248 this->enable_hwecc(mtd, NAND_ECC_READSYN);
1249 this->read_buf(mtd, &oob_data[i], eccbytes);
1250 /* We calc error correction directly, it checks the hw
1251 * generator for an error, reads back the syndrome and
1252 * does the error correction on the fly */
1253 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1254 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1255 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
1256 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
1257 ecc_failed++;
1258 }
1259 } else {
1260 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1261 }
1262 } 1000 }
1263 break;
1264 }
1265
1266 /* read oobdata */
1267 this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
1268
1269 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
1270 if (!compareecc)
1271 goto readoob;
1272
1273 /* Pick the ECC bytes out of the oob data */
1274 for (j = 0; j < oobsel->eccbytes; j++)
1275 ecc_code[j] = oob_data[oob_config[j]];
1276 1001
1277 /* correct data, if neccecary */ 1002 buf += bytes;
1278 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
1279 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
1280 1003
1281 /* Get next chunk of ecc bytes */ 1004 if (unlikely(oob)) {
1282 j += eccbytes; 1005 /* Raw mode does data:oob:data:oob */
1283 1006 if (ops->mode != MTD_OOB_RAW)
1284 /* Check, if we have a fs supplied oob-buffer, 1007 oob = nand_transfer_oob(chip, oob, ops);
1285 * This is the legacy mode. Used by YAFFS1 1008 else
1286 * Should go away some day 1009 buf = nand_transfer_oob(chip, buf, ops);
1287 */
1288 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
1289 int *p = (int *)(&oob_data[mtd->oobsize]);
1290 p[i] = ecc_status;
1291 } 1010 }
1292 1011
1293 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1012 if (!(chip->options & NAND_NO_READRDY)) {
1294 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); 1013 /*
1295 ecc_failed++; 1014 * Apply delay or wait for ready/busy pin. Do
1015 * this before the AUTOINCR check, so no
1016 * problems arise if a chip which does auto
1017 * increment is marked as NOAUTOINCR by the
1018 * board driver.
1019 */
1020 if (!chip->dev_ready)
1021 udelay(chip->chip_delay);
1022 else
1023 nand_wait_ready(mtd);
1296 } 1024 }
1025 } else {
1026 memcpy(buf, chip->buffers.databuf + col, bytes);
1027 buf += bytes;
1297 } 1028 }
1298 1029
1299 readoob: 1030 readlen -= bytes;
1300 /* check, if we have a fs supplied oob-buffer */
1301 if (oob_buf) {
1302 /* without autoplace. Legacy mode used by YAFFS1 */
1303 switch(oobsel->useecc) {
1304 case MTD_NANDECC_AUTOPLACE:
1305 case MTD_NANDECC_AUTOPL_USR:
1306 /* Walk through the autoplace chunks */
1307 for (i = 0; oobsel->oobfree[i][1]; i++) {
1308 int from = oobsel->oobfree[i][0];
1309 int num = oobsel->oobfree[i][1];
1310 memcpy(&oob_buf[oob], &oob_data[from], num);
1311 oob += num;
1312 }
1313 break;
1314 case MTD_NANDECC_PLACE:
1315 /* YAFFS1 legacy mode */
1316 oob_data += this->eccsteps * sizeof (int);
1317 default:
1318 oob_data += mtd->oobsize;
1319 }
1320 }
1321 readdata:
1322 /* Partial page read, transfer data into fs buffer */
1323 if (!aligned) {
1324 for (j = col; j < end && read < len; j++)
1325 buf[read++] = data_poi[j];
1326 this->pagebuf = realpage;
1327 } else
1328 read += mtd->oobblock;
1329
1330 /* Apply delay or wait for ready/busy pin
1331 * Do this before the AUTOINCR check, so no problems
1332 * arise if a chip which does auto increment
1333 * is marked as NOAUTOINCR by the board driver.
1334 */
1335 if (!this->dev_ready)
1336 udelay (this->chip_delay);
1337 else
1338 nand_wait_ready(mtd);
1339 1031
1340 if (read == len) 1032 if (!readlen)
1341 break; 1033 break;
1342 1034
1343 /* For subsequent reads align to page boundary. */ 1035 /* For subsequent reads align to page boundary. */
@@ -1345,701 +1037,775 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1345 /* Increment page address */ 1037 /* Increment page address */
1346 realpage++; 1038 realpage++;
1347 1039
1348 page = realpage & this->pagemask; 1040 page = realpage & chip->pagemask;
1349 /* Check, if we cross a chip boundary */ 1041 /* Check, if we cross a chip boundary */
1350 if (!page) { 1042 if (!page) {
1351 chipnr++; 1043 chipnr++;
1352 this->select_chip(mtd, -1); 1044 chip->select_chip(mtd, -1);
1353 this->select_chip(mtd, chipnr); 1045 chip->select_chip(mtd, chipnr);
1354 } 1046 }
1047
1355 /* Check, if the chip supports auto page increment 1048 /* Check, if the chip supports auto page increment
1356 * or if we have hit a block boundary. 1049 * or if we have hit a block boundary.
1357 */ 1050 */
1358 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1051 if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
1359 sndcmd = 1; 1052 sndcmd = 1;
1360 } 1053 }
1361 1054
1362 /* Deselect and wake up anyone waiting on the device */ 1055 ops->retlen = ops->len - (size_t) readlen;
1363 if (flags & NAND_GET_DEVICE)
1364 nand_release_device(mtd);
1365 1056
1366 /* 1057 if (ret)
1367 * Return success, if no ECC failures, else -EBADMSG 1058 return ret;
1368 * fs driver will take care of that, because 1059
1369 * retlen == desired len and result == -EBADMSG 1060 if (mtd->ecc_stats.failed - stats.failed)
1370 */ 1061 return -EBADMSG;
1371 *retlen = read; 1062
1372 return ecc_failed ? -EBADMSG : 0; 1063 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
1373} 1064}
1374 1065
1375/** 1066/**
1376 * nand_read_oob - [MTD Interface] NAND read out-of-band 1067 * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
1377 * @mtd: MTD device structure 1068 * @mtd: MTD device structure
1378 * @from: offset to read from 1069 * @from: offset to read from
1379 * @len: number of bytes to read 1070 * @len: number of bytes to read
1380 * @retlen: pointer to variable to store the number of read bytes 1071 * @retlen: pointer to variable to store the number of read bytes
1381 * @buf: the databuffer to put data 1072 * @buf: the databuffer to put data
1382 * 1073 *
1383 * NAND read out-of-band data from the spare area 1074 * Get hold of the chip and call nand_do_read
1384 */ 1075 */
1385static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) 1076static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
1077 size_t *retlen, uint8_t *buf)
1386{ 1078{
1387 int i, col, page, chipnr; 1079 struct nand_chip *chip = mtd->priv;
1388 struct nand_chip *this = mtd->priv; 1080 int ret;
1389 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
1390 1081
1391 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 1082 /* Do not allow reads past end of device */
1083 if ((from + len) > mtd->size)
1084 return -EINVAL;
1085 if (!len)
1086 return 0;
1392 1087
1393 /* Shift to get page */ 1088 nand_get_device(chip, mtd, FL_READING);
1394 page = (int)(from >> this->page_shift);
1395 chipnr = (int)(from >> this->chip_shift);
1396 1089
1397 /* Mask to get column */ 1090 chip->ops.len = len;
1398 col = from & (mtd->oobsize - 1); 1091 chip->ops.datbuf = buf;
1092 chip->ops.oobbuf = NULL;
1399 1093
1400 /* Initialize return length value */ 1094 ret = nand_do_read_ops(mtd, from, &chip->ops);
1401 *retlen = 0;
1402 1095
1403 /* Do not allow reads past end of device */ 1096 nand_release_device(mtd);
1404 if ((from + len) > mtd->size) { 1097
1405 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n"); 1098 *retlen = chip->ops.retlen;
1406 *retlen = 0; 1099 return ret;
1407 return -EINVAL; 1100}
1101
1102/**
1103 * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
1104 * @mtd: mtd info structure
1105 * @chip: nand chip info structure
1106 * @page: page number to read
1107 * @sndcmd: flag whether to issue read command or not
1108 */
1109static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1110 int page, int sndcmd)
1111{
1112 if (sndcmd) {
1113 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
1114 sndcmd = 0;
1408 } 1115 }
1116 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1117 return sndcmd;
1118}
1409 1119
1410 /* Grab the lock and see if the device is available */ 1120/**
1411 nand_get_device (this, mtd , FL_READING); 1121 * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
1122 * with syndromes
1123 * @mtd: mtd info structure
1124 * @chip: nand chip info structure
1125 * @page: page number to read
1126 * @sndcmd: flag whether to issue read command or not
1127 */
1128static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1129 int page, int sndcmd)
1130{
1131 uint8_t *buf = chip->oob_poi;
1132 int length = mtd->oobsize;
1133 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1134 int eccsize = chip->ecc.size;
1135 uint8_t *bufpoi = buf;
1136 int i, toread, sndrnd = 0, pos;
1137
1138 chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
1139 for (i = 0; i < chip->ecc.steps; i++) {
1140 if (sndrnd) {
1141 pos = eccsize + i * (eccsize + chunk);
1142 if (mtd->writesize > 512)
1143 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
1144 else
1145 chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
1146 } else
1147 sndrnd = 1;
1148 toread = min_t(int, length, chunk);
1149 chip->read_buf(mtd, bufpoi, toread);
1150 bufpoi += toread;
1151 length -= toread;
1152 }
1153 if (length > 0)
1154 chip->read_buf(mtd, bufpoi, length);
1412 1155
1413 /* Select the NAND device */ 1156 return 1;
1414 this->select_chip(mtd, chipnr); 1157}
1158
1159/**
1160 * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
1161 * @mtd: mtd info structure
1162 * @chip: nand chip info structure
1163 * @page: page number to write
1164 */
1165static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1166 int page)
1167{
1168 int status = 0;
1169 const uint8_t *buf = chip->oob_poi;
1170 int length = mtd->oobsize;
1171
1172 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
1173 chip->write_buf(mtd, buf, length);
1174 /* Send command to program the OOB data */
1175 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1176
1177 status = chip->waitfunc(mtd, chip);
1178
1179 return status;
1180}
1181
1182/**
1183 * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
1184 * with syndrome - only for large page flash !
1185 * @mtd: mtd info structure
1186 * @chip: nand chip info structure
1187 * @page: page number to write
1188 */
1189static int nand_write_oob_syndrome(struct mtd_info *mtd,
1190 struct nand_chip *chip, int page)
1191{
1192 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1193 int eccsize = chip->ecc.size, length = mtd->oobsize;
1194 int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
1195 const uint8_t *bufpoi = chip->oob_poi;
1415 1196
1416 /* Send the read command */
1417 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
1418 /* 1197 /*
1419 * Read the data, if we read more than one page 1198 * data-ecc-data-ecc ... ecc-oob
1420 * oob data, let the device transfer the data ! 1199 * or
1200 * data-pad-ecc-pad-data-pad .... ecc-pad-oob
1421 */ 1201 */
1422 i = 0; 1202 if (!chip->ecc.prepad && !chip->ecc.postpad) {
1423 while (i < len) { 1203 pos = steps * (eccsize + chunk);
1424 int thislen = mtd->oobsize - col; 1204 steps = 0;
1425 thislen = min_t(int, thislen, len); 1205 } else
1426 this->read_buf(mtd, &buf[i], thislen); 1206 pos = eccsize + chunk;
1427 i += thislen;
1428
1429 /* Read more ? */
1430 if (i < len) {
1431 page++;
1432 col = 0;
1433
1434 /* Check, if we cross a chip boundary */
1435 if (!(page & this->pagemask)) {
1436 chipnr++;
1437 this->select_chip(mtd, -1);
1438 this->select_chip(mtd, chipnr);
1439 }
1440
1441 /* Apply delay or wait for ready/busy pin
1442 * Do this before the AUTOINCR check, so no problems
1443 * arise if a chip which does auto increment
1444 * is marked as NOAUTOINCR by the board driver.
1445 */
1446 if (!this->dev_ready)
1447 udelay (this->chip_delay);
1448 else
1449 nand_wait_ready(mtd);
1450 1207
1451 /* Check, if the chip supports auto page increment 1208 chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
1452 * or if we have hit a block boundary. 1209 for (i = 0; i < steps; i++) {
1453 */ 1210 if (sndcmd) {
1454 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { 1211 if (mtd->writesize <= 512) {
1455 /* For subsequent page reads set offset to 0 */ 1212 uint32_t fill = 0xFFFFFFFF;
1456 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 1213
1214 len = eccsize;
1215 while (len > 0) {
1216 int num = min_t(int, len, 4);
1217 chip->write_buf(mtd, (uint8_t *)&fill,
1218 num);
1219 len -= num;
1220 }
1221 } else {
1222 pos = eccsize + i * (eccsize + chunk);
1223 chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1);
1457 } 1224 }
1458 } 1225 } else
1226 sndcmd = 1;
1227 len = min_t(int, length, chunk);
1228 chip->write_buf(mtd, bufpoi, len);
1229 bufpoi += len;
1230 length -= len;
1459 } 1231 }
1232 if (length > 0)
1233 chip->write_buf(mtd, bufpoi, length);
1460 1234
1461 /* Deselect and wake up anyone waiting on the device */ 1235 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1462 nand_release_device(mtd); 1236 status = chip->waitfunc(mtd, chip);
1463 1237
1464 /* Return happy */ 1238 return status & NAND_STATUS_FAIL ? -EIO : 0;
1465 *retlen = len;
1466 return 0;
1467} 1239}
1468 1240
1469/** 1241/**
1470 * nand_read_raw - [GENERIC] Read raw data including oob into buffer 1242 * nand_do_read_oob - [Intern] NAND read out-of-band
1471 * @mtd: MTD device structure 1243 * @mtd: MTD device structure
1472 * @buf: temporary buffer
1473 * @from: offset to read from 1244 * @from: offset to read from
1474 * @len: number of bytes to read 1245 * @ops: oob operations description structure
1475 * @ooblen: number of oob data bytes to read
1476 * 1246 *
1477 * Read raw data including oob into buffer 1247 * NAND read out-of-band data from the spare area
1478 */ 1248 */
1479int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen) 1249static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1250 struct mtd_oob_ops *ops)
1480{ 1251{
1481 struct nand_chip *this = mtd->priv; 1252 int page, realpage, chipnr, sndcmd = 1;
1482 int page = (int) (from >> this->page_shift); 1253 struct nand_chip *chip = mtd->priv;
1483 int chip = (int) (from >> this->chip_shift); 1254 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1484 int sndcmd = 1; 1255 int readlen = ops->len;
1485 int cnt = 0; 1256 uint8_t *buf = ops->oobbuf;
1486 int pagesize = mtd->oobblock + mtd->oobsize;
1487 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
1488 1257
1489 /* Do not allow reads past end of device */ 1258 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1490 if ((from + len) > mtd->size) { 1259 (unsigned long long)from, readlen);
1491 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
1492 return -EINVAL;
1493 }
1494 1260
1495 /* Grab the lock and see if the device is available */ 1261 chipnr = (int)(from >> chip->chip_shift);
1496 nand_get_device (this, mtd , FL_READING); 1262 chip->select_chip(mtd, chipnr);
1497 1263
1498 this->select_chip (mtd, chip); 1264 /* Shift to get page */
1265 realpage = (int)(from >> chip->page_shift);
1266 page = realpage & chip->pagemask;
1499 1267
1500 /* Add requested oob length */ 1268 chip->oob_poi = chip->buffers.oobrbuf;
1501 len += ooblen;
1502 1269
1503 while (len) { 1270 while(1) {
1504 if (sndcmd) 1271 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
1505 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); 1272 buf = nand_transfer_oob(chip, buf, ops);
1506 sndcmd = 0;
1507 1273
1508 this->read_buf (mtd, &buf[cnt], pagesize); 1274 readlen -= ops->ooblen;
1275 if (!readlen)
1276 break;
1509 1277
1510 len -= pagesize; 1278 if (!(chip->options & NAND_NO_READRDY)) {
1511 cnt += pagesize; 1279 /*
1512 page++; 1280 * Apply delay or wait for ready/busy pin. Do this
1281 * before the AUTOINCR check, so no problems arise if a
1282 * chip which does auto increment is marked as
1283 * NOAUTOINCR by the board driver.
1284 */
1285 if (!chip->dev_ready)
1286 udelay(chip->chip_delay);
1287 else
1288 nand_wait_ready(mtd);
1289 }
1513 1290
1514 if (!this->dev_ready) 1291 /* Increment page address */
1515 udelay (this->chip_delay); 1292 realpage++;
1516 else
1517 nand_wait_ready(mtd);
1518 1293
1519 /* Check, if the chip supports auto page increment */ 1294 page = realpage & chip->pagemask;
1520 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1295 /* Check, if we cross a chip boundary */
1296 if (!page) {
1297 chipnr++;
1298 chip->select_chip(mtd, -1);
1299 chip->select_chip(mtd, chipnr);
1300 }
1301
1302 /* Check, if the chip supports auto page increment
1303 * or if we have hit a block boundary.
1304 */
1305 if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
1521 sndcmd = 1; 1306 sndcmd = 1;
1522 } 1307 }
1523 1308
1524 /* Deselect and wake up anyone waiting on the device */ 1309 ops->retlen = ops->len;
1525 nand_release_device(mtd);
1526 return 0; 1310 return 0;
1527} 1311}
1528 1312
1529
1530/** 1313/**
1531 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer 1314 * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
1532 * @mtd: MTD device structure 1315 * @mtd: MTD device structure
1533 * @fsbuf: buffer given by fs driver 1316 * @from: offset to read from
1534 * @oobsel: out of band selection structre 1317 * @ops: oob operation description structure
1535 * @autoplace: 1 = place given buffer into the oob bytes
1536 * @numpages: number of pages to prepare
1537 *
1538 * Return:
1539 * 1. Filesystem buffer available and autoplacement is off,
1540 * return filesystem buffer
1541 * 2. No filesystem buffer or autoplace is off, return internal
1542 * buffer
1543 * 3. Filesystem buffer is given and autoplace selected
1544 * put data from fs buffer into internal buffer and
1545 * retrun internal buffer
1546 *
1547 * Note: The internal buffer is filled with 0xff. This must
1548 * be done only once, when no autoplacement happens
1549 * Autoplacement sets the buffer dirty flag, which
1550 * forces the 0xff fill before using the buffer again.
1551 * 1318 *
1552*/ 1319 * NAND read data and/or out-of-band data
1553static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel, 1320 */
1554 int autoplace, int numpages) 1321static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1322 struct mtd_oob_ops *ops)
1555{ 1323{
1556 struct nand_chip *this = mtd->priv; 1324 int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
1557 int i, len, ofs; 1325 uint8_t *buf) = NULL;
1558 1326 struct nand_chip *chip = mtd->priv;
1559 /* Zero copy fs supplied buffer */ 1327 int ret = -ENOTSUPP;
1560 if (fsbuf && !autoplace) 1328
1561 return fsbuf; 1329 ops->retlen = 0;
1562 1330
1563 /* Check, if the buffer must be filled with ff again */ 1331 /* Do not allow reads past end of device */
1564 if (this->oobdirty) { 1332 if ((from + ops->len) > mtd->size) {
1565 memset (this->oob_buf, 0xff, 1333 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1566 mtd->oobsize << (this->phys_erase_shift - this->page_shift)); 1334 "Attempt read beyond end of device\n");
1567 this->oobdirty = 0; 1335 return -EINVAL;
1568 } 1336 }
1569 1337
1570 /* If we have no autoplacement or no fs buffer use the internal one */ 1338 nand_get_device(chip, mtd, FL_READING);
1571 if (!autoplace || !fsbuf) 1339
1572 return this->oob_buf; 1340 switch(ops->mode) {
1573 1341 case MTD_OOB_PLACE:
1574 /* Walk through the pages and place the data */ 1342 case MTD_OOB_AUTO:
1575 this->oobdirty = 1; 1343 break;
1576 ofs = 0; 1344
1577 while (numpages--) { 1345 case MTD_OOB_RAW:
1578 for (i = 0, len = 0; len < mtd->oobavail; i++) { 1346 /* Replace the read_page algorithm temporary */
1579 int to = ofs + oobsel->oobfree[i][0]; 1347 read_page = chip->ecc.read_page;
1580 int num = oobsel->oobfree[i][1]; 1348 chip->ecc.read_page = nand_read_page_raw;
1581 memcpy (&this->oob_buf[to], fsbuf, num); 1349 break;
1582 len += num; 1350
1583 fsbuf += num; 1351 default:
1584 } 1352 goto out;
1585 ofs += mtd->oobavail;
1586 } 1353 }
1587 return this->oob_buf; 1354
1355 if (!ops->datbuf)
1356 ret = nand_do_read_oob(mtd, from, ops);
1357 else
1358 ret = nand_do_read_ops(mtd, from, ops);
1359
1360 if (unlikely(ops->mode == MTD_OOB_RAW))
1361 chip->ecc.read_page = read_page;
1362 out:
1363 nand_release_device(mtd);
1364 return ret;
1588} 1365}
1589 1366
1590#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
1591 1367
1592/** 1368/**
1593 * nand_write - [MTD Interface] compability function for nand_write_ecc 1369 * nand_write_page_raw - [Intern] raw page write function
1594 * @mtd: MTD device structure 1370 * @mtd: mtd info structure
1595 * @to: offset to write to 1371 * @chip: nand chip info structure
1596 * @len: number of bytes to write 1372 * @buf: data buffer
1597 * @retlen: pointer to variable to store the number of written bytes 1373 */
1598 * @buf: the data to write 1374static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1599 * 1375 const uint8_t *buf)
1600 * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
1601 *
1602*/
1603static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
1604{ 1376{
1605 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); 1377 chip->write_buf(mtd, buf, mtd->writesize);
1378 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1606} 1379}
1607 1380
1608/** 1381/**
1609 * nand_write_ecc - [MTD Interface] NAND write with ECC 1382 * nand_write_page_swecc - {REPLACABLE] software ecc based page write function
1610 * @mtd: MTD device structure 1383 * @mtd: mtd info structure
1611 * @to: offset to write to 1384 * @chip: nand chip info structure
1612 * @len: number of bytes to write 1385 * @buf: data buffer
1613 * @retlen: pointer to variable to store the number of written bytes
1614 * @buf: the data to write
1615 * @eccbuf: filesystem supplied oob data buffer
1616 * @oobsel: oob selection structure
1617 *
1618 * NAND write with ECC
1619 */ 1386 */
1620static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, 1387static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1621 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) 1388 const uint8_t *buf)
1622{ 1389{
1623 int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr; 1390 int i, eccsize = chip->ecc.size;
1624 int autoplace = 0, numpages, totalpages; 1391 int eccbytes = chip->ecc.bytes;
1625 struct nand_chip *this = mtd->priv; 1392 int eccsteps = chip->ecc.steps;
1626 u_char *oobbuf, *bufstart; 1393 uint8_t *ecc_calc = chip->buffers.ecccalc;
1627 int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); 1394 const uint8_t *p = buf;
1395 int *eccpos = chip->ecc.layout->eccpos;
1628 1396
1629 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1397 /* Software ecc calculation */
1398 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
1399 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1630 1400
1631 /* Initialize retlen, in case of early exit */ 1401 for (i = 0; i < chip->ecc.total; i++)
1632 *retlen = 0; 1402 chip->oob_poi[eccpos[i]] = ecc_calc[i];
1633 1403
1634 /* Do not allow write past end of device */ 1404 nand_write_page_raw(mtd, chip, buf);
1635 if ((to + len) > mtd->size) { 1405}
1636 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
1637 return -EINVAL;
1638 }
1639 1406
1640 /* reject writes, which are not page aligned */ 1407/**
1641 if (NOTALIGNED (to) || NOTALIGNED(len)) { 1408 * nand_write_page_hwecc - {REPLACABLE] hardware ecc based page write function
1642 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1409 * @mtd: mtd info structure
1643 return -EINVAL; 1410 * @chip: nand chip info structure
1411 * @buf: data buffer
1412 */
1413static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1414 const uint8_t *buf)
1415{
1416 int i, eccsize = chip->ecc.size;
1417 int eccbytes = chip->ecc.bytes;
1418 int eccsteps = chip->ecc.steps;
1419 uint8_t *ecc_calc = chip->buffers.ecccalc;
1420 const uint8_t *p = buf;
1421 int *eccpos = chip->ecc.layout->eccpos;
1422
1423 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1424 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1425 chip->write_buf(mtd, p, eccsize);
1426 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1644 } 1427 }
1645 1428
1646 /* Grab the lock and see if the device is available */ 1429 for (i = 0; i < chip->ecc.total; i++)
1647 nand_get_device (this, mtd, FL_WRITING); 1430 chip->oob_poi[eccpos[i]] = ecc_calc[i];
1648 1431
1649 /* Calculate chipnr */ 1432 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1650 chipnr = (int)(to >> this->chip_shift); 1433}
1651 /* Select the NAND device */
1652 this->select_chip(mtd, chipnr);
1653 1434
1654 /* Check, if it is write protected */ 1435/**
1655 if (nand_check_wp(mtd)) 1436 * nand_write_page_syndrome - {REPLACABLE] hardware ecc syndrom based page write
1656 goto out; 1437 * @mtd: mtd info structure
1438 * @chip: nand chip info structure
1439 * @buf: data buffer
1440 *
1441 * The hw generator calculates the error syndrome automatically. Therefor
1442 * we need a special oob layout and handling.
1443 */
1444static void nand_write_page_syndrome(struct mtd_info *mtd,
1445 struct nand_chip *chip, const uint8_t *buf)
1446{
1447 int i, eccsize = chip->ecc.size;
1448 int eccbytes = chip->ecc.bytes;
1449 int eccsteps = chip->ecc.steps;
1450 const uint8_t *p = buf;
1451 uint8_t *oob = chip->oob_poi;
1657 1452
1658 /* if oobsel is NULL, use chip defaults */ 1453 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1659 if (oobsel == NULL)
1660 oobsel = &mtd->oobinfo;
1661 1454
1662 /* Autoplace of oob data ? Use the default placement scheme */ 1455 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1663 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1456 chip->write_buf(mtd, p, eccsize);
1664 oobsel = this->autooob;
1665 autoplace = 1;
1666 }
1667 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1668 autoplace = 1;
1669 1457
1670 /* Setup variables and oob buffer */ 1458 if (chip->ecc.prepad) {
1671 totalpages = len >> this->page_shift; 1459 chip->write_buf(mtd, oob, chip->ecc.prepad);
1672 page = (int) (to >> this->page_shift); 1460 oob += chip->ecc.prepad;
1673 /* Invalidate the page cache, if we write to the cached page */
1674 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
1675 this->pagebuf = -1;
1676
1677 /* Set it relative to chip */
1678 page &= this->pagemask;
1679 startpage = page;
1680 /* Calc number of pages we can write in one go */
1681 numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages);
1682 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
1683 bufstart = (u_char *)buf;
1684
1685 /* Loop until all data is written */
1686 while (written < len) {
1687
1688 this->data_poi = (u_char*) &buf[written];
1689 /* Write one page. If this is the last page to write
1690 * or the last page in this block, then use the
1691 * real pageprogram command, else select cached programming
1692 * if supported by the chip.
1693 */
1694 ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
1695 if (ret) {
1696 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
1697 goto out;
1698 } 1461 }
1699 /* Next oob page */
1700 oob += mtd->oobsize;
1701 /* Update written bytes count */
1702 written += mtd->oobblock;
1703 if (written == len)
1704 goto cmp;
1705 1462
1706 /* Increment page address */ 1463 chip->ecc.calculate(mtd, p, oob);
1707 page++; 1464 chip->write_buf(mtd, oob, eccbytes);
1708 1465 oob += eccbytes;
1709 /* Have we hit a block boundary ? Then we have to verify and 1466
1710 * if verify is ok, we have to setup the oob buffer for 1467 if (chip->ecc.postpad) {
1711 * the next pages. 1468 chip->write_buf(mtd, oob, chip->ecc.postpad);
1712 */ 1469 oob += chip->ecc.postpad;
1713 if (!(page & (ppblock - 1))){
1714 int ofs;
1715 this->data_poi = bufstart;
1716 ret = nand_verify_pages (mtd, this, startpage,
1717 page - startpage,
1718 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1719 if (ret) {
1720 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1721 goto out;
1722 }
1723 *retlen = written;
1724
1725 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
1726 if (eccbuf)
1727 eccbuf += (page - startpage) * ofs;
1728 totalpages -= page - startpage;
1729 numpages = min (totalpages, ppblock);
1730 page &= this->pagemask;
1731 startpage = page;
1732 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
1733 autoplace, numpages);
1734 oob = 0;
1735 /* Check, if we cross a chip boundary */
1736 if (!page) {
1737 chipnr++;
1738 this->select_chip(mtd, -1);
1739 this->select_chip(mtd, chipnr);
1740 }
1741 } 1470 }
1742 } 1471 }
1743 /* Verify the remaining pages */
1744cmp:
1745 this->data_poi = bufstart;
1746 ret = nand_verify_pages (mtd, this, startpage, totalpages,
1747 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1748 if (!ret)
1749 *retlen = written;
1750 else
1751 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1752 1472
1753out: 1473 /* Calculate remaining oob bytes */
1754 /* Deselect and wake up anyone waiting on the device */ 1474 i = mtd->oobsize - (oob - chip->oob_poi);
1755 nand_release_device(mtd); 1475 if (i)
1756 1476 chip->write_buf(mtd, oob, i);
1757 return ret;
1758} 1477}
1759 1478
1760
1761/** 1479/**
1762 * nand_write_oob - [MTD Interface] NAND write out-of-band 1480 * nand_write_page - [INTERNAL] write one page
1763 * @mtd: MTD device structure 1481 * @mtd: MTD device structure
1764 * @to: offset to write to 1482 * @chip: NAND chip descriptor
1765 * @len: number of bytes to write
1766 * @retlen: pointer to variable to store the number of written bytes
1767 * @buf: the data to write 1483 * @buf: the data to write
1768 * 1484 * @page: page number to write
1769 * NAND write out-of-band 1485 * @cached: cached programming
1770 */ 1486 */
1771static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) 1487static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1488 const uint8_t *buf, int page, int cached)
1772{ 1489{
1773 int column, page, status, ret = -EIO, chipnr; 1490 int status;
1774 struct nand_chip *this = mtd->priv;
1775 1491
1776 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1492 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
1777 1493
1778 /* Shift to get page */ 1494 chip->ecc.write_page(mtd, chip, buf);
1779 page = (int) (to >> this->page_shift);
1780 chipnr = (int) (to >> this->chip_shift);
1781 1495
1782 /* Mask to get column */ 1496 /*
1783 column = to & (mtd->oobsize - 1); 1497 * Cached progamming disabled for now, Not sure if its worth the
1498 * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
1499 */
1500 cached = 0;
1784 1501
1785 /* Initialize return length value */ 1502 if (!cached || !(chip->options & NAND_CACHEPRG)) {
1786 *retlen = 0;
1787 1503
1788 /* Do not allow write past end of page */ 1504 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1789 if ((column + len) > mtd->oobsize) { 1505 status = chip->waitfunc(mtd, chip);
1790 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n"); 1506 /*
1791 return -EINVAL; 1507 * See if operation failed and additional status checks are
1508 * available
1509 */
1510 if ((status & NAND_STATUS_FAIL) && (chip->errstat))
1511 status = chip->errstat(mtd, chip, FL_WRITING, status,
1512 page);
1513
1514 if (status & NAND_STATUS_FAIL)
1515 return -EIO;
1516 } else {
1517 chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1);
1518 status = chip->waitfunc(mtd, chip);
1792 } 1519 }
1793 1520
1794 /* Grab the lock and see if the device is available */ 1521#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1795 nand_get_device (this, mtd, FL_WRITING); 1522 /* Send command to read back the data */
1523 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1796 1524
1797 /* Select the NAND device */ 1525 if (chip->verify_buf(mtd, buf, mtd->writesize))
1798 this->select_chip(mtd, chipnr); 1526 return -EIO;
1527#endif
1528 return 0;
1529}
1530
1531/**
1532 * nand_fill_oob - [Internal] Transfer client buffer to oob
1533 * @chip: nand chip structure
1534 * @oob: oob data buffer
1535 * @ops: oob ops structure
1536 */
1537static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
1538 struct mtd_oob_ops *ops)
1539{
1540 size_t len = ops->ooblen;
1541
1542 switch(ops->mode) {
1543
1544 case MTD_OOB_PLACE:
1545 case MTD_OOB_RAW:
1546 memcpy(chip->oob_poi + ops->ooboffs, oob, len);
1547 return oob + len;
1548
1549 case MTD_OOB_AUTO: {
1550 struct nand_oobfree *free = chip->ecc.layout->oobfree;
1551 uint32_t boffs = 0, woffs = ops->ooboffs;
1552 size_t bytes = 0;
1553
1554 for(; free->length && len; free++, len -= bytes) {
1555 /* Write request not from offset 0 ? */
1556 if (unlikely(woffs)) {
1557 if (woffs >= free->length) {
1558 woffs -= free->length;
1559 continue;
1560 }
1561 boffs = free->offset + woffs;
1562 bytes = min_t(size_t, len,
1563 (free->length - woffs));
1564 woffs = 0;
1565 } else {
1566 bytes = min_t(size_t, len, free->length);
1567 boffs = free->offset;
1568 }
1569 memcpy(chip->oob_poi + woffs, oob, bytes);
1570 oob += bytes;
1571 }
1572 return oob;
1573 }
1574 default:
1575 BUG();
1576 }
1577 return NULL;
1578}
1579
1580#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0
1581
1582/**
1583 * nand_do_write_ops - [Internal] NAND write with ECC
1584 * @mtd: MTD device structure
1585 * @to: offset to write to
1586 * @ops: oob operations description structure
1587 *
1588 * NAND write with ECC
1589 */
1590static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1591 struct mtd_oob_ops *ops)
1592{
1593 int chipnr, realpage, page, blockmask;
1594 struct nand_chip *chip = mtd->priv;
1595 uint32_t writelen = ops->len;
1596 uint8_t *oob = ops->oobbuf;
1597 uint8_t *buf = ops->datbuf;
1598 int bytes = mtd->writesize;
1599 int ret;
1799 1600
1800 /* Reset the chip. Some chips (like the Toshiba TC5832DC found 1601 ops->retlen = 0;
1801 in one of my DiskOnChip 2000 test units) will clear the whole 1602
1802 data page too if we don't do this. I have no clue why, but 1603 /* reject writes, which are not page aligned */
1803 I seem to have 'fixed' it in the doc2000 driver in 1604 if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
1804 August 1999. dwmw2. */ 1605 printk(KERN_NOTICE "nand_write: "
1805 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); 1606 "Attempt to write not page aligned data\n");
1607 return -EINVAL;
1608 }
1609
1610 if (!writelen)
1611 return 0;
1806 1612
1807 /* Check, if it is write protected */ 1613 /* Check, if it is write protected */
1808 if (nand_check_wp(mtd)) 1614 if (nand_check_wp(mtd))
1809 goto out; 1615 return -EIO;
1810 1616
1811 /* Invalidate the page cache, if we write to the cached page */ 1617 chipnr = (int)(to >> chip->chip_shift);
1812 if (page == this->pagebuf) 1618 chip->select_chip(mtd, chipnr);
1813 this->pagebuf = -1;
1814
1815 if (NAND_MUST_PAD(this)) {
1816 /* Write out desired data */
1817 this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
1818 /* prepad 0xff for partial programming */
1819 this->write_buf(mtd, ffchars, column);
1820 /* write data */
1821 this->write_buf(mtd, buf, len);
1822 /* postpad 0xff for partial programming */
1823 this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
1824 } else {
1825 /* Write out desired data */
1826 this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
1827 /* write data */
1828 this->write_buf(mtd, buf, len);
1829 }
1830 /* Send command to program the OOB data */
1831 this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
1832 1619
1833 status = this->waitfunc (mtd, this, FL_WRITING); 1620 realpage = (int)(to >> chip->page_shift);
1621 page = realpage & chip->pagemask;
1622 blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1834 1623
1835 /* See if device thinks it succeeded */ 1624 /* Invalidate the page cache, when we write to the cached page */
1836 if (status & NAND_STATUS_FAIL) { 1625 if (to <= (chip->pagebuf << chip->page_shift) &&
1837 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page); 1626 (chip->pagebuf << chip->page_shift) < (to + ops->len))
1838 ret = -EIO; 1627 chip->pagebuf = -1;
1839 goto out;
1840 }
1841 /* Return happy */
1842 *retlen = len;
1843 1628
1844#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 1629 chip->oob_poi = chip->buffers.oobwbuf;
1845 /* Send command to read back the data */
1846 this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
1847 1630
1848 if (this->verify_buf(mtd, buf, len)) { 1631 while(1) {
1849 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page); 1632 int cached = writelen > bytes && page != blockmask;
1850 ret = -EIO; 1633
1851 goto out; 1634 if (unlikely(oob))
1635 oob = nand_fill_oob(chip, oob, ops);
1636
1637 ret = nand_write_page(mtd, chip, buf, page, cached);
1638 if (ret)
1639 break;
1640
1641 writelen -= bytes;
1642 if (!writelen)
1643 break;
1644
1645 buf += bytes;
1646 realpage++;
1647
1648 page = realpage & chip->pagemask;
1649 /* Check, if we cross a chip boundary */
1650 if (!page) {
1651 chipnr++;
1652 chip->select_chip(mtd, -1);
1653 chip->select_chip(mtd, chipnr);
1654 }
1852 } 1655 }
1853#endif
1854 ret = 0;
1855out:
1856 /* Deselect and wake up anyone waiting on the device */
1857 nand_release_device(mtd);
1858 1656
1657 if (unlikely(oob))
1658 memset(chip->oob_poi, 0xff, mtd->oobsize);
1659
1660 ops->retlen = ops->len - writelen;
1859 return ret; 1661 return ret;
1860} 1662}
1861 1663
1862
1863/** 1664/**
1864 * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc 1665 * nand_write - [MTD Interface] NAND write with ECC
1865 * @mtd: MTD device structure 1666 * @mtd: MTD device structure
1866 * @vecs: the iovectors to write
1867 * @count: number of vectors
1868 * @to: offset to write to 1667 * @to: offset to write to
1668 * @len: number of bytes to write
1869 * @retlen: pointer to variable to store the number of written bytes 1669 * @retlen: pointer to variable to store the number of written bytes
1670 * @buf: the data to write
1870 * 1671 *
1871 * NAND write with kvec. This just calls the ecc function 1672 * NAND write with ECC
1872 */ 1673 */
1873static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1674static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1874 loff_t to, size_t * retlen) 1675 size_t *retlen, const uint8_t *buf)
1875{ 1676{
1876 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); 1677 struct nand_chip *chip = mtd->priv;
1678 int ret;
1679
1680 /* Do not allow reads past end of device */
1681 if ((to + len) > mtd->size)
1682 return -EINVAL;
1683 if (!len)
1684 return 0;
1685
1686 nand_get_device(chip, mtd, FL_WRITING);
1687
1688 chip->ops.len = len;
1689 chip->ops.datbuf = (uint8_t *)buf;
1690 chip->ops.oobbuf = NULL;
1691
1692 ret = nand_do_write_ops(mtd, to, &chip->ops);
1693
1694 nand_release_device(mtd);
1695
1696 *retlen = chip->ops.retlen;
1697 return ret;
1877} 1698}
1878 1699
1879/** 1700/**
1880 * nand_writev_ecc - [MTD Interface] write with iovec with ecc 1701 * nand_do_write_oob - [MTD Interface] NAND write out-of-band
1881 * @mtd: MTD device structure 1702 * @mtd: MTD device structure
1882 * @vecs: the iovectors to write
1883 * @count: number of vectors
1884 * @to: offset to write to 1703 * @to: offset to write to
1885 * @retlen: pointer to variable to store the number of written bytes 1704 * @ops: oob operation description structure
1886 * @eccbuf: filesystem supplied oob data buffer
1887 * @oobsel: oob selection structure
1888 * 1705 *
1889 * NAND write with iovec with ecc 1706 * NAND write out-of-band
1890 */ 1707 */
1891static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1708static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1892 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) 1709 struct mtd_oob_ops *ops)
1893{ 1710{
1894 int i, page, len, total_len, ret = -EIO, written = 0, chipnr; 1711 int chipnr, page, status;
1895 int oob, numpages, autoplace = 0, startpage; 1712 struct nand_chip *chip = mtd->priv;
1896 struct nand_chip *this = mtd->priv;
1897 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
1898 u_char *oobbuf, *bufstart;
1899
1900 /* Preset written len for early exit */
1901 *retlen = 0;
1902
1903 /* Calculate total length of data */
1904 total_len = 0;
1905 for (i = 0; i < count; i++)
1906 total_len += (int) vecs[i].iov_len;
1907 1713
1908 DEBUG (MTD_DEBUG_LEVEL3, 1714 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1909 "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count); 1715 (unsigned int)to, (int)ops->len);
1910 1716
1911 /* Do not allow write past end of page */ 1717 /* Do not allow write past end of page */
1912 if ((to + total_len) > mtd->size) { 1718 if ((ops->ooboffs + ops->len) > mtd->oobsize) {
1913 DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n"); 1719 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1720 "Attempt to write past end of page\n");
1914 return -EINVAL; 1721 return -EINVAL;
1915 } 1722 }
1916 1723
1917 /* reject writes, which are not page aligned */ 1724 chipnr = (int)(to >> chip->chip_shift);
1918 if (NOTALIGNED (to) || NOTALIGNED(total_len)) { 1725 chip->select_chip(mtd, chipnr);
1919 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1920 return -EINVAL;
1921 }
1922 1726
1923 /* Grab the lock and see if the device is available */ 1727 /* Shift to get page */
1924 nand_get_device (this, mtd, FL_WRITING); 1728 page = (int)(to >> chip->page_shift);
1925 1729
1926 /* Get the current chip-nr */ 1730 /*
1927 chipnr = (int) (to >> this->chip_shift); 1731 * Reset the chip. Some chips (like the Toshiba TC5832DC found in one
1928 /* Select the NAND device */ 1732 * of my DiskOnChip 2000 test units) will clear the whole data page too
1929 this->select_chip(mtd, chipnr); 1733 * if we don't do this. I have no clue why, but I seem to have 'fixed'
1734 * it in the doc2000 driver in August 1999. dwmw2.
1735 */
1736 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1930 1737
1931 /* Check, if it is write protected */ 1738 /* Check, if it is write protected */
1932 if (nand_check_wp(mtd)) 1739 if (nand_check_wp(mtd))
1933 goto out; 1740 return -EROFS;
1934 1741
1935 /* if oobsel is NULL, use chip defaults */ 1742 /* Invalidate the page cache, if we write to the cached page */
1936 if (oobsel == NULL) 1743 if (page == chip->pagebuf)
1937 oobsel = &mtd->oobinfo; 1744 chip->pagebuf = -1;
1938 1745
1939 /* Autoplace of oob data ? Use the default placement scheme */ 1746 chip->oob_poi = chip->buffers.oobwbuf;
1940 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1747 memset(chip->oob_poi, 0xff, mtd->oobsize);
1941 oobsel = this->autooob; 1748 nand_fill_oob(chip, ops->oobbuf, ops);
1942 autoplace = 1; 1749 status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
1943 } 1750 memset(chip->oob_poi, 0xff, mtd->oobsize);
1944 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1945 autoplace = 1;
1946 1751
1947 /* Setup start page */ 1752 if (status)
1948 page = (int) (to >> this->page_shift); 1753 return status;
1949 /* Invalidate the page cache, if we write to the cached page */
1950 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1951 this->pagebuf = -1;
1952 1754
1953 startpage = page & this->pagemask; 1755 ops->retlen = ops->len;
1954 1756
1955 /* Loop until all kvec' data has been written */ 1757 return 0;
1956 len = 0; 1758}
1957 while (count) {
1958 /* If the given tuple is >= pagesize then
1959 * write it out from the iov
1960 */
1961 if ((vecs->iov_len - len) >= mtd->oobblock) {
1962 /* Calc number of pages we can write
1963 * out of this iov in one go */
1964 numpages = (vecs->iov_len - len) >> this->page_shift;
1965 /* Do not cross block boundaries */
1966 numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
1967 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
1968 bufstart = (u_char *)vecs->iov_base;
1969 bufstart += len;
1970 this->data_poi = bufstart;
1971 oob = 0;
1972 for (i = 1; i <= numpages; i++) {
1973 /* Write one page. If this is the last page to write
1974 * then use the real pageprogram command, else select
1975 * cached programming if supported by the chip.
1976 */
1977 ret = nand_write_page (mtd, this, page & this->pagemask,
1978 &oobbuf[oob], oobsel, i != numpages);
1979 if (ret)
1980 goto out;
1981 this->data_poi += mtd->oobblock;
1982 len += mtd->oobblock;
1983 oob += mtd->oobsize;
1984 page++;
1985 }
1986 /* Check, if we have to switch to the next tuple */
1987 if (len >= (int) vecs->iov_len) {
1988 vecs++;
1989 len = 0;
1990 count--;
1991 }
1992 } else {
1993 /* We must use the internal buffer, read data out of each
1994 * tuple until we have a full page to write
1995 */
1996 int cnt = 0;
1997 while (cnt < mtd->oobblock) {
1998 if (vecs->iov_base != NULL && vecs->iov_len)
1999 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
2000 /* Check, if we have to switch to the next tuple */
2001 if (len >= (int) vecs->iov_len) {
2002 vecs++;
2003 len = 0;
2004 count--;
2005 }
2006 }
2007 this->pagebuf = page;
2008 this->data_poi = this->data_buf;
2009 bufstart = this->data_poi;
2010 numpages = 1;
2011 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
2012 ret = nand_write_page (mtd, this, page & this->pagemask,
2013 oobbuf, oobsel, 0);
2014 if (ret)
2015 goto out;
2016 page++;
2017 }
2018 1759
2019 this->data_poi = bufstart; 1760/**
2020 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); 1761 * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
2021 if (ret) 1762 * @mtd: MTD device structure
2022 goto out; 1763 * @from: offset to read from
1764 * @ops: oob operation description structure
1765 */
1766static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1767 struct mtd_oob_ops *ops)
1768{
1769 void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
1770 const uint8_t *buf) = NULL;
1771 struct nand_chip *chip = mtd->priv;
1772 int ret = -ENOTSUPP;
2023 1773
2024 written += mtd->oobblock * numpages; 1774 ops->retlen = 0;
2025 /* All done ? */
2026 if (!count)
2027 break;
2028 1775
2029 startpage = page & this->pagemask; 1776 /* Do not allow writes past end of device */
2030 /* Check, if we cross a chip boundary */ 1777 if ((to + ops->len) > mtd->size) {
2031 if (!startpage) { 1778 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
2032 chipnr++; 1779 "Attempt read beyond end of device\n");
2033 this->select_chip(mtd, -1); 1780 return -EINVAL;
2034 this->select_chip(mtd, chipnr);
2035 }
2036 } 1781 }
2037 ret = 0;
2038out:
2039 /* Deselect and wake up anyone waiting on the device */
2040 nand_release_device(mtd);
2041 1782
2042 *retlen = written; 1783 nand_get_device(chip, mtd, FL_WRITING);
1784
1785 switch(ops->mode) {
1786 case MTD_OOB_PLACE:
1787 case MTD_OOB_AUTO:
1788 break;
1789
1790 case MTD_OOB_RAW:
1791 /* Replace the write_page algorithm temporary */
1792 write_page = chip->ecc.write_page;
1793 chip->ecc.write_page = nand_write_page_raw;
1794 break;
1795
1796 default:
1797 goto out;
1798 }
1799
1800 if (!ops->datbuf)
1801 ret = nand_do_write_oob(mtd, to, ops);
1802 else
1803 ret = nand_do_write_ops(mtd, to, ops);
1804
1805 if (unlikely(ops->mode == MTD_OOB_RAW))
1806 chip->ecc.write_page = write_page;
1807 out:
1808 nand_release_device(mtd);
2043 return ret; 1809 return ret;
2044} 1810}
2045 1811
@@ -2050,12 +1816,12 @@ out:
2050 * 1816 *
2051 * Standard erase command for NAND chips 1817 * Standard erase command for NAND chips
2052 */ 1818 */
2053static void single_erase_cmd (struct mtd_info *mtd, int page) 1819static void single_erase_cmd(struct mtd_info *mtd, int page)
2054{ 1820{
2055 struct nand_chip *this = mtd->priv; 1821 struct nand_chip *chip = mtd->priv;
2056 /* Send commands to erase a block */ 1822 /* Send commands to erase a block */
2057 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); 1823 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
2058 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); 1824 chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
2059} 1825}
2060 1826
2061/** 1827/**
@@ -2066,15 +1832,15 @@ static void single_erase_cmd (struct mtd_info *mtd, int page)
2066 * AND multi block erase command function 1832 * AND multi block erase command function
2067 * Erase 4 consecutive blocks 1833 * Erase 4 consecutive blocks
2068 */ 1834 */
2069static void multi_erase_cmd (struct mtd_info *mtd, int page) 1835static void multi_erase_cmd(struct mtd_info *mtd, int page)
2070{ 1836{
2071 struct nand_chip *this = mtd->priv; 1837 struct nand_chip *chip = mtd->priv;
2072 /* Send commands to erase a block */ 1838 /* Send commands to erase a block */
2073 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); 1839 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2074 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); 1840 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2075 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); 1841 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
2076 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); 1842 chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
2077 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); 1843 chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
2078} 1844}
2079 1845
2080/** 1846/**
@@ -2084,79 +1850,82 @@ static void multi_erase_cmd (struct mtd_info *mtd, int page)
2084 * 1850 *
2085 * Erase one ore more blocks 1851 * Erase one ore more blocks
2086 */ 1852 */
2087static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) 1853static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
2088{ 1854{
2089 return nand_erase_nand (mtd, instr, 0); 1855 return nand_erase_nand(mtd, instr, 0);
2090} 1856}
2091 1857
2092#define BBT_PAGE_MASK 0xffffff3f 1858#define BBT_PAGE_MASK 0xffffff3f
2093/** 1859/**
2094 * nand_erase_intern - [NAND Interface] erase block(s) 1860 * nand_erase_nand - [Internal] erase block(s)
2095 * @mtd: MTD device structure 1861 * @mtd: MTD device structure
2096 * @instr: erase instruction 1862 * @instr: erase instruction
2097 * @allowbbt: allow erasing the bbt area 1863 * @allowbbt: allow erasing the bbt area
2098 * 1864 *
2099 * Erase one ore more blocks 1865 * Erase one ore more blocks
2100 */ 1866 */
2101int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt) 1867int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
1868 int allowbbt)
2102{ 1869{
2103 int page, len, status, pages_per_block, ret, chipnr; 1870 int page, len, status, pages_per_block, ret, chipnr;
2104 struct nand_chip *this = mtd->priv; 1871 struct nand_chip *chip = mtd->priv;
2105 int rewrite_bbt[NAND_MAX_CHIPS]={0}; /* flags to indicate the page, if bbt needs to be rewritten. */ 1872 int rewrite_bbt[NAND_MAX_CHIPS]={0};
2106 unsigned int bbt_masked_page; /* bbt mask to compare to page being erased. */ 1873 unsigned int bbt_masked_page = 0xffffffff;
2107 /* It is used to see if the current page is in the same */
2108 /* 256 block group and the same bank as the bbt. */
2109 1874
2110 DEBUG (MTD_DEBUG_LEVEL3, 1875 DEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n",
2111 "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len); 1876 (unsigned int)instr->addr, (unsigned int)instr->len);
2112 1877
2113 /* Start address must align on block boundary */ 1878 /* Start address must align on block boundary */
2114 if (instr->addr & ((1 << this->phys_erase_shift) - 1)) { 1879 if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) {
2115 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); 1880 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
2116 return -EINVAL; 1881 return -EINVAL;
2117 } 1882 }
2118 1883
2119 /* Length must align on block boundary */ 1884 /* Length must align on block boundary */
2120 if (instr->len & ((1 << this->phys_erase_shift) - 1)) { 1885 if (instr->len & ((1 << chip->phys_erase_shift) - 1)) {
2121 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n"); 1886 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
1887 "Length not block aligned\n");
2122 return -EINVAL; 1888 return -EINVAL;
2123 } 1889 }
2124 1890
2125 /* Do not allow erase past end of device */ 1891 /* Do not allow erase past end of device */
2126 if ((instr->len + instr->addr) > mtd->size) { 1892 if ((instr->len + instr->addr) > mtd->size) {
2127 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n"); 1893 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
1894 "Erase past end of device\n");
2128 return -EINVAL; 1895 return -EINVAL;
2129 } 1896 }
2130 1897
2131 instr->fail_addr = 0xffffffff; 1898 instr->fail_addr = 0xffffffff;
2132 1899
2133 /* Grab the lock and see if the device is available */ 1900 /* Grab the lock and see if the device is available */
2134 nand_get_device (this, mtd, FL_ERASING); 1901 nand_get_device(chip, mtd, FL_ERASING);
2135 1902
2136 /* Shift to get first page */ 1903 /* Shift to get first page */
2137 page = (int) (instr->addr >> this->page_shift); 1904 page = (int)(instr->addr >> chip->page_shift);
2138 chipnr = (int) (instr->addr >> this->chip_shift); 1905 chipnr = (int)(instr->addr >> chip->chip_shift);
2139 1906
2140 /* Calculate pages in each block */ 1907 /* Calculate pages in each block */
2141 pages_per_block = 1 << (this->phys_erase_shift - this->page_shift); 1908 pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift);
2142 1909
2143 /* Select the NAND device */ 1910 /* Select the NAND device */
2144 this->select_chip(mtd, chipnr); 1911 chip->select_chip(mtd, chipnr);
2145 1912
2146 /* Check the WP bit */
2147 /* Check, if it is write protected */ 1913 /* Check, if it is write protected */
2148 if (nand_check_wp(mtd)) { 1914 if (nand_check_wp(mtd)) {
2149 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n"); 1915 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
1916 "Device is write protected!!!\n");
2150 instr->state = MTD_ERASE_FAILED; 1917 instr->state = MTD_ERASE_FAILED;
2151 goto erase_exit; 1918 goto erase_exit;
2152 } 1919 }
2153 1920
2154 /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */ 1921 /*
2155 if (this->options & BBT_AUTO_REFRESH) { 1922 * If BBT requires refresh, set the BBT page mask to see if the BBT
2156 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; 1923 * should be rewritten. Otherwise the mask is set to 0xffffffff which
2157 } else { 1924 * can not be matched. This is also done when the bbt is actually
2158 bbt_masked_page = 0xffffffff; /* should not match anything */ 1925 * erased to avoid recusrsive updates
2159 } 1926 */
1927 if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
1928 bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
2160 1929
2161 /* Loop through the pages */ 1930 /* Loop through the pages */
2162 len = instr->len; 1931 len = instr->len;
@@ -2164,64 +1933,77 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2164 instr->state = MTD_ERASING; 1933 instr->state = MTD_ERASING;
2165 1934
2166 while (len) { 1935 while (len) {
2167 /* Check if we have a bad block, we do not erase bad blocks ! */ 1936 /*
2168 if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { 1937 * heck if we have a bad block, we do not erase bad blocks !
2169 printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); 1938 */
1939 if (nand_block_checkbad(mtd, ((loff_t) page) <<
1940 chip->page_shift, 0, allowbbt)) {
1941 printk(KERN_WARNING "nand_erase: attempt to erase a "
1942 "bad block at page 0x%08x\n", page);
2170 instr->state = MTD_ERASE_FAILED; 1943 instr->state = MTD_ERASE_FAILED;
2171 goto erase_exit; 1944 goto erase_exit;
2172 } 1945 }
2173 1946
2174 /* Invalidate the page cache, if we erase the block which contains 1947 /*
2175 the current cached page */ 1948 * Invalidate the page cache, if we erase the block which
2176 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) 1949 * contains the current cached page
2177 this->pagebuf = -1; 1950 */
1951 if (page <= chip->pagebuf && chip->pagebuf <
1952 (page + pages_per_block))
1953 chip->pagebuf = -1;
2178 1954
2179 this->erase_cmd (mtd, page & this->pagemask); 1955 chip->erase_cmd(mtd, page & chip->pagemask);
2180 1956
2181 status = this->waitfunc (mtd, this, FL_ERASING); 1957 status = chip->waitfunc(mtd, chip);
2182 1958
2183 /* See if operation failed and additional status checks are available */ 1959 /*
2184 if ((status & NAND_STATUS_FAIL) && (this->errstat)) { 1960 * See if operation failed and additional status checks are
2185 status = this->errstat(mtd, this, FL_ERASING, status, page); 1961 * available
2186 } 1962 */
1963 if ((status & NAND_STATUS_FAIL) && (chip->errstat))
1964 status = chip->errstat(mtd, chip, FL_ERASING,
1965 status, page);
2187 1966
2188 /* See if block erase succeeded */ 1967 /* See if block erase succeeded */
2189 if (status & NAND_STATUS_FAIL) { 1968 if (status & NAND_STATUS_FAIL) {
2190 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); 1969 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: "
1970 "Failed erase, page 0x%08x\n", page);
2191 instr->state = MTD_ERASE_FAILED; 1971 instr->state = MTD_ERASE_FAILED;
2192 instr->fail_addr = (page << this->page_shift); 1972 instr->fail_addr = (page << chip->page_shift);
2193 goto erase_exit; 1973 goto erase_exit;
2194 } 1974 }
2195 1975
2196 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ 1976 /*
2197 if (this->options & BBT_AUTO_REFRESH) { 1977 * If BBT requires refresh, set the BBT rewrite flag to the
2198 if (((page & BBT_PAGE_MASK) == bbt_masked_page) && 1978 * page being erased
2199 (page != this->bbt_td->pages[chipnr])) { 1979 */
2200 rewrite_bbt[chipnr] = (page << this->page_shift); 1980 if (bbt_masked_page != 0xffffffff &&
2201 } 1981 (page & BBT_PAGE_MASK) == bbt_masked_page)
2202 } 1982 rewrite_bbt[chipnr] = (page << chip->page_shift);
2203 1983
2204 /* Increment page address and decrement length */ 1984 /* Increment page address and decrement length */
2205 len -= (1 << this->phys_erase_shift); 1985 len -= (1 << chip->phys_erase_shift);
2206 page += pages_per_block; 1986 page += pages_per_block;
2207 1987
2208 /* Check, if we cross a chip boundary */ 1988 /* Check, if we cross a chip boundary */
2209 if (len && !(page & this->pagemask)) { 1989 if (len && !(page & chip->pagemask)) {
2210 chipnr++; 1990 chipnr++;
2211 this->select_chip(mtd, -1); 1991 chip->select_chip(mtd, -1);
2212 this->select_chip(mtd, chipnr); 1992 chip->select_chip(mtd, chipnr);
2213
2214 /* if BBT requires refresh and BBT-PERCHIP,
2215 * set the BBT page mask to see if this BBT should be rewritten */
2216 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
2217 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
2218 }
2219 1993
1994 /*
1995 * If BBT requires refresh and BBT-PERCHIP, set the BBT
1996 * page mask to see if this BBT should be rewritten
1997 */
1998 if (bbt_masked_page != 0xffffffff &&
1999 (chip->bbt_td->options & NAND_BBT_PERCHIP))
2000 bbt_masked_page = chip->bbt_td->pages[chipnr] &
2001 BBT_PAGE_MASK;
2220 } 2002 }
2221 } 2003 }
2222 instr->state = MTD_ERASE_DONE; 2004 instr->state = MTD_ERASE_DONE;
2223 2005
2224erase_exit: 2006 erase_exit:
2225 2007
2226 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; 2008 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
2227 /* Do call back function */ 2009 /* Do call back function */
@@ -2231,16 +2013,21 @@ erase_exit:
2231 /* Deselect and wake up anyone waiting on the device */ 2013 /* Deselect and wake up anyone waiting on the device */
2232 nand_release_device(mtd); 2014 nand_release_device(mtd);
2233 2015
2234 /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */ 2016 /*
2235 if ((this->options & BBT_AUTO_REFRESH) && (!ret)) { 2017 * If BBT requires refresh and erase was successful, rewrite any
2236 for (chipnr = 0; chipnr < this->numchips; chipnr++) { 2018 * selected bad block tables
2237 if (rewrite_bbt[chipnr]) { 2019 */
2238 /* update the BBT for chip */ 2020 if (bbt_masked_page == 0xffffffff || ret)
2239 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", 2021 return ret;
2240 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); 2022
2241 nand_update_bbt (mtd, rewrite_bbt[chipnr]); 2023 for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
2242 } 2024 if (!rewrite_bbt[chipnr])
2243 } 2025 continue;
2026 /* update the BBT for chip */
2027 DEBUG(MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt "
2028 "(%d:0x%0x 0x%0x)\n", chipnr, rewrite_bbt[chipnr],
2029 chip->bbt_td->pages[chipnr]);
2030 nand_update_bbt(mtd, rewrite_bbt[chipnr]);
2244 } 2031 }
2245 2032
2246 /* Return more or less happy */ 2033 /* Return more or less happy */
@@ -2253,51 +2040,50 @@ erase_exit:
2253 * 2040 *
2254 * Sync is actually a wait for chip ready function 2041 * Sync is actually a wait for chip ready function
2255 */ 2042 */
2256static void nand_sync (struct mtd_info *mtd) 2043static void nand_sync(struct mtd_info *mtd)
2257{ 2044{
2258 struct nand_chip *this = mtd->priv; 2045 struct nand_chip *chip = mtd->priv;
2259 2046
2260 DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n"); 2047 DEBUG(MTD_DEBUG_LEVEL3, "nand_sync: called\n");
2261 2048
2262 /* Grab the lock and see if the device is available */ 2049 /* Grab the lock and see if the device is available */
2263 nand_get_device (this, mtd, FL_SYNCING); 2050 nand_get_device(chip, mtd, FL_SYNCING);
2264 /* Release it and go back */ 2051 /* Release it and go back */
2265 nand_release_device (mtd); 2052 nand_release_device(mtd);
2266} 2053}
2267 2054
2268
2269/** 2055/**
2270 * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad 2056 * nand_block_isbad - [MTD Interface] Check if block at offset is bad
2271 * @mtd: MTD device structure 2057 * @mtd: MTD device structure
2272 * @ofs: offset relative to mtd start 2058 * @ofs: offset relative to mtd start
2273 */ 2059 */
2274static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) 2060static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
2275{ 2061{
2276 /* Check for invalid offset */ 2062 /* Check for invalid offset */
2277 if (ofs > mtd->size) 2063 if (offs > mtd->size)
2278 return -EINVAL; 2064 return -EINVAL;
2279 2065
2280 return nand_block_checkbad (mtd, ofs, 1, 0); 2066 return nand_block_checkbad(mtd, offs, 1, 0);
2281} 2067}
2282 2068
2283/** 2069/**
2284 * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad 2070 * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
2285 * @mtd: MTD device structure 2071 * @mtd: MTD device structure
2286 * @ofs: offset relative to mtd start 2072 * @ofs: offset relative to mtd start
2287 */ 2073 */
2288static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) 2074static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
2289{ 2075{
2290 struct nand_chip *this = mtd->priv; 2076 struct nand_chip *chip = mtd->priv;
2291 int ret; 2077 int ret;
2292 2078
2293 if ((ret = nand_block_isbad(mtd, ofs))) { 2079 if ((ret = nand_block_isbad(mtd, ofs))) {
2294 /* If it was bad already, return success and do nothing. */ 2080 /* If it was bad already, return success and do nothing. */
2295 if (ret > 0) 2081 if (ret > 0)
2296 return 0; 2082 return 0;
2297 return ret; 2083 return ret;
2298 } 2084 }
2299 2085
2300 return this->block_markbad(mtd, ofs); 2086 return chip->block_markbad(mtd, ofs);
2301} 2087}
2302 2088
2303/** 2089/**
@@ -2306,9 +2092,9 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
2306 */ 2092 */
2307static int nand_suspend(struct mtd_info *mtd) 2093static int nand_suspend(struct mtd_info *mtd)
2308{ 2094{
2309 struct nand_chip *this = mtd->priv; 2095 struct nand_chip *chip = mtd->priv;
2310 2096
2311 return nand_get_device (this, mtd, FL_PM_SUSPENDED); 2097 return nand_get_device(chip, mtd, FL_PM_SUSPENDED);
2312} 2098}
2313 2099
2314/** 2100/**
@@ -2317,373 +2103,385 @@ static int nand_suspend(struct mtd_info *mtd)
2317 */ 2103 */
2318static void nand_resume(struct mtd_info *mtd) 2104static void nand_resume(struct mtd_info *mtd)
2319{ 2105{
2320 struct nand_chip *this = mtd->priv; 2106 struct nand_chip *chip = mtd->priv;
2321 2107
2322 if (this->state == FL_PM_SUSPENDED) 2108 if (chip->state == FL_PM_SUSPENDED)
2323 nand_release_device(mtd); 2109 nand_release_device(mtd);
2324 else 2110 else
2325 printk(KERN_ERR "resume() called for the chip which is not " 2111 printk(KERN_ERR "nand_resume() called for a chip which is not "
2326 "in suspended state\n"); 2112 "in suspended state\n");
2327
2328} 2113}
2329 2114
2330 2115/*
2331/** 2116 * Set default functions
2332 * nand_scan - [NAND Interface] Scan for the NAND device
2333 * @mtd: MTD device structure
2334 * @maxchips: Number of chips to scan for
2335 *
2336 * This fills out all the not initialized function pointers
2337 * with the defaults.
2338 * The flash ID is read and the mtd/chip structures are
2339 * filled with the appropriate values. Buffers are allocated if
2340 * they are not provided by the board driver
2341 *
2342 */ 2117 */
2343int nand_scan (struct mtd_info *mtd, int maxchips) 2118static void nand_set_defaults(struct nand_chip *chip, int busw)
2344{ 2119{
2345 int i, nand_maf_id, nand_dev_id, busw, maf_id;
2346 struct nand_chip *this = mtd->priv;
2347
2348 /* Get buswidth to select the correct functions*/
2349 busw = this->options & NAND_BUSWIDTH_16;
2350
2351 /* check for proper chip_delay setup, set 20us if not */ 2120 /* check for proper chip_delay setup, set 20us if not */
2352 if (!this->chip_delay) 2121 if (!chip->chip_delay)
2353 this->chip_delay = 20; 2122 chip->chip_delay = 20;
2354 2123
2355 /* check, if a user supplied command function given */ 2124 /* check, if a user supplied command function given */
2356 if (this->cmdfunc == NULL) 2125 if (chip->cmdfunc == NULL)
2357 this->cmdfunc = nand_command; 2126 chip->cmdfunc = nand_command;
2358 2127
2359 /* check, if a user supplied wait function given */ 2128 /* check, if a user supplied wait function given */
2360 if (this->waitfunc == NULL) 2129 if (chip->waitfunc == NULL)
2361 this->waitfunc = nand_wait; 2130 chip->waitfunc = nand_wait;
2362 2131
2363 if (!this->select_chip) 2132 if (!chip->select_chip)
2364 this->select_chip = nand_select_chip; 2133 chip->select_chip = nand_select_chip;
2365 if (!this->write_byte) 2134 if (!chip->read_byte)
2366 this->write_byte = busw ? nand_write_byte16 : nand_write_byte; 2135 chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
2367 if (!this->read_byte) 2136 if (!chip->read_word)
2368 this->read_byte = busw ? nand_read_byte16 : nand_read_byte; 2137 chip->read_word = nand_read_word;
2369 if (!this->write_word) 2138 if (!chip->block_bad)
2370 this->write_word = nand_write_word; 2139 chip->block_bad = nand_block_bad;
2371 if (!this->read_word) 2140 if (!chip->block_markbad)
2372 this->read_word = nand_read_word; 2141 chip->block_markbad = nand_default_block_markbad;
2373 if (!this->block_bad) 2142 if (!chip->write_buf)
2374 this->block_bad = nand_block_bad; 2143 chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
2375 if (!this->block_markbad) 2144 if (!chip->read_buf)
2376 this->block_markbad = nand_default_block_markbad; 2145 chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
2377 if (!this->write_buf) 2146 if (!chip->verify_buf)
2378 this->write_buf = busw ? nand_write_buf16 : nand_write_buf; 2147 chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
2379 if (!this->read_buf) 2148 if (!chip->scan_bbt)
2380 this->read_buf = busw ? nand_read_buf16 : nand_read_buf; 2149 chip->scan_bbt = nand_default_bbt;
2381 if (!this->verify_buf) 2150
2382 this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; 2151 if (!chip->controller) {
2383 if (!this->scan_bbt) 2152 chip->controller = &chip->hwcontrol;
2384 this->scan_bbt = nand_default_bbt; 2153 spin_lock_init(&chip->controller->lock);
2154 init_waitqueue_head(&chip->controller->wq);
2155 }
2156
2157}
2158
2159/*
2160 * Get the flash and manufacturer id and lookup if the type is supported
2161 */
2162static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
2163 struct nand_chip *chip,
2164 int busw, int *maf_id)
2165{
2166 struct nand_flash_dev *type = NULL;
2167 int i, dev_id, maf_idx;
2385 2168
2386 /* Select the device */ 2169 /* Select the device */
2387 this->select_chip(mtd, 0); 2170 chip->select_chip(mtd, 0);
2388 2171
2389 /* Send the command for reading device ID */ 2172 /* Send the command for reading device ID */
2390 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); 2173 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
2391 2174
2392 /* Read manufacturer and device IDs */ 2175 /* Read manufacturer and device IDs */
2393 nand_maf_id = this->read_byte(mtd); 2176 *maf_id = chip->read_byte(mtd);
2394 nand_dev_id = this->read_byte(mtd); 2177 dev_id = chip->read_byte(mtd);
2395 2178
2396 /* Print and store flash device information */ 2179 /* Lookup the flash id */
2397 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 2180 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
2181 if (dev_id == nand_flash_ids[i].id) {
2182 type = &nand_flash_ids[i];
2183 break;
2184 }
2185 }
2398 2186
2399 if (nand_dev_id != nand_flash_ids[i].id) 2187 if (!type)
2400 continue; 2188 return ERR_PTR(-ENODEV);
2189
2190 if (!mtd->name)
2191 mtd->name = type->name;
2192
2193 chip->chipsize = type->chipsize << 20;
2194
2195 /* Newer devices have all the information in additional id bytes */
2196 if (!type->pagesize) {
2197 int extid;
2198 /* The 3rd id byte contains non relevant data ATM */
2199 extid = chip->read_byte(mtd);
2200 /* The 4th id byte is the important one */
2201 extid = chip->read_byte(mtd);
2202 /* Calc pagesize */
2203 mtd->writesize = 1024 << (extid & 0x3);
2204 extid >>= 2;
2205 /* Calc oobsize */
2206 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
2207 extid >>= 2;
2208 /* Calc blocksize. Blocksize is multiples of 64KiB */
2209 mtd->erasesize = (64 * 1024) << (extid & 0x03);
2210 extid >>= 2;
2211 /* Get buswidth information */
2212 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
2401 2213
2402 if (!mtd->name) mtd->name = nand_flash_ids[i].name; 2214 } else {
2403 this->chipsize = nand_flash_ids[i].chipsize << 20; 2215 /*
2404 2216 * Old devices have chip data hardcoded in the device id table
2405 /* New devices have all the information in additional id bytes */ 2217 */
2406 if (!nand_flash_ids[i].pagesize) { 2218 mtd->erasesize = type->erasesize;
2407 int extid; 2219 mtd->writesize = type->pagesize;
2408 /* The 3rd id byte contains non relevant data ATM */ 2220 mtd->oobsize = mtd->writesize / 32;
2409 extid = this->read_byte(mtd); 2221 busw = type->options & NAND_BUSWIDTH_16;
2410 /* The 4th id byte is the important one */ 2222 }
2411 extid = this->read_byte(mtd);
2412 /* Calc pagesize */
2413 mtd->oobblock = 1024 << (extid & 0x3);
2414 extid >>= 2;
2415 /* Calc oobsize */
2416 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
2417 extid >>= 2;
2418 /* Calc blocksize. Blocksize is multiples of 64KiB */
2419 mtd->erasesize = (64 * 1024) << (extid & 0x03);
2420 extid >>= 2;
2421 /* Get buswidth information */
2422 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
2423 2223
2424 } else { 2224 /* Try to identify manufacturer */
2425 /* Old devices have this data hardcoded in the 2225 for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) {
2426 * device id table */ 2226 if (nand_manuf_ids[maf_idx].id == *maf_id)
2427 mtd->erasesize = nand_flash_ids[i].erasesize; 2227 break;
2428 mtd->oobblock = nand_flash_ids[i].pagesize; 2228 }
2429 mtd->oobsize = mtd->oobblock / 32;
2430 busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
2431 }
2432 2229
2433 /* Try to identify manufacturer */ 2230 /*
2434 for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) { 2231 * Check, if buswidth is correct. Hardware drivers should set
2435 if (nand_manuf_ids[maf_id].id == nand_maf_id) 2232 * chip correct !
2436 break; 2233 */
2437 } 2234 if (busw != (chip->options & NAND_BUSWIDTH_16)) {
2235 printk(KERN_INFO "NAND device: Manufacturer ID:"
2236 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
2237 dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
2238 printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
2239 (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
2240 busw ? 16 : 8);
2241 return ERR_PTR(-EINVAL);
2242 }
2438 2243
2439 /* Check, if buswidth is correct. Hardware drivers should set 2244 /* Calculate the address shift from the page size */
2440 * this correct ! */ 2245 chip->page_shift = ffs(mtd->writesize) - 1;
2441 if (busw != (this->options & NAND_BUSWIDTH_16)) { 2246 /* Convert chipsize to number of pages per chip -1. */
2442 printk (KERN_INFO "NAND device: Manufacturer ID:" 2247 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
2443 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2444 nand_manuf_ids[maf_id].name , mtd->name);
2445 printk (KERN_WARNING
2446 "NAND bus width %d instead %d bit\n",
2447 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
2448 busw ? 16 : 8);
2449 this->select_chip(mtd, -1);
2450 return 1;
2451 }
2452 2248
2453 /* Calculate the address shift from the page size */ 2249 chip->bbt_erase_shift = chip->phys_erase_shift =
2454 this->page_shift = ffs(mtd->oobblock) - 1; 2250 ffs(mtd->erasesize) - 1;
2455 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; 2251 chip->chip_shift = ffs(chip->chipsize) - 1;
2456 this->chip_shift = ffs(this->chipsize) - 1;
2457
2458 /* Set the bad block position */
2459 this->badblockpos = mtd->oobblock > 512 ?
2460 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2461
2462 /* Get chip options, preserve non chip based options */
2463 this->options &= ~NAND_CHIPOPTIONS_MSK;
2464 this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
2465 /* Set this as a default. Board drivers can override it, if neccecary */
2466 this->options |= NAND_NO_AUTOINCR;
2467 /* Check if this is a not a samsung device. Do not clear the options
2468 * for chips which are not having an extended id.
2469 */
2470 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
2471 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2472 2252
2473 /* Check for AND chips with 4 page planes */ 2253 /* Set the bad block position */
2474 if (this->options & NAND_4PAGE_ARRAY) 2254 chip->badblockpos = mtd->writesize > 512 ?
2475 this->erase_cmd = multi_erase_cmd; 2255 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2476 else
2477 this->erase_cmd = single_erase_cmd;
2478 2256
2479 /* Do not replace user supplied command function ! */ 2257 /* Get chip options, preserve non chip based options */
2480 if (mtd->oobblock > 512 && this->cmdfunc == nand_command) 2258 chip->options &= ~NAND_CHIPOPTIONS_MSK;
2481 this->cmdfunc = nand_command_lp; 2259 chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
2482 2260
2483 printk (KERN_INFO "NAND device: Manufacturer ID:" 2261 /*
2484 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2262 * Set chip as a default. Board drivers can override it, if necessary
2485 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); 2263 */
2486 break; 2264 chip->options |= NAND_NO_AUTOINCR;
2487 } 2265
2266 /* Check if chip is a not a samsung device. Do not clear the
2267 * options for chips which are not having an extended id.
2268 */
2269 if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
2270 chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2271
2272 /* Check for AND chips with 4 page planes */
2273 if (chip->options & NAND_4PAGE_ARRAY)
2274 chip->erase_cmd = multi_erase_cmd;
2275 else
2276 chip->erase_cmd = single_erase_cmd;
2277
2278 /* Do not replace user supplied command function ! */
2279 if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
2280 chip->cmdfunc = nand_command_lp;
2281
2282 printk(KERN_INFO "NAND device: Manufacturer ID:"
2283 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
2284 nand_manuf_ids[maf_idx].name, type->name);
2285
2286 return type;
2287}
2288
2289/* module_text_address() isn't exported, and it's mostly a pointless
2290 test if this is a module _anyway_ -- they'd have to try _really_ hard
2291 to call us from in-kernel code if the core NAND support is modular. */
2292#ifdef MODULE
2293#define caller_is_module() (1)
2294#else
2295#define caller_is_module() \
2296 module_text_address((unsigned long)__builtin_return_address(0))
2297#endif
2488 2298
2489 if (!nand_flash_ids[i].name) { 2299/**
2490 printk (KERN_WARNING "No NAND device found!!!\n"); 2300 * nand_scan - [NAND Interface] Scan for the NAND device
2491 this->select_chip(mtd, -1); 2301 * @mtd: MTD device structure
2492 return 1; 2302 * @maxchips: Number of chips to scan for
2303 *
2304 * This fills out all the uninitialized function pointers
2305 * with the defaults.
2306 * The flash ID is read and the mtd/chip structures are
2307 * filled with the appropriate values.
2308 * The mtd->owner field must be set to the module of the caller
2309 *
2310 */
2311int nand_scan(struct mtd_info *mtd, int maxchips)
2312{
2313 int i, busw, nand_maf_id;
2314 struct nand_chip *chip = mtd->priv;
2315 struct nand_flash_dev *type;
2316
2317 /* Many callers got this wrong, so check for it for a while... */
2318 if (!mtd->owner && caller_is_module()) {
2319 printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
2320 BUG();
2493 } 2321 }
2494 2322
2495 for (i=1; i < maxchips; i++) { 2323 /* Get buswidth to select the correct functions */
2496 this->select_chip(mtd, i); 2324 busw = chip->options & NAND_BUSWIDTH_16;
2325 /* Set the default functions */
2326 nand_set_defaults(chip, busw);
2497 2327
2498 /* Send the command for reading device ID */ 2328 /* Read the flash type */
2499 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); 2329 type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
2330
2331 if (IS_ERR(type)) {
2332 printk(KERN_WARNING "No NAND device found!!!\n");
2333 chip->select_chip(mtd, -1);
2334 return PTR_ERR(type);
2335 }
2500 2336
2337 /* Check for a chip array */
2338 for (i = 1; i < maxchips; i++) {
2339 chip->select_chip(mtd, i);
2340 /* Send the command for reading device ID */
2341 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
2501 /* Read manufacturer and device IDs */ 2342 /* Read manufacturer and device IDs */
2502 if (nand_maf_id != this->read_byte(mtd) || 2343 if (nand_maf_id != chip->read_byte(mtd) ||
2503 nand_dev_id != this->read_byte(mtd)) 2344 type->id != chip->read_byte(mtd))
2504 break; 2345 break;
2505 } 2346 }
2506 if (i > 1) 2347 if (i > 1)
2507 printk(KERN_INFO "%d NAND chips detected\n", i); 2348 printk(KERN_INFO "%d NAND chips detected\n", i);
2508 2349
2509 /* Allocate buffers, if neccecary */ 2350 /* Store the number of chips and calc total size for mtd */
2510 if (!this->oob_buf) { 2351 chip->numchips = i;
2511 size_t len; 2352 mtd->size = i * chip->chipsize;
2512 len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
2513 this->oob_buf = kmalloc (len, GFP_KERNEL);
2514 if (!this->oob_buf) {
2515 printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
2516 return -ENOMEM;
2517 }
2518 this->options |= NAND_OOBBUF_ALLOC;
2519 }
2520 2353
2521 if (!this->data_buf) { 2354 /* Preset the internal oob write buffer */
2522 size_t len; 2355 memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
2523 len = mtd->oobblock + mtd->oobsize;
2524 this->data_buf = kmalloc (len, GFP_KERNEL);
2525 if (!this->data_buf) {
2526 if (this->options & NAND_OOBBUF_ALLOC)
2527 kfree (this->oob_buf);
2528 printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
2529 return -ENOMEM;
2530 }
2531 this->options |= NAND_DATABUF_ALLOC;
2532 }
2533 2356
2534 /* Store the number of chips and calc total size for mtd */ 2357 /*
2535 this->numchips = i; 2358 * If no default placement scheme is given, select an appropriate one
2536 mtd->size = i * this->chipsize; 2359 */
2537 /* Convert chipsize to number of pages per chip -1. */ 2360 if (!chip->ecc.layout) {
2538 this->pagemask = (this->chipsize >> this->page_shift) - 1;
2539 /* Preset the internal oob buffer */
2540 memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
2541
2542 /* If no default placement scheme is given, select an
2543 * appropriate one */
2544 if (!this->autooob) {
2545 /* Select the appropriate default oob placement scheme for
2546 * placement agnostic filesystems */
2547 switch (mtd->oobsize) { 2361 switch (mtd->oobsize) {
2548 case 8: 2362 case 8:
2549 this->autooob = &nand_oob_8; 2363 chip->ecc.layout = &nand_oob_8;
2550 break; 2364 break;
2551 case 16: 2365 case 16:
2552 this->autooob = &nand_oob_16; 2366 chip->ecc.layout = &nand_oob_16;
2553 break; 2367 break;
2554 case 64: 2368 case 64:
2555 this->autooob = &nand_oob_64; 2369 chip->ecc.layout = &nand_oob_64;
2556 break; 2370 break;
2557 default: 2371 default:
2558 printk (KERN_WARNING "No oob scheme defined for oobsize %d\n", 2372 printk(KERN_WARNING "No oob scheme defined for "
2559 mtd->oobsize); 2373 "oobsize %d\n", mtd->oobsize);
2560 BUG(); 2374 BUG();
2561 } 2375 }
2562 } 2376 }
2563 2377
2564 /* The number of bytes available for the filesystem to place fs dependend
2565 * oob data */
2566 mtd->oobavail = 0;
2567 for (i = 0; this->autooob->oobfree[i][1]; i++)
2568 mtd->oobavail += this->autooob->oobfree[i][1];
2569
2570 /* 2378 /*
2571 * check ECC mode, default to software 2379 * check ECC mode, default to software if 3byte/512byte hardware ECC is
2572 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize 2380 * selected and we have 256 byte pagesize fallback to software ECC
2573 * fallback to software ECC 2381 */
2574 */ 2382 switch (chip->ecc.mode) {
2575 this->eccsize = 256; /* set default eccsize */ 2383 case NAND_ECC_HW:
2576 this->eccbytes = 3; 2384 /* Use standard hwecc read page function ? */
2577 2385 if (!chip->ecc.read_page)
2578 switch (this->eccmode) { 2386 chip->ecc.read_page = nand_read_page_hwecc;
2579 case NAND_ECC_HW12_2048: 2387 if (!chip->ecc.write_page)
2580 if (mtd->oobblock < 2048) { 2388 chip->ecc.write_page = nand_write_page_hwecc;
2581 printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", 2389 if (!chip->ecc.read_oob)
2582 mtd->oobblock); 2390 chip->ecc.read_oob = nand_read_oob_std;
2583 this->eccmode = NAND_ECC_SOFT; 2391 if (!chip->ecc.write_oob)
2584 this->calculate_ecc = nand_calculate_ecc; 2392 chip->ecc.write_oob = nand_write_oob_std;
2585 this->correct_data = nand_correct_data; 2393
2586 } else 2394 case NAND_ECC_HW_SYNDROME:
2587 this->eccsize = 2048; 2395 if (!chip->ecc.calculate || !chip->ecc.correct ||
2588 break; 2396 !chip->ecc.hwctl) {
2589 2397 printk(KERN_WARNING "No ECC functions supplied, "
2590 case NAND_ECC_HW3_512: 2398 "Hardware ECC not possible\n");
2591 case NAND_ECC_HW6_512: 2399 BUG();
2592 case NAND_ECC_HW8_512: 2400 }
2593 if (mtd->oobblock == 256) { 2401 /* Use standard syndrome read/write page function ? */
2594 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); 2402 if (!chip->ecc.read_page)
2595 this->eccmode = NAND_ECC_SOFT; 2403 chip->ecc.read_page = nand_read_page_syndrome;
2596 this->calculate_ecc = nand_calculate_ecc; 2404 if (!chip->ecc.write_page)
2597 this->correct_data = nand_correct_data; 2405 chip->ecc.write_page = nand_write_page_syndrome;
2598 } else 2406 if (!chip->ecc.read_oob)
2599 this->eccsize = 512; /* set eccsize to 512 */ 2407 chip->ecc.read_oob = nand_read_oob_syndrome;
2600 break; 2408 if (!chip->ecc.write_oob)
2409 chip->ecc.write_oob = nand_write_oob_syndrome;
2410
2411 if (mtd->writesize >= chip->ecc.size)
2412 break;
2413 printk(KERN_WARNING "%d byte HW ECC not possible on "
2414 "%d byte page size, fallback to SW ECC\n",
2415 chip->ecc.size, mtd->writesize);
2416 chip->ecc.mode = NAND_ECC_SOFT;
2601 2417
2602 case NAND_ECC_HW3_256: 2418 case NAND_ECC_SOFT:
2419 chip->ecc.calculate = nand_calculate_ecc;
2420 chip->ecc.correct = nand_correct_data;
2421 chip->ecc.read_page = nand_read_page_swecc;
2422 chip->ecc.write_page = nand_write_page_swecc;
2423 chip->ecc.read_oob = nand_read_oob_std;
2424 chip->ecc.write_oob = nand_write_oob_std;
2425 chip->ecc.size = 256;
2426 chip->ecc.bytes = 3;
2603 break; 2427 break;
2604 2428
2605 case NAND_ECC_NONE: 2429 case NAND_ECC_NONE:
2606 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); 2430 printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
2607 this->eccmode = NAND_ECC_NONE; 2431 "This is not recommended !!\n");
2432 chip->ecc.read_page = nand_read_page_raw;
2433 chip->ecc.write_page = nand_write_page_raw;
2434 chip->ecc.read_oob = nand_read_oob_std;
2435 chip->ecc.write_oob = nand_write_oob_std;
2436 chip->ecc.size = mtd->writesize;
2437 chip->ecc.bytes = 0;
2608 break; 2438 break;
2609
2610 case NAND_ECC_SOFT:
2611 this->calculate_ecc = nand_calculate_ecc;
2612 this->correct_data = nand_correct_data;
2613 break;
2614
2615 default: 2439 default:
2616 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); 2440 printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
2617 BUG(); 2441 chip->ecc.mode);
2618 }
2619
2620 /* Check hardware ecc function availability and adjust number of ecc bytes per
2621 * calculation step
2622 */
2623 switch (this->eccmode) {
2624 case NAND_ECC_HW12_2048:
2625 this->eccbytes += 4;
2626 case NAND_ECC_HW8_512:
2627 this->eccbytes += 2;
2628 case NAND_ECC_HW6_512:
2629 this->eccbytes += 3;
2630 case NAND_ECC_HW3_512:
2631 case NAND_ECC_HW3_256:
2632 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
2633 break;
2634 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
2635 BUG(); 2442 BUG();
2636 } 2443 }
2637 2444
2638 mtd->eccsize = this->eccsize; 2445 /*
2639 2446 * The number of bytes available for a client to place data into
2640 /* Set the number of read / write steps for one page to ensure ECC generation */ 2447 * the out of band area
2641 switch (this->eccmode) { 2448 */
2642 case NAND_ECC_HW12_2048: 2449 chip->ecc.layout->oobavail = 0;
2643 this->eccsteps = mtd->oobblock / 2048; 2450 for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
2644 break; 2451 chip->ecc.layout->oobavail +=
2645 case NAND_ECC_HW3_512: 2452 chip->ecc.layout->oobfree[i].length;
2646 case NAND_ECC_HW6_512:
2647 case NAND_ECC_HW8_512:
2648 this->eccsteps = mtd->oobblock / 512;
2649 break;
2650 case NAND_ECC_HW3_256:
2651 case NAND_ECC_SOFT:
2652 this->eccsteps = mtd->oobblock / 256;
2653 break;
2654 2453
2655 case NAND_ECC_NONE: 2454 /*
2656 this->eccsteps = 1; 2455 * Set the number of read / write steps for one page depending on ECC
2657 break; 2456 * mode
2457 */
2458 chip->ecc.steps = mtd->writesize / chip->ecc.size;
2459 if(chip->ecc.steps * chip->ecc.size != mtd->writesize) {
2460 printk(KERN_WARNING "Invalid ecc parameters\n");
2461 BUG();
2658 } 2462 }
2463 chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
2659 2464
2660 /* Initialize state, waitqueue and spinlock */ 2465 /* Initialize state */
2661 this->state = FL_READY; 2466 chip->state = FL_READY;
2662 init_waitqueue_head (&this->wq);
2663 spin_lock_init (&this->chip_lock);
2664 2467
2665 /* De-select the device */ 2468 /* De-select the device */
2666 this->select_chip(mtd, -1); 2469 chip->select_chip(mtd, -1);
2667 2470
2668 /* Invalidate the pagebuffer reference */ 2471 /* Invalidate the pagebuffer reference */
2669 this->pagebuf = -1; 2472 chip->pagebuf = -1;
2670 2473
2671 /* Fill in remaining MTD driver data */ 2474 /* Fill in remaining MTD driver data */
2672 mtd->type = MTD_NANDFLASH; 2475 mtd->type = MTD_NANDFLASH;
2673 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; 2476 mtd->flags = MTD_CAP_NANDFLASH;
2674 mtd->ecctype = MTD_ECC_SW; 2477 mtd->ecctype = MTD_ECC_SW;
2675 mtd->erase = nand_erase; 2478 mtd->erase = nand_erase;
2676 mtd->point = NULL; 2479 mtd->point = NULL;
2677 mtd->unpoint = NULL; 2480 mtd->unpoint = NULL;
2678 mtd->read = nand_read; 2481 mtd->read = nand_read;
2679 mtd->write = nand_write; 2482 mtd->write = nand_write;
2680 mtd->read_ecc = nand_read_ecc;
2681 mtd->write_ecc = nand_write_ecc;
2682 mtd->read_oob = nand_read_oob; 2483 mtd->read_oob = nand_read_oob;
2683 mtd->write_oob = nand_write_oob; 2484 mtd->write_oob = nand_write_oob;
2684 mtd->readv = NULL;
2685 mtd->writev = nand_writev;
2686 mtd->writev_ecc = nand_writev_ecc;
2687 mtd->sync = nand_sync; 2485 mtd->sync = nand_sync;
2688 mtd->lock = NULL; 2486 mtd->lock = NULL;
2689 mtd->unlock = NULL; 2487 mtd->unlock = NULL;
@@ -2692,47 +2490,38 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2692 mtd->block_isbad = nand_block_isbad; 2490 mtd->block_isbad = nand_block_isbad;
2693 mtd->block_markbad = nand_block_markbad; 2491 mtd->block_markbad = nand_block_markbad;
2694 2492
2695 /* and make the autooob the default one */ 2493 /* propagate ecc.layout to mtd_info */
2696 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 2494 mtd->ecclayout = chip->ecc.layout;
2697
2698 mtd->owner = THIS_MODULE;
2699 2495
2700 /* Check, if we should skip the bad block table scan */ 2496 /* Check, if we should skip the bad block table scan */
2701 if (this->options & NAND_SKIP_BBTSCAN) 2497 if (chip->options & NAND_SKIP_BBTSCAN)
2702 return 0; 2498 return 0;
2703 2499
2704 /* Build bad block table */ 2500 /* Build bad block table */
2705 return this->scan_bbt (mtd); 2501 return chip->scan_bbt(mtd);
2706} 2502}
2707 2503
2708/** 2504/**
2709 * nand_release - [NAND Interface] Free resources held by the NAND device 2505 * nand_release - [NAND Interface] Free resources held by the NAND device
2710 * @mtd: MTD device structure 2506 * @mtd: MTD device structure
2711*/ 2507*/
2712void nand_release (struct mtd_info *mtd) 2508void nand_release(struct mtd_info *mtd)
2713{ 2509{
2714 struct nand_chip *this = mtd->priv; 2510 struct nand_chip *chip = mtd->priv;
2715 2511
2716#ifdef CONFIG_MTD_PARTITIONS 2512#ifdef CONFIG_MTD_PARTITIONS
2717 /* Deregister partitions */ 2513 /* Deregister partitions */
2718 del_mtd_partitions (mtd); 2514 del_mtd_partitions(mtd);
2719#endif 2515#endif
2720 /* Deregister the device */ 2516 /* Deregister the device */
2721 del_mtd_device (mtd); 2517 del_mtd_device(mtd);
2722 2518
2723 /* Free bad block table memory */ 2519 /* Free bad block table memory */
2724 kfree (this->bbt); 2520 kfree(chip->bbt);
2725 /* Buffer allocated by nand_scan ? */
2726 if (this->options & NAND_OOBBUF_ALLOC)
2727 kfree (this->oob_buf);
2728 /* Buffer allocated by nand_scan ? */
2729 if (this->options & NAND_DATABUF_ALLOC)
2730 kfree (this->data_buf);
2731} 2521}
2732 2522
2733EXPORT_SYMBOL_GPL (nand_scan); 2523EXPORT_SYMBOL_GPL(nand_scan);
2734EXPORT_SYMBOL_GPL (nand_release); 2524EXPORT_SYMBOL_GPL(nand_release);
2735
2736 2525
2737static int __init nand_base_init(void) 2526static int __init nand_base_init(void)
2738{ 2527{
@@ -2748,6 +2537,6 @@ static void __exit nand_base_exit(void)
2748module_init(nand_base_init); 2537module_init(nand_base_init);
2749module_exit(nand_base_exit); 2538module_exit(nand_base_exit);
2750 2539
2751MODULE_LICENSE ("GPL"); 2540MODULE_LICENSE("GPL");
2752MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); 2541MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
2753MODULE_DESCRIPTION ("Generic NAND flash driver code"); 2542MODULE_DESCRIPTION("Generic NAND flash driver code");
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index ca286999fe08..a612c4ea8194 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -48,7 +48,7 @@
48 * 48 *
49 * Following assumptions are made: 49 * Following assumptions are made:
50 * - bbts start at a page boundary, if autolocated on a block boundary 50 * - bbts start at a page boundary, if autolocated on a block boundary
51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary 51 * - the space necessary for a bbt in FLASH does not exceed a block boundary
52 * 52 *
53 */ 53 */
54 54
@@ -60,7 +60,7 @@
60#include <linux/mtd/compatmac.h> 60#include <linux/mtd/compatmac.h>
61#include <linux/bitops.h> 61#include <linux/bitops.h>
62#include <linux/delay.h> 62#include <linux/delay.h>
63 63#include <linux/vmalloc.h>
64 64
65/** 65/**
66 * check_pattern - [GENERIC] check if a pattern is in the buffer 66 * check_pattern - [GENERIC] check if a pattern is in the buffer
@@ -75,7 +75,7 @@
75 * pattern area contain 0xff 75 * pattern area contain 0xff
76 * 76 *
77*/ 77*/
78static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) 78static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
79{ 79{
80 int i, end = 0; 80 int i, end = 0;
81 uint8_t *p = buf; 81 uint8_t *p = buf;
@@ -116,7 +116,7 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
116 * no optional empty check 116 * no optional empty check
117 * 117 *
118*/ 118*/
119static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td) 119static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
120{ 120{
121 int i; 121 int i;
122 uint8_t *p = buf; 122 uint8_t *p = buf;
@@ -142,8 +142,8 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
142 * Read the bad block table starting from page. 142 * Read the bad block table starting from page.
143 * 143 *
144 */ 144 */
145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, 145static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
146 int bits, int offs, int reserved_block_code) 146 int bits, int offs, int reserved_block_code)
147{ 147{
148 int res, i, j, act = 0; 148 int res, i, j, act = 0;
149 struct nand_chip *this = mtd->priv; 149 struct nand_chip *this = mtd->priv;
@@ -152,17 +152,17 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
152 uint8_t msk = (uint8_t) ((1 << bits) - 1); 152 uint8_t msk = (uint8_t) ((1 << bits) - 1);
153 153
154 totlen = (num * bits) >> 3; 154 totlen = (num * bits) >> 3;
155 from = ((loff_t)page) << this->page_shift; 155 from = ((loff_t) page) << this->page_shift;
156 156
157 while (totlen) { 157 while (totlen) {
158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); 158 len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); 159 res = mtd->read(mtd, from, len, &retlen, buf);
160 if (res < 0) { 160 if (res < 0) {
161 if (retlen != len) { 161 if (retlen != len) {
162 printk (KERN_INFO "nand_bbt: Error reading bad block table\n"); 162 printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
163 return res; 163 return res;
164 } 164 }
165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); 165 printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
166 } 166 }
167 167
168 /* Analyse data */ 168 /* Analyse data */
@@ -172,22 +172,23 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
172 uint8_t tmp = (dat >> j) & msk; 172 uint8_t tmp = (dat >> j) & msk;
173 if (tmp == msk) 173 if (tmp == msk)
174 continue; 174 continue;
175 if (reserved_block_code && 175 if (reserved_block_code && (tmp == reserved_block_code)) {
176 (tmp == reserved_block_code)) { 176 printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
177 printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", 177 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
178 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
179 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); 178 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
179 mtd->ecc_stats.bbtblocks++;
180 continue; 180 continue;
181 } 181 }
182 /* Leave it for now, if its matured we can move this 182 /* Leave it for now, if its matured we can move this
183 * message to MTD_DEBUG_LEVEL0 */ 183 * message to MTD_DEBUG_LEVEL0 */
184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", 184 printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
186 /* Factory marked bad or worn out ? */ 186 /* Factory marked bad or worn out ? */
187 if (tmp == 0) 187 if (tmp == 0)
188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); 188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
189 else 189 else
190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); 190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
191 mtd->ecc_stats.badblocks++;
191 } 192 }
192 } 193 }
193 totlen -= len; 194 totlen -= len;
@@ -207,7 +208,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
207 * Read the bad block table for all chips starting at a given page 208 * Read the bad block table for all chips starting at a given page
208 * We assume that the bbt bits are in consecutive order. 209 * We assume that the bbt bits are in consecutive order.
209*/ 210*/
210static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) 211static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
211{ 212{
212 struct nand_chip *this = mtd->priv; 213 struct nand_chip *this = mtd->priv;
213 int res = 0, i; 214 int res = 0, i;
@@ -231,6 +232,42 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
231 return 0; 232 return 0;
232} 233}
233 234
235/*
236 * Scan read raw data from flash
237 */
238static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
239 size_t len)
240{
241 struct mtd_oob_ops ops;
242
243 ops.mode = MTD_OOB_RAW;
244 ops.ooboffs = 0;
245 ops.ooblen = mtd->oobsize;
246 ops.oobbuf = buf;
247 ops.datbuf = buf;
248 ops.len = len;
249
250 return mtd->read_oob(mtd, offs, &ops);
251}
252
253/*
254 * Scan write data with oob to flash
255 */
256static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
257 uint8_t *buf, uint8_t *oob)
258{
259 struct mtd_oob_ops ops;
260
261 ops.mode = MTD_OOB_PLACE;
262 ops.ooboffs = 0;
263 ops.ooblen = mtd->oobsize;
264 ops.datbuf = buf;
265 ops.oobbuf = oob;
266 ops.len = len;
267
268 return mtd->write_oob(mtd, offs, &ops);
269}
270
234/** 271/**
235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 272 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
236 * @mtd: MTD device structure 273 * @mtd: MTD device structure
@@ -242,28 +279,85 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
242 * We assume that the bbt bits are in consecutive order. 279 * We assume that the bbt bits are in consecutive order.
243 * 280 *
244*/ 281*/
245static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, 282static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
246 struct nand_bbt_descr *md) 283 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
247{ 284{
248 struct nand_chip *this = mtd->priv; 285 struct nand_chip *this = mtd->priv;
249 286
250 /* Read the primary version, if available */ 287 /* Read the primary version, if available */
251 if (td->options & NAND_BBT_VERSION) { 288 if (td->options & NAND_BBT_VERSION) {
252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 289 scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
253 td->version[0] = buf[mtd->oobblock + td->veroffs]; 290 mtd->writesize);
254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); 291 td->version[0] = buf[mtd->writesize + td->veroffs];
292 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
293 td->pages[0], td->version[0]);
255 } 294 }
256 295
257 /* Read the mirror version, if available */ 296 /* Read the mirror version, if available */
258 if (md && (md->options & NAND_BBT_VERSION)) { 297 if (md && (md->options & NAND_BBT_VERSION)) {
259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 298 scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
260 md->version[0] = buf[mtd->oobblock + md->veroffs]; 299 mtd->writesize);
261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); 300 md->version[0] = buf[mtd->writesize + md->veroffs];
301 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
302 md->pages[0], md->version[0]);
262 } 303 }
263
264 return 1; 304 return 1;
265} 305}
266 306
307/*
308 * Scan a given block full
309 */
310static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
311 loff_t offs, uint8_t *buf, size_t readlen,
312 int scanlen, int len)
313{
314 int ret, j;
315
316 ret = scan_read_raw(mtd, buf, offs, readlen);
317 if (ret)
318 return ret;
319
320 for (j = 0; j < len; j++, buf += scanlen) {
321 if (check_pattern(buf, scanlen, mtd->writesize, bd))
322 return 1;
323 }
324 return 0;
325}
326
327/*
328 * Scan a given block partially
329 */
330static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
331 loff_t offs, uint8_t *buf, int len)
332{
333 struct mtd_oob_ops ops;
334 int j, ret;
335
336 ops.len = mtd->oobsize;
337 ops.ooblen = mtd->oobsize;
338 ops.oobbuf = buf;
339 ops.ooboffs = 0;
340 ops.datbuf = NULL;
341 ops.mode = MTD_OOB_PLACE;
342
343 for (j = 0; j < len; j++) {
344 /*
345 * Read the full oob until read_oob is fixed to
346 * handle single byte reads for 16 bit
347 * buswidth
348 */
349 ret = mtd->read_oob(mtd, offs, &ops);
350 if (ret)
351 return ret;
352
353 if (check_short_pattern(buf, bd))
354 return 1;
355
356 offs += mtd->writesize;
357 }
358 return 0;
359}
360
267/** 361/**
268 * create_bbt - [GENERIC] Create a bad block table by scanning the device 362 * create_bbt - [GENERIC] Create a bad block table by scanning the device
269 * @mtd: MTD device structure 363 * @mtd: MTD device structure
@@ -275,15 +369,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
275 * Create a bad block table by scanning the device 369 * Create a bad block table by scanning the device
276 * for the given good/bad block identify pattern 370 * for the given good/bad block identify pattern
277 */ 371 */
278static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) 372static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
373 struct nand_bbt_descr *bd, int chip)
279{ 374{
280 struct nand_chip *this = mtd->priv; 375 struct nand_chip *this = mtd->priv;
281 int i, j, numblocks, len, scanlen; 376 int i, numblocks, len, scanlen;
282 int startblock; 377 int startblock;
283 loff_t from; 378 loff_t from;
284 size_t readlen, ooblen; 379 size_t readlen;
285 380
286 printk (KERN_INFO "Scanning device for bad blocks\n"); 381 printk(KERN_INFO "Scanning device for bad blocks\n");
287 382
288 if (bd->options & NAND_BBT_SCANALLPAGES) 383 if (bd->options & NAND_BBT_SCANALLPAGES)
289 len = 1 << (this->bbt_erase_shift - this->page_shift); 384 len = 1 << (this->bbt_erase_shift - this->page_shift);
@@ -296,25 +391,24 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
296 391
297 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 392 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
298 /* We need only read few bytes from the OOB area */ 393 /* We need only read few bytes from the OOB area */
299 scanlen = ooblen = 0; 394 scanlen = 0;
300 readlen = bd->len; 395 readlen = bd->len;
301 } else { 396 } else {
302 /* Full page content should be read */ 397 /* Full page content should be read */
303 scanlen = mtd->oobblock + mtd->oobsize; 398 scanlen = mtd->writesize + mtd->oobsize;
304 readlen = len * mtd->oobblock; 399 readlen = len * mtd->writesize;
305 ooblen = len * mtd->oobsize;
306 } 400 }
307 401
308 if (chip == -1) { 402 if (chip == -1) {
309 /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it 403 /* Note that numblocks is 2 * (real numblocks) here, see i+=2
310 * makes shifting and masking less painful */ 404 * below as it makes shifting and masking less painful */
311 numblocks = mtd->size >> (this->bbt_erase_shift - 1); 405 numblocks = mtd->size >> (this->bbt_erase_shift - 1);
312 startblock = 0; 406 startblock = 0;
313 from = 0; 407 from = 0;
314 } else { 408 } else {
315 if (chip >= this->numchips) { 409 if (chip >= this->numchips) {
316 printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", 410 printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
317 chip + 1, this->numchips); 411 chip + 1, this->numchips);
318 return -EINVAL; 412 return -EINVAL;
319 } 413 }
320 numblocks = this->chipsize >> (this->bbt_erase_shift - 1); 414 numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
@@ -326,36 +420,22 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
326 for (i = startblock; i < numblocks;) { 420 for (i = startblock; i < numblocks;) {
327 int ret; 421 int ret;
328 422
329 if (bd->options & NAND_BBT_SCANEMPTY) 423 if (bd->options & NAND_BBT_SCANALLPAGES)
330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) 424 ret = scan_block_full(mtd, bd, from, buf, readlen,
331 return ret; 425 scanlen, len);
332 426 else
333 for (j = 0; j < len; j++) { 427 ret = scan_block_fast(mtd, bd, from, buf, len);
334 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 428
335 size_t retlen; 429 if (ret < 0)
336 430 return ret;
337 /* Read the full oob until read_oob is fixed to 431
338 * handle single byte reads for 16 bit buswidth */ 432 if (ret) {
339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock, 433 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
340 mtd->oobsize, &retlen, buf); 434 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
341 if (ret) 435 i >> 1, (unsigned int)from);
342 return ret; 436 mtd->ecc_stats.badblocks++;
343
344 if (check_short_pattern (buf, bd)) {
345 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
347 i >> 1, (unsigned int) from);
348 break;
349 }
350 } else {
351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
352 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
354 i >> 1, (unsigned int) from);
355 break;
356 }
357 }
358 } 437 }
438
359 i += 2; 439 i += 2;
360 from += (1 << this->bbt_erase_shift); 440 from += (1 << this->bbt_erase_shift);
361 } 441 }
@@ -374,22 +454,23 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
374 * block. 454 * block.
375 * If the option NAND_BBT_PERCHIP is given, each chip is searched 455 * If the option NAND_BBT_PERCHIP is given, each chip is searched
376 * for a bbt, which contains the bad block information of this chip. 456 * for a bbt, which contains the bad block information of this chip.
377 * This is neccecary to provide support for certain DOC devices. 457 * This is necessary to provide support for certain DOC devices.
378 * 458 *
379 * The bbt ident pattern resides in the oob area of the first page 459 * The bbt ident pattern resides in the oob area of the first page
380 * in a block. 460 * in a block.
381 */ 461 */
382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) 462static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
383{ 463{
384 struct nand_chip *this = mtd->priv; 464 struct nand_chip *this = mtd->priv;
385 int i, chips; 465 int i, chips;
386 int bits, startblock, block, dir; 466 int bits, startblock, block, dir;
387 int scanlen = mtd->oobblock + mtd->oobsize; 467 int scanlen = mtd->writesize + mtd->oobsize;
388 int bbtblocks; 468 int bbtblocks;
469 int blocktopage = this->bbt_erase_shift - this->page_shift;
389 470
390 /* Search direction top -> down ? */ 471 /* Search direction top -> down ? */
391 if (td->options & NAND_BBT_LASTBLOCK) { 472 if (td->options & NAND_BBT_LASTBLOCK) {
392 startblock = (mtd->size >> this->bbt_erase_shift) -1; 473 startblock = (mtd->size >> this->bbt_erase_shift) - 1;
393 dir = -1; 474 dir = -1;
394 } else { 475 } else {
395 startblock = 0; 476 startblock = 0;
@@ -415,13 +496,16 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
415 td->pages[i] = -1; 496 td->pages[i] = -1;
416 /* Scan the maximum number of blocks */ 497 /* Scan the maximum number of blocks */
417 for (block = 0; block < td->maxblocks; block++) { 498 for (block = 0; block < td->maxblocks; block++) {
499
418 int actblock = startblock + dir * block; 500 int actblock = startblock + dir * block;
501 loff_t offs = actblock << this->bbt_erase_shift;
502
419 /* Read first page */ 503 /* Read first page */
420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); 504 scan_read_raw(mtd, buf, offs, mtd->writesize);
421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { 505 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); 506 td->pages[i] = actblock << blocktopage;
423 if (td->options & NAND_BBT_VERSION) { 507 if (td->options & NAND_BBT_VERSION) {
424 td->version[i] = buf[mtd->oobblock + td->veroffs]; 508 td->version[i] = buf[mtd->writesize + td->veroffs];
425 } 509 }
426 break; 510 break;
427 } 511 }
@@ -431,9 +515,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
431 /* Check, if we found a bbt for each requested chip */ 515 /* Check, if we found a bbt for each requested chip */
432 for (i = 0; i < chips; i++) { 516 for (i = 0; i < chips; i++) {
433 if (td->pages[i] == -1) 517 if (td->pages[i] == -1)
434 printk (KERN_WARNING "Bad block table not found for chip %d\n", i); 518 printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
435 else 519 else
436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); 520 printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
521 td->version[i]);
437 } 522 }
438 return 0; 523 return 0;
439} 524}
@@ -447,21 +532,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
447 * 532 *
448 * Search and read the bad block table(s) 533 * Search and read the bad block table(s)
449*/ 534*/
450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, 535static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
451 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
452{ 536{
453 /* Search the primary table */ 537 /* Search the primary table */
454 search_bbt (mtd, buf, td); 538 search_bbt(mtd, buf, td);
455 539
456 /* Search the mirror table */ 540 /* Search the mirror table */
457 if (md) 541 if (md)
458 search_bbt (mtd, buf, md); 542 search_bbt(mtd, buf, md);
459 543
460 /* Force result check */ 544 /* Force result check */
461 return 1; 545 return 1;
462} 546}
463 547
464
465/** 548/**
466 * write_bbt - [GENERIC] (Re)write the bad block table 549 * write_bbt - [GENERIC] (Re)write the bad block table
467 * 550 *
@@ -474,25 +557,31 @@ static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
474 * (Re)write the bad block table 557 * (Re)write the bad block table
475 * 558 *
476*/ 559*/
477static int write_bbt (struct mtd_info *mtd, uint8_t *buf, 560static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) 561 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
562 int chipsel)
479{ 563{
480 struct nand_chip *this = mtd->priv; 564 struct nand_chip *this = mtd->priv;
481 struct nand_oobinfo oobinfo;
482 struct erase_info einfo; 565 struct erase_info einfo;
483 int i, j, res, chip = 0; 566 int i, j, res, chip = 0;
484 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; 567 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
485 int nrchips, bbtoffs, pageoffs; 568 int nrchips, bbtoffs, pageoffs, ooboffs;
486 uint8_t msk[4]; 569 uint8_t msk[4];
487 uint8_t rcode = td->reserved_block_code; 570 uint8_t rcode = td->reserved_block_code;
488 size_t retlen, len = 0; 571 size_t retlen, len = 0;
489 loff_t to; 572 loff_t to;
573 struct mtd_oob_ops ops;
574
575 ops.ooblen = mtd->oobsize;
576 ops.ooboffs = 0;
577 ops.datbuf = NULL;
578 ops.mode = MTD_OOB_PLACE;
490 579
491 if (!rcode) 580 if (!rcode)
492 rcode = 0xff; 581 rcode = 0xff;
493 /* Write bad block table per chip rather than per device ? */ 582 /* Write bad block table per chip rather than per device ? */
494 if (td->options & NAND_BBT_PERCHIP) { 583 if (td->options & NAND_BBT_PERCHIP) {
495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift); 584 numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
496 /* Full device write or specific chip ? */ 585 /* Full device write or specific chip ? */
497 if (chipsel == -1) { 586 if (chipsel == -1) {
498 nrchips = this->numchips; 587 nrchips = this->numchips;
@@ -501,7 +590,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
501 chip = chipsel; 590 chip = chipsel;
502 } 591 }
503 } else { 592 } else {
504 numblocks = (int) (mtd->size >> this->bbt_erase_shift); 593 numblocks = (int)(mtd->size >> this->bbt_erase_shift);
505 nrchips = 1; 594 nrchips = 1;
506 } 595 }
507 596
@@ -530,27 +619,38 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
530 for (i = 0; i < td->maxblocks; i++) { 619 for (i = 0; i < td->maxblocks; i++) {
531 int block = startblock + dir * i; 620 int block = startblock + dir * i;
532 /* Check, if the block is bad */ 621 /* Check, if the block is bad */
533 switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) { 622 switch ((this->bbt[block >> 2] >>
623 (2 * (block & 0x03))) & 0x03) {
534 case 0x01: 624 case 0x01:
535 case 0x03: 625 case 0x03:
536 continue; 626 continue;
537 } 627 }
538 page = block << (this->bbt_erase_shift - this->page_shift); 628 page = block <<
629 (this->bbt_erase_shift - this->page_shift);
539 /* Check, if the block is used by the mirror table */ 630 /* Check, if the block is used by the mirror table */
540 if (!md || md->pages[chip] != page) 631 if (!md || md->pages[chip] != page)
541 goto write; 632 goto write;
542 } 633 }
543 printk (KERN_ERR "No space left to write bad block table\n"); 634 printk(KERN_ERR "No space left to write bad block table\n");
544 return -ENOSPC; 635 return -ENOSPC;
545write: 636 write:
546 637
547 /* Set up shift count and masks for the flash table */ 638 /* Set up shift count and masks for the flash table */
548 bits = td->options & NAND_BBT_NRBITS_MSK; 639 bits = td->options & NAND_BBT_NRBITS_MSK;
640 msk[2] = ~rcode;
549 switch (bits) { 641 switch (bits) {
550 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break; 642 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01;
551 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break; 643 msk[3] = 0x01;
552 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break; 644 break;
553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; 645 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01;
646 msk[3] = 0x03;
647 break;
648 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C;
649 msk[3] = 0x0f;
650 break;
651 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F;
652 msk[3] = 0xff;
653 break;
554 default: return -EINVAL; 654 default: return -EINVAL;
555 } 655 }
556 656
@@ -558,82 +658,92 @@ write:
558 658
559 to = ((loff_t) page) << this->page_shift; 659 to = ((loff_t) page) << this->page_shift;
560 660
561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
562 oobinfo.useecc = MTD_NANDECC_PLACEONLY;
563
564 /* Must we save the block contents ? */ 661 /* Must we save the block contents ? */
565 if (td->options & NAND_BBT_SAVECONTENT) { 662 if (td->options & NAND_BBT_SAVECONTENT) {
566 /* Make it block aligned */ 663 /* Make it block aligned */
567 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); 664 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
568 len = 1 << this->bbt_erase_shift; 665 len = 1 << this->bbt_erase_shift;
569 res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 666 res = mtd->read(mtd, to, len, &retlen, buf);
570 if (res < 0) { 667 if (res < 0) {
571 if (retlen != len) { 668 if (retlen != len) {
572 printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n"); 669 printk(KERN_INFO "nand_bbt: Error "
670 "reading block for writing "
671 "the bad block table\n");
573 return res; 672 return res;
574 } 673 }
575 printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n"); 674 printk(KERN_WARNING "nand_bbt: ECC error "
675 "while reading block for writing "
676 "bad block table\n");
576 } 677 }
678 /* Read oob data */
679 ops.len = (len >> this->page_shift) * mtd->oobsize;
680 ops.oobbuf = &buf[len];
681 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
682 if (res < 0 || ops.retlen != ops.len)
683 goto outerr;
684
577 /* Calc the byte offset in the buffer */ 685 /* Calc the byte offset in the buffer */
578 pageoffs = page - (int)(to >> this->page_shift); 686 pageoffs = page - (int)(to >> this->page_shift);
579 offs = pageoffs << this->page_shift; 687 offs = pageoffs << this->page_shift;
580 /* Preset the bbt area with 0xff */ 688 /* Preset the bbt area with 0xff */
581 memset (&buf[offs], 0xff, (size_t)(numblocks >> sft)); 689 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
582 /* Preset the bbt's oob area with 0xff */ 690 ooboffs = len + (pageoffs * mtd->oobsize);
583 memset (&buf[len + pageoffs * mtd->oobsize], 0xff, 691
584 ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
585 if (td->options & NAND_BBT_VERSION) {
586 buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
587 }
588 } else { 692 } else {
589 /* Calc length */ 693 /* Calc length */
590 len = (size_t) (numblocks >> sft); 694 len = (size_t) (numblocks >> sft);
591 /* Make it page aligned ! */ 695 /* Make it page aligned ! */
592 len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1); 696 len = (len + (mtd->writesize - 1)) &
697 ~(mtd->writesize - 1);
593 /* Preset the buffer with 0xff */ 698 /* Preset the buffer with 0xff */
594 memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize); 699 memset(buf, 0xff, len +
700 (len >> this->page_shift)* mtd->oobsize);
595 offs = 0; 701 offs = 0;
702 ooboffs = len;
596 /* Pattern is located in oob area of first page */ 703 /* Pattern is located in oob area of first page */
597 memcpy (&buf[len + td->offs], td->pattern, td->len); 704 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
598 if (td->options & NAND_BBT_VERSION) {
599 buf[len + td->veroffs] = td->version[chip];
600 }
601 } 705 }
602 706
707 if (td->options & NAND_BBT_VERSION)
708 buf[ooboffs + td->veroffs] = td->version[chip];
709
603 /* walk through the memory table */ 710 /* walk through the memory table */
604 for (i = 0; i < numblocks; ) { 711 for (i = 0; i < numblocks;) {
605 uint8_t dat; 712 uint8_t dat;
606 dat = this->bbt[bbtoffs + (i >> 2)]; 713 dat = this->bbt[bbtoffs + (i >> 2)];
607 for (j = 0; j < 4; j++ , i++) { 714 for (j = 0; j < 4; j++, i++) {
608 int sftcnt = (i << (3 - sft)) & sftmsk; 715 int sftcnt = (i << (3 - sft)) & sftmsk;
609 /* Do not store the reserved bbt blocks ! */ 716 /* Do not store the reserved bbt blocks ! */
610 buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt); 717 buf[offs + (i >> sft)] &=
718 ~(msk[dat & 0x03] << sftcnt);
611 dat >>= 2; 719 dat >>= 2;
612 } 720 }
613 } 721 }
614 722
615 memset (&einfo, 0, sizeof (einfo)); 723 memset(&einfo, 0, sizeof(einfo));
616 einfo.mtd = mtd; 724 einfo.mtd = mtd;
617 einfo.addr = (unsigned long) to; 725 einfo.addr = (unsigned long)to;
618 einfo.len = 1 << this->bbt_erase_shift; 726 einfo.len = 1 << this->bbt_erase_shift;
619 res = nand_erase_nand (mtd, &einfo, 1); 727 res = nand_erase_nand(mtd, &einfo, 1);
620 if (res < 0) { 728 if (res < 0)
621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); 729 goto outerr;
622 return res;
623 }
624 730
625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 731 res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
626 if (res < 0) { 732 if (res < 0)
627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); 733 goto outerr;
628 return res; 734
629 } 735 printk(KERN_DEBUG "Bad block table written to 0x%08x, version "
630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", 736 "0x%02X\n", (unsigned int)to, td->version[chip]);
631 (unsigned int) to, td->version[chip]);
632 737
633 /* Mark it as used */ 738 /* Mark it as used */
634 td->pages[chip] = page; 739 td->pages[chip] = page;
635 } 740 }
636 return 0; 741 return 0;
742
743 outerr:
744 printk(KERN_WARNING
745 "nand_bbt: Error while writing bad block table %d\n", res);
746 return res;
637} 747}
638 748
639/** 749/**
@@ -644,27 +754,27 @@ write:
644 * The function creates a memory based bbt by scanning the device 754 * The function creates a memory based bbt by scanning the device
645 * for manufacturer / software marked good / bad blocks 755 * for manufacturer / software marked good / bad blocks
646*/ 756*/
647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 757static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
648{ 758{
649 struct nand_chip *this = mtd->priv; 759 struct nand_chip *this = mtd->priv;
650 760
651 bd->options &= ~NAND_BBT_SCANEMPTY; 761 bd->options &= ~NAND_BBT_SCANEMPTY;
652 return create_bbt (mtd, this->data_buf, bd, -1); 762 return create_bbt(mtd, this->buffers.databuf, bd, -1);
653} 763}
654 764
655/** 765/**
656 * check_create - [GENERIC] create and write bbt(s) if neccecary 766 * check_create - [GENERIC] create and write bbt(s) if necessary
657 * @mtd: MTD device structure 767 * @mtd: MTD device structure
658 * @buf: temporary buffer 768 * @buf: temporary buffer
659 * @bd: descriptor for the good/bad block search pattern 769 * @bd: descriptor for the good/bad block search pattern
660 * 770 *
661 * The function checks the results of the previous call to read_bbt 771 * The function checks the results of the previous call to read_bbt
662 * and creates / updates the bbt(s) if neccecary 772 * and creates / updates the bbt(s) if necessary
663 * Creation is neccecary if no bbt was found for the chip/device 773 * Creation is necessary if no bbt was found for the chip/device
664 * Update is neccecary if one of the tables is missing or the 774 * Update is necessary if one of the tables is missing or the
665 * version nr. of one table is less than the other 775 * version nr. of one table is less than the other
666*/ 776*/
667static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) 777static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
668{ 778{
669 int i, chips, writeops, chipsel, res; 779 int i, chips, writeops, chipsel, res;
670 struct nand_chip *this = mtd->priv; 780 struct nand_chip *this = mtd->priv;
@@ -732,35 +842,35 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
732 rd = td; 842 rd = td;
733 goto writecheck; 843 goto writecheck;
734 } 844 }
735create: 845 create:
736 /* Create the bad block table by scanning the device ? */ 846 /* Create the bad block table by scanning the device ? */
737 if (!(td->options & NAND_BBT_CREATE)) 847 if (!(td->options & NAND_BBT_CREATE))
738 continue; 848 continue;
739 849
740 /* Create the table in memory by scanning the chip(s) */ 850 /* Create the table in memory by scanning the chip(s) */
741 create_bbt (mtd, buf, bd, chipsel); 851 create_bbt(mtd, buf, bd, chipsel);
742 852
743 td->version[i] = 1; 853 td->version[i] = 1;
744 if (md) 854 if (md)
745 md->version[i] = 1; 855 md->version[i] = 1;
746writecheck: 856 writecheck:
747 /* read back first ? */ 857 /* read back first ? */
748 if (rd) 858 if (rd)
749 read_abs_bbt (mtd, buf, rd, chipsel); 859 read_abs_bbt(mtd, buf, rd, chipsel);
750 /* If they weren't versioned, read both. */ 860 /* If they weren't versioned, read both. */
751 if (rd2) 861 if (rd2)
752 read_abs_bbt (mtd, buf, rd2, chipsel); 862 read_abs_bbt(mtd, buf, rd2, chipsel);
753 863
754 /* Write the bad block table to the device ? */ 864 /* Write the bad block table to the device ? */
755 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 865 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
756 res = write_bbt (mtd, buf, td, md, chipsel); 866 res = write_bbt(mtd, buf, td, md, chipsel);
757 if (res < 0) 867 if (res < 0)
758 return res; 868 return res;
759 } 869 }
760 870
761 /* Write the mirror bad block table to the device ? */ 871 /* Write the mirror bad block table to the device ? */
762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 872 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
763 res = write_bbt (mtd, buf, md, td, chipsel); 873 res = write_bbt(mtd, buf, md, td, chipsel);
764 if (res < 0) 874 if (res < 0)
765 return res; 875 return res;
766 } 876 }
@@ -777,7 +887,7 @@ writecheck:
777 * accidental erasures / writes. The regions are identified by 887 * accidental erasures / writes. The regions are identified by
778 * the mark 0x02. 888 * the mark 0x02.
779*/ 889*/
780static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) 890static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
781{ 891{
782 struct nand_chip *this = mtd->priv; 892 struct nand_chip *this = mtd->priv;
783 int i, j, chips, block, nrblocks, update; 893 int i, j, chips, block, nrblocks, update;
@@ -795,7 +905,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
795 for (i = 0; i < chips; i++) { 905 for (i = 0; i < chips; i++) {
796 if ((td->options & NAND_BBT_ABSPAGE) || 906 if ((td->options & NAND_BBT_ABSPAGE) ||
797 !(td->options & NAND_BBT_WRITE)) { 907 !(td->options & NAND_BBT_WRITE)) {
798 if (td->pages[i] == -1) continue; 908 if (td->pages[i] == -1)
909 continue;
799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 910 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
800 block <<= 1; 911 block <<= 1;
801 oldval = this->bbt[(block >> 3)]; 912 oldval = this->bbt[(block >> 3)];
@@ -815,7 +926,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
815 oldval = this->bbt[(block >> 3)]; 926 oldval = this->bbt[(block >> 3)];
816 newval = oldval | (0x2 << (block & 0x06)); 927 newval = oldval | (0x2 << (block & 0x06));
817 this->bbt[(block >> 3)] = newval; 928 this->bbt[(block >> 3)] = newval;
818 if (oldval != newval) update = 1; 929 if (oldval != newval)
930 update = 1;
819 block += 2; 931 block += 2;
820 } 932 }
821 /* If we want reserved blocks to be recorded to flash, and some 933 /* If we want reserved blocks to be recorded to flash, and some
@@ -840,7 +952,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
840 * by calling the nand_free_bbt function. 952 * by calling the nand_free_bbt function.
841 * 953 *
842*/ 954*/
843int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 955int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
844{ 956{
845 struct nand_chip *this = mtd->priv; 957 struct nand_chip *this = mtd->priv;
846 int len, res = 0; 958 int len, res = 0;
@@ -850,21 +962,21 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
850 962
851 len = mtd->size >> (this->bbt_erase_shift + 2); 963 len = mtd->size >> (this->bbt_erase_shift + 2);
852 /* Allocate memory (2bit per block) */ 964 /* Allocate memory (2bit per block) */
853 this->bbt = kmalloc (len, GFP_KERNEL); 965 this->bbt = kmalloc(len, GFP_KERNEL);
854 if (!this->bbt) { 966 if (!this->bbt) {
855 printk (KERN_ERR "nand_scan_bbt: Out of memory\n"); 967 printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
856 return -ENOMEM; 968 return -ENOMEM;
857 } 969 }
858 /* Clear the memory bad block table */ 970 /* Clear the memory bad block table */
859 memset (this->bbt, 0x00, len); 971 memset(this->bbt, 0x00, len);
860 972
861 /* If no primary table decriptor is given, scan the device 973 /* If no primary table decriptor is given, scan the device
862 * to build a memory based bad block table 974 * to build a memory based bad block table
863 */ 975 */
864 if (!td) { 976 if (!td) {
865 if ((res = nand_memory_bbt(mtd, bd))) { 977 if ((res = nand_memory_bbt(mtd, bd))) {
866 printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n"); 978 printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
867 kfree (this->bbt); 979 kfree(this->bbt);
868 this->bbt = NULL; 980 this->bbt = NULL;
869 } 981 }
870 return res; 982 return res;
@@ -873,35 +985,34 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
873 /* Allocate a temporary buffer for one eraseblock incl. oob */ 985 /* Allocate a temporary buffer for one eraseblock incl. oob */
874 len = (1 << this->bbt_erase_shift); 986 len = (1 << this->bbt_erase_shift);
875 len += (len >> this->page_shift) * mtd->oobsize; 987 len += (len >> this->page_shift) * mtd->oobsize;
876 buf = kmalloc (len, GFP_KERNEL); 988 buf = vmalloc(len);
877 if (!buf) { 989 if (!buf) {
878 printk (KERN_ERR "nand_bbt: Out of memory\n"); 990 printk(KERN_ERR "nand_bbt: Out of memory\n");
879 kfree (this->bbt); 991 kfree(this->bbt);
880 this->bbt = NULL; 992 this->bbt = NULL;
881 return -ENOMEM; 993 return -ENOMEM;
882 } 994 }
883 995
884 /* Is the bbt at a given page ? */ 996 /* Is the bbt at a given page ? */
885 if (td->options & NAND_BBT_ABSPAGE) { 997 if (td->options & NAND_BBT_ABSPAGE) {
886 res = read_abs_bbts (mtd, buf, td, md); 998 res = read_abs_bbts(mtd, buf, td, md);
887 } else { 999 } else {
888 /* Search the bad block table using a pattern in oob */ 1000 /* Search the bad block table using a pattern in oob */
889 res = search_read_bbts (mtd, buf, td, md); 1001 res = search_read_bbts(mtd, buf, td, md);
890 } 1002 }
891 1003
892 if (res) 1004 if (res)
893 res = check_create (mtd, buf, bd); 1005 res = check_create(mtd, buf, bd);
894 1006
895 /* Prevent the bbt regions from erasing / writing */ 1007 /* Prevent the bbt regions from erasing / writing */
896 mark_bbt_region (mtd, td); 1008 mark_bbt_region(mtd, td);
897 if (md) 1009 if (md)
898 mark_bbt_region (mtd, md); 1010 mark_bbt_region(mtd, md);
899 1011
900 kfree (buf); 1012 vfree(buf);
901 return res; 1013 return res;
902} 1014}
903 1015
904
905/** 1016/**
906 * nand_update_bbt - [NAND Interface] update bad block table(s) 1017 * nand_update_bbt - [NAND Interface] update bad block table(s)
907 * @mtd: MTD device structure 1018 * @mtd: MTD device structure
@@ -909,7 +1020,7 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
909 * 1020 *
910 * The function updates the bad block table(s) 1021 * The function updates the bad block table(s)
911*/ 1022*/
912int nand_update_bbt (struct mtd_info *mtd, loff_t offs) 1023int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
913{ 1024{
914 struct nand_chip *this = mtd->priv; 1025 struct nand_chip *this = mtd->priv;
915 int len, res = 0, writeops = 0; 1026 int len, res = 0, writeops = 0;
@@ -925,9 +1036,9 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
925 /* Allocate a temporary buffer for one eraseblock incl. oob */ 1036 /* Allocate a temporary buffer for one eraseblock incl. oob */
926 len = (1 << this->bbt_erase_shift); 1037 len = (1 << this->bbt_erase_shift);
927 len += (len >> this->page_shift) * mtd->oobsize; 1038 len += (len >> this->page_shift) * mtd->oobsize;
928 buf = kmalloc (len, GFP_KERNEL); 1039 buf = kmalloc(len, GFP_KERNEL);
929 if (!buf) { 1040 if (!buf) {
930 printk (KERN_ERR "nand_update_bbt: Out of memory\n"); 1041 printk(KERN_ERR "nand_update_bbt: Out of memory\n");
931 return -ENOMEM; 1042 return -ENOMEM;
932 } 1043 }
933 1044
@@ -935,7 +1046,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
935 1046
936 /* Do we have a bbt per chip ? */ 1047 /* Do we have a bbt per chip ? */
937 if (td->options & NAND_BBT_PERCHIP) { 1048 if (td->options & NAND_BBT_PERCHIP) {
938 chip = (int) (offs >> this->chip_shift); 1049 chip = (int)(offs >> this->chip_shift);
939 chipsel = chip; 1050 chipsel = chip;
940 } else { 1051 } else {
941 chip = 0; 1052 chip = 0;
@@ -948,17 +1059,17 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
948 1059
949 /* Write the bad block table to the device ? */ 1060 /* Write the bad block table to the device ? */
950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 1061 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
951 res = write_bbt (mtd, buf, td, md, chipsel); 1062 res = write_bbt(mtd, buf, td, md, chipsel);
952 if (res < 0) 1063 if (res < 0)
953 goto out; 1064 goto out;
954 } 1065 }
955 /* Write the mirror bad block table to the device ? */ 1066 /* Write the mirror bad block table to the device ? */
956 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 1067 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
957 res = write_bbt (mtd, buf, md, td, chipsel); 1068 res = write_bbt(mtd, buf, md, td, chipsel);
958 } 1069 }
959 1070
960out: 1071 out:
961 kfree (buf); 1072 kfree(buf);
962 return res; 1073 return res;
963} 1074}
964 1075
@@ -981,14 +1092,14 @@ static struct nand_bbt_descr largepage_memorybased = {
981}; 1092};
982 1093
983static struct nand_bbt_descr smallpage_flashbased = { 1094static struct nand_bbt_descr smallpage_flashbased = {
984 .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, 1095 .options = NAND_BBT_SCAN2NDPAGE,
985 .offs = 5, 1096 .offs = 5,
986 .len = 1, 1097 .len = 1,
987 .pattern = scan_ff_pattern 1098 .pattern = scan_ff_pattern
988}; 1099};
989 1100
990static struct nand_bbt_descr largepage_flashbased = { 1101static struct nand_bbt_descr largepage_flashbased = {
991 .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, 1102 .options = NAND_BBT_SCAN2NDPAGE,
992 .offs = 0, 1103 .offs = 0,
993 .len = 2, 1104 .len = 2,
994 .pattern = scan_ff_pattern 1105 .pattern = scan_ff_pattern
@@ -1036,7 +1147,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1036 * support for the device and calls the nand_scan_bbt function 1147 * support for the device and calls the nand_scan_bbt function
1037 * 1148 *
1038*/ 1149*/
1039int nand_default_bbt (struct mtd_info *mtd) 1150int nand_default_bbt(struct mtd_info *mtd)
1040{ 1151{
1041 struct nand_chip *this = mtd->priv; 1152 struct nand_chip *this = mtd->priv;
1042 1153
@@ -1046,7 +1157,7 @@ int nand_default_bbt (struct mtd_info *mtd)
1046 * of the good / bad information, so we _must_ store 1157 * of the good / bad information, so we _must_ store
1047 * this information in a good / bad table during 1158 * this information in a good / bad table during
1048 * startup 1159 * startup
1049 */ 1160 */
1050 if (this->options & NAND_IS_AND) { 1161 if (this->options & NAND_IS_AND) {
1051 /* Use the default pattern descriptors */ 1162 /* Use the default pattern descriptors */
1052 if (!this->bbt_td) { 1163 if (!this->bbt_td) {
@@ -1054,10 +1165,9 @@ int nand_default_bbt (struct mtd_info *mtd)
1054 this->bbt_md = &bbt_mirror_descr; 1165 this->bbt_md = &bbt_mirror_descr;
1055 } 1166 }
1056 this->options |= NAND_USE_FLASH_BBT; 1167 this->options |= NAND_USE_FLASH_BBT;
1057 return nand_scan_bbt (mtd, &agand_flashbased); 1168 return nand_scan_bbt(mtd, &agand_flashbased);
1058 } 1169 }
1059 1170
1060
1061 /* Is a flash based bad block table requested ? */ 1171 /* Is a flash based bad block table requested ? */
1062 if (this->options & NAND_USE_FLASH_BBT) { 1172 if (this->options & NAND_USE_FLASH_BBT) {
1063 /* Use the default pattern descriptors */ 1173 /* Use the default pattern descriptors */
@@ -1066,18 +1176,17 @@ int nand_default_bbt (struct mtd_info *mtd)
1066 this->bbt_md = &bbt_mirror_descr; 1176 this->bbt_md = &bbt_mirror_descr;
1067 } 1177 }
1068 if (!this->badblock_pattern) { 1178 if (!this->badblock_pattern) {
1069 this->badblock_pattern = (mtd->oobblock > 512) ? 1179 this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
1070 &largepage_flashbased : &smallpage_flashbased;
1071 } 1180 }
1072 } else { 1181 } else {
1073 this->bbt_td = NULL; 1182 this->bbt_td = NULL;
1074 this->bbt_md = NULL; 1183 this->bbt_md = NULL;
1075 if (!this->badblock_pattern) { 1184 if (!this->badblock_pattern) {
1076 this->badblock_pattern = (mtd->oobblock > 512) ? 1185 this->badblock_pattern = (mtd->writesize > 512) ?
1077 &largepage_memorybased : &smallpage_memorybased; 1186 &largepage_memorybased : &smallpage_memorybased;
1078 } 1187 }
1079 } 1188 }
1080 return nand_scan_bbt (mtd, this->badblock_pattern); 1189 return nand_scan_bbt(mtd, this->badblock_pattern);
1081} 1190}
1082 1191
1083/** 1192/**
@@ -1087,26 +1196,29 @@ int nand_default_bbt (struct mtd_info *mtd)
1087 * @allowbbt: allow access to bad block table region 1196 * @allowbbt: allow access to bad block table region
1088 * 1197 *
1089*/ 1198*/
1090int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) 1199int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
1091{ 1200{
1092 struct nand_chip *this = mtd->priv; 1201 struct nand_chip *this = mtd->priv;
1093 int block; 1202 int block;
1094 uint8_t res; 1203 uint8_t res;
1095 1204
1096 /* Get block number * 2 */ 1205 /* Get block number * 2 */
1097 block = (int) (offs >> (this->bbt_erase_shift - 1)); 1206 block = (int)(offs >> (this->bbt_erase_shift - 1));
1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; 1207 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1099 1208
1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 1209 DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1101 (unsigned int)offs, block >> 1, res); 1210 (unsigned int)offs, block >> 1, res);
1102 1211
1103 switch ((int)res) { 1212 switch ((int)res) {
1104 case 0x00: return 0; 1213 case 0x00:
1105 case 0x01: return 1; 1214 return 0;
1106 case 0x02: return allowbbt ? 0 : 1; 1215 case 0x01:
1216 return 1;
1217 case 0x02:
1218 return allowbbt ? 0 : 1;
1107 } 1219 }
1108 return 1; 1220 return 1;
1109} 1221}
1110 1222
1111EXPORT_SYMBOL (nand_scan_bbt); 1223EXPORT_SYMBOL(nand_scan_bbt);
1112EXPORT_SYMBOL (nand_default_bbt); 1224EXPORT_SYMBOL(nand_default_bbt);
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 40ac909150a3..2a163e4084df 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,6 +7,8 @@
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
8 * Toshiba America Electronics Components, Inc. 8 * Toshiba America Electronics Components, Inc.
9 * 9 *
10 * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de>
11 *
10 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $ 12 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
11 * 13 *
12 * This file is free software; you can redistribute it and/or modify it 14 * This file is free software; you can redistribute it and/or modify it
@@ -62,90 +64,76 @@ static const u_char nand_ecc_precalc_table[] = {
62 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 64 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
63}; 65};
64 66
65
66/** 67/**
67 * nand_trans_result - [GENERIC] create non-inverted ECC 68 * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code
68 * @reg2: line parity reg 2 69 * for 256 byte block
69 * @reg3: line parity reg 3
70 * @ecc_code: ecc
71 *
72 * Creates non-inverted ECC code from line parity
73 */
74static void nand_trans_result(u_char reg2, u_char reg3,
75 u_char *ecc_code)
76{
77 u_char a, b, i, tmp1, tmp2;
78
79 /* Initialize variables */
80 a = b = 0x80;
81 tmp1 = tmp2 = 0;
82
83 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
86 tmp1 |= b;
87 b >>= 1;
88 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
89 tmp1 |= b;
90 b >>= 1;
91 a >>= 1;
92 }
93
94 /* Calculate second ECC byte */
95 b = 0x80;
96 for (i = 0; i < 4; i++) {
97 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
98 tmp2 |= b;
99 b >>= 1;
100 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
101 tmp2 |= b;
102 b >>= 1;
103 a >>= 1;
104 }
105
106 /* Store two of the ECC bytes */
107 ecc_code[0] = tmp1;
108 ecc_code[1] = tmp2;
109}
110
111/**
112 * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block
113 * @mtd: MTD block structure 70 * @mtd: MTD block structure
114 * @dat: raw data 71 * @dat: raw data
115 * @ecc_code: buffer for ECC 72 * @ecc_code: buffer for ECC
116 */ 73 */
117int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 74int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
75 u_char *ecc_code)
118{ 76{
119 u_char idx, reg1, reg2, reg3; 77 uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
120 int j; 78 int i;
121 79
122 /* Initialize variables */ 80 /* Initialize variables */
123 reg1 = reg2 = reg3 = 0; 81 reg1 = reg2 = reg3 = 0;
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 82
126 /* Build up column parity */ 83 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 84 for(i = 0; i < 256; i++) {
128
129 /* Get CP0 - CP5 from table */ 85 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 86 idx = nand_ecc_precalc_table[*dat++];
131 reg1 ^= (idx & 0x3f); 87 reg1 ^= (idx & 0x3f);
132 88
133 /* All bit XOR = 1 ? */ 89 /* All bit XOR = 1 ? */
134 if (idx & 0x40) { 90 if (idx & 0x40) {
135 reg3 ^= (u_char) j; 91 reg3 ^= (uint8_t) i;
136 reg2 ^= ~((u_char) j); 92 reg2 ^= ~((uint8_t) i);
137 } 93 }
138 } 94 }
139 95
140 /* Create non-inverted ECC code from line parity */ 96 /* Create non-inverted ECC code from line parity */
141 nand_trans_result(reg2, reg3, ecc_code); 97 tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */
98 tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
99 tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
100 tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
101 tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
102 tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
103 tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
104 tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
105
106 tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */
107 tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
108 tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
109 tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
110 tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
111 tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
112 tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
113 tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
142 114
143 /* Calculate final ECC code */ 115 /* Calculate final ECC code */
144 ecc_code[0] = ~ecc_code[0]; 116#ifdef CONFIG_NAND_ECC_SMC
145 ecc_code[1] = ~ecc_code[1]; 117 ecc_code[0] = ~tmp2;
118 ecc_code[1] = ~tmp1;
119#else
120 ecc_code[0] = ~tmp1;
121 ecc_code[1] = ~tmp2;
122#endif
146 ecc_code[2] = ((~reg1) << 2) | 0x03; 123 ecc_code[2] = ((~reg1) << 2) | 0x03;
124
147 return 0; 125 return 0;
148} 126}
127EXPORT_SYMBOL(nand_calculate_ecc);
128
129static inline int countbits(uint32_t byte)
130{
131 int res = 0;
132
133 for (;byte; byte >>= 1)
134 res += byte & 0x01;
135 return res;
136}
149 137
150/** 138/**
151 * nand_correct_data - [NAND Interface] Detect and correct bit error(s) 139 * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
@@ -156,93 +144,54 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
156 * 144 *
157 * Detect and correct a 1 bit error for 256 byte block 145 * Detect and correct a 1 bit error for 256 byte block
158 */ 146 */
159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 147int nand_correct_data(struct mtd_info *mtd, u_char *dat,
148 u_char *read_ecc, u_char *calc_ecc)
160{ 149{
161 u_char a, b, c, d1, d2, d3, add, bit, i; 150 uint8_t s0, s1, s2;
151
152#ifdef CONFIG_NAND_ECC_SMC
153 s0 = calc_ecc[0] ^ read_ecc[0];
154 s1 = calc_ecc[1] ^ read_ecc[1];
155 s2 = calc_ecc[2] ^ read_ecc[2];
156#else
157 s1 = calc_ecc[0] ^ read_ecc[0];
158 s0 = calc_ecc[1] ^ read_ecc[1];
159 s2 = calc_ecc[2] ^ read_ecc[2];
160#endif
161 if ((s0 | s1 | s2) == 0)
162 return 0;
162 163
163 /* Do error detection */ 164 /* Check for a single bit error */
164 d1 = calc_ecc[0] ^ read_ecc[0]; 165 if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
165 d2 = calc_ecc[1] ^ read_ecc[1]; 166 ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
166 d3 = calc_ecc[2] ^ read_ecc[2]; 167 ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
167 168
168 if ((d1 | d2 | d3) == 0) { 169 uint32_t byteoffs, bitnum;
169 /* No errors */ 170
170 return 0; 171 byteoffs = (s1 << 0) & 0x80;
171 } 172 byteoffs |= (s1 << 1) & 0x40;
172 else { 173 byteoffs |= (s1 << 2) & 0x20;
173 a = (d1 ^ (d1 >> 1)) & 0x55; 174 byteoffs |= (s1 << 3) & 0x10;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 175
175 c = (d3 ^ (d3 >> 1)) & 0x54; 176 byteoffs |= (s0 >> 4) & 0x08;
176 177 byteoffs |= (s0 >> 3) & 0x04;
177 /* Found and will correct single bit error in the data */ 178 byteoffs |= (s0 >> 2) & 0x02;
178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { 179 byteoffs |= (s0 >> 1) & 0x01;
179 c = 0x80; 180
180 add = 0; 181 bitnum = (s2 >> 5) & 0x04;
181 a = 0x80; 182 bitnum |= (s2 >> 4) & 0x02;
182 for (i=0; i<4; i++) { 183 bitnum |= (s2 >> 3) & 0x01;
183 if (d1 & c) 184
184 add |= a; 185 dat[byteoffs] ^= (1 << bitnum);
185 c >>= 2; 186
186 a >>= 1; 187 return 1;
187 }
188 c = 0x80;
189 for (i=0; i<4; i++) {
190 if (d2 & c)
191 add |= a;
192 c >>= 2;
193 a >>= 1;
194 }
195 bit = 0;
196 b = 0x04;
197 c = 0x80;
198 for (i=0; i<3; i++) {
199 if (d3 & c)
200 bit |= b;
201 c >>= 2;
202 b >>= 1;
203 }
204 b = 0x01;
205 a = dat[add];
206 a ^= (b << bit);
207 dat[add] = a;
208 return 1;
209 }
210 else {
211 i = 0;
212 while (d1) {
213 if (d1 & 0x01)
214 ++i;
215 d1 >>= 1;
216 }
217 while (d2) {
218 if (d2 & 0x01)
219 ++i;
220 d2 >>= 1;
221 }
222 while (d3) {
223 if (d3 & 0x01)
224 ++i;
225 d3 >>= 1;
226 }
227 if (i == 1) {
228 /* ECC Code Error Correction */
229 read_ecc[0] = calc_ecc[0];
230 read_ecc[1] = calc_ecc[1];
231 read_ecc[2] = calc_ecc[2];
232 return 2;
233 }
234 else {
235 /* Uncorrectable Error */
236 return -1;
237 }
238 }
239 } 188 }
240 189
241 /* Should never happen */ 190 if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
191 return 1;
192
242 return -1; 193 return -1;
243} 194}
244
245EXPORT_SYMBOL(nand_calculate_ecc);
246EXPORT_SYMBOL(nand_correct_data); 195EXPORT_SYMBOL(nand_correct_data);
247 196
248MODULE_LICENSE("GPL"); 197MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index dbc7e55a4247..2e2cdf2fc91d 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -18,99 +18,110 @@
18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, 18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
19* options 19* options
20* 20*
21* Pagesize; 0, 256, 512 21* Pagesize; 0, 256, 512
22* 0 get this information from the extended chip ID 22* 0 get this information from the extended chip ID
23+ 256 256 Byte page size 23+ 256 256 Byte page size
24* 512 512 Byte page size 24* 512 512 Byte page size
25*/ 25*/
26struct nand_flash_dev nand_flash_ids[] = { 26struct nand_flash_dev nand_flash_ids[] = {
27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, 27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
28 {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, 28 {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
29 {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, 29 {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
30 {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, 30 {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
31 {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, 31 {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
32 {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, 32 {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
33 {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, 33 {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, 34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, 35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, 36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
37 37
38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, 38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, 39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
42 42
43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, 43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, 44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
47 47
48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, 48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, 49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
52 52
53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, 53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, 54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
57 57
58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, 58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, 59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, 60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
61 {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 61 {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
65 65
66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, 66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
67 67
68 /* These are the new chips with large page size. The pagesize 68 /*
69 * and the erasesize is determined from the extended id bytes 69 * These are the new chips with large page size. The pagesize and the
70 */ 70 * erasesize is determined from the extended id bytes
71 */
72#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR)
73#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
74
71 /*512 Megabit */ 75 /*512 Megabit */
72 {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 76 {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS},
73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 77 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS},
74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 78 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16},
75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 79 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16},
76 80
77 /* 1 Gigabit */ 81 /* 1 Gigabit */
78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 82 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS},
79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 83 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, LP_OPTIONS},
80 {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 84 {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16},
81 {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 85 {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16},
82 86
83 /* 2 Gigabit */ 87 /* 2 Gigabit */
84 {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 88 {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 89 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, LP_OPTIONS},
86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 90 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, LP_OPTIONS16},
87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 91 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, LP_OPTIONS16},
88 92
89 /* 4 Gigabit */ 93 /* 4 Gigabit */
90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 94 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, LP_OPTIONS},
91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 95 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, LP_OPTIONS},
92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 96 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, LP_OPTIONS16},
93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 97 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, LP_OPTIONS16},
94 98
95 /* 8 Gigabit */ 99 /* 8 Gigabit */
96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 100 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS},
97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 101 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS},
98 {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 102 {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16},
99 {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 103 {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16},
100 104
101 /* 16 Gigabit */ 105 /* 16 Gigabit */
102 {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 106 {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS},
103 {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 107 {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS},
104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 108 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16},
105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 109 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16},
106 110
107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! 111 /*
108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes 112 * Renesas AND 1 Gigabit. Those chips do not support extended id and
109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 113 * have a strange page/block layout ! The chosen minimum erasesize is
110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go 114 * 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page
111 * There are more speed improvements for reads and writes possible, but not implemented now 115 * planes 1 block = 2 pages, but due to plane arrangement the blocks
116 * 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 Anyway JFFS2 would
117 * increase the eraseblock size so we chose a combined one which can be
118 * erased in one go There are more speed improvements for reads and
119 * writes possible, but not implemented now
112 */ 120 */
113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, 121 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000,
122 NAND_IS_AND | NAND_NO_AUTOINCR |NAND_NO_READRDY | NAND_4PAGE_ARRAY |
123 BBT_AUTO_REFRESH
124 },
114 125
115 {NULL,} 126 {NULL,}
116}; 127};
@@ -125,13 +136,13 @@ struct nand_manufacturers nand_manuf_ids[] = {
125 {NAND_MFR_NATIONAL, "National"}, 136 {NAND_MFR_NATIONAL, "National"},
126 {NAND_MFR_RENESAS, "Renesas"}, 137 {NAND_MFR_RENESAS, "Renesas"},
127 {NAND_MFR_STMICRO, "ST Micro"}, 138 {NAND_MFR_STMICRO, "ST Micro"},
128 {NAND_MFR_HYNIX, "Hynix"}, 139 {NAND_MFR_HYNIX, "Hynix"},
129 {0x0, "Unknown"} 140 {0x0, "Unknown"}
130}; 141};
131 142
132EXPORT_SYMBOL (nand_manuf_ids); 143EXPORT_SYMBOL(nand_manuf_ids);
133EXPORT_SYMBOL (nand_flash_ids); 144EXPORT_SYMBOL(nand_flash_ids);
134 145
135MODULE_LICENSE ("GPL"); 146MODULE_LICENSE("GPL");
136MODULE_AUTHOR ("Thomas Gleixner <tglx@linutronix.de>"); 147MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
137MODULE_DESCRIPTION ("Nand device & manufacturer ID's"); 148MODULE_DESCRIPTION("Nand device & manufacturer IDs");
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index a0af92cc7efd..ebd64abc8be8 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -369,7 +369,7 @@ init_nandsim(struct mtd_info *mtd)
369 /* Initialize the NAND flash parameters */ 369 /* Initialize the NAND flash parameters */
370 ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8; 370 ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8;
371 ns->geom.totsz = mtd->size; 371 ns->geom.totsz = mtd->size;
372 ns->geom.pgsz = mtd->oobblock; 372 ns->geom.pgsz = mtd->writesize;
373 ns->geom.oobsz = mtd->oobsize; 373 ns->geom.oobsz = mtd->oobsize;
374 ns->geom.secsz = mtd->erasesize; 374 ns->geom.secsz = mtd->erasesize;
375 ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; 375 ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz;
@@ -1071,68 +1071,6 @@ switch_state(struct nandsim *ns)
1071 } 1071 }
1072} 1072}
1073 1073
1074static void
1075ns_hwcontrol(struct mtd_info *mtd, int cmd)
1076{
1077 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
1078
1079 switch (cmd) {
1080
1081 /* set CLE line high */
1082 case NAND_CTL_SETCLE:
1083 NS_DBG("ns_hwcontrol: start command latch cycles\n");
1084 ns->lines.cle = 1;
1085 break;
1086
1087 /* set CLE line low */
1088 case NAND_CTL_CLRCLE:
1089 NS_DBG("ns_hwcontrol: stop command latch cycles\n");
1090 ns->lines.cle = 0;
1091 break;
1092
1093 /* set ALE line high */
1094 case NAND_CTL_SETALE:
1095 NS_DBG("ns_hwcontrol: start address latch cycles\n");
1096 ns->lines.ale = 1;
1097 break;
1098
1099 /* set ALE line low */
1100 case NAND_CTL_CLRALE:
1101 NS_DBG("ns_hwcontrol: stop address latch cycles\n");
1102 ns->lines.ale = 0;
1103 break;
1104
1105 /* set WP line high */
1106 case NAND_CTL_SETWP:
1107 NS_DBG("ns_hwcontrol: enable write protection\n");
1108 ns->lines.wp = 1;
1109 break;
1110
1111 /* set WP line low */
1112 case NAND_CTL_CLRWP:
1113 NS_DBG("ns_hwcontrol: disable write protection\n");
1114 ns->lines.wp = 0;
1115 break;
1116
1117 /* set CE line low */
1118 case NAND_CTL_SETNCE:
1119 NS_DBG("ns_hwcontrol: enable chip\n");
1120 ns->lines.ce = 1;
1121 break;
1122
1123 /* set CE line high */
1124 case NAND_CTL_CLRNCE:
1125 NS_DBG("ns_hwcontrol: disable chip\n");
1126 ns->lines.ce = 0;
1127 break;
1128
1129 default:
1130 NS_ERR("hwcontrol: unknown command\n");
1131 }
1132
1133 return;
1134}
1135
1136static u_char 1074static u_char
1137ns_nand_read_byte(struct mtd_info *mtd) 1075ns_nand_read_byte(struct mtd_info *mtd)
1138{ 1076{
@@ -1359,6 +1297,18 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1359 return; 1297 return;
1360} 1298}
1361 1299
1300static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask)
1301{
1302 struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
1303
1304 ns->lines.cle = bitmask & NAND_CLE ? 1 : 0;
1305 ns->lines.ale = bitmask & NAND_ALE ? 1 : 0;
1306 ns->lines.ce = bitmask & NAND_NCE ? 1 : 0;
1307
1308 if (cmd != NAND_CMD_NONE)
1309 ns_nand_write_byte(mtd, cmd);
1310}
1311
1362static int 1312static int
1363ns_device_ready(struct mtd_info *mtd) 1313ns_device_ready(struct mtd_info *mtd)
1364{ 1314{
@@ -1377,17 +1327,6 @@ ns_nand_read_word(struct mtd_info *mtd)
1377} 1327}
1378 1328
1379static void 1329static void
1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
1381{
1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1383
1384 NS_DBG("write_word\n");
1385
1386 chip->write_byte(mtd, word & 0xFF);
1387 chip->write_byte(mtd, word >> 8);
1388}
1389
1390static void
1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 1330ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1392{ 1331{
1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1332 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1514,16 +1453,14 @@ static int __init ns_init_module(void)
1514 /* 1453 /*
1515 * Register simulator's callbacks. 1454 * Register simulator's callbacks.
1516 */ 1455 */
1517 chip->hwcontrol = ns_hwcontrol; 1456 chip->cmd_ctrl = ns_hwcontrol;
1518 chip->read_byte = ns_nand_read_byte; 1457 chip->read_byte = ns_nand_read_byte;
1519 chip->dev_ready = ns_device_ready; 1458 chip->dev_ready = ns_device_ready;
1520 chip->write_byte = ns_nand_write_byte;
1521 chip->write_buf = ns_nand_write_buf; 1459 chip->write_buf = ns_nand_write_buf;
1522 chip->read_buf = ns_nand_read_buf; 1460 chip->read_buf = ns_nand_read_buf;
1523 chip->verify_buf = ns_nand_verify_buf; 1461 chip->verify_buf = ns_nand_verify_buf;
1524 chip->write_word = ns_nand_write_word;
1525 chip->read_word = ns_nand_read_word; 1462 chip->read_word = ns_nand_read_word;
1526 chip->eccmode = NAND_ECC_SOFT; 1463 chip->ecc.mode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN; 1464 chip->options |= NAND_SKIP_BBTSCAN;
1528 1465
1529 /* 1466 /*
@@ -1546,6 +1483,8 @@ static int __init ns_init_module(void)
1546 chip->options |= NAND_BUSWIDTH_16; 1483 chip->options |= NAND_BUSWIDTH_16;
1547 } 1484 }
1548 1485
1486 nsmtd->owner = THIS_MODULE;
1487
1549 if ((retval = nand_scan(nsmtd, 1)) != 0) { 1488 if ((retval = nand_scan(nsmtd, 1)) != 0) {
1550 NS_ERR("can't register NAND Simulator\n"); 1489 NS_ERR("can't register NAND Simulator\n");
1551 if (retval > 0) 1490 if (retval > 0)
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
new file mode 100644
index 000000000000..fe8d38514ba6
--- /dev/null
+++ b/drivers/mtd/nand/ndfc.c
@@ -0,0 +1,311 @@
1/*
2 * drivers/mtd/ndfc.c
3 *
4 * Overview:
5 * Platform independend driver for NDFC (NanD Flash Controller)
6 * integrated into EP440 cores
7 *
8 * Author: Thomas Gleixner
9 *
10 * Copyright 2006 IBM
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18#include <linux/module.h>
19#include <linux/mtd/nand.h>
20#include <linux/mtd/nand_ecc.h>
21#include <linux/mtd/partitions.h>
22#include <linux/mtd/ndfc.h>
23#include <linux/mtd/mtd.h>
24#include <linux/platform_device.h>
25
26#include <asm/io.h>
27#include <asm/ibm44x.h>
28
29struct ndfc_nand_mtd {
30 struct mtd_info mtd;
31 struct nand_chip chip;
32 struct platform_nand_chip *pl_chip;
33};
34
35static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS];
36
37struct ndfc_controller {
38 void __iomem *ndfcbase;
39 struct nand_hw_control ndfc_control;
40 atomic_t childs_active;
41};
42
43static struct ndfc_controller ndfc_ctrl;
44
45static void ndfc_select_chip(struct mtd_info *mtd, int chip)
46{
47 uint32_t ccr;
48 struct ndfc_controller *ndfc = &ndfc_ctrl;
49 struct nand_chip *nandchip = mtd->priv;
50 struct ndfc_nand_mtd *nandmtd = nandchip->priv;
51 struct platform_nand_chip *pchip = nandmtd->pl_chip;
52
53 ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
54 if (chip >= 0) {
55 ccr &= ~NDFC_CCR_BS_MASK;
56 ccr |= NDFC_CCR_BS(chip + pchip->chip_offset);
57 } else
58 ccr |= NDFC_CCR_RESET_CE;
59 writel(ccr, ndfc->ndfcbase + NDFC_CCR);
60}
61
62static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
63{
64 struct nand_chip *chip = mtd->priv;
65
66 if (cmd == NAND_CMD_NONE)
67 return;
68
69 if (ctrl & NAND_CLE)
70 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD);
71 else
72 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE);
73}
74
75static int ndfc_ready(struct mtd_info *mtd)
76{
77 struct ndfc_controller *ndfc = &ndfc_ctrl;
78
79 return __raw_readl(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
80}
81
82static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
83{
84 uint32_t ccr;
85 struct ndfc_controller *ndfc = &ndfc_ctrl;
86
87 ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
88 ccr |= NDFC_CCR_RESET_ECC;
89 __raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
90 wmb();
91}
92
93static int ndfc_calculate_ecc(struct mtd_info *mtd,
94 const u_char *dat, u_char *ecc_code)
95{
96 struct ndfc_controller *ndfc = &ndfc_ctrl;
97 uint32_t ecc;
98 uint8_t *p = (uint8_t *)&ecc;
99
100 wmb();
101 ecc = __raw_readl(ndfc->ndfcbase + NDFC_ECC);
102 ecc_code[0] = p[1];
103 ecc_code[1] = p[2];
104 ecc_code[2] = p[3];
105
106 return 0;
107}
108
109/*
110 * Speedups for buffer read/write/verify
111 *
112 * NDFC allows 32bit read/write of data. So we can speed up the buffer
113 * functions. No further checking, as nand_base will always read/write
114 * page aligned.
115 */
116static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
117{
118 struct ndfc_controller *ndfc = &ndfc_ctrl;
119 uint32_t *p = (uint32_t *) buf;
120
121 for(;len > 0; len -= 4)
122 *p++ = __raw_readl(ndfc->ndfcbase + NDFC_DATA);
123}
124
125static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
126{
127 struct ndfc_controller *ndfc = &ndfc_ctrl;
128 uint32_t *p = (uint32_t *) buf;
129
130 for(;len > 0; len -= 4)
131 __raw_writel(*p++, ndfc->ndfcbase + NDFC_DATA);
132}
133
134static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
135{
136 struct ndfc_controller *ndfc = &ndfc_ctrl;
137 uint32_t *p = (uint32_t *) buf;
138
139 for(;len > 0; len -= 4)
140 if (*p++ != __raw_readl(ndfc->ndfcbase + NDFC_DATA))
141 return -EFAULT;
142 return 0;
143}
144
145/*
146 * Initialize chip structure
147 */
148static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
149{
150 struct ndfc_controller *ndfc = &ndfc_ctrl;
151 struct nand_chip *chip = &mtd->chip;
152
153 chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
154 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
155 chip->cmd_ctrl = ndfc_hwcontrol;
156 chip->dev_ready = ndfc_ready;
157 chip->select_chip = ndfc_select_chip;
158 chip->chip_delay = 50;
159 chip->priv = mtd;
160 chip->options = mtd->pl_chip->options;
161 chip->controller = &ndfc->ndfc_control;
162 chip->read_buf = ndfc_read_buf;
163 chip->write_buf = ndfc_write_buf;
164 chip->verify_buf = ndfc_verify_buf;
165 chip->ecc.correct = nand_correct_data;
166 chip->ecc.hwctl = ndfc_enable_hwecc;
167 chip->ecc.calculate = ndfc_calculate_ecc;
168 chip->ecc.mode = NAND_ECC_HW;
169 chip->ecc.size = 256;
170 chip->ecc.bytes = 3;
171 chip->ecclayout = mtd->pl_chip->ecclayout;
172 mtd->mtd.priv = chip;
173 mtd->mtd.owner = THIS_MODULE;
174}
175
176static int ndfc_chip_probe(struct platform_device *pdev)
177{
178 struct platform_nand_chip *nc = pdev->dev.platform_data;
179 struct ndfc_chip_settings *settings = nc->priv;
180 struct ndfc_controller *ndfc = &ndfc_ctrl;
181 struct ndfc_nand_mtd *nandmtd;
182
183 if (nc->chip_offset >= NDFC_MAX_BANKS || nc->nr_chips > NDFC_MAX_BANKS)
184 return -EINVAL;
185
186 /* Set the bank settings */
187 __raw_writel(settings->bank_settings,
188 ndfc->ndfcbase + NDFC_BCFG0 + (nc->chip_offset << 2));
189
190 nandmtd = &ndfc_mtd[pdev->id];
191 if (nandmtd->pl_chip)
192 return -EBUSY;
193
194 nandmtd->pl_chip = nc;
195 ndfc_chip_init(nandmtd);
196
197 /* Scan for chips */
198 if (nand_scan(&nandmtd->mtd, nc->nr_chips)) {
199 nandmtd->pl_chip = NULL;
200 return -ENODEV;
201 }
202
203#ifdef CONFIG_MTD_PARTITIONS
204 printk("Number of partitions %d\n", nc->nr_partitions);
205 if (nc->nr_partitions) {
206 /* Add the full device, so complete dumps can be made */
207 add_mtd_device(&nandmtd->mtd);
208 add_mtd_partitions(&nandmtd->mtd, nc->partitions,
209 nc->nr_partitions);
210
211 } else
212#else
213 add_mtd_device(&nandmtd->mtd);
214#endif
215
216 atomic_inc(&ndfc->childs_active);
217 return 0;
218}
219
220static int ndfc_chip_remove(struct platform_device *pdev)
221{
222 return 0;
223}
224
225static int ndfc_nand_probe(struct platform_device *pdev)
226{
227 struct platform_nand_ctrl *nc = pdev->dev.platform_data;
228 struct ndfc_controller_settings *settings = nc->priv;
229 struct resource *res = pdev->resource;
230 struct ndfc_controller *ndfc = &ndfc_ctrl;
231 unsigned long long phys = settings->ndfc_erpn | res->start;
232
233 ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
234 if (!ndfc->ndfcbase) {
235 printk(KERN_ERR "NDFC: ioremap failed\n");
236 return -EIO;
237 }
238
239 __raw_writel(settings->ccr_settings, ndfc->ndfcbase + NDFC_CCR);
240
241 spin_lock_init(&ndfc->ndfc_control.lock);
242 init_waitqueue_head(&ndfc->ndfc_control.wq);
243
244 platform_set_drvdata(pdev, ndfc);
245
246 printk("NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n",
247 __raw_readl(ndfc->ndfcbase + NDFC_REVID));
248
249 return 0;
250}
251
252static int ndfc_nand_remove(struct platform_device *pdev)
253{
254 struct ndfc_controller *ndfc = platform_get_drvdata(pdev);
255
256 if (atomic_read(&ndfc->childs_active))
257 return -EBUSY;
258
259 if (ndfc) {
260 platform_set_drvdata(pdev, NULL);
261 iounmap(ndfc_ctrl.ndfcbase);
262 ndfc_ctrl.ndfcbase = NULL;
263 }
264 return 0;
265}
266
267/* driver device registration */
268
269static struct platform_driver ndfc_chip_driver = {
270 .probe = ndfc_chip_probe,
271 .remove = ndfc_chip_remove,
272 .driver = {
273 .name = "ndfc-chip",
274 .owner = THIS_MODULE,
275 },
276};
277
278static struct platform_driver ndfc_nand_driver = {
279 .probe = ndfc_nand_probe,
280 .remove = ndfc_nand_remove,
281 .driver = {
282 .name = "ndfc-nand",
283 .owner = THIS_MODULE,
284 },
285};
286
287static int __init ndfc_nand_init(void)
288{
289 int ret;
290
291 spin_lock_init(&ndfc_ctrl.ndfc_control.lock);
292 init_waitqueue_head(&ndfc_ctrl.ndfc_control.wq);
293
294 ret = platform_driver_register(&ndfc_nand_driver);
295 if (!ret)
296 ret = platform_driver_register(&ndfc_chip_driver);
297 return ret;
298}
299
300static void __exit ndfc_nand_exit(void)
301{
302 platform_driver_unregister(&ndfc_chip_driver);
303 platform_driver_unregister(&ndfc_nand_driver);
304}
305
306module_init(ndfc_nand_init);
307module_exit(ndfc_nand_exit);
308
309MODULE_LICENSE("GPL");
310MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
311MODULE_DESCRIPTION("Platform driver for NDFC");
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index 91a95f34a6ee..22fa65c12ab9 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -58,21 +58,21 @@
58/* 58/*
59 * MTD structure for PPChameleonEVB board 59 * MTD structure for PPChameleonEVB board
60 */ 60 */
61static struct mtd_info *ppchameleon_mtd = NULL; 61static struct mtd_info *ppchameleon_mtd = NULL;
62static struct mtd_info *ppchameleonevb_mtd = NULL; 62static struct mtd_info *ppchameleonevb_mtd = NULL;
63 63
64/* 64/*
65 * Module stuff 65 * Module stuff
66 */ 66 */
67static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR; 67static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR;
68static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR; 68static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR;
69 69
70#ifdef MODULE 70#ifdef MODULE
71module_param(ppchameleon_fio_pbase, ulong, 0); 71module_param(ppchameleon_fio_pbase, ulong, 0);
72module_param(ppchameleonevb_fio_pbase, ulong, 0); 72module_param(ppchameleonevb_fio_pbase, ulong, 0);
73#else 73#else
74__setup("ppchameleon_fio_pbase=",ppchameleon_fio_pbase); 74__setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase);
75__setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase); 75__setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
76#endif 76#endif
77 77
78#ifdef CONFIG_MTD_PARTITIONS 78#ifdef CONFIG_MTD_PARTITIONS
@@ -80,82 +80,96 @@ __setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase);
80 * Define static partitions for flash devices 80 * Define static partitions for flash devices
81 */ 81 */
82static struct mtd_partition partition_info_hi[] = { 82static struct mtd_partition partition_info_hi[] = {
83 { name: "PPChameleon HI Nand Flash", 83 { .name = "PPChameleon HI Nand Flash",
84 offset: 0, 84 offset = 0,
85 size: 128*1024*1024 } 85 .size = 128 * 1024 * 1024
86 }
86}; 87};
87 88
88static struct mtd_partition partition_info_me[] = { 89static struct mtd_partition partition_info_me[] = {
89 { name: "PPChameleon ME Nand Flash", 90 { .name = "PPChameleon ME Nand Flash",
90 offset: 0, 91 .offset = 0,
91 size: 32*1024*1024 } 92 .size = 32 * 1024 * 1024
93 }
92}; 94};
93 95
94static struct mtd_partition partition_info_evb[] = { 96static struct mtd_partition partition_info_evb[] = {
95 { name: "PPChameleonEVB Nand Flash", 97 { .name = "PPChameleonEVB Nand Flash",
96 offset: 0, 98 .offset = 0,
97 size: 32*1024*1024 } 99 .size = 32 * 1024 * 1024
100 }
98}; 101};
99 102
100#define NUM_PARTITIONS 1 103#define NUM_PARTITIONS 1
101 104
102extern int parse_cmdline_partitions(struct mtd_info *master, 105extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
103 struct mtd_partition **pparts,
104 const char *mtd_id);
105#endif 106#endif
106 107
107
108/* 108/*
109 * hardware specific access to control-lines 109 * hardware specific access to control-lines
110 */ 110 */
111static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd) 111static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd,
112 unsigned int ctrl)
112{ 113{
113 switch(cmd) { 114 struct nand_chip *chip = mtd->priv;
114 115
115 case NAND_CTL_SETCLE: 116 if (ctrl & NAND_CTRL_CHANGE) {
116 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR); 117#error Missing headerfiles. No way to fix this. -tglx
117 break; 118 switch (cmd) {
118 case NAND_CTL_CLRCLE: 119 case NAND_CTL_SETCLE:
119 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR); 120 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
120 break; 121 break;
121 case NAND_CTL_SETALE: 122 case NAND_CTL_CLRCLE:
122 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR); 123 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
123 break; 124 break;
124 case NAND_CTL_CLRALE: 125 case NAND_CTL_SETALE:
125 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR); 126 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
126 break; 127 break;
127 case NAND_CTL_SETNCE: 128 case NAND_CTL_CLRALE:
129 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
130 break;
131 case NAND_CTL_SETNCE:
128 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR); 132 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
129 break; 133 break;
130 case NAND_CTL_CLRNCE: 134 case NAND_CTL_CLRNCE:
131 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR); 135 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
132 break; 136 break;
137 }
133 } 138 }
139 if (cmd != NAND_CMD_NONE)
140 writeb(cmd, chip->IO_ADDR_W);
134} 141}
135 142
136static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) 143static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd,
144 unsigned int ctrl)
137{ 145{
138 switch(cmd) { 146 struct nand_chip *chip = mtd->priv;
139 147
140 case NAND_CTL_SETCLE: 148 if (ctrl & NAND_CTRL_CHANGE) {
141 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR); 149#error Missing headerfiles. No way to fix this. -tglx
142 break; 150 switch (cmd) {
143 case NAND_CTL_CLRCLE: 151 case NAND_CTL_SETCLE:
144 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR); 152 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
145 break; 153 break;
146 case NAND_CTL_SETALE: 154 case NAND_CTL_CLRCLE:
147 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR); 155 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
148 break; 156 break;
149 case NAND_CTL_CLRALE: 157 case NAND_CTL_SETALE:
150 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR); 158 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
151 break; 159 break;
152 case NAND_CTL_SETNCE: 160 case NAND_CTL_CLRALE:
153 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR); 161 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
154 break; 162 break;
155 case NAND_CTL_CLRNCE: 163 case NAND_CTL_SETNCE:
156 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR); 164 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
157 break; 165 break;
166 case NAND_CTL_CLRNCE:
167 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
168 break;
169 }
158 } 170 }
171 if (cmd != NAND_CMD_NONE)
172 writeb(cmd, chip->IO_ADDR_W);
159} 173}
160 174
161#ifdef USE_READY_BUSY_PIN 175#ifdef USE_READY_BUSY_PIN
@@ -164,15 +178,15 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
164 */ 178 */
165static int ppchameleon_device_ready(struct mtd_info *minfo) 179static int ppchameleon_device_ready(struct mtd_info *minfo)
166{ 180{
167 if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_RB_GPIO_PIN) 181 if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_RB_GPIO_PIN)
168 return 1; 182 return 1;
169 return 0; 183 return 0;
170} 184}
171 185
172static int ppchameleonevb_device_ready(struct mtd_info *minfo) 186static int ppchameleonevb_device_ready(struct mtd_info *minfo)
173{ 187{
174 if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN) 188 if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
175 return 1; 189 return 1;
176 return 0; 190 return 0;
177} 191}
178#endif 192#endif
@@ -185,7 +199,7 @@ const char *part_probes_evb[] = { "cmdlinepart", NULL };
185/* 199/*
186 * Main initialization routine 200 * Main initialization routine
187 */ 201 */
188static int __init ppchameleonevb_init (void) 202static int __init ppchameleonevb_init(void)
189{ 203{
190 struct nand_chip *this; 204 struct nand_chip *this;
191 const char *part_type = 0; 205 const char *part_type = 0;
@@ -194,13 +208,11 @@ static int __init ppchameleonevb_init (void)
194 void __iomem *ppchameleon_fio_base; 208 void __iomem *ppchameleon_fio_base;
195 void __iomem *ppchameleonevb_fio_base; 209 void __iomem *ppchameleonevb_fio_base;
196 210
197
198 /********************************* 211 /*********************************
199 * Processor module NAND (if any) * 212 * Processor module NAND (if any) *
200 *********************************/ 213 *********************************/
201 /* Allocate memory for MTD device structure and private data */ 214 /* Allocate memory for MTD device structure and private data */
202 ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + 215 ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
203 sizeof(struct nand_chip), GFP_KERNEL);
204 if (!ppchameleon_mtd) { 216 if (!ppchameleon_mtd) {
205 printk("Unable to allocate PPChameleon NAND MTD device structure.\n"); 217 printk("Unable to allocate PPChameleon NAND MTD device structure.\n");
206 return -ENOMEM; 218 return -ENOMEM;
@@ -208,63 +220,65 @@ static int __init ppchameleonevb_init (void)
208 220
209 /* map physical address */ 221 /* map physical address */
210 ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M); 222 ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M);
211 if(!ppchameleon_fio_base) { 223 if (!ppchameleon_fio_base) {
212 printk("ioremap PPChameleon NAND flash failed\n"); 224 printk("ioremap PPChameleon NAND flash failed\n");
213 kfree(ppchameleon_mtd); 225 kfree(ppchameleon_mtd);
214 return -EIO; 226 return -EIO;
215 } 227 }
216 228
217 /* Get pointer to private data */ 229 /* Get pointer to private data */
218 this = (struct nand_chip *) (&ppchameleon_mtd[1]); 230 this = (struct nand_chip *)(&ppchameleon_mtd[1]);
219 231
220 /* Initialize structures */ 232 /* Initialize structures */
221 memset((char *) ppchameleon_mtd, 0, sizeof(struct mtd_info)); 233 memset(ppchameleon_mtd, 0, sizeof(struct mtd_info));
222 memset((char *) this, 0, sizeof(struct nand_chip)); 234 memset(this, 0, sizeof(struct nand_chip));
223 235
224 /* Link the private data with the MTD structure */ 236 /* Link the private data with the MTD structure */
225 ppchameleon_mtd->priv = this; 237 ppchameleon_mtd->priv = this;
238 ppchameleon_mtd->owner = THIS_MODULE;
226 239
227 /* Initialize GPIOs */ 240 /* Initialize GPIOs */
228 /* Pin mapping for NAND chip */ 241 /* Pin mapping for NAND chip */
229 /* 242 /*
230 CE GPIO_01 243 CE GPIO_01
231 CLE GPIO_02 244 CLE GPIO_02
232 ALE GPIO_03 245 ALE GPIO_03
233 R/B GPIO_04 246 R/B GPIO_04
234 */ 247 */
235 /* output select */ 248 /* output select */
236 out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xC0FFFFFF); 249 out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF);
237 /* three-state select */ 250 /* three-state select */
238 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xC0FFFFFF); 251 out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF);
239 /* enable output driver */ 252 /* enable output driver */
240 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN); 253 out_be32((volatile unsigned *)GPIO0_TCR,
254 in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
241#ifdef USE_READY_BUSY_PIN 255#ifdef USE_READY_BUSY_PIN
242 /* three-state select */ 256 /* three-state select */
243 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFF3FFFFF); 257 out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF);
244 /* high-impedecence */ 258 /* high-impedecence */
245 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_RB_GPIO_PIN)); 259 out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
246 /* input select */ 260 /* input select */
247 out_be32((volatile unsigned*)GPIO0_ISR1H, (in_be32((volatile unsigned*)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000); 261 out_be32((volatile unsigned *)GPIO0_ISR1H,
262 (in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
248#endif 263#endif
249 264
250 /* insert callbacks */ 265 /* insert callbacks */
251 this->IO_ADDR_R = ppchameleon_fio_base; 266 this->IO_ADDR_R = ppchameleon_fio_base;
252 this->IO_ADDR_W = ppchameleon_fio_base; 267 this->IO_ADDR_W = ppchameleon_fio_base;
253 this->hwcontrol = ppchameleon_hwcontrol; 268 this->cmd_ctrl = ppchameleon_hwcontrol;
254#ifdef USE_READY_BUSY_PIN 269#ifdef USE_READY_BUSY_PIN
255 this->dev_ready = ppchameleon_device_ready; 270 this->dev_ready = ppchameleon_device_ready;
256#endif 271#endif
257 this->chip_delay = NAND_BIG_DELAY_US; 272 this->chip_delay = NAND_BIG_DELAY_US;
258 /* ECC mode */ 273 /* ECC mode */
259 this->eccmode = NAND_ECC_SOFT; 274 this->ecc.mode = NAND_ECC_SOFT;
260 275
261 /* Scan to find existence of the device (it could not be mounted) */ 276 /* Scan to find existence of the device (it could not be mounted) */
262 if (nand_scan (ppchameleon_mtd, 1)) { 277 if (nand_scan(ppchameleon_mtd, 1)) {
263 iounmap((void *)ppchameleon_fio_base); 278 iounmap((void *)ppchameleon_fio_base);
264 kfree (ppchameleon_mtd); 279 kfree(ppchameleon_mtd);
265 goto nand_evb_init; 280 goto nand_evb_init;
266 } 281 }
267
268#ifndef USE_READY_BUSY_PIN 282#ifndef USE_READY_BUSY_PIN
269 /* Adjust delay if necessary */ 283 /* Adjust delay if necessary */
270 if (ppchameleon_mtd->size == NAND_SMALL_SIZE) 284 if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
@@ -275,12 +289,11 @@ static int __init ppchameleonevb_init (void)
275 ppchameleon_mtd->name = "ppchameleon-nand"; 289 ppchameleon_mtd->name = "ppchameleon-nand";
276 mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0); 290 mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
277 if (mtd_parts_nb > 0) 291 if (mtd_parts_nb > 0)
278 part_type = "command line"; 292 part_type = "command line";
279 else 293 else
280 mtd_parts_nb = 0; 294 mtd_parts_nb = 0;
281#endif 295#endif
282 if (mtd_parts_nb == 0) 296 if (mtd_parts_nb == 0) {
283 {
284 if (ppchameleon_mtd->size == NAND_SMALL_SIZE) 297 if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
285 mtd_parts = partition_info_me; 298 mtd_parts = partition_info_me;
286 else 299 else
@@ -293,13 +306,12 @@ static int __init ppchameleonevb_init (void)
293 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 306 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
294 add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb); 307 add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
295 308
296nand_evb_init: 309 nand_evb_init:
297 /**************************** 310 /****************************
298 * EVB NAND (always present) * 311 * EVB NAND (always present) *
299 ****************************/ 312 ****************************/
300 /* Allocate memory for MTD device structure and private data */ 313 /* Allocate memory for MTD device structure and private data */
301 ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + 314 ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
302 sizeof(struct nand_chip), GFP_KERNEL);
303 if (!ppchameleonevb_mtd) { 315 if (!ppchameleonevb_mtd) {
304 printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n"); 316 printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
305 return -ENOMEM; 317 return -ENOMEM;
@@ -307,77 +319,76 @@ nand_evb_init:
307 319
308 /* map physical address */ 320 /* map physical address */
309 ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M); 321 ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M);
310 if(!ppchameleonevb_fio_base) { 322 if (!ppchameleonevb_fio_base) {
311 printk("ioremap PPChameleonEVB NAND flash failed\n"); 323 printk("ioremap PPChameleonEVB NAND flash failed\n");
312 kfree(ppchameleonevb_mtd); 324 kfree(ppchameleonevb_mtd);
313 return -EIO; 325 return -EIO;
314 } 326 }
315 327
316 /* Get pointer to private data */ 328 /* Get pointer to private data */
317 this = (struct nand_chip *) (&ppchameleonevb_mtd[1]); 329 this = (struct nand_chip *)(&ppchameleonevb_mtd[1]);
318 330
319 /* Initialize structures */ 331 /* Initialize structures */
320 memset((char *) ppchameleonevb_mtd, 0, sizeof(struct mtd_info)); 332 memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
321 memset((char *) this, 0, sizeof(struct nand_chip)); 333 memset(this, 0, sizeof(struct nand_chip));
322 334
323 /* Link the private data with the MTD structure */ 335 /* Link the private data with the MTD structure */
324 ppchameleonevb_mtd->priv = this; 336 ppchameleonevb_mtd->priv = this;
325 337
326 /* Initialize GPIOs */ 338 /* Initialize GPIOs */
327 /* Pin mapping for NAND chip */ 339 /* Pin mapping for NAND chip */
328 /* 340 /*
329 CE GPIO_14 341 CE GPIO_14
330 CLE GPIO_15 342 CLE GPIO_15
331 ALE GPIO_16 343 ALE GPIO_16
332 R/B GPIO_31 344 R/B GPIO_31
333 */ 345 */
334 /* output select */ 346 /* output select */
335 out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xFFFFFFF0); 347 out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0);
336 out_be32((volatile unsigned*)GPIO0_OSRL, in_be32((volatile unsigned*)GPIO0_OSRL) & 0x3FFFFFFF); 348 out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF);
337 /* three-state select */ 349 /* three-state select */
338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); 350 out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0);
339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); 351 out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF);
340 /* enable output driver */ 352 /* enable output driver */
341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | 353 out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); 354 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
343#ifdef USE_READY_BUSY_PIN 355#ifdef USE_READY_BUSY_PIN
344 /* three-state select */ 356 /* three-state select */
345 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0xFFFFFFFC); 357 out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC);
346 /* high-impedecence */ 358 /* high-impedecence */
347 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN)); 359 out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
348 /* input select */ 360 /* input select */
349 out_be32((volatile unsigned*)GPIO0_ISR1L, (in_be32((volatile unsigned*)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001); 361 out_be32((volatile unsigned *)GPIO0_ISR1L,
362 (in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
350#endif 363#endif
351 364
352 /* insert callbacks */ 365 /* insert callbacks */
353 this->IO_ADDR_R = ppchameleonevb_fio_base; 366 this->IO_ADDR_R = ppchameleonevb_fio_base;
354 this->IO_ADDR_W = ppchameleonevb_fio_base; 367 this->IO_ADDR_W = ppchameleonevb_fio_base;
355 this->hwcontrol = ppchameleonevb_hwcontrol; 368 this->cmd_ctrl = ppchameleonevb_hwcontrol;
356#ifdef USE_READY_BUSY_PIN 369#ifdef USE_READY_BUSY_PIN
357 this->dev_ready = ppchameleonevb_device_ready; 370 this->dev_ready = ppchameleonevb_device_ready;
358#endif 371#endif
359 this->chip_delay = NAND_SMALL_DELAY_US; 372 this->chip_delay = NAND_SMALL_DELAY_US;
360 373
361 /* ECC mode */ 374 /* ECC mode */
362 this->eccmode = NAND_ECC_SOFT; 375 this->ecc.mode = NAND_ECC_SOFT;
363 376
364 /* Scan to find existence of the device */ 377 /* Scan to find existence of the device */
365 if (nand_scan (ppchameleonevb_mtd, 1)) { 378 if (nand_scan(ppchameleonevb_mtd, 1)) {
366 iounmap((void *)ppchameleonevb_fio_base); 379 iounmap((void *)ppchameleonevb_fio_base);
367 kfree (ppchameleonevb_mtd); 380 kfree(ppchameleonevb_mtd);
368 return -ENXIO; 381 return -ENXIO;
369 } 382 }
370
371#ifdef CONFIG_MTD_PARTITIONS 383#ifdef CONFIG_MTD_PARTITIONS
372 ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; 384 ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
373 mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0); 385 mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
374 if (mtd_parts_nb > 0) 386 if (mtd_parts_nb > 0)
375 part_type = "command line"; 387 part_type = "command line";
376 else 388 else
377 mtd_parts_nb = 0; 389 mtd_parts_nb = 0;
378#endif 390#endif
379 if (mtd_parts_nb == 0) 391 if (mtd_parts_nb == 0) {
380 {
381 mtd_parts = partition_info_evb; 392 mtd_parts = partition_info_evb;
382 mtd_parts_nb = NUM_PARTITIONS; 393 mtd_parts_nb = NUM_PARTITIONS;
383 part_type = "static"; 394 part_type = "static";
@@ -390,18 +401,19 @@ nand_evb_init:
390 /* Return happy */ 401 /* Return happy */
391 return 0; 402 return 0;
392} 403}
404
393module_init(ppchameleonevb_init); 405module_init(ppchameleonevb_init);
394 406
395/* 407/*
396 * Clean up routine 408 * Clean up routine
397 */ 409 */
398static void __exit ppchameleonevb_cleanup (void) 410static void __exit ppchameleonevb_cleanup(void)
399{ 411{
400 struct nand_chip *this; 412 struct nand_chip *this;
401 413
402 /* Release resources, unregister device(s) */ 414 /* Release resources, unregister device(s) */
403 nand_release (ppchameleon_mtd); 415 nand_release(ppchameleon_mtd);
404 nand_release (ppchameleonevb_mtd); 416 nand_release(ppchameleonevb_mtd);
405 417
406 /* Release iomaps */ 418 /* Release iomaps */
407 this = (struct nand_chip *) &ppchameleon_mtd[1]; 419 this = (struct nand_chip *) &ppchameleon_mtd[1];
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 4129c03dfd90..f8c49645324d 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -97,12 +97,12 @@ static struct mtd_info *rtc_from4_mtd = NULL;
97static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); 97static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
98 98
99static const struct mtd_partition partition_info[] = { 99static const struct mtd_partition partition_info[] = {
100 { 100 {
101 .name = "Renesas flash partition 1", 101 .name = "Renesas flash partition 1",
102 .offset = 0, 102 .offset = 0,
103 .size = MTDPART_SIZ_FULL 103 .size = MTDPART_SIZ_FULL},
104 },
105}; 104};
105
106#define NUM_PARTITIONS 1 106#define NUM_PARTITIONS 1
107 107
108/* 108/*
@@ -111,8 +111,8 @@ static const struct mtd_partition partition_info[] = {
111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE 111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE
112 * 112 *
113 */ 113 */
114static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; 114static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
115static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 115static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
116 116
117static struct nand_bbt_descr rtc_from4_bbt_main_descr = { 117static struct nand_bbt_descr rtc_from4_bbt_main_descr = {
118 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 118 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
@@ -134,8 +134,6 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
134 .pattern = mirror_pattern 134 .pattern = mirror_pattern
135}; 135};
136 136
137
138
139#ifdef RTC_FROM4_HWECC 137#ifdef RTC_FROM4_HWECC
140 138
141/* the Reed Solomon control structure */ 139/* the Reed Solomon control structure */
@@ -144,15 +142,14 @@ static struct rs_control *rs_decoder;
144/* 142/*
145 * hardware specific Out Of Band information 143 * hardware specific Out Of Band information
146 */ 144 */
147static struct nand_oobinfo rtc_from4_nand_oobinfo = { 145static struct nand_ecclayout rtc_from4_nand_oobinfo = {
148 .useecc = MTD_NANDECC_AUTOPLACE,
149 .eccbytes = 32, 146 .eccbytes = 32,
150 .eccpos = { 147 .eccpos = {
151 0, 1, 2, 3, 4, 5, 6, 7, 148 0, 1, 2, 3, 4, 5, 6, 7,
152 8, 9, 10, 11, 12, 13, 14, 15, 149 8, 9, 10, 11, 12, 13, 14, 15,
153 16, 17, 18, 19, 20, 21, 22, 23, 150 16, 17, 18, 19, 20, 21, 22, 23,
154 24, 25, 26, 27, 28, 29, 30, 31}, 151 24, 25, 26, 27, 28, 29, 30, 31},
155 .oobfree = { {32, 32} } 152 .oobfree = {{32, 32}}
156}; 153};
157 154
158/* Aargh. I missed the reversed bit order, when I 155/* Aargh. I missed the reversed bit order, when I
@@ -162,44 +159,42 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
162 * of the ecc byte which we get from the FPGA 159 * of the ecc byte which we get from the FPGA
163 */ 160 */
164static uint8_t revbits[256] = { 161static uint8_t revbits[256] = {
165 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 162 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
166 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 163 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
167 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 164 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
168 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 165 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
169 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 166 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
170 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 167 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
171 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 168 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
172 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 169 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
173 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 170 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
174 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 171 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
175 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 172 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
176 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 173 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
177 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 174 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
178 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 175 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
179 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 176 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
180 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 177 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
181 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 178 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
182 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 179 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
183 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 180 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
184 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 181 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
185 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 182 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
186 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 183 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
187 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 184 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
188 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 185 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
189 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 186 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
190 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 187 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
191 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 188 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
192 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 189 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
193 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 190 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
194 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 191 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
195 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 192 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
196 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 193 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
197}; 194};
198 195
199#endif 196#endif
200 197
201
202
203/* 198/*
204 * rtc_from4_hwcontrol - hardware specific access to control-lines 199 * rtc_from4_hwcontrol - hardware specific access to control-lines
205 * @mtd: MTD device structure 200 * @mtd: MTD device structure
@@ -212,35 +207,20 @@ static uint8_t revbits[256] = {
212 * Address lines (A24-A22), so no action is required here. 207 * Address lines (A24-A22), so no action is required here.
213 * 208 *
214 */ 209 */
215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 210static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd,
211 unsigned int ctrl)
216{ 212{
217 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 213 struct nand_chip *chip = (mtd->priv);
218
219 switch(cmd) {
220 214
221 case NAND_CTL_SETCLE: 215 if (cmd == NAND_CMD_NONE)
222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 216 return;
223 break;
224 case NAND_CTL_CLRCLE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
226 break;
227
228 case NAND_CTL_SETALE:
229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
230 break;
231 case NAND_CTL_CLRALE:
232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
233 break;
234 217
235 case NAND_CTL_SETNCE: 218 if (ctrl & NAND_CLE)
236 break; 219 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE);
237 case NAND_CTL_CLRNCE: 220 else
238 break; 221 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE);
239
240 }
241} 222}
242 223
243
244/* 224/*
245 * rtc_from4_nand_select_chip - hardware specific chip select 225 * rtc_from4_nand_select_chip - hardware specific chip select
246 * @mtd: MTD device structure 226 * @mtd: MTD device structure
@@ -252,26 +232,25 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
252 */ 232 */
253static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip) 233static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
254{ 234{
255 struct nand_chip *this = mtd->priv; 235 struct nand_chip *this = mtd->priv;
256 236
257 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK); 237 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK);
258 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK); 238 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK);
259 239
260 switch(chip) { 240 switch (chip) {
261 241
262 case 0: /* select slot 3 chip */ 242 case 0: /* select slot 3 chip */
263 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3); 243 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3);
264 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3); 244 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3);
265 break; 245 break;
266 case 1: /* select slot 4 chip */ 246 case 1: /* select slot 4 chip */
267 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4); 247 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4);
268 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4); 248 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4);
269 break; 249 break;
270 250
271 } 251 }
272} 252}
273 253
274
275/* 254/*
276 * rtc_from4_nand_device_ready - hardware specific ready/busy check 255 * rtc_from4_nand_device_ready - hardware specific ready/busy check
277 * @mtd: MTD device structure 256 * @mtd: MTD device structure
@@ -290,7 +269,6 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
290 269
291} 270}
292 271
293
294/* 272/*
295 * deplete - code to perform device recovery in case there was a power loss 273 * deplete - code to perform device recovery in case there was a power loss
296 * @mtd: MTD device structure 274 * @mtd: MTD device structure
@@ -306,24 +284,23 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
306 */ 284 */
307static void deplete(struct mtd_info *mtd, int chip) 285static void deplete(struct mtd_info *mtd, int chip)
308{ 286{
309 struct nand_chip *this = mtd->priv; 287 struct nand_chip *this = mtd->priv;
310 288
311 /* wait until device is ready */ 289 /* wait until device is ready */
312 while (!this->dev_ready(mtd)); 290 while (!this->dev_ready(mtd)) ;
313 291
314 this->select_chip(mtd, chip); 292 this->select_chip(mtd, chip);
315 293
316 /* Send the commands for device recovery, phase 1 */ 294 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); 295 this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 296 this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
319 297
320 /* Send the commands for device recovery, phase 2 */ 298 /* Send the commands for device recovery, phase 2 */
321 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004); 299 this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
322 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 300 this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
323 301
324} 302}
325 303
326
327#ifdef RTC_FROM4_HWECC 304#ifdef RTC_FROM4_HWECC
328/* 305/*
329 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function 306 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -335,39 +312,35 @@ static void deplete(struct mtd_info *mtd, int chip)
335 */ 312 */
336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) 313static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
337{ 314{
338 volatile unsigned short * rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL); 315 volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
339 unsigned short status; 316 unsigned short status;
340 317
341 switch (mode) { 318 switch (mode) {
342 case NAND_ECC_READ : 319 case NAND_ECC_READ:
343 status = RTC_FROM4_RS_ECC_CTL_CLR 320 status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E;
344 | RTC_FROM4_RS_ECC_CTL_FD_E;
345 321
346 *rs_ecc_ctl = status; 322 *rs_ecc_ctl = status;
347 break; 323 break;
348 324
349 case NAND_ECC_READSYN : 325 case NAND_ECC_READSYN:
350 status = 0x00; 326 status = 0x00;
351 327
352 *rs_ecc_ctl = status; 328 *rs_ecc_ctl = status;
353 break; 329 break;
354 330
355 case NAND_ECC_WRITE : 331 case NAND_ECC_WRITE:
356 status = RTC_FROM4_RS_ECC_CTL_CLR 332 status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E;
357 | RTC_FROM4_RS_ECC_CTL_GEN
358 | RTC_FROM4_RS_ECC_CTL_FD_E;
359 333
360 *rs_ecc_ctl = status; 334 *rs_ecc_ctl = status;
361 break; 335 break;
362 336
363 default: 337 default:
364 BUG(); 338 BUG();
365 break; 339 break;
366 } 340 }
367 341
368} 342}
369 343
370
371/* 344/*
372 * rtc_from4_calculate_ecc - hardware specific code to read ECC code 345 * rtc_from4_calculate_ecc - hardware specific code to read ECC code
373 * @mtd: MTD device structure 346 * @mtd: MTD device structure
@@ -383,7 +356,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
383 */ 356 */
384static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 357static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
385{ 358{
386 volatile unsigned short * rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN); 359 volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
387 unsigned short value; 360 unsigned short value;
388 int i; 361 int i;
389 362
@@ -395,7 +368,6 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
395 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */ 368 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */
396} 369}
397 370
398
399/* 371/*
400 * rtc_from4_correct_data - hardware specific code to correct data using ECC code 372 * rtc_from4_correct_data - hardware specific code to correct data using ECC code
401 * @mtd: MTD device structure 373 * @mtd: MTD device structure
@@ -414,7 +386,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
414 unsigned short status; 386 unsigned short status;
415 uint16_t par[6], syn[6]; 387 uint16_t par[6], syn[6];
416 uint8_t ecc[8]; 388 uint8_t ecc[8];
417 volatile unsigned short *rs_ecc; 389 volatile unsigned short *rs_ecc;
418 390
419 status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK)); 391 status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK));
420 392
@@ -424,23 +396,18 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
424 396
425 /* Read the syndrom pattern from the FPGA and correct the bitorder */ 397 /* Read the syndrom pattern from the FPGA and correct the bitorder */
426 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC); 398 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
427 for (i = 0; i < 8; i++) { 399 for (i = 0; i < 8; i++) {
428 ecc[i] = revbits[(*rs_ecc) & 0xFF]; 400 ecc[i] = revbits[(*rs_ecc) & 0xFF];
429 rs_ecc++; 401 rs_ecc++;
430 } 402 }
431 403
432 /* convert into 6 10bit syndrome fields */ 404 /* convert into 6 10bit syndrome fields */
433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | 405 par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)];
434 (((uint16_t)ecc[1] << 8) & 0x300)]; 406 par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)];
435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | 407 par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)];
436 (((uint16_t)ecc[2] << 6) & 0x3c0)]; 408 par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)];
437 par[3] = rs_decoder->index_of[(((uint16_t)ecc[2] >> 4) & 0x00f) | 409 par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)];
438 (((uint16_t)ecc[3] << 4) & 0x3f0)]; 410 par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0);
439 par[2] = rs_decoder->index_of[(((uint16_t)ecc[3] >> 6) & 0x003) |
440 (((uint16_t)ecc[4] << 2) & 0x3fc)];
441 par[1] = rs_decoder->index_of[(((uint16_t)ecc[5] >> 0) & 0x0ff) |
442 (((uint16_t)ecc[6] << 8) & 0x300)];
443 par[0] = (((uint16_t)ecc[6] >> 2) & 0x03f) | (((uint16_t)ecc[7] << 6) & 0x3c0);
444 411
445 /* Convert to computable syndrome */ 412 /* Convert to computable syndrome */
446 for (i = 0; i < 6; i++) { 413 for (i = 0; i < 6; i++) {
@@ -453,16 +420,14 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
453 syn[i] = rs_decoder->index_of[syn[i]]; 420 syn[i] = rs_decoder->index_of[syn[i]];
454 } 421 }
455 422
456 /* Let the library code do its magic.*/ 423 /* Let the library code do its magic. */
457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); 424 res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
458 if (res > 0) { 425 if (res > 0) {
459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 426 DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
460 "ECC corrected %d errors on read\n", res);
461 } 427 }
462 return res; 428 return res;
463} 429}
464 430
465
466/** 431/**
467 * rtc_from4_errstat - perform additional error status checks 432 * rtc_from4_errstat - perform additional error status checks
468 * @mtd: MTD device structure 433 * @mtd: MTD device structure
@@ -478,54 +443,66 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
478 * note: see pages 34..37 of data sheet for details. 443 * note: see pages 34..37 of data sheet for details.
479 * 444 *
480 */ 445 */
481static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page) 446static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
447 int state, int status, int page)
482{ 448{
483 int er_stat=0; 449 int er_stat = 0;
484 int rtn, retlen; 450 int rtn, retlen;
485 size_t len; 451 size_t len;
486 uint8_t *buf; 452 uint8_t *buf;
487 int i; 453 int i;
488 454
489 this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1); 455 this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
490 456
491 if (state == FL_ERASING) { 457 if (state == FL_ERASING) {
492 for (i=0; i<4; i++) { 458
493 if (status & 1<<(i+1)) { 459 for (i = 0; i < 4; i++) {
494 this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1); 460 if (!(status & 1 << (i + 1)))
495 rtn = this->read_byte(mtd); 461 continue;
496 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1); 462 this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1),
497 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) { 463 -1, -1);
498 er_stat |= 1<<(i+1); /* err_ecc_not_avail */ 464 rtn = this->read_byte(mtd);
499 } 465 this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
500 } 466
467 /* err_ecc_not_avail */
468 if (!(rtn & ERR_STAT_ECC_AVAILABLE))
469 er_stat |= 1 << (i + 1);
501 } 470 }
471
502 } else if (state == FL_WRITING) { 472 } else if (state == FL_WRITING) {
473
474 unsigned long corrected = mtd->ecc_stats.corrected;
475
503 /* single bank write logic */ 476 /* single bank write logic */
504 this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1); 477 this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
505 rtn = this->read_byte(mtd); 478 rtn = this->read_byte(mtd);
506 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1); 479 this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
480
507 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) { 481 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
508 er_stat |= 1<<1; /* err_ecc_not_avail */ 482 /* err_ecc_not_avail */
509 } else { 483 er_stat |= 1 << 1;
510 len = mtd->oobblock; 484 goto out;
511 buf = kmalloc (len, GFP_KERNEL); 485 }
512 if (!buf) { 486
513 printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n"); 487 len = mtd->writesize;
514 er_stat = 1; /* if we can't check, assume failed */ 488 buf = kmalloc(len, GFP_KERNEL);
515 } else { 489 if (!buf) {
516 /* recovery read */ 490 printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
517 /* page read */ 491 er_stat = 1;
518 rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1); 492 goto out;
519 if (rtn) { /* if read failed or > 1-bit error corrected */
520 er_stat |= 1<<1; /* ECC read failed */
521 }
522 kfree(buf);
523 }
524 } 493 }
494
495 /* recovery read */
496 rtn = nand_do_read(mtd, page, len, &retlen, buf);
497
498 /* if read failed or > 1-bit error corrected */
499 if (rtn || (mtd->ecc_stats.corrected - corrected) > 1) {
500 er_stat |= 1 << 1;
501 kfree(buf);
525 } 502 }
526 503
527 rtn = status; 504 rtn = status;
528 if (er_stat == 0) { /* if ECC is available */ 505 if (er_stat == 0) { /* if ECC is available */
529 rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */ 506 rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */
530 } 507 }
531 508
@@ -533,33 +510,32 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
533} 510}
534#endif 511#endif
535 512
536
537/* 513/*
538 * Main initialization routine 514 * Main initialization routine
539 */ 515 */
540int __init rtc_from4_init (void) 516static int __init rtc_from4_init(void)
541{ 517{
542 struct nand_chip *this; 518 struct nand_chip *this;
543 unsigned short bcr1, bcr2, wcr2; 519 unsigned short bcr1, bcr2, wcr2;
544 int i; 520 int i;
545 521
546 /* Allocate memory for MTD device structure and private data */ 522 /* Allocate memory for MTD device structure and private data */
547 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), 523 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
548 GFP_KERNEL);
549 if (!rtc_from4_mtd) { 524 if (!rtc_from4_mtd) {
550 printk ("Unable to allocate Renesas NAND MTD device structure.\n"); 525 printk("Unable to allocate Renesas NAND MTD device structure.\n");
551 return -ENOMEM; 526 return -ENOMEM;
552 } 527 }
553 528
554 /* Get pointer to private data */ 529 /* Get pointer to private data */
555 this = (struct nand_chip *) (&rtc_from4_mtd[1]); 530 this = (struct nand_chip *)(&rtc_from4_mtd[1]);
556 531
557 /* Initialize structures */ 532 /* Initialize structures */
558 memset((char *) rtc_from4_mtd, 0, sizeof(struct mtd_info)); 533 memset(rtc_from4_mtd, 0, sizeof(struct mtd_info));
559 memset((char *) this, 0, sizeof(struct nand_chip)); 534 memset(this, 0, sizeof(struct nand_chip));
560 535
561 /* Link the private data with the MTD structure */ 536 /* Link the private data with the MTD structure */
562 rtc_from4_mtd->priv = this; 537 rtc_from4_mtd->priv = this;
538 rtc_from4_mtd->owner = THIS_MODULE;
563 539
564 /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */ 540 /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */
565 bcr1 = *SH77X9_BCR1 & ~0x0002; 541 bcr1 = *SH77X9_BCR1 & ~0x0002;
@@ -580,9 +556,9 @@ int __init rtc_from4_init (void)
580 this->IO_ADDR_R = rtc_from4_fio_base; 556 this->IO_ADDR_R = rtc_from4_fio_base;
581 this->IO_ADDR_W = rtc_from4_fio_base; 557 this->IO_ADDR_W = rtc_from4_fio_base;
582 /* Set address of hardware control function */ 558 /* Set address of hardware control function */
583 this->hwcontrol = rtc_from4_hwcontrol; 559 this->cmd_ctrl = rtc_from4_hwcontrol;
584 /* Set address of chip select function */ 560 /* Set address of chip select function */
585 this->select_chip = rtc_from4_nand_select_chip; 561 this->select_chip = rtc_from4_nand_select_chip;
586 /* command delay time (in us) */ 562 /* command delay time (in us) */
587 this->chip_delay = 100; 563 this->chip_delay = 100;
588 /* return the status of the Ready/Busy line */ 564 /* return the status of the Ready/Busy line */
@@ -591,19 +567,20 @@ int __init rtc_from4_init (void)
591#ifdef RTC_FROM4_HWECC 567#ifdef RTC_FROM4_HWECC
592 printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n"); 568 printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n");
593 569
594 this->eccmode = NAND_ECC_HW8_512; 570 this->ecc.mode = NAND_ECC_HW_SYNDROME;
595 this->options |= NAND_HWECC_SYNDROME; 571 this->ecc.size = 512;
572 this->ecc.bytes = 8;
596 /* return the status of extra status and ECC checks */ 573 /* return the status of extra status and ECC checks */
597 this->errstat = rtc_from4_errstat; 574 this->errstat = rtc_from4_errstat;
598 /* set the nand_oobinfo to support FPGA H/W error detection */ 575 /* set the nand_oobinfo to support FPGA H/W error detection */
599 this->autooob = &rtc_from4_nand_oobinfo; 576 this->ecc.layout = &rtc_from4_nand_oobinfo;
600 this->enable_hwecc = rtc_from4_enable_hwecc; 577 this->ecc.hwctl = rtc_from4_enable_hwecc;
601 this->calculate_ecc = rtc_from4_calculate_ecc; 578 this->ecc.calculate = rtc_from4_calculate_ecc;
602 this->correct_data = rtc_from4_correct_data; 579 this->ecc.correct = rtc_from4_correct_data;
603#else 580#else
604 printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); 581 printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n");
605 582
606 this->eccmode = NAND_ECC_SOFT; 583 this->ecc.mode = NAND_ECC_SOFT;
607#endif 584#endif
608 585
609 /* set the bad block tables to support debugging */ 586 /* set the bad block tables to support debugging */
@@ -617,7 +594,7 @@ int __init rtc_from4_init (void)
617 } 594 }
618 595
619 /* Perform 'device recovery' for each chip in case there was a power loss. */ 596 /* Perform 'device recovery' for each chip in case there was a power loss. */
620 for (i=0; i < this->numchips; i++) { 597 for (i = 0; i < this->numchips; i++) {
621 deplete(rtc_from4_mtd, i); 598 deplete(rtc_from4_mtd, i);
622 } 599 }
623 600
@@ -643,7 +620,7 @@ int __init rtc_from4_init (void)
643 */ 620 */
644 rs_decoder = init_rs(10, 0x409, 0, 1, 6); 621 rs_decoder = init_rs(10, 0x409, 0, 1, 6);
645 if (!rs_decoder) { 622 if (!rs_decoder) {
646 printk (KERN_ERR "Could not create a RS decoder\n"); 623 printk(KERN_ERR "Could not create a RS decoder\n");
647 nand_release(rtc_from4_mtd); 624 nand_release(rtc_from4_mtd);
648 kfree(rtc_from4_mtd); 625 kfree(rtc_from4_mtd);
649 return -ENOMEM; 626 return -ENOMEM;
@@ -652,20 +629,19 @@ int __init rtc_from4_init (void)
652 /* Return happy */ 629 /* Return happy */
653 return 0; 630 return 0;
654} 631}
655module_init(rtc_from4_init);
656 632
633module_init(rtc_from4_init);
657 634
658/* 635/*
659 * Clean up routine 636 * Clean up routine
660 */ 637 */
661#ifdef MODULE 638static void __exit rtc_from4_cleanup(void)
662static void __exit rtc_from4_cleanup (void)
663{ 639{
664 /* Release resource, unregister partitions */ 640 /* Release resource, unregister partitions */
665 nand_release(rtc_from4_mtd); 641 nand_release(rtc_from4_mtd);
666 642
667 /* Free the MTD device structure */ 643 /* Free the MTD device structure */
668 kfree (rtc_from4_mtd); 644 kfree(rtc_from4_mtd);
669 645
670#ifdef RTC_FROM4_HWECC 646#ifdef RTC_FROM4_HWECC
671 /* Free the reed solomon resources */ 647 /* Free the reed solomon resources */
@@ -674,10 +650,9 @@ static void __exit rtc_from4_cleanup (void)
674 } 650 }
675#endif 651#endif
676} 652}
653
677module_exit(rtc_from4_cleanup); 654module_exit(rtc_from4_cleanup);
678#endif
679 655
680MODULE_LICENSE("GPL"); 656MODULE_LICENSE("GPL");
681MODULE_AUTHOR("d.marlin <dmarlin@redhat.com"); 657MODULE_AUTHOR("d.marlin <dmarlin@redhat.com");
682MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4"); 658MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4");
683
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 5b55599739f3..2c262fe03d8a 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -18,8 +18,9 @@
18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug 18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied 19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
20 * 20-Oct-2005 BJD Fix timing calculation bug 20 * 20-Oct-2005 BJD Fix timing calculation bug
21 * 14-Jan-2006 BJD Allow clock to be stopped when idle
21 * 22 *
22 * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $ 23 * $Id: s3c2410.c,v 1.23 2006/04/01 18:06:29 bjd Exp $
23 * 24 *
24 * This program is free software; you can redistribute it and/or modify 25 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by 26 * it under the terms of the GNU General Public License as published by
@@ -36,9 +37,6 @@
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37*/ 38*/
38 39
39#include <config/mtd/nand/s3c2410/hwecc.h>
40#include <config/mtd/nand/s3c2410/debug.h>
41
42#ifdef CONFIG_MTD_NAND_S3C2410_DEBUG 40#ifdef CONFIG_MTD_NAND_S3C2410_DEBUG
43#define DEBUG 41#define DEBUG
44#endif 42#endif
@@ -73,14 +71,20 @@ static int hardware_ecc = 1;
73static int hardware_ecc = 0; 71static int hardware_ecc = 0;
74#endif 72#endif
75 73
74#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
75static int clock_stop = 1;
76#else
77static const int clock_stop = 0;
78#endif
79
80
76/* new oob placement block for use with hardware ecc generation 81/* new oob placement block for use with hardware ecc generation
77 */ 82 */
78 83
79static struct nand_oobinfo nand_hw_eccoob = { 84static struct nand_ecclayout nand_hw_eccoob = {
80 .useecc = MTD_NANDECC_AUTOPLACE, 85 .eccbytes = 3,
81 .eccbytes = 3, 86 .eccpos = {0, 1, 2},
82 .eccpos = {0, 1, 2 }, 87 .oobfree = {{8, 8}}
83 .oobfree = { {8, 8} }
84}; 88};
85 89
86/* controller and mtd information */ 90/* controller and mtd information */
@@ -135,6 +139,11 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev)
135 return dev->dev.platform_data; 139 return dev->dev.platform_data;
136} 140}
137 141
142static inline int allow_clk_stop(struct s3c2410_nand_info *info)
143{
144 return clock_stop;
145}
146
138/* timing calculations */ 147/* timing calculations */
139 148
140#define NS_IN_KHZ 1000000 149#define NS_IN_KHZ 1000000
@@ -149,8 +158,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
149 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 158 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
150 159
151 if (result > max) { 160 if (result > max) {
152 printk("%d ns is too big for current clock rate %ld\n", 161 printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
153 wanted, clk);
154 return -1; 162 return -1;
155 } 163 }
156 164
@@ -164,8 +172,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
164 172
165/* controller setup */ 173/* controller setup */
166 174
167static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, 175static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev)
168 struct platform_device *pdev)
169{ 176{
170 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 177 struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
171 unsigned long clkrate = clk_get_rate(info->clk); 178 unsigned long clkrate = clk_get_rate(info->clk);
@@ -177,7 +184,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
177 clkrate /= 1000; /* turn clock into kHz for ease of use */ 184 clkrate /= 1000; /* turn clock into kHz for ease of use */
178 185
179 if (plat != NULL) { 186 if (plat != NULL) {
180 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 187 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
181 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 188 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
182 twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8); 189 twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
183 } else { 190 } else {
@@ -193,19 +200,22 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
193 } 200 }
194 201
195 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", 202 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
196 tacls, to_ns(tacls, clkrate), 203 tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
197 twrph0, to_ns(twrph0, clkrate),
198 twrph1, to_ns(twrph1, clkrate));
199 204
200 if (!info->is_s3c2440) { 205 if (!info->is_s3c2440) {
201 cfg = S3C2410_NFCONF_EN; 206 cfg = S3C2410_NFCONF_EN;
202 cfg |= S3C2410_NFCONF_TACLS(tacls-1); 207 cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
203 cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1); 208 cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
204 cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1); 209 cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
205 } else { 210 } else {
206 cfg = S3C2440_NFCONF_TACLS(tacls-1); 211 cfg = S3C2440_NFCONF_TACLS(tacls - 1);
207 cfg |= S3C2440_NFCONF_TWRPH0(twrph0-1); 212 cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
208 cfg |= S3C2440_NFCONF_TWRPH1(twrph1-1); 213 cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
214
215 /* enable the controller and de-assert nFCE */
216
217 writel(S3C2440_NFCONT_ENABLE | S3C2440_NFCONT_ENABLE,
218 info->regs + S3C2440_NFCONT);
209 } 219 }
210 220
211 pr_debug(PFX "NF_CONF is 0x%lx\n", cfg); 221 pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
@@ -229,7 +239,10 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
229 info = nmtd->info; 239 info = nmtd->info;
230 240
231 bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE; 241 bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
232 reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF); 242 reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF);
243
244 if (chip != -1 && allow_clk_stop(info))
245 clk_enable(info->clk);
233 246
234 cur = readl(reg); 247 cur = readl(reg);
235 248
@@ -243,77 +256,51 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
243 256
244 if (info->platform != NULL) { 257 if (info->platform != NULL) {
245 if (info->platform->select_chip != NULL) 258 if (info->platform->select_chip != NULL)
246 (info->platform->select_chip)(nmtd->set, chip); 259 (info->platform->select_chip) (nmtd->set, chip);
247 } 260 }
248 261
249 cur &= ~bit; 262 cur &= ~bit;
250 } 263 }
251 264
252 writel(cur, reg); 265 writel(cur, reg);
266
267 if (chip == -1 && allow_clk_stop(info))
268 clk_disable(info->clk);
253} 269}
254 270
255/* command and control functions 271/* s3c2410_nand_hwcontrol
256 *
257 * Note, these all use tglx's method of changing the IO_ADDR_W field
258 * to make the code simpler, and use the nand layer's code to issue the
259 * command and address sequences via the proper IO ports.
260 * 272 *
273 * Issue command and address cycles to the chip
261*/ 274*/
262 275
263static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) 276static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd,
277 unsigned int ctrl)
264{ 278{
265 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 279 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
266 struct nand_chip *chip = mtd->priv; 280
267 281 if (cmd == NAND_CMD_NONE)
268 switch (cmd) { 282 return;
269 case NAND_CTL_SETNCE: 283
270 case NAND_CTL_CLRNCE: 284 if (ctrl & NAND_CLE)
271 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); 285 writeb(cmd, info->regs + S3C2410_NFCMD);
272 break; 286 else
273 287 writeb(cmd, info->regs + S3C2410_NFADDR);
274 case NAND_CTL_SETCLE:
275 chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
276 break;
277
278 case NAND_CTL_SETALE:
279 chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
280 break;
281
282 /* NAND_CTL_CLRCLE: */
283 /* NAND_CTL_CLRALE: */
284 default:
285 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
286 break;
287 }
288} 288}
289 289
290/* command and control functions */ 290/* command and control functions */
291 291
292static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd) 292static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd,
293 unsigned int ctrl)
293{ 294{
294 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 295 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
295 struct nand_chip *chip = mtd->priv; 296
296 297 if (cmd == NAND_CMD_NONE)
297 switch (cmd) { 298 return;
298 case NAND_CTL_SETNCE: 299
299 case NAND_CTL_CLRNCE: 300 if (ctrl & NAND_CLE)
300 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); 301 writeb(cmd, info->regs + S3C2440_NFCMD);
301 break; 302 else
302 303 writeb(cmd, info->regs + S3C2440_NFADDR);
303 case NAND_CTL_SETCLE:
304 chip->IO_ADDR_W = info->regs + S3C2440_NFCMD;
305 break;
306
307 case NAND_CTL_SETALE:
308 chip->IO_ADDR_W = info->regs + S3C2440_NFADDR;
309 break;
310
311 /* NAND_CTL_CLRCLE: */
312 /* NAND_CTL_CLRALE: */
313 default:
314 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
315 break;
316 }
317} 304}
318 305
319/* s3c2410_nand_devready() 306/* s3c2410_nand_devready()
@@ -330,22 +317,16 @@ static int s3c2410_nand_devready(struct mtd_info *mtd)
330 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 317 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
331} 318}
332 319
333
334/* ECC handling functions */ 320/* ECC handling functions */
335 321
336static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, 322static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
337 u_char *read_ecc, u_char *calc_ecc)
338{ 323{
339 pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", 324 pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc);
340 mtd, dat, read_ecc, calc_ecc);
341 325
342 pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n", 326 pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n",
343 read_ecc[0], read_ecc[1], read_ecc[2], 327 read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]);
344 calc_ecc[0], calc_ecc[1], calc_ecc[2]);
345 328
346 if (read_ecc[0] == calc_ecc[0] && 329 if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2])
347 read_ecc[1] == calc_ecc[1] &&
348 read_ecc[2] == calc_ecc[2])
349 return 0; 330 return 0;
350 331
351 /* we curently have no method for correcting the error */ 332 /* we curently have no method for correcting the error */
@@ -378,8 +359,7 @@ static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
378 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT); 359 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
379} 360}
380 361
381static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, 362static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
382 const u_char *dat, u_char *ecc_code)
383{ 363{
384 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 364 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
385 365
@@ -387,15 +367,12 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
387 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1); 367 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
388 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2); 368 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
389 369
390 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", 370 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
391 ecc_code[0], ecc_code[1], ecc_code[2]);
392 371
393 return 0; 372 return 0;
394} 373}
395 374
396 375static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
397static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
398 const u_char *dat, u_char *ecc_code)
399{ 376{
400 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 377 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
401 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0); 378 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
@@ -404,13 +381,11 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
404 ecc_code[1] = ecc >> 8; 381 ecc_code[1] = ecc >> 8;
405 ecc_code[2] = ecc >> 16; 382 ecc_code[2] = ecc >> 16;
406 383
407 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", 384 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
408 ecc_code[0], ecc_code[1], ecc_code[2]);
409 385
410 return 0; 386 return 0;
411} 387}
412 388
413
414/* over-ride the standard functions for a little more speed. We can 389/* over-ride the standard functions for a little more speed. We can
415 * use read/write block to move the data buffers to/from the controller 390 * use read/write block to move the data buffers to/from the controller
416*/ 391*/
@@ -421,8 +396,7 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
421 readsb(this->IO_ADDR_R, buf, len); 396 readsb(this->IO_ADDR_R, buf, len);
422} 397}
423 398
424static void s3c2410_nand_write_buf(struct mtd_info *mtd, 399static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
425 const u_char *buf, int len)
426{ 400{
427 struct nand_chip *this = mtd->priv; 401 struct nand_chip *this = mtd->priv;
428 writesb(this->IO_ADDR_W, buf, len); 402 writesb(this->IO_ADDR_W, buf, len);
@@ -459,7 +433,8 @@ static int s3c2410_nand_remove(struct platform_device *pdev)
459 /* free the common resources */ 433 /* free the common resources */
460 434
461 if (info->clk != NULL && !IS_ERR(info->clk)) { 435 if (info->clk != NULL && !IS_ERR(info->clk)) {
462 clk_disable(info->clk); 436 if (!allow_clk_stop(info))
437 clk_disable(info->clk);
463 clk_put(info->clk); 438 clk_put(info->clk);
464 } 439 }
465 440
@@ -488,9 +463,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
488 return add_mtd_device(&mtd->mtd); 463 return add_mtd_device(&mtd->mtd);
489 464
490 if (set->nr_partitions > 0 && set->partitions != NULL) { 465 if (set->nr_partitions > 0 && set->partitions != NULL) {
491 return add_mtd_partitions(&mtd->mtd, 466 return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
492 set->partitions,
493 set->nr_partitions);
494 } 467 }
495 468
496 return add_mtd_device(&mtd->mtd); 469 return add_mtd_device(&mtd->mtd);
@@ -517,7 +490,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
517 490
518 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; 491 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA;
519 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; 492 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
520 chip->hwcontrol = s3c2410_nand_hwcontrol; 493 chip->cmd_ctrl = s3c2410_nand_hwcontrol;
521 chip->dev_ready = s3c2410_nand_devready; 494 chip->dev_ready = s3c2410_nand_devready;
522 chip->write_buf = s3c2410_nand_write_buf; 495 chip->write_buf = s3c2410_nand_write_buf;
523 chip->read_buf = s3c2410_nand_read_buf; 496 chip->read_buf = s3c2410_nand_read_buf;
@@ -530,26 +503,29 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
530 if (info->is_s3c2440) { 503 if (info->is_s3c2440) {
531 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; 504 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA;
532 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; 505 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
533 chip->hwcontrol = s3c2440_nand_hwcontrol; 506 chip->cmd_ctrl = s3c2440_nand_hwcontrol;
534 } 507 }
535 508
536 nmtd->info = info; 509 nmtd->info = info;
537 nmtd->mtd.priv = chip; 510 nmtd->mtd.priv = chip;
511 nmtd->mtd.owner = THIS_MODULE;
538 nmtd->set = set; 512 nmtd->set = set;
539 513
540 if (hardware_ecc) { 514 if (hardware_ecc) {
541 chip->correct_data = s3c2410_nand_correct_data; 515 chip->ecc.correct = s3c2410_nand_correct_data;
542 chip->enable_hwecc = s3c2410_nand_enable_hwecc; 516 chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
543 chip->calculate_ecc = s3c2410_nand_calculate_ecc; 517 chip->ecc.calculate = s3c2410_nand_calculate_ecc;
544 chip->eccmode = NAND_ECC_HW3_512; 518 chip->ecc.mode = NAND_ECC_HW;
545 chip->autooob = &nand_hw_eccoob; 519 chip->ecc.size = 512;
520 chip->ecc.bytes = 3;
521 chip->ecc.layout = &nand_hw_eccoob;
546 522
547 if (info->is_s3c2440) { 523 if (info->is_s3c2440) {
548 chip->enable_hwecc = s3c2440_nand_enable_hwecc; 524 chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
549 chip->calculate_ecc = s3c2440_nand_calculate_ecc; 525 chip->ecc.calculate = s3c2440_nand_calculate_ecc;
550 } 526 }
551 } else { 527 } else {
552 chip->eccmode = NAND_ECC_SOFT; 528 chip->ecc.mode = NAND_ECC_SOFT;
553 } 529 }
554} 530}
555 531
@@ -654,13 +630,11 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
654 nmtd = info->mtds; 630 nmtd = info->mtds;
655 631
656 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 632 for (setno = 0; setno < nr_sets; setno++, nmtd++) {
657 pr_debug("initialising set %d (%p, info %p)\n", 633 pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info);
658 setno, nmtd, info);
659 634
660 s3c2410_nand_init_chip(info, nmtd, sets); 635 s3c2410_nand_init_chip(info, nmtd, sets);
661 636
662 nmtd->scan_res = nand_scan(&nmtd->mtd, 637 nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);
663 (sets) ? sets->nr_chips : 1);
664 638
665 if (nmtd->scan_res == 0) { 639 if (nmtd->scan_res == 0) {
666 s3c2410_nand_add_partition(info, nmtd, sets); 640 s3c2410_nand_add_partition(info, nmtd, sets);
@@ -670,6 +644,11 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
670 sets++; 644 sets++;
671 } 645 }
672 646
647 if (allow_clk_stop(info)) {
648 dev_info(&pdev->dev, "clock idle support enabled\n");
649 clk_disable(info->clk);
650 }
651
673 pr_debug("initialised ok\n"); 652 pr_debug("initialised ok\n");
674 return 0; 653 return 0;
675 654
@@ -681,6 +660,41 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
681 return err; 660 return err;
682} 661}
683 662
663/* PM Support */
664#ifdef CONFIG_PM
665
666static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm)
667{
668 struct s3c2410_nand_info *info = platform_get_drvdata(dev);
669
670 if (info) {
671 if (!allow_clk_stop(info))
672 clk_disable(info->clk);
673 }
674
675 return 0;
676}
677
678static int s3c24xx_nand_resume(struct platform_device *dev)
679{
680 struct s3c2410_nand_info *info = platform_get_drvdata(dev);
681
682 if (info) {
683 clk_enable(info->clk);
684 s3c2410_nand_inithw(info, dev);
685
686 if (allow_clk_stop(info))
687 clk_disable(info->clk);
688 }
689
690 return 0;
691}
692
693#else
694#define s3c24xx_nand_suspend NULL
695#define s3c24xx_nand_resume NULL
696#endif
697
684/* driver device registration */ 698/* driver device registration */
685 699
686static int s3c2410_nand_probe(struct platform_device *dev) 700static int s3c2410_nand_probe(struct platform_device *dev)
@@ -696,6 +710,8 @@ static int s3c2440_nand_probe(struct platform_device *dev)
696static struct platform_driver s3c2410_nand_driver = { 710static struct platform_driver s3c2410_nand_driver = {
697 .probe = s3c2410_nand_probe, 711 .probe = s3c2410_nand_probe,
698 .remove = s3c2410_nand_remove, 712 .remove = s3c2410_nand_remove,
713 .suspend = s3c24xx_nand_suspend,
714 .resume = s3c24xx_nand_resume,
699 .driver = { 715 .driver = {
700 .name = "s3c2410-nand", 716 .name = "s3c2410-nand",
701 .owner = THIS_MODULE, 717 .owner = THIS_MODULE,
@@ -705,6 +721,8 @@ static struct platform_driver s3c2410_nand_driver = {
705static struct platform_driver s3c2440_nand_driver = { 721static struct platform_driver s3c2440_nand_driver = {
706 .probe = s3c2440_nand_probe, 722 .probe = s3c2440_nand_probe,
707 .remove = s3c2410_nand_remove, 723 .remove = s3c2410_nand_remove,
724 .suspend = s3c24xx_nand_suspend,
725 .resume = s3c24xx_nand_resume,
708 .driver = { 726 .driver = {
709 .name = "s3c2440-nand", 727 .name = "s3c2440-nand",
710 .owner = THIS_MODULE, 728 .owner = THIS_MODULE,
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 1924a4f137c7..21743658d150 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -46,7 +46,6 @@ static int sharpsl_phys_base = 0x0C000000;
46#define FLCLE (1 << 1) 46#define FLCLE (1 << 1)
47#define FLCE0 (1 << 0) 47#define FLCE0 (1 << 0)
48 48
49
50/* 49/*
51 * MTD structure for SharpSL 50 * MTD structure for SharpSL
52 */ 51 */
@@ -60,50 +59,44 @@ static struct mtd_info *sharpsl_mtd = NULL;
60static int nr_partitions; 59static int nr_partitions;
61static struct mtd_partition sharpsl_nand_default_partition_info[] = { 60static struct mtd_partition sharpsl_nand_default_partition_info[] = {
62 { 61 {
63 .name = "System Area", 62 .name = "System Area",
64 .offset = 0, 63 .offset = 0,
65 .size = 7 * 1024 * 1024, 64 .size = 7 * 1024 * 1024,
66 }, 65 },
67 { 66 {
68 .name = "Root Filesystem", 67 .name = "Root Filesystem",
69 .offset = 7 * 1024 * 1024, 68 .offset = 7 * 1024 * 1024,
70 .size = 30 * 1024 * 1024, 69 .size = 30 * 1024 * 1024,
71 }, 70 },
72 { 71 {
73 .name = "Home Filesystem", 72 .name = "Home Filesystem",
74 .offset = MTDPART_OFS_APPEND , 73 .offset = MTDPART_OFS_APPEND,
75 .size = MTDPART_SIZ_FULL , 74 .size = MTDPART_SIZ_FULL,
76 }, 75 },
77}; 76};
78 77
79/* 78/*
80 * hardware specific access to control-lines 79 * hardware specific access to control-lines
80 * ctrl:
81 * NAND_CNE: bit 0 -> bit 0 & 4
82 * NAND_CLE: bit 1 -> bit 1
83 * NAND_ALE: bit 2 -> bit 2
84 *
81 */ 85 */
82static void 86static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd,
83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) 87 unsigned int ctrl)
84{ 88{
85 switch (cmd) { 89 struct nand_chip *chip = mtd->priv;
86 case NAND_CTL_SETCLE: 90
87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 91 if (ctrl & NAND_CTRL_CHANGE) {
88 break; 92 unsigned char bits = ctrl & 0x07;
89 case NAND_CTL_CLRCLE: 93
90 writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL); 94 bits |= (ctrl & 0x01) << 4;
91 break; 95 writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL);
92
93 case NAND_CTL_SETALE:
94 writeb(readb(FLASHCTL) | FLALE, FLASHCTL);
95 break;
96 case NAND_CTL_CLRALE:
97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
98 break;
99
100 case NAND_CTL_SETNCE:
101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
102 break;
103 case NAND_CTL_CLRNCE:
104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
105 break;
106 } 96 }
97
98 if (cmd != NAND_CMD_NONE)
99 writeb(cmd, chip->IO_ADDR_W);
107} 100}
108 101
109static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 102static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -122,31 +115,26 @@ static struct nand_bbt_descr sharpsl_akita_bbt = {
122 .pattern = scan_ff_pattern 115 .pattern = scan_ff_pattern
123}; 116};
124 117
125static struct nand_oobinfo akita_oobinfo = { 118static struct nand_ecclayout akita_oobinfo = {
126 .useecc = MTD_NANDECC_AUTOPLACE,
127 .eccbytes = 24, 119 .eccbytes = 24,
128 .eccpos = { 120 .eccpos = {
129 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, 121 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
130 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, 122 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
131 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37}, 123 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
132 .oobfree = { {0x08, 0x09} } 124 .oobfree = {{0x08, 0x09}}
133}; 125};
134 126
135static int 127static int sharpsl_nand_dev_ready(struct mtd_info *mtd)
136sharpsl_nand_dev_ready(struct mtd_info* mtd)
137{ 128{
138 return !((readb(FLASHCTL) & FLRYBY) == 0); 129 return !((readb(FLASHCTL) & FLRYBY) == 0);
139} 130}
140 131
141static void 132static void sharpsl_nand_enable_hwecc(struct mtd_info *mtd, int mode)
142sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
143{ 133{
144 writeb(0 ,ECCCLRR); 134 writeb(0, ECCCLRR);
145} 135}
146 136
147static int 137static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, u_char * ecc_code)
148sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
149 u_char* ecc_code)
150{ 138{
151 ecc_code[0] = ~readb(ECCLPUB); 139 ecc_code[0] = ~readb(ECCLPUB);
152 ecc_code[1] = ~readb(ECCLPLB); 140 ecc_code[1] = ~readb(ECCLPLB);
@@ -154,47 +142,44 @@ sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
154 return readb(ECCCNTR) != 0; 142 return readb(ECCCNTR) != 0;
155} 143}
156 144
157
158#ifdef CONFIG_MTD_PARTITIONS 145#ifdef CONFIG_MTD_PARTITIONS
159const char *part_probes[] = { "cmdlinepart", NULL }; 146const char *part_probes[] = { "cmdlinepart", NULL };
160#endif 147#endif
161 148
162
163/* 149/*
164 * Main initialization routine 150 * Main initialization routine
165 */ 151 */
166int __init 152static int __init sharpsl_nand_init(void)
167sharpsl_nand_init(void)
168{ 153{
169 struct nand_chip *this; 154 struct nand_chip *this;
170 struct mtd_partition* sharpsl_partition_info; 155 struct mtd_partition *sharpsl_partition_info;
171 int err = 0; 156 int err = 0;
172 157
173 /* Allocate memory for MTD device structure and private data */ 158 /* Allocate memory for MTD device structure and private data */
174 sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), 159 sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
175 GFP_KERNEL);
176 if (!sharpsl_mtd) { 160 if (!sharpsl_mtd) {
177 printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); 161 printk("Unable to allocate SharpSL NAND MTD device structure.\n");
178 return -ENOMEM; 162 return -ENOMEM;
179 } 163 }
180 164
181 /* map physical adress */ 165 /* map physical adress */
182 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); 166 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
183 if(!sharpsl_io_base){ 167 if (!sharpsl_io_base) {
184 printk("ioremap to access Sharp SL NAND chip failed\n"); 168 printk("ioremap to access Sharp SL NAND chip failed\n");
185 kfree(sharpsl_mtd); 169 kfree(sharpsl_mtd);
186 return -EIO; 170 return -EIO;
187 } 171 }
188 172
189 /* Get pointer to private data */ 173 /* Get pointer to private data */
190 this = (struct nand_chip *) (&sharpsl_mtd[1]); 174 this = (struct nand_chip *)(&sharpsl_mtd[1]);
191 175
192 /* Initialize structures */ 176 /* Initialize structures */
193 memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info)); 177 memset(sharpsl_mtd, 0, sizeof(struct mtd_info));
194 memset((char *) this, 0, sizeof(struct nand_chip)); 178 memset(this, 0, sizeof(struct nand_chip));
195 179
196 /* Link the private data with the MTD structure */ 180 /* Link the private data with the MTD structure */
197 sharpsl_mtd->priv = this; 181 sharpsl_mtd->priv = this;
182 sharpsl_mtd->owner = THIS_MODULE;
198 183
199 /* 184 /*
200 * PXA initialize 185 * PXA initialize
@@ -205,23 +190,25 @@ sharpsl_nand_init(void)
205 this->IO_ADDR_R = FLASHIO; 190 this->IO_ADDR_R = FLASHIO;
206 this->IO_ADDR_W = FLASHIO; 191 this->IO_ADDR_W = FLASHIO;
207 /* Set address of hardware control function */ 192 /* Set address of hardware control function */
208 this->hwcontrol = sharpsl_nand_hwcontrol; 193 this->cmd_ctrl = sharpsl_nand_hwcontrol;
209 this->dev_ready = sharpsl_nand_dev_ready; 194 this->dev_ready = sharpsl_nand_dev_ready;
210 /* 15 us command delay time */ 195 /* 15 us command delay time */
211 this->chip_delay = 15; 196 this->chip_delay = 15;
212 /* set eccmode using hardware ECC */ 197 /* set eccmode using hardware ECC */
213 this->eccmode = NAND_ECC_HW3_256; 198 this->ecc.mode = NAND_ECC_HW;
199 this->ecc.size = 256;
200 this->ecc.bytes = 3;
214 this->badblock_pattern = &sharpsl_bbt; 201 this->badblock_pattern = &sharpsl_bbt;
215 if (machine_is_akita() || machine_is_borzoi()) { 202 if (machine_is_akita() || machine_is_borzoi()) {
216 this->badblock_pattern = &sharpsl_akita_bbt; 203 this->badblock_pattern = &sharpsl_akita_bbt;
217 this->autooob = &akita_oobinfo; 204 this->ecc.layout = &akita_oobinfo;
218 } 205 }
219 this->enable_hwecc = sharpsl_nand_enable_hwecc; 206 this->ecc.hwctl = sharpsl_nand_enable_hwecc;
220 this->calculate_ecc = sharpsl_nand_calculate_ecc; 207 this->ecc.calculate = sharpsl_nand_calculate_ecc;
221 this->correct_data = nand_correct_data; 208 this->ecc.correct = nand_correct_data;
222 209
223 /* Scan to find existence of the device */ 210 /* Scan to find existence of the device */
224 err=nand_scan(sharpsl_mtd,1); 211 err = nand_scan(sharpsl_mtd, 1);
225 if (err) { 212 if (err) {
226 iounmap(sharpsl_io_base); 213 iounmap(sharpsl_io_base);
227 kfree(sharpsl_mtd); 214 kfree(sharpsl_mtd);
@@ -230,24 +217,23 @@ sharpsl_nand_init(void)
230 217
231 /* Register the partitions */ 218 /* Register the partitions */
232 sharpsl_mtd->name = "sharpsl-nand"; 219 sharpsl_mtd->name = "sharpsl-nand";
233 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, 220 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, &sharpsl_partition_info, 0);
234 &sharpsl_partition_info, 0);
235 221
236 if (nr_partitions <= 0) { 222 if (nr_partitions <= 0) {
237 nr_partitions = DEFAULT_NUM_PARTITIONS; 223 nr_partitions = DEFAULT_NUM_PARTITIONS;
238 sharpsl_partition_info = sharpsl_nand_default_partition_info; 224 sharpsl_partition_info = sharpsl_nand_default_partition_info;
239 if (machine_is_poodle()) { 225 if (machine_is_poodle()) {
240 sharpsl_partition_info[1].size=30 * 1024 * 1024; 226 sharpsl_partition_info[1].size = 22 * 1024 * 1024;
241 } else if (machine_is_corgi() || machine_is_shepherd()) { 227 } else if (machine_is_corgi() || machine_is_shepherd()) {
242 sharpsl_partition_info[1].size=25 * 1024 * 1024; 228 sharpsl_partition_info[1].size = 25 * 1024 * 1024;
243 } else if (machine_is_husky()) { 229 } else if (machine_is_husky()) {
244 sharpsl_partition_info[1].size=53 * 1024 * 1024; 230 sharpsl_partition_info[1].size = 53 * 1024 * 1024;
245 } else if (machine_is_spitz()) { 231 } else if (machine_is_spitz()) {
246 sharpsl_partition_info[1].size=5 * 1024 * 1024; 232 sharpsl_partition_info[1].size = 5 * 1024 * 1024;
247 } else if (machine_is_akita()) { 233 } else if (machine_is_akita()) {
248 sharpsl_partition_info[1].size=58 * 1024 * 1024; 234 sharpsl_partition_info[1].size = 58 * 1024 * 1024;
249 } else if (machine_is_borzoi()) { 235 } else if (machine_is_borzoi()) {
250 sharpsl_partition_info[1].size=32 * 1024 * 1024; 236 sharpsl_partition_info[1].size = 32 * 1024 * 1024;
251 } 237 }
252 } 238 }
253 239
@@ -261,15 +247,15 @@ sharpsl_nand_init(void)
261 /* Return happy */ 247 /* Return happy */
262 return 0; 248 return 0;
263} 249}
250
264module_init(sharpsl_nand_init); 251module_init(sharpsl_nand_init);
265 252
266/* 253/*
267 * Clean up routine 254 * Clean up routine
268 */ 255 */
269#ifdef MODULE
270static void __exit sharpsl_nand_cleanup(void) 256static void __exit sharpsl_nand_cleanup(void)
271{ 257{
272 struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1]; 258 struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1];
273 259
274 /* Release resources, unregister device */ 260 /* Release resources, unregister device */
275 nand_release(sharpsl_mtd); 261 nand_release(sharpsl_mtd);
@@ -279,8 +265,8 @@ static void __exit sharpsl_nand_cleanup(void)
279 /* Free the MTD device structure */ 265 /* Free the MTD device structure */
280 kfree(sharpsl_mtd); 266 kfree(sharpsl_mtd);
281} 267}
268
282module_exit(sharpsl_nand_cleanup); 269module_exit(sharpsl_nand_cleanup);
283#endif
284 270
285MODULE_LICENSE("GPL"); 271MODULE_LICENSE("GPL");
286MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 272MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index 9cf1ce718ec1..1f6d429b1583 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -39,16 +39,16 @@ static struct mtd_info *spia_mtd = NULL;
39 */ 39 */
40#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */ 40#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */
41#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */ 41#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */
42#define SPIA_PEDR 0x0080 /* 42#define SPIA_PEDR 0x0080 /*
43 * IO offset to Port E data register 43 * IO offset to Port E data register
44 * where the CLE, ALE and NCE pins 44 * where the CLE, ALE and NCE pins
45 * are wired to. 45 * are wired to.
46 */ 46 */
47#define SPIA_PEDDR 0x00c0 /* 47#define SPIA_PEDDR 0x00c0 /*
48 * IO offset to Port E data direction 48 * IO offset to Port E data direction
49 * register so we can control the IO 49 * register so we can control the IO
50 * lines. 50 * lines.
51 */ 51 */
52 52
53/* 53/*
54 * Module stuff 54 * Module stuff
@@ -69,79 +69,84 @@ module_param(spia_peddr, int, 0);
69 */ 69 */
70static const struct mtd_partition partition_info[] = { 70static const struct mtd_partition partition_info[] = {
71 { 71 {
72 .name = "SPIA flash partition 1", 72 .name = "SPIA flash partition 1",
73 .offset = 0, 73 .offset = 0,
74 .size = 2*1024*1024 74 .size = 2 * 1024 * 1024},
75 },
76 { 75 {
77 .name = "SPIA flash partition 2", 76 .name = "SPIA flash partition 2",
78 .offset = 2*1024*1024, 77 .offset = 2 * 1024 * 1024,
79 .size = 6*1024*1024 78 .size = 6 * 1024 * 1024}
80 }
81}; 79};
82#define NUM_PARTITIONS 2
83 80
81#define NUM_PARTITIONS 2
84 82
85/* 83/*
86 * hardware specific access to control-lines 84 * hardware specific access to control-lines
87*/ 85 *
88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ 86 * ctrl:
89 87 * NAND_CNE: bit 0 -> bit 2
90 switch(cmd){ 88 * NAND_CLE: bit 1 -> bit 0
89 * NAND_ALE: bit 2 -> bit 1
90 */
91static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
92{
93 struct nand_chip *chip = mtd->priv;
91 94
92 case NAND_CTL_SETCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x01; break; 95 if (ctrl & NAND_CTRL_CHANGE) {
93 case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x01; break; 96 void __iomem *addr = spia_io_base + spia_pedr;
97 unsigned char bits;
94 98
95 case NAND_CTL_SETALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x02; break; 99 bits = (ctrl & NAND_CNE) << 2;
96 case NAND_CTL_CLRALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x02; break; 100 bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1;
101 writeb((readb(addr) & ~0x7) | bits, addr);
102 }
97 103
98 case NAND_CTL_SETNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x04; break; 104 if (cmd != NAND_CMD_NONE)
99 case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x04; break; 105 writeb(cmd, chip->IO_ADDR_W);
100 }
101} 106}
102 107
103/* 108/*
104 * Main initialization routine 109 * Main initialization routine
105 */ 110 */
106int __init spia_init (void) 111static int __init spia_init(void)
107{ 112{
108 struct nand_chip *this; 113 struct nand_chip *this;
109 114
110 /* Allocate memory for MTD device structure and private data */ 115 /* Allocate memory for MTD device structure and private data */
111 spia_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), 116 spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
112 GFP_KERNEL);
113 if (!spia_mtd) { 117 if (!spia_mtd) {
114 printk ("Unable to allocate SPIA NAND MTD device structure.\n"); 118 printk("Unable to allocate SPIA NAND MTD device structure.\n");
115 return -ENOMEM; 119 return -ENOMEM;
116 } 120 }
117 121
118 /* Get pointer to private data */ 122 /* Get pointer to private data */
119 this = (struct nand_chip *) (&spia_mtd[1]); 123 this = (struct nand_chip *)(&spia_mtd[1]);
120 124
121 /* Initialize structures */ 125 /* Initialize structures */
122 memset((char *) spia_mtd, 0, sizeof(struct mtd_info)); 126 memset(spia_mtd, 0, sizeof(struct mtd_info));
123 memset((char *) this, 0, sizeof(struct nand_chip)); 127 memset(this, 0, sizeof(struct nand_chip));
124 128
125 /* Link the private data with the MTD structure */ 129 /* Link the private data with the MTD structure */
126 spia_mtd->priv = this; 130 spia_mtd->priv = this;
131 spia_mtd->owner = THIS_MODULE;
127 132
128 /* 133 /*
129 * Set GPIO Port E control register so that the pins are configured 134 * Set GPIO Port E control register so that the pins are configured
130 * to be outputs for controlling the NAND flash. 135 * to be outputs for controlling the NAND flash.
131 */ 136 */
132 (*(volatile unsigned char *) (spia_io_base + spia_peddr)) = 0x07; 137 (*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07;
133 138
134 /* Set address of NAND IO lines */ 139 /* Set address of NAND IO lines */
135 this->IO_ADDR_R = (void __iomem *) spia_fio_base; 140 this->IO_ADDR_R = (void __iomem *)spia_fio_base;
136 this->IO_ADDR_W = (void __iomem *) spia_fio_base; 141 this->IO_ADDR_W = (void __iomem *)spia_fio_base;
137 /* Set address of hardware control function */ 142 /* Set address of hardware control function */
138 this->hwcontrol = spia_hwcontrol; 143 this->cmd_ctrl = spia_hwcontrol;
139 /* 15 us command delay time */ 144 /* 15 us command delay time */
140 this->chip_delay = 15; 145 this->chip_delay = 15;
141 146
142 /* Scan to find existence of the device */ 147 /* Scan to find existence of the device */
143 if (nand_scan (spia_mtd, 1)) { 148 if (nand_scan(spia_mtd, 1)) {
144 kfree (spia_mtd); 149 kfree(spia_mtd);
145 return -ENXIO; 150 return -ENXIO;
146 } 151 }
147 152
@@ -151,22 +156,22 @@ int __init spia_init (void)
151 /* Return happy */ 156 /* Return happy */
152 return 0; 157 return 0;
153} 158}
159
154module_init(spia_init); 160module_init(spia_init);
155 161
156/* 162/*
157 * Clean up routine 163 * Clean up routine
158 */ 164 */
159#ifdef MODULE 165static void __exit spia_cleanup(void)
160static void __exit spia_cleanup (void)
161{ 166{
162 /* Release resources, unregister device */ 167 /* Release resources, unregister device */
163 nand_release (spia_mtd); 168 nand_release(spia_mtd);
164 169
165 /* Free the MTD device structure */ 170 /* Free the MTD device structure */
166 kfree (spia_mtd); 171 kfree(spia_mtd);
167} 172}
173
168module_exit(spia_cleanup); 174module_exit(spia_cleanup);
169#endif
170 175
171MODULE_LICENSE("GPL"); 176MODULE_LICENSE("GPL");
172MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com"); 177MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 7609c43cb3ec..f9e2d4a0ab8c 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -32,6 +32,8 @@
32#include <asm/arch-omap1510/hardware.h> 32#include <asm/arch-omap1510/hardware.h>
33#include <asm/arch/gpio.h> 33#include <asm/arch/gpio.h>
34 34
35#define CONFIG_NAND_WORKAROUND 1
36
35/* 37/*
36 * MTD structure for TOTO board 38 * MTD structure for TOTO board
37 */ 39 */
@@ -39,25 +41,6 @@ static struct mtd_info *toto_mtd = NULL;
39 41
40static unsigned long toto_io_base = OMAP_FLASH_1_BASE; 42static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
41 43
42#define CONFIG_NAND_WORKAROUND 1
43
44#define NAND_NCE 0x4000
45#define NAND_CLE 0x1000
46#define NAND_ALE 0x0002
47#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE)
48
49#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0)
50#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE)
51#ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */
52#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
53#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
54#else
55#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0)
56#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE)
57#endif
58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
60
61/* 44/*
62 * Define partitions for flash devices 45 * Define partitions for flash devices
63 */ 46 */
@@ -91,91 +74,110 @@ static struct mtd_partition partition_info32M[] = {
91 74
92#define NUM_PARTITIONS32M 3 75#define NUM_PARTITIONS32M 3
93#define NUM_PARTITIONS64M 4 76#define NUM_PARTITIONS64M 4
77
94/* 78/*
95 * hardware specific access to control-lines 79 * hardware specific access to control-lines
96*/ 80 *
97 81 * ctrl:
98static void toto_hwcontrol(struct mtd_info *mtd, int cmd) 82 * NAND_NCE: bit 0 -> bit 14 (0x4000)
83 * NAND_CLE: bit 1 -> bit 12 (0x1000)
84 * NAND_ALE: bit 2 -> bit 1 (0x0002)
85 */
86static void toto_hwcontrol(struct mtd_info *mtd, int cmd,
87 unsigned int ctrl)
99{ 88{
89 struct nand_chip *chip = mtd->priv;
90
91 if (ctrl & NAND_CTRL_CHANGE) {
92 unsigned long bits;
100 93
101 udelay(1); /* hopefully enough time for tc make proceding write to clear */ 94 /* hopefully enough time for tc make proceding write to clear */
102 switch(cmd){ 95 udelay(1);
103 96
104 case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break; 97 bits = (~ctrl & NAND_NCE) << 14;
105 case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break; 98 bits |= (ctrl & NAND_CLE) << 12;
99 bits |= (ctrl & NAND_ALE) >> 1;
106 100
107 case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; 101#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx
108 case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; 102 gpiosetout(0x5002, bits);
109 103
110 case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; 104#ifdef CONFIG_NAND_WORKAROUND
111 case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; 105 /* "some" dev boards busted, blue wired to rts2 :( */
106 rts2setout(2, (ctrl & NAND_CLE) << 1);
107#endif
108 /* allow time to ensure gpio state to over take memory write */
109 udelay(1);
112 } 110 }
113 udelay(1); /* allow time to ensure gpio state to over take memory write */ 111
112 if (cmd != NAND_CMD_NONE)
113 writeb(cmd, chip->IO_ADDR_W);
114} 114}
115 115
116/* 116/*
117 * Main initialization routine 117 * Main initialization routine
118 */ 118 */
119int __init toto_init (void) 119static int __init toto_init(void)
120{ 120{
121 struct nand_chip *this; 121 struct nand_chip *this;
122 int err = 0; 122 int err = 0;
123 123
124 /* Allocate memory for MTD device structure and private data */ 124 /* Allocate memory for MTD device structure and private data */
125 toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), 125 toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
126 GFP_KERNEL);
127 if (!toto_mtd) { 126 if (!toto_mtd) {
128 printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n"); 127 printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
129 err = -ENOMEM; 128 err = -ENOMEM;
130 goto out; 129 goto out;
131 } 130 }
132 131
133 /* Get pointer to private data */ 132 /* Get pointer to private data */
134 this = (struct nand_chip *) (&toto_mtd[1]); 133 this = (struct nand_chip *)(&toto_mtd[1]);
135 134
136 /* Initialize structures */ 135 /* Initialize structures */
137 memset((char *) toto_mtd, 0, sizeof(struct mtd_info)); 136 memset(toto_mtd, 0, sizeof(struct mtd_info));
138 memset((char *) this, 0, sizeof(struct nand_chip)); 137 memset(this, 0, sizeof(struct nand_chip));
139 138
140 /* Link the private data with the MTD structure */ 139 /* Link the private data with the MTD structure */
141 toto_mtd->priv = this; 140 toto_mtd->priv = this;
141 toto_mtd->owner = THIS_MODULE;
142 142
143 /* Set address of NAND IO lines */ 143 /* Set address of NAND IO lines */
144 this->IO_ADDR_R = toto_io_base; 144 this->IO_ADDR_R = toto_io_base;
145 this->IO_ADDR_W = toto_io_base; 145 this->IO_ADDR_W = toto_io_base;
146 this->hwcontrol = toto_hwcontrol; 146 this->cmd_ctrl = toto_hwcontrol;
147 this->dev_ready = NULL; 147 this->dev_ready = NULL;
148 /* 25 us command delay time */ 148 /* 25 us command delay time */
149 this->chip_delay = 30; 149 this->chip_delay = 30;
150 this->eccmode = NAND_ECC_SOFT; 150 this->ecc.mode = NAND_ECC_SOFT;
151 151
152 /* Scan to find existance of the device */ 152 /* Scan to find existance of the device */
153 if (nand_scan (toto_mtd, 1)) { 153 if (nand_scan(toto_mtd, 1)) {
154 err = -ENXIO; 154 err = -ENXIO;
155 goto out_mtd; 155 goto out_mtd;
156 } 156 }
157 157
158 /* Register the partitions */ 158 /* Register the partitions */
159 switch(toto_mtd->size){ 159 switch (toto_mtd->size) {
160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; 160 case SZ_64M:
161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; 161 add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M);
162 default: { 162 break;
163 printk (KERN_WARNING "Unsupported Nand device\n"); 163 case SZ_32M:
164 add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M);
165 break;
166 default:{
167 printk(KERN_WARNING "Unsupported Nand device\n");
164 err = -ENXIO; 168 err = -ENXIO;
165 goto out_buf; 169 goto out_buf;
166 } 170 }
167 } 171 }
168 172
169 gpioreserve(NAND_MASK); /* claim our gpios */ 173 gpioreserve(NAND_MASK); /* claim our gpios */
170 archflashwp(0,0); /* open up flash for writing */ 174 archflashwp(0, 0); /* open up flash for writing */
171 175
172 goto out; 176 goto out;
173 177
174out_buf: 178 out_mtd:
175 kfree (this->data_buf); 179 kfree(toto_mtd);
176out_mtd: 180 out:
177 kfree (toto_mtd);
178out:
179 return err; 181 return err;
180} 182}
181 183
@@ -184,20 +186,21 @@ module_init(toto_init);
184/* 186/*
185 * Clean up routine 187 * Clean up routine
186 */ 188 */
187static void __exit toto_cleanup (void) 189static void __exit toto_cleanup(void)
188{ 190{
189 /* Release resources, unregister device */ 191 /* Release resources, unregister device */
190 nand_release (toto_mtd); 192 nand_release(toto_mtd);
191 193
192 /* Free the MTD device structure */ 194 /* Free the MTD device structure */
193 kfree (toto_mtd); 195 kfree(toto_mtd);
194 196
195 /* stop flash writes */ 197 /* stop flash writes */
196 archflashwp(0,1); 198 archflashwp(0, 1);
197 199
198 /* release gpios to system */ 200 /* release gpios to system */
199 gpiorelease(NAND_MASK); 201 gpiorelease(NAND_MASK);
200} 202}
203
201module_exit(toto_cleanup); 204module_exit(toto_cleanup);
202 205
203MODULE_LICENSE("GPL"); 206MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
new file mode 100644
index 000000000000..a0b4b1edcb0d
--- /dev/null
+++ b/drivers/mtd/nand/ts7250.c
@@ -0,0 +1,206 @@
1/*
2 * drivers/mtd/nand/ts7250.c
3 *
4 * Copyright (C) 2004 Technologic Systems (support@embeddedARM.com)
5 *
6 * Derived from drivers/mtd/nand/edb7312.c
7 * Copyright (C) 2004 Marius Gröger (mag@sysgo.de)
8 *
9 * Derived from drivers/mtd/nand/autcpu12.c
10 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
11 *
12 * $Id: ts7250.c,v 1.4 2004/12/30 22:02:07 joff Exp $
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 * Overview:
19 * This is a device driver for the NAND flash device found on the
20 * TS-7250 board which utilizes a Samsung 32 Mbyte part.
21 */
22
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
28#include <linux/mtd/partitions.h>
29#include <asm/io.h>
30#include <asm/arch/hardware.h>
31#include <asm/sizes.h>
32#include <asm/mach-types.h>
33
34/*
35 * MTD structure for TS7250 board
36 */
37static struct mtd_info *ts7250_mtd = NULL;
38
39#ifdef CONFIG_MTD_PARTITIONS
40static const char *part_probes[] = { "cmdlinepart", NULL };
41
42#define NUM_PARTITIONS 3
43
44/*
45 * Define static partitions for flash device
46 */
47static struct mtd_partition partition_info32[] = {
48 {
49 .name = "TS-BOOTROM",
50 .offset = 0x00000000,
51 .size = 0x00004000,
52 }, {
53 .name = "Linux",
54 .offset = 0x00004000,
55 .size = 0x01d00000,
56 }, {
57 .name = "RedBoot",
58 .offset = 0x01d04000,
59 .size = 0x002fc000,
60 },
61};
62
63/*
64 * Define static partitions for flash device
65 */
66static struct mtd_partition partition_info128[] = {
67 {
68 .name = "TS-BOOTROM",
69 .offset = 0x00000000,
70 .size = 0x00004000,
71 }, {
72 .name = "Linux",
73 .offset = 0x00004000,
74 .size = 0x07d00000,
75 }, {
76 .name = "RedBoot",
77 .offset = 0x07d04000,
78 .size = 0x002fc000,
79 },
80};
81#endif
82
83
84/*
85 * hardware specific access to control-lines
86 *
87 * ctrl:
88 * NAND_NCE: bit 0 -> bit 2
89 * NAND_CLE: bit 1 -> bit 1
90 * NAND_ALE: bit 2 -> bit 0
91 */
92static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
93{
94 struct nand_chip *chip = mtd->priv;
95
96 if (ctrl & NAND_CTRL_CHANGE) {
97 unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE;
98 unsigned char bits;
99
100 bits = (ctrl & NAND_CNE) << 2;
101 bits |= ctrl & NAND_CLE;
102 bits |= (ctrl & NAND_ALE) >> 2;
103
104 __raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr);
105 }
106
107 if (cmd != NAND_CMD_NONE)
108 writeb(cmd, chip->IO_ADDR_W);
109}
110
111/*
112 * read device ready pin
113 */
114static int ts7250_device_ready(struct mtd_info *mtd)
115{
116 return __raw_readb(TS72XX_NAND_BUSY_VIRT_BASE) & 0x20;
117}
118
119/*
120 * Main initialization routine
121 */
122static int __init ts7250_init(void)
123{
124 struct nand_chip *this;
125 const char *part_type = 0;
126 int mtd_parts_nb = 0;
127 struct mtd_partition *mtd_parts = 0;
128
129 if (!machine_is_ts72xx() || board_is_ts7200())
130 return -ENXIO;
131
132 /* Allocate memory for MTD device structure and private data */
133 ts7250_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
134 if (!ts7250_mtd) {
135 printk("Unable to allocate TS7250 NAND MTD device structure.\n");
136 return -ENOMEM;
137 }
138
139 /* Get pointer to private data */
140 this = (struct nand_chip *)(&ts7250_mtd[1]);
141
142 /* Initialize structures */
143 memset(ts7250_mtd, 0, sizeof(struct mtd_info));
144 memset(this, 0, sizeof(struct nand_chip));
145
146 /* Link the private data with the MTD structure */
147 ts7250_mtd->priv = this;
148 ts7250_mtd->owner = THIS_MODULE;
149
150 /* insert callbacks */
151 this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE;
152 this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE;
153 this->cmd_ctrl = ts7250_hwcontrol;
154 this->dev_ready = ts7250_device_ready;
155 this->chip_delay = 15;
156 this->ecc.mode = NAND_ECC_SOFT;
157
158 printk("Searching for NAND flash...\n");
159 /* Scan to find existence of the device */
160 if (nand_scan(ts7250_mtd, 1)) {
161 kfree(ts7250_mtd);
162 return -ENXIO;
163 }
164#ifdef CONFIG_MTD_PARTITIONS
165 ts7250_mtd->name = "ts7250-nand";
166 mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes, &mtd_parts, 0);
167 if (mtd_parts_nb > 0)
168 part_type = "command line";
169 else
170 mtd_parts_nb = 0;
171#endif
172 if (mtd_parts_nb == 0) {
173 mtd_parts = partition_info32;
174 if (ts7250_mtd->size >= (128 * 0x100000))
175 mtd_parts = partition_info128;
176 mtd_parts_nb = NUM_PARTITIONS;
177 part_type = "static";
178 }
179
180 /* Register the partitions */
181 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
182 add_mtd_partitions(ts7250_mtd, mtd_parts, mtd_parts_nb);
183
184 /* Return happy */
185 return 0;
186}
187
188module_init(ts7250_init);
189
190/*
191 * Clean up routine
192 */
193static void __exit ts7250_cleanup(void)
194{
195 /* Unregister the device */
196 del_mtd_device(ts7250_mtd);
197
198 /* Free the MTD device structure */
199 kfree(ts7250_mtd);
200}
201
202module_exit(ts7250_cleanup);
203
204MODULE_LICENSE("GPL");
205MODULE_AUTHOR("Jesse Off <joff@embeddedARM.com>");
206MODULE_DESCRIPTION("MTD map driver for Technologic Systems TS-7250 board");
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d7cd5fa16ba4..dc7573501d8c 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -70,8 +70,6 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
70 nftl->mbd.devnum = -1; 70 nftl->mbd.devnum = -1;
71 nftl->mbd.blksize = 512; 71 nftl->mbd.blksize = 512;
72 nftl->mbd.tr = tr; 72 nftl->mbd.tr = tr;
73 memcpy(&nftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));
74 nftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;
75 73
76 if (NFTL_mount(nftl) < 0) { 74 if (NFTL_mount(nftl) < 0) {
77 printk(KERN_WARNING "NFTL: could not mount device\n"); 75 printk(KERN_WARNING "NFTL: could not mount device\n");
@@ -136,6 +134,69 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
136 kfree(nftl); 134 kfree(nftl);
137} 135}
138 136
137/*
138 * Read oob data from flash
139 */
140int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
141 size_t *retlen, uint8_t *buf)
142{
143 struct mtd_oob_ops ops;
144 int res;
145
146 ops.mode = MTD_OOB_PLACE;
147 ops.ooboffs = offs & (mtd->writesize - 1);
148 ops.ooblen = len;
149 ops.oobbuf = buf;
150 ops.datbuf = NULL;
151 ops.len = len;
152
153 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
154 *retlen = ops.retlen;
155 return res;
156}
157
158/*
159 * Write oob data to flash
160 */
161int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
162 size_t *retlen, uint8_t *buf)
163{
164 struct mtd_oob_ops ops;
165 int res;
166
167 ops.mode = MTD_OOB_PLACE;
168 ops.ooboffs = offs & (mtd->writesize - 1);
169 ops.ooblen = len;
170 ops.oobbuf = buf;
171 ops.datbuf = NULL;
172 ops.len = len;
173
174 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
175 *retlen = ops.retlen;
176 return res;
177}
178
179/*
180 * Write data and oob to flash
181 */
182static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
183 size_t *retlen, uint8_t *buf, uint8_t *oob)
184{
185 struct mtd_oob_ops ops;
186 int res;
187
188 ops.mode = MTD_OOB_PLACE;
189 ops.ooboffs = offs;
190 ops.ooblen = mtd->oobsize;
191 ops.oobbuf = oob;
192 ops.datbuf = buf;
193 ops.len = len;
194
195 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
196 *retlen = ops.retlen;
197 return res;
198}
199
139#ifdef CONFIG_NFTL_RW 200#ifdef CONFIG_NFTL_RW
140 201
141/* Actual NFTL access routines */ 202/* Actual NFTL access routines */
@@ -185,6 +246,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
185 246
186static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ) 247static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock )
187{ 248{
249 struct mtd_info *mtd = nftl->mbd.mtd;
188 u16 BlockMap[MAX_SECTORS_PER_UNIT]; 250 u16 BlockMap[MAX_SECTORS_PER_UNIT];
189 unsigned char BlockLastState[MAX_SECTORS_PER_UNIT]; 251 unsigned char BlockLastState[MAX_SECTORS_PER_UNIT];
190 unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT]; 252 unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT];
@@ -194,7 +256,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
194 unsigned int targetEUN; 256 unsigned int targetEUN;
195 struct nftl_oob oob; 257 struct nftl_oob oob;
196 int inplace = 1; 258 int inplace = 1;
197 size_t retlen; 259 size_t retlen;
198 260
199 memset(BlockMap, 0xff, sizeof(BlockMap)); 261 memset(BlockMap, 0xff, sizeof(BlockMap));
200 memset(BlockFreeFound, 0, sizeof(BlockFreeFound)); 262 memset(BlockFreeFound, 0, sizeof(BlockFreeFound));
@@ -210,21 +272,21 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
210 /* Scan to find the Erase Unit which holds the actual data for each 272 /* Scan to find the Erase Unit which holds the actual data for each
211 512-byte block within the Chain. 273 512-byte block within the Chain.
212 */ 274 */
213 silly = MAX_LOOPS; 275 silly = MAX_LOOPS;
214 targetEUN = BLOCK_NIL; 276 targetEUN = BLOCK_NIL;
215 while (thisEUN <= nftl->lastEUN ) { 277 while (thisEUN <= nftl->lastEUN ) {
216 unsigned int status, foldmark; 278 unsigned int status, foldmark;
217 279
218 targetEUN = thisEUN; 280 targetEUN = thisEUN;
219 for (block = 0; block < nftl->EraseSize / 512; block ++) { 281 for (block = 0; block < nftl->EraseSize / 512; block ++) {
220 MTD_READOOB(nftl->mbd.mtd, 282 nftl_read_oob(mtd, (thisEUN * nftl->EraseSize) +
221 (thisEUN * nftl->EraseSize) + (block * 512), 283 (block * 512), 16 , &retlen,
222 16 , &retlen, (char *)&oob); 284 (char *)&oob);
223 if (block == 2) { 285 if (block == 2) {
224 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1; 286 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
225 if (foldmark == FOLD_MARK_IN_PROGRESS) { 287 if (foldmark == FOLD_MARK_IN_PROGRESS) {
226 DEBUG(MTD_DEBUG_LEVEL1, 288 DEBUG(MTD_DEBUG_LEVEL1,
227 "Write Inhibited on EUN %d\n", thisEUN); 289 "Write Inhibited on EUN %d\n", thisEUN);
228 inplace = 0; 290 inplace = 0;
229 } else { 291 } else {
230 /* There's no other reason not to do inplace, 292 /* There's no other reason not to do inplace,
@@ -233,7 +295,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
233 inplace = 1; 295 inplace = 1;
234 } 296 }
235 } 297 }
236 status = oob.b.Status | oob.b.Status1; 298 status = oob.b.Status | oob.b.Status1;
237 BlockLastState[block] = status; 299 BlockLastState[block] = status;
238 300
239 switch(status) { 301 switch(status) {
@@ -328,15 +390,15 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
328 return BLOCK_NIL; 390 return BLOCK_NIL;
329 } 391 }
330 } else { 392 } else {
331 /* We put a fold mark in the chain we are folding only if 393 /* We put a fold mark in the chain we are folding only if we
332 we fold in place to help the mount check code. If we do 394 fold in place to help the mount check code. If we do not fold in
333 not fold in place, it is possible to find the valid 395 place, it is possible to find the valid chain by selecting the
334 chain by selecting the longer one */ 396 longer one */
335 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); 397 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
336 oob.u.c.unused = 0xffffffff; 398 oob.u.c.unused = 0xffffffff;
337 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 399 nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
338 8, &retlen, (char *)&oob.u); 400 8, &retlen, (char *)&oob.u);
339 } 401 }
340 402
341 /* OK. We now know the location of every block in the Virtual Unit Chain, 403 /* OK. We now know the location of every block in the Virtual Unit Chain,
342 and the Erase Unit into which we are supposed to be copying. 404 and the Erase Unit into which we are supposed to be copying.
@@ -353,33 +415,33 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
353 continue; 415 continue;
354 } 416 }
355 417
356 /* copy only in non free block (free blocks can only 418 /* copy only in non free block (free blocks can only
357 happen in case of media errors or deleted blocks) */ 419 happen in case of media errors or deleted blocks) */
358 if (BlockMap[block] == BLOCK_NIL) 420 if (BlockMap[block] == BLOCK_NIL)
359 continue; 421 continue;
360 422
361 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 423 ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
362 512, &retlen, movebuf); 424 512, &retlen, movebuf);
363 if (ret < 0) { 425 if (ret < 0 && ret != -EUCLEAN) {
364 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) 426 ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block])
365 + (block * 512), 512, &retlen, 427 + (block * 512), 512, &retlen,
366 movebuf); 428 movebuf);
367 if (ret != -EIO) 429 if (ret != -EIO)
368 printk("Error went away on retry.\n"); 430 printk("Error went away on retry.\n");
369 } 431 }
370 memset(&oob, 0xff, sizeof(struct nftl_oob)); 432 memset(&oob, 0xff, sizeof(struct nftl_oob));
371 oob.b.Status = oob.b.Status1 = SECTOR_USED; 433 oob.b.Status = oob.b.Status1 = SECTOR_USED;
372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 434
373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 435 nftl_write(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) +
436 (block * 512), 512, &retlen, movebuf, (char *)&oob);
374 } 437 }
375 438
376 /* add the header so that it is now a valid chain */ 439 /* add the header so that it is now a valid chain */
377 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum 440 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
378 = cpu_to_le16(thisVUC); 441 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
379 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
380 442
381 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 443 nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8,
382 8, &retlen, (char *)&oob.u); 444 8, &retlen, (char *)&oob.u);
383 445
384 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ 446 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
385 447
@@ -396,18 +458,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
396 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { 458 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
397 unsigned int EUNtmp; 459 unsigned int EUNtmp;
398 460
399 EUNtmp = nftl->ReplUnitTable[thisEUN]; 461 EUNtmp = nftl->ReplUnitTable[thisEUN];
400 462
401 if (NFTL_formatblock(nftl, thisEUN) < 0) { 463 if (NFTL_formatblock(nftl, thisEUN) < 0) {
402 /* could not erase : mark block as reserved 464 /* could not erase : mark block as reserved
403 */ 465 */
404 nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED; 466 nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED;
405 } else { 467 } else {
406 /* correctly erased : mark it as free */ 468 /* correctly erased : mark it as free */
407 nftl->ReplUnitTable[thisEUN] = BLOCK_FREE; 469 nftl->ReplUnitTable[thisEUN] = BLOCK_FREE;
408 nftl->numfreeEUNs++; 470 nftl->numfreeEUNs++;
409 } 471 }
410 thisEUN = EUNtmp; 472 thisEUN = EUNtmp;
411 } 473 }
412 474
413 /* Make this the new start of chain for thisVUC */ 475 /* Make this the new start of chain for thisVUC */
@@ -473,6 +535,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
473{ 535{
474 u16 lastEUN; 536 u16 lastEUN;
475 u16 thisVUC = block / (nftl->EraseSize / 512); 537 u16 thisVUC = block / (nftl->EraseSize / 512);
538 struct mtd_info *mtd = nftl->mbd.mtd;
476 unsigned int writeEUN; 539 unsigned int writeEUN;
477 unsigned long blockofs = (block * 512) & (nftl->EraseSize -1); 540 unsigned long blockofs = (block * 512) & (nftl->EraseSize -1);
478 size_t retlen; 541 size_t retlen;
@@ -489,21 +552,22 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
489 */ 552 */
490 lastEUN = BLOCK_NIL; 553 lastEUN = BLOCK_NIL;
491 writeEUN = nftl->EUNtable[thisVUC]; 554 writeEUN = nftl->EUNtable[thisVUC];
492 silly = MAX_LOOPS; 555 silly = MAX_LOOPS;
493 while (writeEUN <= nftl->lastEUN) { 556 while (writeEUN <= nftl->lastEUN) {
494 struct nftl_bci bci; 557 struct nftl_bci bci;
495 size_t retlen; 558 size_t retlen;
496 unsigned int status; 559 unsigned int status;
497 560
498 lastEUN = writeEUN; 561 lastEUN = writeEUN;
499 562
500 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 563 nftl_read_oob(mtd,
501 8, &retlen, (char *)&bci); 564 (writeEUN * nftl->EraseSize) + blockofs,
565 8, &retlen, (char *)&bci);
502 566
503 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", 567 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
504 block , writeEUN, le16_to_cpu(bci.Status)); 568 block , writeEUN, le16_to_cpu(bci.Status));
505 569
506 status = bci.Status | bci.Status1; 570 status = bci.Status | bci.Status1;
507 switch(status) { 571 switch(status) {
508 case SECTOR_FREE: 572 case SECTOR_FREE:
509 return writeEUN; 573 return writeEUN;
@@ -574,10 +638,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
574 /* We've found a free block. Insert it into the chain. */ 638 /* We've found a free block. Insert it into the chain. */
575 639
576 if (lastEUN != BLOCK_NIL) { 640 if (lastEUN != BLOCK_NIL) {
577 thisVUC |= 0x8000; /* It's a replacement block */ 641 thisVUC |= 0x8000; /* It's a replacement block */
578 } else { 642 } else {
579 /* The first block in a new chain */ 643 /* The first block in a new chain */
580 nftl->EUNtable[thisVUC] = writeEUN; 644 nftl->EUNtable[thisVUC] = writeEUN;
581 } 645 }
582 646
583 /* set up the actual EUN we're writing into */ 647 /* set up the actual EUN we're writing into */
@@ -585,29 +649,29 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
585 nftl->ReplUnitTable[writeEUN] = BLOCK_NIL; 649 nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
586 650
587 /* ... and on the flash itself */ 651 /* ... and on the flash itself */
588 MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, 652 nftl_read_oob(mtd, writeEUN * nftl->EraseSize + 8, 8,
589 &retlen, (char *)&oob.u); 653 &retlen, (char *)&oob.u);
590 654
591 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); 655 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
592 656
593 MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, 657 nftl_write_oob(mtd, writeEUN * nftl->EraseSize + 8, 8,
594 &retlen, (char *)&oob.u); 658 &retlen, (char *)&oob.u);
595 659
596 /* we link the new block to the chain only after the 660 /* we link the new block to the chain only after the
597 block is ready. It avoids the case where the chain 661 block is ready. It avoids the case where the chain
598 could point to a free block */ 662 could point to a free block */
599 if (lastEUN != BLOCK_NIL) { 663 if (lastEUN != BLOCK_NIL) {
600 /* Both in our cache... */ 664 /* Both in our cache... */
601 nftl->ReplUnitTable[lastEUN] = writeEUN; 665 nftl->ReplUnitTable[lastEUN] = writeEUN;
602 /* ... and on the flash itself */ 666 /* ... and on the flash itself */
603 MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, 667 nftl_read_oob(mtd, (lastEUN * nftl->EraseSize) + 8,
604 8, &retlen, (char *)&oob.u); 668 8, &retlen, (char *)&oob.u);
605 669
606 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum 670 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
607 = cpu_to_le16(writeEUN); 671 = cpu_to_le16(writeEUN);
608 672
609 MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, 673 nftl_write_oob(mtd, (lastEUN * nftl->EraseSize) + 8,
610 8, &retlen, (char *)&oob.u); 674 8, &retlen, (char *)&oob.u);
611 } 675 }
612 676
613 return writeEUN; 677 return writeEUN;
@@ -639,10 +703,9 @@ static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
639 703
640 memset(&oob, 0xff, sizeof(struct nftl_oob)); 704 memset(&oob, 0xff, sizeof(struct nftl_oob));
641 oob.b.Status = oob.b.Status1 = SECTOR_USED; 705 oob.b.Status = oob.b.Status1 = SECTOR_USED;
642 MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
643 512, &retlen, (char *)buffer, (char *)&oob, &nftl->oobinfo);
644 /* need to write SECTOR_USED flags since they are not written in mtd_writeecc */
645 706
707 nftl_write(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
708 512, &retlen, (char *)buffer, (char *)&oob);
646 return 0; 709 return 0;
647} 710}
648#endif /* CONFIG_NFTL_RW */ 711#endif /* CONFIG_NFTL_RW */
@@ -651,20 +714,22 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
651 char *buffer) 714 char *buffer)
652{ 715{
653 struct NFTLrecord *nftl = (void *)mbd; 716 struct NFTLrecord *nftl = (void *)mbd;
717 struct mtd_info *mtd = nftl->mbd.mtd;
654 u16 lastgoodEUN; 718 u16 lastgoodEUN;
655 u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)]; 719 u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
656 unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); 720 unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
657 unsigned int status; 721 unsigned int status;
658 int silly = MAX_LOOPS; 722 int silly = MAX_LOOPS;
659 size_t retlen; 723 size_t retlen;
660 struct nftl_bci bci; 724 struct nftl_bci bci;
661 725
662 lastgoodEUN = BLOCK_NIL; 726 lastgoodEUN = BLOCK_NIL;
663 727
664 if (thisEUN != BLOCK_NIL) { 728 if (thisEUN != BLOCK_NIL) {
665 while (thisEUN < nftl->nb_blocks) { 729 while (thisEUN < nftl->nb_blocks) {
666 if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs, 730 if (nftl_read_oob(mtd, (thisEUN * nftl->EraseSize) +
667 8, &retlen, (char *)&bci) < 0) 731 blockofs, 8, &retlen,
732 (char *)&bci) < 0)
668 status = SECTOR_IGNORE; 733 status = SECTOR_IGNORE;
669 else 734 else
670 status = bci.Status | bci.Status1; 735 status = bci.Status | bci.Status1;
@@ -694,7 +759,7 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
694 } 759 }
695 thisEUN = nftl->ReplUnitTable[thisEUN]; 760 thisEUN = nftl->ReplUnitTable[thisEUN];
696 } 761 }
697 } 762 }
698 763
699 the_end: 764 the_end:
700 if (lastgoodEUN == BLOCK_NIL) { 765 if (lastgoodEUN == BLOCK_NIL) {
@@ -703,7 +768,9 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
703 } else { 768 } else {
704 loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs; 769 loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
705 size_t retlen; 770 size_t retlen;
706 if (MTD_READ(nftl->mbd.mtd, ptr, 512, &retlen, buffer)) 771 int res = mtd->read(mtd, ptr, 512, &retlen, buffer);
772
773 if (res < 0 && res != -EUCLEAN)
707 return -EIO; 774 return -EIO;
708 } 775 }
709 return 0; 776 return 0;
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 3b104ebb219a..067262ee8df0 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -33,6 +33,11 @@
33 33
34char nftlmountrev[]="$Revision: 1.41 $"; 34char nftlmountrev[]="$Revision: 1.41 $";
35 35
36extern int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
37 size_t *retlen, uint8_t *buf);
38extern int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
39 size_t *retlen, uint8_t *buf);
40
36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 41/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
37 * various device information of the NFTL partition and Bad Unit Table. Update 42 * various device information of the NFTL partition and Bad Unit Table. Update
38 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] 43 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
@@ -45,6 +50,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
45 size_t retlen; 50 size_t retlen;
46 u8 buf[SECTORSIZE]; 51 u8 buf[SECTORSIZE];
47 struct NFTLMediaHeader *mh = &nftl->MediaHdr; 52 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
53 struct mtd_info *mtd = nftl->mbd.mtd;
48 unsigned int i; 54 unsigned int i;
49 55
50 /* Assume logical EraseSize == physical erasesize for starting the scan. 56 /* Assume logical EraseSize == physical erasesize for starting the scan.
@@ -65,7 +71,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
65 71
66 /* Check for ANAND header first. Then can whinge if it's found but later 72 /* Check for ANAND header first. Then can whinge if it's found but later
67 checks fail */ 73 checks fail */
68 ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf); 74 ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
75 &retlen, buf);
69 /* We ignore ret in case the ECC of the MediaHeader is invalid 76 /* We ignore ret in case the ECC of the MediaHeader is invalid
70 (which is apparently acceptable) */ 77 (which is apparently acceptable) */
71 if (retlen != SECTORSIZE) { 78 if (retlen != SECTORSIZE) {
@@ -90,8 +97,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
90 } 97 }
91 98
92 /* To be safer with BIOS, also use erase mark as discriminant */ 99 /* To be safer with BIOS, also use erase mark as discriminant */
93 if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 100 if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
94 8, &retlen, (char *)&h1) < 0)) { 101 SECTORSIZE + 8, 8, &retlen,
102 (char *)&h1) < 0)) {
95 printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", 103 printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
96 block * nftl->EraseSize, nftl->mbd.mtd->index, ret); 104 block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
97 continue; 105 continue;
@@ -109,8 +117,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
109 } 117 }
110 118
111 /* Finally reread to check ECC */ 119 /* Finally reread to check ECC */
112 if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, 120 if ((ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
113 &retlen, buf, (char *)&oob, NULL) < 0)) { 121 &retlen, buf) < 0)) {
114 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", 122 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
115 block * nftl->EraseSize, nftl->mbd.mtd->index, ret); 123 block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
116 continue; 124 continue;
@@ -228,9 +236,9 @@ device is already correct.
228The new DiskOnChip driver already scanned the bad block table. Just query it. 236The new DiskOnChip driver already scanned the bad block table. Just query it.
229 if ((i & (SECTORSIZE - 1)) == 0) { 237 if ((i & (SECTORSIZE - 1)) == 0) {
230 /* read one sector for every SECTORSIZE of blocks */ 238 /* read one sector for every SECTORSIZE of blocks */
231 if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize + 239 if ((ret = mtd->read(nftl->mbd.mtd, block * nftl->EraseSize +
232 i + SECTORSIZE, SECTORSIZE, &retlen, buf, 240 i + SECTORSIZE, SECTORSIZE, &retlen,
233 (char *)&oob, NULL)) < 0) { 241 buf)) < 0) {
234 printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n", 242 printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
235 ret); 243 ret);
236 kfree(nftl->ReplUnitTable); 244 kfree(nftl->ReplUnitTable);
@@ -268,18 +276,22 @@ static int memcmpb(void *a, int c, int n)
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 276static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 277 int check_oob)
270{ 278{
271 int i;
272 size_t retlen;
273 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; 279 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize];
280 struct mtd_info *mtd = nftl->mbd.mtd;
281 size_t retlen;
282 int i;
274 283
275 for (i = 0; i < len; i += SECTORSIZE) { 284 for (i = 0; i < len; i += SECTORSIZE) {
276 if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0) 285 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
277 return -1; 286 return -1;
278 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 287 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
279 return -1; 288 return -1;
280 289
281 if (check_oob) { 290 if (check_oob) {
282 if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0) 291 if(nftl_read_oob(mtd, address, mtd->oobsize,
292 &retlen, &buf[SECTORSIZE]) < 0)
293 return -1;
294 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
283 return -1; 295 return -1;
284 } 296 }
285 address += SECTORSIZE; 297 address += SECTORSIZE;
@@ -301,10 +313,11 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
301 unsigned int nb_erases, erase_mark; 313 unsigned int nb_erases, erase_mark;
302 struct nftl_uci1 uci; 314 struct nftl_uci1 uci;
303 struct erase_info *instr = &nftl->instr; 315 struct erase_info *instr = &nftl->instr;
316 struct mtd_info *mtd = nftl->mbd.mtd;
304 317
305 /* Read the Unit Control Information #1 for Wear-Leveling */ 318 /* Read the Unit Control Information #1 for Wear-Leveling */
306 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 319 if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8,
307 8, &retlen, (char *)&uci) < 0) 320 8, &retlen, (char *)&uci) < 0)
308 goto default_uci1; 321 goto default_uci1;
309 322
310 erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1)); 323 erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1));
@@ -321,7 +334,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
321 instr->mtd = nftl->mbd.mtd; 334 instr->mtd = nftl->mbd.mtd;
322 instr->addr = block * nftl->EraseSize; 335 instr->addr = block * nftl->EraseSize;
323 instr->len = nftl->EraseSize; 336 instr->len = nftl->EraseSize;
324 MTD_ERASE(nftl->mbd.mtd, instr); 337 mtd->erase(mtd, instr);
325 338
326 if (instr->state == MTD_ERASE_FAILED) { 339 if (instr->state == MTD_ERASE_FAILED) {
327 printk("Error while formatting block %d\n", block); 340 printk("Error while formatting block %d\n", block);
@@ -343,8 +356,8 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
343 goto fail; 356 goto fail;
344 357
345 uci.WearInfo = le32_to_cpu(nb_erases); 358 uci.WearInfo = le32_to_cpu(nb_erases);
346 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 359 if (nftl_write_oob(mtd, block * nftl->EraseSize + SECTORSIZE +
347 &retlen, (char *)&uci) < 0) 360 8, 8, &retlen, (char *)&uci) < 0)
348 goto fail; 361 goto fail;
349 return 0; 362 return 0;
350fail: 363fail:
@@ -365,6 +378,7 @@ fail:
365 * case. */ 378 * case. */
366static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block) 379static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
367{ 380{
381 struct mtd_info *mtd = nftl->mbd.mtd;
368 unsigned int block, i, status; 382 unsigned int block, i, status;
369 struct nftl_bci bci; 383 struct nftl_bci bci;
370 int sectors_per_block; 384 int sectors_per_block;
@@ -374,8 +388,9 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
374 block = first_block; 388 block = first_block;
375 for (;;) { 389 for (;;) {
376 for (i = 0; i < sectors_per_block; i++) { 390 for (i = 0; i < sectors_per_block; i++) {
377 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 391 if (nftl_read_oob(mtd,
378 8, &retlen, (char *)&bci) < 0) 392 block * nftl->EraseSize + i * SECTORSIZE,
393 8, &retlen, (char *)&bci) < 0)
379 status = SECTOR_IGNORE; 394 status = SECTOR_IGNORE;
380 else 395 else
381 status = bci.Status | bci.Status1; 396 status = bci.Status | bci.Status1;
@@ -394,9 +409,10 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
394 /* sector not free actually : mark it as SECTOR_IGNORE */ 409 /* sector not free actually : mark it as SECTOR_IGNORE */
395 bci.Status = SECTOR_IGNORE; 410 bci.Status = SECTOR_IGNORE;
396 bci.Status1 = SECTOR_IGNORE; 411 bci.Status1 = SECTOR_IGNORE;
397 MTD_WRITEOOB(nftl->mbd.mtd, 412 nftl_write_oob(mtd, block *
398 block * nftl->EraseSize + i * SECTORSIZE, 413 nftl->EraseSize +
399 8, &retlen, (char *)&bci); 414 i * SECTORSIZE, 8,
415 &retlen, (char *)&bci);
400 } 416 }
401 break; 417 break;
402 default: 418 default:
@@ -481,13 +497,14 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
481 * 1. */ 497 * 1. */
482static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) 498static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
483{ 499{
500 struct mtd_info *mtd = nftl->mbd.mtd;
484 struct nftl_uci1 h1; 501 struct nftl_uci1 h1;
485 unsigned int erase_mark; 502 unsigned int erase_mark;
486 size_t retlen; 503 size_t retlen;
487 504
488 /* check erase mark. */ 505 /* check erase mark. */
489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 506 if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
490 &retlen, (char *)&h1) < 0) 507 &retlen, (char *)&h1) < 0)
491 return -1; 508 return -1;
492 509
493 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1)); 510 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
@@ -501,8 +518,9 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
501 h1.EraseMark = cpu_to_le16(ERASE_MARK); 518 h1.EraseMark = cpu_to_le16(ERASE_MARK);
502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK); 519 h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
503 h1.WearInfo = cpu_to_le32(0); 520 h1.WearInfo = cpu_to_le32(0);
504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 521 if (nftl_write_oob(mtd,
505 &retlen, (char *)&h1) < 0) 522 block * nftl->EraseSize + SECTORSIZE + 8, 8,
523 &retlen, (char *)&h1) < 0)
506 return -1; 524 return -1;
507 } else { 525 } else {
508#if 0 526#if 0
@@ -513,8 +531,8 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
513 SECTORSIZE, 0) != 0) 531 SECTORSIZE, 0) != 0)
514 return -1; 532 return -1;
515 533
516 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i, 534 if (nftl_read_oob(mtd, block * nftl->EraseSize + i,
517 16, &retlen, buf) < 0) 535 16, &retlen, buf) < 0)
518 return -1; 536 return -1;
519 if (i == SECTORSIZE) { 537 if (i == SECTORSIZE) {
520 /* skip erase mark */ 538 /* skip erase mark */
@@ -540,11 +558,12 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
540 */ 558 */
541static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block) 559static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block)
542{ 560{
561 struct mtd_info *mtd = nftl->mbd.mtd;
543 struct nftl_uci2 uci; 562 struct nftl_uci2 uci;
544 size_t retlen; 563 size_t retlen;
545 564
546 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, 565 if (nftl_read_oob(mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
547 8, &retlen, (char *)&uci) < 0) 566 8, &retlen, (char *)&uci) < 0)
548 return 0; 567 return 0;
549 568
550 return le16_to_cpu((uci.FoldMark | uci.FoldMark1)); 569 return le16_to_cpu((uci.FoldMark | uci.FoldMark1));
@@ -558,6 +577,7 @@ int NFTL_mount(struct NFTLrecord *s)
558 int chain_length, do_format_chain; 577 int chain_length, do_format_chain;
559 struct nftl_uci0 h0; 578 struct nftl_uci0 h0;
560 struct nftl_uci1 h1; 579 struct nftl_uci1 h1;
580 struct mtd_info *mtd = s->mbd.mtd;
561 size_t retlen; 581 size_t retlen;
562 582
563 /* search for NFTL MediaHeader and Spare NFTL Media Header */ 583 /* search for NFTL MediaHeader and Spare NFTL Media Header */
@@ -582,10 +602,13 @@ int NFTL_mount(struct NFTLrecord *s)
582 602
583 for (;;) { 603 for (;;) {
584 /* read the block header. If error, we format the chain */ 604 /* read the block header. If error, we format the chain */
585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 605 if (nftl_read_oob(mtd,
586 &retlen, (char *)&h0) < 0 || 606 block * s->EraseSize + 8, 8,
587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 607 &retlen, (char *)&h0) < 0 ||
588 &retlen, (char *)&h1) < 0) { 608 nftl_read_oob(mtd,
609 block * s->EraseSize +
610 SECTORSIZE + 8, 8,
611 &retlen, (char *)&h1) < 0) {
589 s->ReplUnitTable[block] = BLOCK_NIL; 612 s->ReplUnitTable[block] = BLOCK_NIL;
590 do_format_chain = 1; 613 do_format_chain = 1;
591 break; 614 break;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 126ff6bf63d5..5930a03736d7 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -29,6 +29,20 @@ config MTD_ONENAND_GENERIC
29 help 29 help
30 Support for OneNAND flash via platform device driver. 30 Support for OneNAND flash via platform device driver.
31 31
32config MTD_ONENAND_OTP
33 bool "OneNAND OTP Support"
34 depends on MTD_ONENAND
35 help
36 One Block of the NAND Flash Array memory is reserved as
37 a One-Time Programmable Block memory area.
38 Also, 1st Block of NAND Flash Array can be used as OTP.
39
40 The OTP block can be read, programmed and locked using the same
41 operations as any other NAND Flash Array memory block.
42 OTP block cannot be erased.
43
44 OTP block is fully-guaranteed to be a valid block.
45
32config MTD_ONENAND_SYNC_READ 46config MTD_ONENAND_SYNC_READ
33 bool "OneNAND Sync. Burst Read Support" 47 bool "OneNAND Sync. Burst Read Support"
34 depends on ARCH_OMAP 48 depends on ARCH_OMAP
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index a53a73fc2a5a..84ec40d25438 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -23,8 +23,7 @@
23/** 23/**
24 * onenand_oob_64 - oob info for large (2KB) page 24 * onenand_oob_64 - oob info for large (2KB) page
25 */ 25 */
26static struct nand_oobinfo onenand_oob_64 = { 26static struct nand_ecclayout onenand_oob_64 = {
27 .useecc = MTD_NANDECC_AUTOPLACE,
28 .eccbytes = 20, 27 .eccbytes = 20,
29 .eccpos = { 28 .eccpos = {
30 8, 9, 10, 11, 12, 29 8, 9, 10, 11, 12,
@@ -34,14 +33,14 @@ static struct nand_oobinfo onenand_oob_64 = {
34 }, 33 },
35 .oobfree = { 34 .oobfree = {
36 {2, 3}, {14, 2}, {18, 3}, {30, 2}, 35 {2, 3}, {14, 2}, {18, 3}, {30, 2},
37 {24, 3}, {46, 2}, {40, 3}, {62, 2} } 36 {34, 3}, {46, 2}, {50, 3}, {62, 2}
37 }
38}; 38};
39 39
40/** 40/**
41 * onenand_oob_32 - oob info for middle (1KB) page 41 * onenand_oob_32 - oob info for middle (1KB) page
42 */ 42 */
43static struct nand_oobinfo onenand_oob_32 = { 43static struct nand_ecclayout onenand_oob_32 = {
44 .useecc = MTD_NANDECC_AUTOPLACE,
45 .eccbytes = 10, 44 .eccbytes = 10,
46 .eccpos = { 45 .eccpos = {
47 8, 9, 10, 11, 12, 46 8, 9, 10, 11, 12,
@@ -190,7 +189,7 @@ static int onenand_buffer_address(int dataram1, int sectors, int count)
190static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len) 189static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
191{ 190{
192 struct onenand_chip *this = mtd->priv; 191 struct onenand_chip *this = mtd->priv;
193 int value, readcmd = 0; 192 int value, readcmd = 0, block_cmd = 0;
194 int block, page; 193 int block, page;
195 /* Now we use page size operation */ 194 /* Now we use page size operation */
196 int sectors = 4, count = 4; 195 int sectors = 4, count = 4;
@@ -206,6 +205,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
206 205
207 case ONENAND_CMD_ERASE: 206 case ONENAND_CMD_ERASE:
208 case ONENAND_CMD_BUFFERRAM: 207 case ONENAND_CMD_BUFFERRAM:
208 case ONENAND_CMD_OTP_ACCESS:
209 block_cmd = 1;
209 block = (int) (addr >> this->erase_shift); 210 block = (int) (addr >> this->erase_shift);
210 page = -1; 211 page = -1;
211 break; 212 break;
@@ -233,6 +234,12 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
233 /* Write 'DFS, FBA' of Flash */ 234 /* Write 'DFS, FBA' of Flash */
234 value = onenand_block_address(this, block); 235 value = onenand_block_address(this, block);
235 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); 236 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
237
238 if (block_cmd) {
239 /* Select DataRAM for DDP */
240 value = onenand_bufferram_address(this, block);
241 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
242 }
236 } 243 }
237 244
238 if (page != -1) { 245 if (page != -1) {
@@ -301,6 +308,7 @@ static int onenand_wait(struct mtd_info *mtd, int state)
301 308
302 if (state != FL_READING) 309 if (state != FL_READING)
303 cond_resched(); 310 cond_resched();
311 touch_softlockup_watchdog();
304 } 312 }
305 /* To get correct interrupt status in timeout case */ 313 /* To get correct interrupt status in timeout case */
306 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); 314 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
@@ -344,7 +352,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
344 352
345 if (ONENAND_CURRENT_BUFFERRAM(this)) { 353 if (ONENAND_CURRENT_BUFFERRAM(this)) {
346 if (area == ONENAND_DATARAM) 354 if (area == ONENAND_DATARAM)
347 return mtd->oobblock; 355 return mtd->writesize;
348 if (area == ONENAND_SPARERAM) 356 if (area == ONENAND_SPARERAM)
349 return mtd->oobsize; 357 return mtd->oobsize;
350 } 358 }
@@ -372,6 +380,17 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area,
372 380
373 bufferram += onenand_bufferram_offset(mtd, area); 381 bufferram += onenand_bufferram_offset(mtd, area);
374 382
383 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
384 unsigned short word;
385
386 /* Align with word(16-bit) size */
387 count--;
388
389 /* Read word and save byte */
390 word = this->read_word(bufferram + offset + count);
391 buffer[count] = (word & 0xff);
392 }
393
375 memcpy(buffer, bufferram + offset, count); 394 memcpy(buffer, bufferram + offset, count);
376 395
377 return 0; 396 return 0;
@@ -399,6 +418,17 @@ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
399 418
400 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); 419 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
401 420
421 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
422 unsigned short word;
423
424 /* Align with word(16-bit) size */
425 count--;
426
427 /* Read word and save byte */
428 word = this->read_word(bufferram + offset + count);
429 buffer[count] = (word & 0xff);
430 }
431
402 memcpy(buffer, bufferram + offset, count); 432 memcpy(buffer, bufferram + offset, count);
403 433
404 this->mmcontrol(mtd, 0); 434 this->mmcontrol(mtd, 0);
@@ -426,6 +456,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
426 456
427 bufferram += onenand_bufferram_offset(mtd, area); 457 bufferram += onenand_bufferram_offset(mtd, area);
428 458
459 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
460 unsigned short word;
461 int byte_offset;
462
463 /* Align with word(16-bit) size */
464 count--;
465
466 /* Calculate byte access offset */
467 byte_offset = offset + count;
468
469 /* Read word and save byte */
470 word = this->read_word(bufferram + byte_offset);
471 word = (word & ~0xff) | buffer[count];
472 this->write_word(word, bufferram + byte_offset);
473 }
474
429 memcpy(bufferram + offset, buffer, count); 475 memcpy(bufferram + offset, buffer, count);
430 476
431 return 0; 477 return 0;
@@ -549,31 +595,28 @@ static void onenand_release_device(struct mtd_info *mtd)
549} 595}
550 596
551/** 597/**
552 * onenand_read_ecc - [MTD Interface] Read data with ECC 598 * onenand_read - [MTD Interface] Read data from flash
553 * @param mtd MTD device structure 599 * @param mtd MTD device structure
554 * @param from offset to read from 600 * @param from offset to read from
555 * @param len number of bytes to read 601 * @param len number of bytes to read
556 * @param retlen pointer to variable to store the number of read bytes 602 * @param retlen pointer to variable to store the number of read bytes
557 * @param buf the databuffer to put data 603 * @param buf the databuffer to put data
558 * @param oob_buf filesystem supplied oob data buffer
559 * @param oobsel oob selection structure
560 * 604 *
561 * OneNAND read with ECC 605 * Read with ecc
562 */ 606*/
563static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 607static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
564 size_t *retlen, u_char *buf, 608 size_t *retlen, u_char *buf)
565 u_char *oob_buf, struct nand_oobinfo *oobsel)
566{ 609{
567 struct onenand_chip *this = mtd->priv; 610 struct onenand_chip *this = mtd->priv;
568 int read = 0, column; 611 int read = 0, column;
569 int thislen; 612 int thislen;
570 int ret = 0; 613 int ret = 0;
571 614
572 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 615 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
573 616
574 /* Do not allow reads past end of device */ 617 /* Do not allow reads past end of device */
575 if ((from + len) > mtd->size) { 618 if ((from + len) > mtd->size) {
576 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n"); 619 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n");
577 *retlen = 0; 620 *retlen = 0;
578 return -EINVAL; 621 return -EINVAL;
579 } 622 }
@@ -584,14 +627,14 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
584 /* TODO handling oob */ 627 /* TODO handling oob */
585 628
586 while (read < len) { 629 while (read < len) {
587 thislen = min_t(int, mtd->oobblock, len - read); 630 thislen = min_t(int, mtd->writesize, len - read);
588 631
589 column = from & (mtd->oobblock - 1); 632 column = from & (mtd->writesize - 1);
590 if (column + thislen > mtd->oobblock) 633 if (column + thislen > mtd->writesize)
591 thislen = mtd->oobblock - column; 634 thislen = mtd->writesize - column;
592 635
593 if (!onenand_check_bufferram(mtd, from)) { 636 if (!onenand_check_bufferram(mtd, from)) {
594 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock); 637 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
595 638
596 ret = this->wait(mtd, FL_READING); 639 ret = this->wait(mtd, FL_READING);
597 /* First copy data and check return value for ECC handling */ 640 /* First copy data and check return value for ECC handling */
@@ -606,7 +649,7 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
606 break; 649 break;
607 650
608 if (ret) { 651 if (ret) {
609 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret); 652 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
610 goto out; 653 goto out;
611 } 654 }
612 655
@@ -628,23 +671,7 @@ out:
628} 671}
629 672
630/** 673/**
631 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc 674 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
632 * @param mtd MTD device structure
633 * @param from offset to read from
634 * @param len number of bytes to read
635 * @param retlen pointer to variable to store the number of read bytes
636 * @param buf the databuffer to put data
637 *
638 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
639*/
640static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
641 size_t *retlen, u_char *buf)
642{
643 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
644}
645
646/**
647 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
648 * @param mtd MTD device structure 675 * @param mtd MTD device structure
649 * @param from offset to read from 676 * @param from offset to read from
650 * @param len number of bytes to read 677 * @param len number of bytes to read
@@ -653,8 +680,8 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
653 * 680 *
654 * OneNAND read out-of-band data from the spare area 681 * OneNAND read out-of-band data from the spare area
655 */ 682 */
656static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 683int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
657 size_t *retlen, u_char *buf) 684 size_t *retlen, u_char *buf)
658{ 685{
659 struct onenand_chip *this = mtd->priv; 686 struct onenand_chip *this = mtd->priv;
660 int read = 0, thislen, column; 687 int read = 0, thislen, column;
@@ -704,7 +731,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
704 /* Read more? */ 731 /* Read more? */
705 if (read < len) { 732 if (read < len) {
706 /* Page size */ 733 /* Page size */
707 from += mtd->oobblock; 734 from += mtd->writesize;
708 column = 0; 735 column = 0;
709 } 736 }
710 } 737 }
@@ -717,8 +744,53 @@ out:
717 return ret; 744 return ret;
718} 745}
719 746
747/**
748 * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
749 * @mtd: MTD device structure
750 * @from: offset to read from
751 * @ops: oob operation description structure
752 */
753static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
754 struct mtd_oob_ops *ops)
755{
756 BUG_ON(ops->mode != MTD_OOB_PLACE);
757
758 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->len,
759 &ops->retlen, ops->oobbuf);
760}
761
720#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE 762#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
721/** 763/**
764 * onenand_verify_oob - [GENERIC] verify the oob contents after a write
765 * @param mtd MTD device structure
766 * @param buf the databuffer to verify
767 * @param to offset to read from
768 * @param len number of bytes to read and compare
769 *
770 */
771static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len)
772{
773 struct onenand_chip *this = mtd->priv;
774 char *readp = this->page_buf;
775 int column = to & (mtd->oobsize - 1);
776 int status, i;
777
778 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
779 onenand_update_bufferram(mtd, to, 0);
780 status = this->wait(mtd, FL_READING);
781 if (status)
782 return status;
783
784 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len);
785
786 for(i = 0; i < len; i++)
787 if (buf[i] != 0xFF && buf[i] != readp[i])
788 return -EBADMSG;
789
790 return 0;
791}
792
793/**
722 * onenand_verify_page - [GENERIC] verify the chip contents after a write 794 * onenand_verify_page - [GENERIC] verify the chip contents after a write
723 * @param mtd MTD device structure 795 * @param mtd MTD device structure
724 * @param buf the databuffer to verify 796 * @param buf the databuffer to verify
@@ -731,7 +803,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
731 void __iomem *dataram0, *dataram1; 803 void __iomem *dataram0, *dataram1;
732 int ret = 0; 804 int ret = 0;
733 805
734 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock); 806 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
735 807
736 ret = this->wait(mtd, FL_READING); 808 ret = this->wait(mtd, FL_READING);
737 if (ret) 809 if (ret)
@@ -741,53 +813,51 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
741 813
742 /* Check, if the two dataram areas are same */ 814 /* Check, if the two dataram areas are same */
743 dataram0 = this->base + ONENAND_DATARAM; 815 dataram0 = this->base + ONENAND_DATARAM;
744 dataram1 = dataram0 + mtd->oobblock; 816 dataram1 = dataram0 + mtd->writesize;
745 817
746 if (memcmp(dataram0, dataram1, mtd->oobblock)) 818 if (memcmp(dataram0, dataram1, mtd->writesize))
747 return -EBADMSG; 819 return -EBADMSG;
748 820
749 return 0; 821 return 0;
750} 822}
751#else 823#else
752#define onenand_verify_page(...) (0) 824#define onenand_verify_page(...) (0)
825#define onenand_verify_oob(...) (0)
753#endif 826#endif
754 827
755#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0) 828#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
756 829
757/** 830/**
758 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC 831 * onenand_write - [MTD Interface] write buffer to FLASH
759 * @param mtd MTD device structure 832 * @param mtd MTD device structure
760 * @param to offset to write to 833 * @param to offset to write to
761 * @param len number of bytes to write 834 * @param len number of bytes to write
762 * @param retlen pointer to variable to store the number of written bytes 835 * @param retlen pointer to variable to store the number of written bytes
763 * @param buf the data to write 836 * @param buf the data to write
764 * @param eccbuf filesystem supplied oob data buffer
765 * @param oobsel oob selection structure
766 * 837 *
767 * OneNAND write with ECC 838 * Write with ECC
768 */ 839 */
769static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 840static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
770 size_t *retlen, const u_char *buf, 841 size_t *retlen, const u_char *buf)
771 u_char *eccbuf, struct nand_oobinfo *oobsel)
772{ 842{
773 struct onenand_chip *this = mtd->priv; 843 struct onenand_chip *this = mtd->priv;
774 int written = 0; 844 int written = 0;
775 int ret = 0; 845 int ret = 0;
776 846
777 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 847 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
778 848
779 /* Initialize retlen, in case of early exit */ 849 /* Initialize retlen, in case of early exit */
780 *retlen = 0; 850 *retlen = 0;
781 851
782 /* Do not allow writes past end of device */ 852 /* Do not allow writes past end of device */
783 if (unlikely((to + len) > mtd->size)) { 853 if (unlikely((to + len) > mtd->size)) {
784 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n"); 854 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n");
785 return -EINVAL; 855 return -EINVAL;
786 } 856 }
787 857
788 /* Reject writes, which are not page aligned */ 858 /* Reject writes, which are not page aligned */
789 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 859 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
790 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n"); 860 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n");
791 return -EINVAL; 861 return -EINVAL;
792 } 862 }
793 863
@@ -796,20 +866,20 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
796 866
797 /* Loop until all data write */ 867 /* Loop until all data write */
798 while (written < len) { 868 while (written < len) {
799 int thislen = min_t(int, mtd->oobblock, len - written); 869 int thislen = min_t(int, mtd->writesize, len - written);
800 870
801 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock); 871 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
802 872
803 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen); 873 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
804 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 874 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
805 875
806 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock); 876 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
807 877
808 onenand_update_bufferram(mtd, to, 1); 878 onenand_update_bufferram(mtd, to, 1);
809 879
810 ret = this->wait(mtd, FL_WRITING); 880 ret = this->wait(mtd, FL_WRITING);
811 if (ret) { 881 if (ret) {
812 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret); 882 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
813 goto out; 883 goto out;
814 } 884 }
815 885
@@ -818,7 +888,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
818 /* Only check verify write turn on */ 888 /* Only check verify write turn on */
819 ret = onenand_verify_page(mtd, (u_char *) buf, to); 889 ret = onenand_verify_page(mtd, (u_char *) buf, to);
820 if (ret) { 890 if (ret) {
821 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret); 891 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
822 goto out; 892 goto out;
823 } 893 }
824 894
@@ -839,24 +909,7 @@ out:
839} 909}
840 910
841/** 911/**
842 * onenand_write - [MTD Interface] compability function for onenand_write_ecc 912 * onenand_do_write_oob - [Internal] OneNAND write out-of-band
843 * @param mtd MTD device structure
844 * @param to offset to write to
845 * @param len number of bytes to write
846 * @param retlen pointer to variable to store the number of written bytes
847 * @param buf the data to write
848 *
849 * This function simply calls onenand_write_ecc
850 * with oob buffer and oobsel = NULL
851 */
852static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
853 size_t *retlen, const u_char *buf)
854{
855 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
856}
857
858/**
859 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
860 * @param mtd MTD device structure 913 * @param mtd MTD device structure
861 * @param to offset to write to 914 * @param to offset to write to
862 * @param len number of bytes to write 915 * @param len number of bytes to write
@@ -865,11 +918,11 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
865 * 918 *
866 * OneNAND write out-of-band 919 * OneNAND write out-of-band
867 */ 920 */
868static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 921static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
869 size_t *retlen, const u_char *buf) 922 size_t *retlen, const u_char *buf)
870{ 923{
871 struct onenand_chip *this = mtd->priv; 924 struct onenand_chip *this = mtd->priv;
872 int column, status; 925 int column, ret = 0;
873 int written = 0; 926 int written = 0;
874 927
875 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 928 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
@@ -894,16 +947,27 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
894 947
895 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); 948 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
896 949
897 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 950 /* We send data to spare ram with oobsize
898 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 951 * to prevent byte access */
952 memset(this->page_buf, 0xff, mtd->oobsize);
953 memcpy(this->page_buf + column, buf, thislen);
954 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
899 955
900 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 956 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
901 957
902 onenand_update_bufferram(mtd, to, 0); 958 onenand_update_bufferram(mtd, to, 0);
903 959
904 status = this->wait(mtd, FL_WRITING); 960 ret = this->wait(mtd, FL_WRITING);
905 if (status) 961 if (ret) {
962 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret);
963 goto out;
964 }
965
966 ret = onenand_verify_oob(mtd, buf, to, thislen);
967 if (ret) {
968 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret);
906 goto out; 969 goto out;
970 }
907 971
908 written += thislen; 972 written += thislen;
909 973
@@ -920,145 +984,22 @@ out:
920 984
921 *retlen = written; 985 *retlen = written;
922 986
923 return 0; 987 return ret;
924} 988}
925 989
926/** 990/**
927 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc 991 * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
928 * @param mtd MTD device structure 992 * @mtd: MTD device structure
929 * @param vecs the iovectors to write 993 * @from: offset to read from
930 * @param count number of vectors 994 * @ops: oob operation description structure
931 * @param to offset to write to
932 * @param retlen pointer to variable to store the number of written bytes
933 * @param eccbuf filesystem supplied oob data buffer
934 * @param oobsel oob selection structure
935 *
936 * OneNAND write with iovec with ecc
937 */ 995 */
938static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 996static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
939 unsigned long count, loff_t to, size_t *retlen, 997 struct mtd_oob_ops *ops)
940 u_char *eccbuf, struct nand_oobinfo *oobsel)
941{ 998{
942 struct onenand_chip *this = mtd->priv; 999 BUG_ON(ops->mode != MTD_OOB_PLACE);
943 unsigned char *pbuf;
944 size_t total_len, len;
945 int i, written = 0;
946 int ret = 0;
947
948 /* Preset written len for early exit */
949 *retlen = 0;
950
951 /* Calculate total length of data */
952 total_len = 0;
953 for (i = 0; i < count; i++)
954 total_len += vecs[i].iov_len;
955
956 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
957
958 /* Do not allow write past end of the device */
959 if (unlikely((to + total_len) > mtd->size)) {
960 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
961 return -EINVAL;
962 }
963
964 /* Reject writes, which are not page aligned */
965 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
966 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
967 return -EINVAL;
968 }
969
970 /* Grab the lock and see if the device is available */
971 onenand_get_device(mtd, FL_WRITING);
972
973 /* TODO handling oob */
974
975 /* Loop until all keve's data has been written */
976 len = 0;
977 while (count) {
978 pbuf = this->page_buf;
979 /*
980 * If the given tuple is >= pagesize then
981 * write it out from the iov
982 */
983 if ((vecs->iov_len - len) >= mtd->oobblock) {
984 pbuf = vecs->iov_base + len;
985
986 len += mtd->oobblock;
987
988 /* Check, if we have to switch to the next tuple */
989 if (len >= (int) vecs->iov_len) {
990 vecs++;
991 len = 0;
992 count--;
993 }
994 } else {
995 int cnt = 0, thislen;
996 while (cnt < mtd->oobblock) {
997 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
998 memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
999 cnt += thislen;
1000 len += thislen;
1001
1002 /* Check, if we have to switch to the next tuple */
1003 if (len >= (int) vecs->iov_len) {
1004 vecs++;
1005 len = 0;
1006 count--;
1007 }
1008 }
1009 }
1010
1011 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1012 1000
1013 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock); 1001 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->len,
1014 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1002 &ops->retlen, ops->oobbuf);
1015
1016 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1017
1018 onenand_update_bufferram(mtd, to, 1);
1019
1020 ret = this->wait(mtd, FL_WRITING);
1021 if (ret) {
1022 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1023 goto out;
1024 }
1025
1026
1027 /* Only check verify write turn on */
1028 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1029 if (ret) {
1030 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1031 goto out;
1032 }
1033
1034 written += mtd->oobblock;
1035
1036 to += mtd->oobblock;
1037 }
1038
1039out:
1040 /* Deselect and wakt up anyone waiting on the device */
1041 onenand_release_device(mtd);
1042
1043 *retlen = written;
1044
1045 return 0;
1046}
1047
1048/**
1049 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1050 * @param mtd MTD device structure
1051 * @param vecs the iovectors to write
1052 * @param count number of vectors
1053 * @param to offset to write to
1054 * @param retlen pointer to variable to store the number of written bytes
1055 *
1056 * OneNAND write with kvec. This just calls the ecc function
1057 */
1058static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1059 unsigned long count, loff_t to, size_t *retlen)
1060{
1061 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1062} 1003}
1063 1004
1064/** 1005/**
@@ -1227,7 +1168,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1227 1168
1228 /* We write two bytes, so we dont have to mess with 16 bit access */ 1169 /* We write two bytes, so we dont have to mess with 16 bit access */
1229 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1170 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1230 return mtd->write_oob(mtd, ofs , 2, &retlen, buf); 1171 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf);
1231} 1172}
1232 1173
1233/** 1174/**
@@ -1324,6 +1265,304 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1324 return 0; 1265 return 0;
1325} 1266}
1326 1267
1268#ifdef CONFIG_MTD_ONENAND_OTP
1269
1270/* Interal OTP operation */
1271typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
1272 size_t *retlen, u_char *buf);
1273
1274/**
1275 * do_otp_read - [DEFAULT] Read OTP block area
1276 * @param mtd MTD device structure
1277 * @param from The offset to read
1278 * @param len number of bytes to read
1279 * @param retlen pointer to variable to store the number of readbytes
1280 * @param buf the databuffer to put/get data
1281 *
1282 * Read OTP block area.
1283 */
1284static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
1285 size_t *retlen, u_char *buf)
1286{
1287 struct onenand_chip *this = mtd->priv;
1288 int ret;
1289
1290 /* Enter OTP access mode */
1291 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1292 this->wait(mtd, FL_OTPING);
1293
1294 ret = mtd->read(mtd, from, len, retlen, buf);
1295
1296 /* Exit OTP access mode */
1297 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1298 this->wait(mtd, FL_RESETING);
1299
1300 return ret;
1301}
1302
1303/**
1304 * do_otp_write - [DEFAULT] Write OTP block area
1305 * @param mtd MTD device structure
1306 * @param from The offset to write
1307 * @param len number of bytes to write
1308 * @param retlen pointer to variable to store the number of write bytes
1309 * @param buf the databuffer to put/get data
1310 *
1311 * Write OTP block area.
1312 */
1313static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len,
1314 size_t *retlen, u_char *buf)
1315{
1316 struct onenand_chip *this = mtd->priv;
1317 unsigned char *pbuf = buf;
1318 int ret;
1319
1320 /* Force buffer page aligned */
1321 if (len < mtd->writesize) {
1322 memcpy(this->page_buf, buf, len);
1323 memset(this->page_buf + len, 0xff, mtd->writesize - len);
1324 pbuf = this->page_buf;
1325 len = mtd->writesize;
1326 }
1327
1328 /* Enter OTP access mode */
1329 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1330 this->wait(mtd, FL_OTPING);
1331
1332 ret = mtd->write(mtd, from, len, retlen, pbuf);
1333
1334 /* Exit OTP access mode */
1335 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1336 this->wait(mtd, FL_RESETING);
1337
1338 return ret;
1339}
1340
1341/**
1342 * do_otp_lock - [DEFAULT] Lock OTP block area
1343 * @param mtd MTD device structure
1344 * @param from The offset to lock
1345 * @param len number of bytes to lock
1346 * @param retlen pointer to variable to store the number of lock bytes
1347 * @param buf the databuffer to put/get data
1348 *
1349 * Lock OTP block area.
1350 */
1351static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1352 size_t *retlen, u_char *buf)
1353{
1354 struct onenand_chip *this = mtd->priv;
1355 int ret;
1356
1357 /* Enter OTP access mode */
1358 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1359 this->wait(mtd, FL_OTPING);
1360
1361 ret = onenand_do_write_oob(mtd, from, len, retlen, buf);
1362
1363 /* Exit OTP access mode */
1364 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1365 this->wait(mtd, FL_RESETING);
1366
1367 return ret;
1368}
1369
1370/**
1371 * onenand_otp_walk - [DEFAULT] Handle OTP operation
1372 * @param mtd MTD device structure
1373 * @param from The offset to read/write
1374 * @param len number of bytes to read/write
1375 * @param retlen pointer to variable to store the number of read bytes
1376 * @param buf the databuffer to put/get data
1377 * @param action do given action
1378 * @param mode specify user and factory
1379 *
1380 * Handle OTP operation.
1381 */
1382static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
1383 size_t *retlen, u_char *buf,
1384 otp_op_t action, int mode)
1385{
1386 struct onenand_chip *this = mtd->priv;
1387 int otp_pages;
1388 int density;
1389 int ret = 0;
1390
1391 *retlen = 0;
1392
1393 density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1394 if (density < ONENAND_DEVICE_DENSITY_512Mb)
1395 otp_pages = 20;
1396 else
1397 otp_pages = 10;
1398
1399 if (mode == MTD_OTP_FACTORY) {
1400 from += mtd->writesize * otp_pages;
1401 otp_pages = 64 - otp_pages;
1402 }
1403
1404 /* Check User/Factory boundary */
1405 if (((mtd->writesize * otp_pages) - (from + len)) < 0)
1406 return 0;
1407
1408 while (len > 0 && otp_pages > 0) {
1409 if (!action) { /* OTP Info functions */
1410 struct otp_info *otpinfo;
1411
1412 len -= sizeof(struct otp_info);
1413 if (len <= 0)
1414 return -ENOSPC;
1415
1416 otpinfo = (struct otp_info *) buf;
1417 otpinfo->start = from;
1418 otpinfo->length = mtd->writesize;
1419 otpinfo->locked = 0;
1420
1421 from += mtd->writesize;
1422 buf += sizeof(struct otp_info);
1423 *retlen += sizeof(struct otp_info);
1424 } else {
1425 size_t tmp_retlen;
1426 int size = len;
1427
1428 ret = action(mtd, from, len, &tmp_retlen, buf);
1429
1430 buf += size;
1431 len -= size;
1432 *retlen += size;
1433
1434 if (ret < 0)
1435 return ret;
1436 }
1437 otp_pages--;
1438 }
1439
1440 return 0;
1441}
1442
1443/**
1444 * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
1445 * @param mtd MTD device structure
1446 * @param buf the databuffer to put/get data
1447 * @param len number of bytes to read
1448 *
1449 * Read factory OTP info.
1450 */
1451static int onenand_get_fact_prot_info(struct mtd_info *mtd,
1452 struct otp_info *buf, size_t len)
1453{
1454 size_t retlen;
1455 int ret;
1456
1457 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_FACTORY);
1458
1459 return ret ? : retlen;
1460}
1461
1462/**
1463 * onenand_read_fact_prot_reg - [MTD Interface] Read factory OTP area
1464 * @param mtd MTD device structure
1465 * @param from The offset to read
1466 * @param len number of bytes to read
1467 * @param retlen pointer to variable to store the number of read bytes
1468 * @param buf the databuffer to put/get data
1469 *
1470 * Read factory OTP area.
1471 */
1472static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
1473 size_t len, size_t *retlen, u_char *buf)
1474{
1475 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_FACTORY);
1476}
1477
1478/**
1479 * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
1480 * @param mtd MTD device structure
1481 * @param buf the databuffer to put/get data
1482 * @param len number of bytes to read
1483 *
1484 * Read user OTP info.
1485 */
1486static int onenand_get_user_prot_info(struct mtd_info *mtd,
1487 struct otp_info *buf, size_t len)
1488{
1489 size_t retlen;
1490 int ret;
1491
1492 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_USER);
1493
1494 return ret ? : retlen;
1495}
1496
1497/**
1498 * onenand_read_user_prot_reg - [MTD Interface] Read user OTP area
1499 * @param mtd MTD device structure
1500 * @param from The offset to read
1501 * @param len number of bytes to read
1502 * @param retlen pointer to variable to store the number of read bytes
1503 * @param buf the databuffer to put/get data
1504 *
1505 * Read user OTP area.
1506 */
1507static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
1508 size_t len, size_t *retlen, u_char *buf)
1509{
1510 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_USER);
1511}
1512
1513/**
1514 * onenand_write_user_prot_reg - [MTD Interface] Write user OTP area
1515 * @param mtd MTD device structure
1516 * @param from The offset to write
1517 * @param len number of bytes to write
1518 * @param retlen pointer to variable to store the number of write bytes
1519 * @param buf the databuffer to put/get data
1520 *
1521 * Write user OTP area.
1522 */
1523static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
1524 size_t len, size_t *retlen, u_char *buf)
1525{
1526 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
1527}
1528
1529/**
1530 * onenand_lock_user_prot_reg - [MTD Interface] Lock user OTP area
1531 * @param mtd MTD device structure
1532 * @param from The offset to lock
1533 * @param len number of bytes to unlock
1534 *
1535 * Write lock mark on spare area in page 0 in OTP block
1536 */
1537static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
1538 size_t len)
1539{
1540 unsigned char oob_buf[64];
1541 size_t retlen;
1542 int ret;
1543
1544 memset(oob_buf, 0xff, mtd->oobsize);
1545 /*
1546 * Note: OTP lock operation
1547 * OTP block : 0xXXFC
1548 * 1st block : 0xXXF3 (If chip support)
1549 * Both : 0xXXF0 (If chip support)
1550 */
1551 oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
1552
1553 /*
1554 * Write lock mark to 8th word of sector0 of page0 of the spare0.
1555 * We write 16 bytes spare area instead of 2 bytes.
1556 */
1557 from = 0;
1558 len = 16;
1559
1560 ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER);
1561
1562 return ret ? : retlen;
1563}
1564#endif /* CONFIG_MTD_ONENAND_OTP */
1565
1327/** 1566/**
1328 * onenand_print_device_info - Print device ID 1567 * onenand_print_device_info - Print device ID
1329 * @param device device ID 1568 * @param device device ID
@@ -1423,15 +1662,15 @@ static int onenand_probe(struct mtd_info *mtd)
1423 1662
1424 /* OneNAND page size & block size */ 1663 /* OneNAND page size & block size */
1425 /* The data buffer size is equal to page size */ 1664 /* The data buffer size is equal to page size */
1426 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 1665 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1427 mtd->oobsize = mtd->oobblock >> 5; 1666 mtd->oobsize = mtd->writesize >> 5;
1428 /* Pagers per block is always 64 in OneNAND */ 1667 /* Pagers per block is always 64 in OneNAND */
1429 mtd->erasesize = mtd->oobblock << 6; 1668 mtd->erasesize = mtd->writesize << 6;
1430 1669
1431 this->erase_shift = ffs(mtd->erasesize) - 1; 1670 this->erase_shift = ffs(mtd->erasesize) - 1;
1432 this->page_shift = ffs(mtd->oobblock) - 1; 1671 this->page_shift = ffs(mtd->writesize) - 1;
1433 this->ppb_shift = (this->erase_shift - this->page_shift); 1672 this->ppb_shift = (this->erase_shift - this->page_shift);
1434 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1; 1673 this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
1435 1674
1436 /* REVIST: Multichip handling */ 1675 /* REVIST: Multichip handling */
1437 1676
@@ -1475,7 +1714,6 @@ static void onenand_resume(struct mtd_info *mtd)
1475 "in suspended state\n"); 1714 "in suspended state\n");
1476} 1715}
1477 1716
1478
1479/** 1717/**
1480 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device 1718 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1481 * @param mtd MTD device structure 1719 * @param mtd MTD device structure
@@ -1522,7 +1760,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1522 /* Allocate buffers, if necessary */ 1760 /* Allocate buffers, if necessary */
1523 if (!this->page_buf) { 1761 if (!this->page_buf) {
1524 size_t len; 1762 size_t len;
1525 len = mtd->oobblock + mtd->oobsize; 1763 len = mtd->writesize + mtd->oobsize;
1526 this->page_buf = kmalloc(len, GFP_KERNEL); 1764 this->page_buf = kmalloc(len, GFP_KERNEL);
1527 if (!this->page_buf) { 1765 if (!this->page_buf) {
1528 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); 1766 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
@@ -1537,40 +1775,42 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1537 1775
1538 switch (mtd->oobsize) { 1776 switch (mtd->oobsize) {
1539 case 64: 1777 case 64:
1540 this->autooob = &onenand_oob_64; 1778 this->ecclayout = &onenand_oob_64;
1541 break; 1779 break;
1542 1780
1543 case 32: 1781 case 32:
1544 this->autooob = &onenand_oob_32; 1782 this->ecclayout = &onenand_oob_32;
1545 break; 1783 break;
1546 1784
1547 default: 1785 default:
1548 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", 1786 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1549 mtd->oobsize); 1787 mtd->oobsize);
1550 /* To prevent kernel oops */ 1788 /* To prevent kernel oops */
1551 this->autooob = &onenand_oob_32; 1789 this->ecclayout = &onenand_oob_32;
1552 break; 1790 break;
1553 } 1791 }
1554 1792
1555 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 1793 mtd->ecclayout = this->ecclayout;
1556 1794
1557 /* Fill in remaining MTD driver data */ 1795 /* Fill in remaining MTD driver data */
1558 mtd->type = MTD_NANDFLASH; 1796 mtd->type = MTD_NANDFLASH;
1559 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; 1797 mtd->flags = MTD_CAP_NANDFLASH;
1560 mtd->ecctype = MTD_ECC_SW; 1798 mtd->ecctype = MTD_ECC_SW;
1561 mtd->erase = onenand_erase; 1799 mtd->erase = onenand_erase;
1562 mtd->point = NULL; 1800 mtd->point = NULL;
1563 mtd->unpoint = NULL; 1801 mtd->unpoint = NULL;
1564 mtd->read = onenand_read; 1802 mtd->read = onenand_read;
1565 mtd->write = onenand_write; 1803 mtd->write = onenand_write;
1566 mtd->read_ecc = onenand_read_ecc;
1567 mtd->write_ecc = onenand_write_ecc;
1568 mtd->read_oob = onenand_read_oob; 1804 mtd->read_oob = onenand_read_oob;
1569 mtd->write_oob = onenand_write_oob; 1805 mtd->write_oob = onenand_write_oob;
1570 mtd->readv = NULL; 1806#ifdef CONFIG_MTD_ONENAND_OTP
1571 mtd->readv_ecc = NULL; 1807 mtd->get_fact_prot_info = onenand_get_fact_prot_info;
1572 mtd->writev = onenand_writev; 1808 mtd->read_fact_prot_reg = onenand_read_fact_prot_reg;
1573 mtd->writev_ecc = onenand_writev_ecc; 1809 mtd->get_user_prot_info = onenand_get_user_prot_info;
1810 mtd->read_user_prot_reg = onenand_read_user_prot_reg;
1811 mtd->write_user_prot_reg = onenand_write_user_prot_reg;
1812 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
1813#endif
1574 mtd->sync = onenand_sync; 1814 mtd->sync = onenand_sync;
1575 mtd->lock = NULL; 1815 mtd->lock = NULL;
1576 mtd->unlock = onenand_unlock; 1816 mtd->unlock = onenand_unlock;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 4510d3361eaa..1b00dac3d7d6 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -17,6 +17,9 @@
17#include <linux/mtd/onenand.h> 17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
19 19
20extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
21 size_t *retlen, u_char *buf);
22
20/** 23/**
21 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 24 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
22 * @param buf the buffer to search 25 * @param buf the buffer to search
@@ -87,13 +90,13 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
87 90
88 /* No need to read pages fully, 91 /* No need to read pages fully,
89 * just read required OOB bytes */ 92 * just read required OOB bytes */
90 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs, 93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,
91 readlen, &retlen, &buf[0]); 94 readlen, &retlen, &buf[0]);
92 95
93 if (ret) 96 if (ret)
94 return ret; 97 return ret;
95 98
96 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 99 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
97 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); 100 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
98 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 101 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
99 i >> 1, (unsigned int) from); 102 i >> 1, (unsigned int) from);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index c077d2ec9cdd..5b58523e4d4e 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redboot.c,v 1.19 2005/12/01 10:03:51 dwmw2 Exp $ 2 * $Id: redboot.c,v 1.21 2006/03/30 18:34:37 bjd Exp $
3 * 3 *
4 * Parse RedBoot-style Flash Image System (FIS) tables and 4 * Parse RedBoot-style Flash Image System (FIS) tables and
5 * produce a Linux partition array to match. 5 * produce a Linux partition array to match.
@@ -15,14 +15,14 @@
15 15
16struct fis_image_desc { 16struct fis_image_desc {
17 unsigned char name[16]; // Null terminated name 17 unsigned char name[16]; // Null terminated name
18 unsigned long flash_base; // Address within FLASH of image 18 uint32_t flash_base; // Address within FLASH of image
19 unsigned long mem_base; // Address in memory where it executes 19 uint32_t mem_base; // Address in memory where it executes
20 unsigned long size; // Length of image 20 uint32_t size; // Length of image
21 unsigned long entry_point; // Execution entry point 21 uint32_t entry_point; // Execution entry point
22 unsigned long data_length; // Length of actual data 22 uint32_t data_length; // Length of actual data
23 unsigned char _pad[256-(16+7*sizeof(unsigned long))]; 23 unsigned char _pad[256-(16+7*sizeof(uint32_t))];
24 unsigned long desc_cksum; // Checksum over image descriptor 24 uint32_t desc_cksum; // Checksum over image descriptor
25 unsigned long file_cksum; // Checksum over image data 25 uint32_t file_cksum; // Checksum over image data
26}; 26};
27 27
28struct fis_list { 28struct fis_list {
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index a3e00a4635a5..fa4362fb4dd8 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org> 4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 * 5 *
6 * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $ 6 * $Id: rfd_ftl.c,v 1.8 2006/01/15 12:51:44 sean Exp $
7 * 7 *
8 * This type of flash translation layer (FTL) is used by the Embedded BIOS 8 * This type of flash translation layer (FTL) is used by the Embedded BIOS
9 * by General Software. It is known as the Resident Flash Disk (RFD), see: 9 * by General Software. It is known as the Resident Flash Disk (RFD), see:
@@ -61,6 +61,7 @@ struct block {
61 BLOCK_OK, 61 BLOCK_OK,
62 BLOCK_ERASING, 62 BLOCK_ERASING,
63 BLOCK_ERASED, 63 BLOCK_ERASED,
64 BLOCK_UNUSED,
64 BLOCK_FAILED 65 BLOCK_FAILED
65 } state; 66 } state;
66 int free_sectors; 67 int free_sectors;
@@ -99,10 +100,8 @@ static int build_block_map(struct partition *part, int block_no)
99 block->offset = part->block_size * block_no; 100 block->offset = part->block_size * block_no;
100 101
101 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) { 102 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
102 block->state = BLOCK_ERASED; /* assumption */ 103 block->state = BLOCK_UNUSED;
103 block->free_sectors = part->data_sectors_per_block; 104 return -ENOENT;
104 part->reserved_block = block_no;
105 return 1;
106 } 105 }
107 106
108 block->state = BLOCK_OK; 107 block->state = BLOCK_OK;
@@ -124,7 +123,7 @@ static int build_block_map(struct partition *part, int block_no)
124 entry = 0; 123 entry = 0;
125 124
126 if (entry >= part->sector_count) { 125 if (entry >= part->sector_count) {
127 printk(KERN_NOTICE PREFIX 126 printk(KERN_WARNING PREFIX
128 "'%s': unit #%d: entry %d corrupt, " 127 "'%s': unit #%d: entry %d corrupt, "
129 "sector %d out of range\n", 128 "sector %d out of range\n",
130 part->mbd.mtd->name, block_no, i, entry); 129 part->mbd.mtd->name, block_no, i, entry);
@@ -132,7 +131,7 @@ static int build_block_map(struct partition *part, int block_no)
132 } 131 }
133 132
134 if (part->sector_map[entry] != -1) { 133 if (part->sector_map[entry] != -1) {
135 printk(KERN_NOTICE PREFIX 134 printk(KERN_WARNING PREFIX
136 "'%s': more than one entry for sector %d\n", 135 "'%s': more than one entry for sector %d\n",
137 part->mbd.mtd->name, entry); 136 part->mbd.mtd->name, entry);
138 part->errors = 1; 137 part->errors = 1;
@@ -167,7 +166,7 @@ static int scan_header(struct partition *part)
167 /* each erase block has three bytes header, followed by the map */ 166 /* each erase block has three bytes header, followed by the map */
168 part->header_sectors_per_block = 167 part->header_sectors_per_block =
169 ((HEADER_MAP_OFFSET + sectors_per_block) * 168 ((HEADER_MAP_OFFSET + sectors_per_block) *
170 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE; 169 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
171 170
172 part->data_sectors_per_block = sectors_per_block - 171 part->data_sectors_per_block = sectors_per_block -
173 part->header_sectors_per_block; 172 part->header_sectors_per_block;
@@ -226,7 +225,7 @@ static int scan_header(struct partition *part)
226 } 225 }
227 226
228 if (part->reserved_block == -1) { 227 if (part->reserved_block == -1) {
229 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n", 228 printk(KERN_WARNING PREFIX "'%s': no empty erase unit found\n",
230 part->mbd.mtd->name); 229 part->mbd.mtd->name);
231 230
232 part->errors = 1; 231 part->errors = 1;
@@ -315,7 +314,7 @@ static void erase_callback(struct erase_info *erase)
315 rc = -EIO; 314 rc = -EIO;
316 315
317 if (rc) { 316 if (rc) {
318 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD " 317 printk(KERN_ERR PREFIX "'%s': unable to write RFD "
319 "header at 0x%lx\n", 318 "header at 0x%lx\n",
320 part->mbd.mtd->name, 319 part->mbd.mtd->name,
321 part->blocks[i].offset); 320 part->blocks[i].offset);
@@ -348,7 +347,7 @@ static int erase_block(struct partition *part, int block)
348 rc = part->mbd.mtd->erase(part->mbd.mtd, erase); 347 rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
349 348
350 if (rc) { 349 if (rc) {
351 printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' " 350 printk(KERN_ERR PREFIX "erase of region %x,%x on '%s' "
352 "failed\n", erase->addr, erase->len, 351 "failed\n", erase->addr, erase->len,
353 part->mbd.mtd->name); 352 part->mbd.mtd->name);
354 kfree(erase); 353 kfree(erase);
@@ -383,7 +382,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
383 rc = -EIO; 382 rc = -EIO;
384 383
385 if (rc) { 384 if (rc) {
386 printk(KERN_NOTICE PREFIX "error reading '%s' at " 385 printk(KERN_ERR PREFIX "error reading '%s' at "
387 "0x%lx\n", part->mbd.mtd->name, 386 "0x%lx\n", part->mbd.mtd->name,
388 part->blocks[block_no].offset); 387 part->blocks[block_no].offset);
389 388
@@ -423,7 +422,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
423 rc = -EIO; 422 rc = -EIO;
424 423
425 if (rc) { 424 if (rc) {
426 printk(KERN_NOTICE PREFIX "'%s': Unable to " 425 printk(KERN_ERR PREFIX "'%s': Unable to "
427 "read sector for relocation\n", 426 "read sector for relocation\n",
428 part->mbd.mtd->name); 427 part->mbd.mtd->name);
429 428
@@ -520,7 +519,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
520 * because if we fill that one up first it'll have the most chance of having 519 * because if we fill that one up first it'll have the most chance of having
521 * the least live sectors at reclaim. 520 * the least live sectors at reclaim.
522 */ 521 */
523static int find_free_block(const struct partition *part) 522static int find_free_block(struct partition *part)
524{ 523{
525 int block, stop; 524 int block, stop;
526 525
@@ -533,6 +532,9 @@ static int find_free_block(const struct partition *part)
533 block != part->reserved_block) 532 block != part->reserved_block)
534 return block; 533 return block;
535 534
535 if (part->blocks[block].state == BLOCK_UNUSED)
536 erase_block(part, block);
537
536 if (++block >= part->total_blocks) 538 if (++block >= part->total_blocks)
537 block = 0; 539 block = 0;
538 540
@@ -541,7 +543,7 @@ static int find_free_block(const struct partition *part)
541 return -1; 543 return -1;
542} 544}
543 545
544static int find_writeable_block(struct partition *part, u_long *old_sector) 546static int find_writable_block(struct partition *part, u_long *old_sector)
545{ 547{
546 int rc, block; 548 int rc, block;
547 size_t retlen; 549 size_t retlen;
@@ -570,7 +572,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
570 rc = -EIO; 572 rc = -EIO;
571 573
572 if (rc) { 574 if (rc) {
573 printk(KERN_NOTICE PREFIX "'%s': unable to read header at " 575 printk(KERN_ERR PREFIX "'%s': unable to read header at "
574 "0x%lx\n", part->mbd.mtd->name, 576 "0x%lx\n", part->mbd.mtd->name,
575 part->blocks[block].offset); 577 part->blocks[block].offset);
576 goto err; 578 goto err;
@@ -602,7 +604,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
602 rc = -EIO; 604 rc = -EIO;
603 605
604 if (rc) { 606 if (rc) {
605 printk(KERN_WARNING PREFIX "error writing '%s' at " 607 printk(KERN_ERR PREFIX "error writing '%s' at "
606 "0x%lx\n", part->mbd.mtd->name, addr); 608 "0x%lx\n", part->mbd.mtd->name, addr);
607 if (rc) 609 if (rc)
608 goto err; 610 goto err;
@@ -652,7 +654,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
652 if (part->current_block == -1 || 654 if (part->current_block == -1 ||
653 !part->blocks[part->current_block].free_sectors) { 655 !part->blocks[part->current_block].free_sectors) {
654 656
655 rc = find_writeable_block(part, old_addr); 657 rc = find_writable_block(part, old_addr);
656 if (rc) 658 if (rc)
657 goto err; 659 goto err;
658 } 660 }
@@ -675,7 +677,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
675 rc = -EIO; 677 rc = -EIO;
676 678
677 if (rc) { 679 if (rc) {
678 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", 680 printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
679 part->mbd.mtd->name, addr); 681 part->mbd.mtd->name, addr);
680 if (rc) 682 if (rc)
681 goto err; 683 goto err;
@@ -695,7 +697,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
695 rc = -EIO; 697 rc = -EIO;
696 698
697 if (rc) { 699 if (rc) {
698 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", 700 printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
699 part->mbd.mtd->name, addr); 701 part->mbd.mtd->name, addr);
700 if (rc) 702 if (rc)
701 goto err; 703 goto err;
@@ -776,7 +778,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
776 part->block_size = block_size; 778 part->block_size = block_size;
777 else { 779 else {
778 if (!mtd->erasesize) { 780 if (!mtd->erasesize) {
779 printk(KERN_NOTICE PREFIX "please provide block_size"); 781 printk(KERN_WARNING PREFIX "please provide block_size");
780 return; 782 return;
781 } 783 }
782 else 784 else
@@ -791,8 +793,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
791 if (!(mtd->flags & MTD_WRITEABLE)) 793 if (!(mtd->flags & MTD_WRITEABLE))
792 part->mbd.readonly = 1; 794 part->mbd.readonly = 1;
793 else if (part->errors) { 795 else if (part->errors) {
794 printk(KERN_NOTICE PREFIX "'%s': errors found, " 796 printk(KERN_WARNING PREFIX "'%s': errors found, "
795 "setting read-only", mtd->name); 797 "setting read-only\n", mtd->name);
796 part->mbd.readonly = 1; 798 part->mbd.readonly = 1;
797 } 799 }
798 800
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index f72a4f57905a..bf776125ca38 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -260,15 +260,17 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
260#define RPC_LSA_DEFAULT RPC_LED_TX_RX 260#define RPC_LSA_DEFAULT RPC_LED_TX_RX
261#define RPC_LSB_DEFAULT RPC_LED_100_10 261#define RPC_LSB_DEFAULT RPC_LED_100_10
262 262
263#elif defined(CONFIG_MACH_LPD7A400) || defined(CONFIG_MACH_LPD7A404) 263#elif defined(CONFIG_MACH_LPD79520) \
264 || defined(CONFIG_MACH_LPD7A400) \
265 || defined(CONFIG_MACH_LPD7A404)
264 266
265/* The LPD7A40X_IOBARRIER is necessary to overcome a mismatch between 267/* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the
266 * the way that the CPU handles chip selects and the way that the SMC 268 * way that the CPU handles chip selects and the way that the SMC chip
267 * chip expects the chip select to operate. Refer to 269 * expects the chip select to operate. Refer to
268 * Documentation/arm/Sharp-LH/IOBarrier for details. The read from 270 * Documentation/arm/Sharp-LH/IOBarrier for details. The read from
269 * IOBARRIER is a byte as a least-common denominator of possible 271 * IOBARRIER is a byte, in order that we read the least-common
270 * regions to use as the barrier. It would be wasteful to read 32 272 * denominator. It would be wasteful to read 32 bits from an 8-bit
271 * bits from a byte oriented region. 273 * accessible region.
272 * 274 *
273 * There is no explicit protection against interrupts intervening 275 * There is no explicit protection against interrupts intervening
274 * between the writew and the IOBARRIER. In SMC ISR there is a 276 * between the writew and the IOBARRIER. In SMC ISR there is a
@@ -287,25 +289,35 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
287#define SMC_CAN_USE_16BIT 1 289#define SMC_CAN_USE_16BIT 1
288#define SMC_CAN_USE_32BIT 0 290#define SMC_CAN_USE_32BIT 0
289#define SMC_NOWAIT 0 291#define SMC_NOWAIT 0
290#define LPD7A40X_IOBARRIER readb (IOBARRIER_VIRT) 292#define LPD7X_IOBARRIER readb (IOBARRIER_VIRT)
291 293
292#define SMC_inw(a,r) readw ((void*) ((a) + (r))) 294#define SMC_inw(a,r)\
293#define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) 295 ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; })
294#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) 296#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; })
295 297
296#define SMC_outsw LPD7A40X_SMC_outsw 298#define SMC_insw LPD7_SMC_insw
299static inline void LPD7_SMC_insw (unsigned char* a, int r,
300 unsigned char* p, int l)
301{
302 unsigned short* ps = (unsigned short*) p;
303 while (l-- > 0) {
304 *ps++ = readw (a + r);
305 LPD7X_IOBARRIER;
306 }
307}
297 308
298static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, 309#define SMC_outsw LPD7_SMC_outsw
299 unsigned char* p, int l) 310static inline void LPD7_SMC_outsw (unsigned char* a, int r,
311 unsigned char* p, int l)
300{ 312{
301 unsigned short* ps = (unsigned short*) p; 313 unsigned short* ps = (unsigned short*) p;
302 while (l-- > 0) { 314 while (l-- > 0) {
303 writew (*ps++, a + r); 315 writew (*ps++, a + r);
304 LPD7A40X_IOBARRIER; 316 LPD7X_IOBARRIER;
305 } 317 }
306} 318}
307 319
308#define SMC_INTERRUPT_PREAMBLE LPD7A40X_IOBARRIER 320#define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER
309 321
310#define RPC_LSA_DEFAULT RPC_LED_TX_RX 322#define RPC_LSA_DEFAULT RPC_LED_TX_RX
311#define RPC_LSB_DEFAULT RPC_LED_100_10 323#define RPC_LSB_DEFAULT RPC_LED_100_10
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index f63c387976cf..6c8452ede0e1 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -48,7 +48,7 @@ config PARPORT_PC
48 48
49config PARPORT_SERIAL 49config PARPORT_SERIAL
50 tristate "Multi-IO cards (parallel and serial)" 50 tristate "Multi-IO cards (parallel and serial)"
51 depends on SERIAL_8250 && PARPORT_PC && PCI 51 depends on SERIAL_8250_PCI && PARPORT_PC && PCI
52 help 52 help
53 This adds support for multi-IO PCI cards that have parallel and 53 This adds support for multi-IO PCI cards that have parallel and
54 serial ports. You should say Y or M here. If you say M, the module 54 serial ports. You should say Y or M here. If you say M, the module
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h
index 5e6b1f535f62..0ca1d126ccb6 100644
--- a/drivers/s390/crypto/z90crypt.h
+++ b/drivers/s390/crypto/z90crypt.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/s390/crypto/z90crypt.h 2 * linux/drivers/s390/crypto/z90crypt.h
3 * 3 *
4 * z90crypt 1.3.3 4 * z90crypt 1.3.3 (kernel-private header)
5 * 5 *
6 * Copyright (C) 2001, 2005 IBM Corporation 6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com) 7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
@@ -27,188 +27,7 @@
27#ifndef _Z90CRYPT_H_ 27#ifndef _Z90CRYPT_H_
28#define _Z90CRYPT_H_ 28#define _Z90CRYPT_H_
29 29
30#include <linux/ioctl.h> 30#include <asm/z90crypt.h>
31
32#define z90crypt_VERSION 1
33#define z90crypt_RELEASE 3 // 2 = PCIXCC, 3 = rewrite for coding standards
34#define z90crypt_VARIANT 3 // 3 = CEX2A support
35
36/**
37 * struct ica_rsa_modexpo
38 *
39 * Requirements:
40 * - outputdatalength is at least as large as inputdatalength.
41 * - All key parts are right justified in their fields, padded on
42 * the left with zeroes.
43 * - length(b_key) = inputdatalength
44 * - length(n_modulus) = inputdatalength
45 */
46struct ica_rsa_modexpo {
47 char __user * inputdata;
48 unsigned int inputdatalength;
49 char __user * outputdata;
50 unsigned int outputdatalength;
51 char __user * b_key;
52 char __user * n_modulus;
53};
54
55/**
56 * struct ica_rsa_modexpo_crt
57 *
58 * Requirements:
59 * - inputdatalength is even.
60 * - outputdatalength is at least as large as inputdatalength.
61 * - All key parts are right justified in their fields, padded on
62 * the left with zeroes.
63 * - length(bp_key) = inputdatalength/2 + 8
64 * - length(bq_key) = inputdatalength/2
65 * - length(np_key) = inputdatalength/2 + 8
66 * - length(nq_key) = inputdatalength/2
67 * - length(u_mult_inv) = inputdatalength/2 + 8
68 */
69struct ica_rsa_modexpo_crt {
70 char __user * inputdata;
71 unsigned int inputdatalength;
72 char __user * outputdata;
73 unsigned int outputdatalength;
74 char __user * bp_key;
75 char __user * bq_key;
76 char __user * np_prime;
77 char __user * nq_prime;
78 char __user * u_mult_inv;
79};
80
81#define Z90_IOCTL_MAGIC 'z' // NOTE: Need to allocate from linux folks
82
83/**
84 * Interface notes:
85 *
86 * The ioctl()s which are implemented (along with relevant details)
87 * are:
88 *
89 * ICARSAMODEXPO
90 * Perform an RSA operation using a Modulus-Exponent pair
91 * This takes an ica_rsa_modexpo struct as its arg.
92 *
93 * NOTE: please refer to the comments preceding this structure
94 * for the implementation details for the contents of the
95 * block
96 *
97 * ICARSACRT
98 * Perform an RSA operation using a Chinese-Remainder Theorem key
99 * This takes an ica_rsa_modexpo_crt struct as its arg.
100 *
101 * NOTE: please refer to the comments preceding this structure
102 * for the implementation details for the contents of the
103 * block
104 *
105 * Z90STAT_TOTALCOUNT
106 * Return an integer count of all device types together.
107 *
108 * Z90STAT_PCICACOUNT
109 * Return an integer count of all PCICAs.
110 *
111 * Z90STAT_PCICCCOUNT
112 * Return an integer count of all PCICCs.
113 *
114 * Z90STAT_PCIXCCMCL2COUNT
115 * Return an integer count of all MCL2 PCIXCCs.
116 *
117 * Z90STAT_PCIXCCMCL3COUNT
118 * Return an integer count of all MCL3 PCIXCCs.
119 *
120 * Z90STAT_CEX2CCOUNT
121 * Return an integer count of all CEX2Cs.
122 *
123 * Z90STAT_CEX2ACOUNT
124 * Return an integer count of all CEX2As.
125 *
126 * Z90STAT_REQUESTQ_COUNT
127 * Return an integer count of the number of entries waiting to be
128 * sent to a device.
129 *
130 * Z90STAT_PENDINGQ_COUNT
131 * Return an integer count of the number of entries sent to a
132 * device awaiting the reply.
133 *
134 * Z90STAT_TOTALOPEN_COUNT
135 * Return an integer count of the number of open file handles.
136 *
137 * Z90STAT_DOMAIN_INDEX
138 * Return the integer value of the Cryptographic Domain.
139 *
140 * Z90STAT_STATUS_MASK
141 * Return an 64 element array of unsigned chars for the status of
142 * all devices.
143 * 0x01: PCICA
144 * 0x02: PCICC
145 * 0x03: PCIXCC_MCL2
146 * 0x04: PCIXCC_MCL3
147 * 0x05: CEX2C
148 * 0x06: CEX2A
149 * 0x0d: device is disabled via the proc filesystem
150 *
151 * Z90STAT_QDEPTH_MASK
152 * Return an 64 element array of unsigned chars for the queue
153 * depth of all devices.
154 *
155 * Z90STAT_PERDEV_REQCNT
156 * Return an 64 element array of unsigned integers for the number
157 * of successfully completed requests per device since the device
158 * was detected and made available.
159 *
160 * ICAZ90STATUS (deprecated)
161 * Return some device driver status in a ica_z90_status struct
162 * This takes an ica_z90_status struct as its arg.
163 *
164 * NOTE: this ioctl() is deprecated, and has been replaced with
165 * single ioctl()s for each type of status being requested
166 *
167 * Z90STAT_PCIXCCCOUNT (deprecated)
168 * Return an integer count of all PCIXCCs (MCL2 + MCL3).
169 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
170 * MCL2 PCIXCCs.
171 *
172 * Z90QUIESCE (not recommended)
173 * Quiesce the driver. This is intended to stop all new
174 * requests from being processed. Its use is NOT recommended,
175 * except in circumstances where there is no other way to stop
176 * callers from accessing the driver. Its original use was to
177 * allow the driver to be "drained" of work in preparation for
178 * a system shutdown.
179 *
180 * NOTE: once issued, this ban on new work cannot be undone
181 * except by unloading and reloading the driver.
182 */
183
184/**
185 * Supported ioctl calls
186 */
187#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x05, 0)
188#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x06, 0)
189
190/* DEPRECATED status calls (bound for removal at some point) */
191#define ICAZ90STATUS _IOR(Z90_IOCTL_MAGIC, 0x10, struct ica_z90_status)
192#define Z90STAT_PCIXCCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x43, int)
193
194/* unrelated to ICA callers */
195#define Z90QUIESCE _IO(Z90_IOCTL_MAGIC, 0x11)
196
197/* New status calls */
198#define Z90STAT_TOTALCOUNT _IOR(Z90_IOCTL_MAGIC, 0x40, int)
199#define Z90STAT_PCICACOUNT _IOR(Z90_IOCTL_MAGIC, 0x41, int)
200#define Z90STAT_PCICCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x42, int)
201#define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int)
202#define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int)
203#define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int)
204#define Z90STAT_CEX2ACOUNT _IOR(Z90_IOCTL_MAGIC, 0x4e, int)
205#define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int)
206#define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int)
207#define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
208#define Z90STAT_DOMAIN_INDEX _IOR(Z90_IOCTL_MAGIC, 0x47, int)
209#define Z90STAT_STATUS_MASK _IOR(Z90_IOCTL_MAGIC, 0x48, char[64])
210#define Z90STAT_QDEPTH_MASK _IOR(Z90_IOCTL_MAGIC, 0x49, char[64])
211#define Z90STAT_PERDEV_REQCNT _IOR(Z90_IOCTL_MAGIC, 0x4a, int[64])
212 31
213/** 32/**
214 * local errno definitions 33 * local errno definitions
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index f5aac92fb798..53c2465bad2d 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1365,7 +1365,7 @@ static inline void s3c2410_serial_exit(void)
1365 1365
1366#endif /* CONFIG_CPU_S3C2410 */ 1366#endif /* CONFIG_CPU_S3C2410 */
1367 1367
1368#ifdef CONFIG_CPU_S3C2440 1368#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
1369 1369
1370static int s3c2440_serial_setsource(struct uart_port *port, 1370static int s3c2440_serial_setsource(struct uart_port *port,
1371 struct s3c24xx_uart_clksrc *clk) 1371 struct s3c24xx_uart_clksrc *clk)
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index aa521b8e0d4e..776d4ff06084 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -145,14 +145,15 @@ lh7a40xuart_rx_chars (struct uart_port* port)
145{ 145{
146 struct tty_struct* tty = port->info->tty; 146 struct tty_struct* tty = port->info->tty;
147 int cbRxMax = 256; /* (Gross) limit on receive */ 147 int cbRxMax = 256; /* (Gross) limit on receive */
148 unsigned int data, flag;/* Received data and status */ 148 unsigned int data; /* Received data and status */
149 unsigned int flag;
149 150
150 while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { 151 while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) {
151 data = UR (port, UART_R_DATA); 152 data = UR (port, UART_R_DATA);
152 flag = TTY_NORMAL; 153 flag = TTY_NORMAL;
153 ++port->icount.rx; 154 ++port->icount.rx;
154 155
155 if (unlikely(data & RxError)) { /* Quick check, short-circuit */ 156 if (unlikely(data & RxError)) {
156 if (data & RxBreak) { 157 if (data & RxBreak) {
157 data &= ~(RxFramingError | RxParityError); 158 data &= ~(RxFramingError | RxParityError);
158 ++port->icount.brk; 159 ++port->icount.brk;
@@ -303,7 +304,7 @@ static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl)
303 /* Note, kernel appears to be setting DTR and RTS on console. */ 304 /* Note, kernel appears to be setting DTR and RTS on console. */
304 305
305 /* *** FIXME: this deserves more work. There's some work in 306 /* *** FIXME: this deserves more work. There's some work in
306 tracing all of the IO pins. */ 307 tracing all of the IO pins. */
307#if 0 308#if 0
308 if( port->mapbase == UART1_PHYS) { 309 if( port->mapbase == UART1_PHYS) {
309 gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS); 310 gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS);
@@ -662,9 +663,13 @@ static int __init lh7a40xuart_init(void)
662 if (ret == 0) { 663 if (ret == 0) {
663 int i; 664 int i;
664 665
665 for (i = 0; i < DEV_NR; i++) 666 for (i = 0; i < DEV_NR; i++) {
667 /* UART3, when used, requires GPIO pin reallocation */
668 if (lh7a40x_ports[i].port.mapbase == UART3_PHYS)
669 GPIO_PINMUX |= 1<<3;
666 uart_add_one_port (&lh7a40x_reg, 670 uart_add_one_port (&lh7a40x_reg,
667 &lh7a40x_ports[i].port); 671 &lh7a40x_ports[i].port);
672 }
668 } 673 }
669 return ret; 674 return ret;
670} 675}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5641498725d0..5a2840aeb547 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -167,6 +167,69 @@ config FB_ARMCLCD
167 here and read <file:Documentation/modules.txt>. The module 167 here and read <file:Documentation/modules.txt>. The module
168 will be called amba-clcd. 168 will be called amba-clcd.
169 169
170choice
171
172 depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X)
173 prompt "LCD Panel"
174 default FB_ARMCLCD_SHARP_LQ035Q7DB02
175
176config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
177 bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
178 help
179 This is an implementation of the Sharp LQ035Q7DB02, a 3.5"
180 color QVGA, HRTFT panel. The LogicPD device includes an
181 an integrated HRTFT controller IC.
182 The native resolution is 240x320.
183
184config FB_ARMCLCD_SHARP_LQ057Q3DC02
185 bool "LogicPD LCD 5.7\" QVGA"
186 help
187 This is an implementation of the Sharp LQ057Q3DC02, a 5.7"
188 color QVGA, TFT panel. The LogicPD device includes an
189 The native resolution is 320x240.
190
191config FB_ARMCLCD_SHARP_LQ64D343
192 bool "LogicPD LCD 6.4\" VGA"
193 help
194 This is an implementation of the Sharp LQ64D343, a 6.4"
195 color VGA, TFT panel. The LogicPD device includes an
196 The native resolution is 640x480.
197
198config FB_ARMCLCD_SHARP_LQ10D368
199 bool "LogicPD LCD 10.4\" VGA"
200 help
201 This is an implementation of the Sharp LQ10D368, a 10.4"
202 color VGA, TFT panel. The LogicPD device includes an
203 The native resolution is 640x480.
204
205
206config FB_ARMCLCD_SHARP_LQ121S1DG41
207 bool "LogicPD LCD 12.1\" SVGA"
208 help
209 This is an implementation of the Sharp LQ121S1DG41, a 12.1"
210 color SVGA, TFT panel. The LogicPD device includes an
211 The native resolution is 800x600.
212
213 This panel requires a clock rate may be an integer fraction
214 of the base LCDCLK frequency. The driver will select the
215 highest frequency available that is lower than the maximum
216 allowed. The panel may flicker if the clock rate is
217 slower than the recommended minimum.
218
219config FB_ARMCLCD_AUO_A070VW01_WIDE
220 bool "AU Optronics A070VW01 LCD 7.0\" WIDE"
221 help
222 This is an implementation of the AU Optronics, a 7.0"
223 WIDE Color. The native resolution is 234x480.
224
225config FB_ARMCLCD_HITACHI
226 bool "Hitachi Wide Screen 800x480"
227 help
228 This is an implementation of the Hitachi 800x480.
229
230endchoice
231
232
170config FB_ACORN 233config FB_ACORN
171 bool "Acorn VIDC support" 234 bool "Acorn VIDC support"
172 depends on (FB = y) && ARM && (ARCH_ACORN || ARCH_CLPS7500) 235 depends on (FB = y) && ARM && (ARCH_ACORN || ARCH_CLPS7500)
diff --git a/fs/Kconfig b/fs/Kconfig
index f9b5842c8d2d..20f9b557732d 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -393,18 +393,30 @@ config INOTIFY
393 bool "Inotify file change notification support" 393 bool "Inotify file change notification support"
394 default y 394 default y
395 ---help--- 395 ---help---
396 Say Y here to enable inotify support and the associated system 396 Say Y here to enable inotify support. Inotify is a file change
397 calls. Inotify is a file change notification system and a 397 notification system and a replacement for dnotify. Inotify fixes
398 replacement for dnotify. Inotify fixes numerous shortcomings in 398 numerous shortcomings in dnotify and introduces several new features
399 dnotify and introduces several new features. It allows monitoring 399 including multiple file events, one-shot support, and unmount
400 of both files and directories via a single open fd. Other features
401 include multiple file events, one-shot support, and unmount
402 notification. 400 notification.
403 401
404 For more information, see Documentation/filesystems/inotify.txt 402 For more information, see Documentation/filesystems/inotify.txt
405 403
406 If unsure, say Y. 404 If unsure, say Y.
407 405
406config INOTIFY_USER
407 bool "Inotify support for userspace"
408 depends on INOTIFY
409 default y
410 ---help---
411 Say Y here to enable inotify support for userspace, including the
412 associated system calls. Inotify allows monitoring of both files and
413 directories via a single open fd. Events are read from the file
414 descriptor, which is also select()- and poll()-able.
415
416 For more information, see Documentation/filesystems/inotify.txt
417
418 If unsure, say Y.
419
408config QUOTA 420config QUOTA
409 bool "Quota support" 421 bool "Quota support"
410 help 422 help
@@ -1101,6 +1113,44 @@ config JFFS2_SUMMARY
1101 1113
1102 If unsure, say 'N'. 1114 If unsure, say 'N'.
1103 1115
1116config JFFS2_FS_XATTR
1117 bool "JFFS2 XATTR support (EXPERIMENTAL)"
1118 depends on JFFS2_FS && EXPERIMENTAL && !JFFS2_FS_WRITEBUFFER
1119 default n
1120 help
1121 Extended attributes are name:value pairs associated with inodes by
1122 the kernel or by users (see the attr(5) manual page, or visit
1123 <http://acl.bestbits.at/> for details).
1124
1125 If unsure, say N.
1126
1127config JFFS2_FS_POSIX_ACL
1128 bool "JFFS2 POSIX Access Control Lists"
1129 depends on JFFS2_FS_XATTR
1130 default y
1131 select FS_POSIX_ACL
1132 help
1133 Posix Access Control Lists (ACLs) support permissions for users and
1134 groups beyond the owner/group/world scheme.
1135
1136 To learn more about Access Control Lists, visit the Posix ACLs for
1137 Linux website <http://acl.bestbits.at/>.
1138
1139 If you don't know what Access Control Lists are, say N
1140
1141config JFFS2_FS_SECURITY
1142 bool "JFFS2 Security Labels"
1143 depends on JFFS2_FS_XATTR
1144 default y
1145 help
1146 Security labels support alternative access control models
1147 implemented by security modules like SELinux. This option
1148 enables an extended attribute handler for file security
1149 labels in the jffs2 filesystem.
1150
1151 If you are not using a security module that requires using
1152 extended attributes for file security labels, say N.
1153
1104config JFFS2_COMPRESSION_OPTIONS 1154config JFFS2_COMPRESSION_OPTIONS
1105 bool "Advanced compression options for JFFS2" 1155 bool "Advanced compression options for JFFS2"
1106 depends on JFFS2_FS 1156 depends on JFFS2_FS
diff --git a/fs/Makefile b/fs/Makefile
index 078d3d1191a5..d0ea6bfccf29 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -13,6 +13,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
13 ioprio.o pnode.o drop_caches.o splice.o sync.o 13 ioprio.o pnode.o drop_caches.o splice.o sync.o
14 14
15obj-$(CONFIG_INOTIFY) += inotify.o 15obj-$(CONFIG_INOTIFY) += inotify.o
16obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
16obj-$(CONFIG_EPOLL) += eventpoll.o 17obj-$(CONFIG_EPOLL) += eventpoll.o
17obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o 18obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
18 19
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 1b4491cdd115..2695337d4d64 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -337,20 +337,20 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1,
337/* Special initialization for the rb-tree node to detect linkage */ 337/* Special initialization for the rb-tree node to detect linkage */
338static inline void ep_rb_initnode(struct rb_node *n) 338static inline void ep_rb_initnode(struct rb_node *n)
339{ 339{
340 n->rb_parent = n; 340 rb_set_parent(n, n);
341} 341}
342 342
343/* Removes a node from the rb-tree and marks it for a fast is-linked check */ 343/* Removes a node from the rb-tree and marks it for a fast is-linked check */
344static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r) 344static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r)
345{ 345{
346 rb_erase(n, r); 346 rb_erase(n, r);
347 n->rb_parent = n; 347 rb_set_parent(n, n);
348} 348}
349 349
350/* Fast check to verify that the item is linked to the main rb-tree */ 350/* Fast check to verify that the item is linked to the main rb-tree */
351static inline int ep_rb_linked(struct rb_node *n) 351static inline int ep_rb_linked(struct rb_node *n)
352{ 352{
353 return n->rb_parent != n; 353 return rb_parent(n) != n;
354} 354}
355 355
356/* 356/*
diff --git a/fs/exec.c b/fs/exec.c
index 3a79d97ac234..d07858c0b7c4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -49,6 +49,7 @@
49#include <linux/rmap.h> 49#include <linux/rmap.h>
50#include <linux/acct.h> 50#include <linux/acct.h>
51#include <linux/cn_proc.h> 51#include <linux/cn_proc.h>
52#include <linux/audit.h>
52 53
53#include <asm/uaccess.h> 54#include <asm/uaccess.h>
54#include <asm/mmu_context.h> 55#include <asm/mmu_context.h>
@@ -1085,6 +1086,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1085 /* kernel module loader fixup */ 1086 /* kernel module loader fixup */
1086 /* so we don't try to load run modprobe in kernel space. */ 1087 /* so we don't try to load run modprobe in kernel space. */
1087 set_fs(USER_DS); 1088 set_fs(USER_DS);
1089
1090 retval = audit_bprm(bprm);
1091 if (retval)
1092 return retval;
1093
1088 retval = -ENOENT; 1094 retval = -ENOENT;
1089 for (try=0; try<2; try++) { 1095 for (try=0; try<2; try++) {
1090 read_lock(&binfmt_lock); 1096 read_lock(&binfmt_lock);
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index f37528ed222e..fbb0d4ed07d4 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -284,7 +284,7 @@ static void free_rb_tree_fname(struct rb_root *root)
284 * beginning of the loop and try to free the parent 284 * beginning of the loop and try to free the parent
285 * node. 285 * node.
286 */ 286 */
287 parent = n->rb_parent; 287 parent = rb_parent(n);
288 fname = rb_entry(n, struct fname, rb_hash); 288 fname = rb_entry(n, struct fname, rb_hash);
289 while (fname) { 289 while (fname) {
290 struct fname * old = fname; 290 struct fname * old = fname;
diff --git a/fs/inotify.c b/fs/inotify.c
index 732ec4bd5774..723836a1f718 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -5,7 +5,10 @@
5 * John McCutchan <ttb@tentacle.dhs.org> 5 * John McCutchan <ttb@tentacle.dhs.org>
6 * Robert Love <rml@novell.com> 6 * Robert Love <rml@novell.com>
7 * 7 *
8 * Kernel API added by: Amy Griffis <amy.griffis@hp.com>
9 *
8 * Copyright (C) 2005 John McCutchan 10 * Copyright (C) 2005 John McCutchan
11 * Copyright 2006 Hewlett-Packard Development Company, L.P.
9 * 12 *
10 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 14 * under the terms of the GNU General Public License as published by the
@@ -20,35 +23,17 @@
20 23
21#include <linux/module.h> 24#include <linux/module.h>
22#include <linux/kernel.h> 25#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/spinlock.h> 26#include <linux/spinlock.h>
25#include <linux/idr.h> 27#include <linux/idr.h>
26#include <linux/slab.h> 28#include <linux/slab.h>
27#include <linux/fs.h> 29#include <linux/fs.h>
28#include <linux/file.h>
29#include <linux/mount.h>
30#include <linux/namei.h>
31#include <linux/poll.h>
32#include <linux/init.h> 30#include <linux/init.h>
33#include <linux/list.h> 31#include <linux/list.h>
34#include <linux/writeback.h> 32#include <linux/writeback.h>
35#include <linux/inotify.h> 33#include <linux/inotify.h>
36#include <linux/syscalls.h>
37
38#include <asm/ioctls.h>
39 34
40static atomic_t inotify_cookie; 35static atomic_t inotify_cookie;
41 36
42static kmem_cache_t *watch_cachep __read_mostly;
43static kmem_cache_t *event_cachep __read_mostly;
44
45static struct vfsmount *inotify_mnt __read_mostly;
46
47/* these are configurable via /proc/sys/fs/inotify/ */
48int inotify_max_user_instances __read_mostly;
49int inotify_max_user_watches __read_mostly;
50int inotify_max_queued_events __read_mostly;
51
52/* 37/*
53 * Lock ordering: 38 * Lock ordering:
54 * 39 *
@@ -56,327 +41,108 @@ int inotify_max_queued_events __read_mostly;
56 * iprune_mutex (synchronize shrink_icache_memory()) 41 * iprune_mutex (synchronize shrink_icache_memory())
57 * inode_lock (protects the super_block->s_inodes list) 42 * inode_lock (protects the super_block->s_inodes list)
58 * inode->inotify_mutex (protects inode->inotify_watches and watches->i_list) 43 * inode->inotify_mutex (protects inode->inotify_watches and watches->i_list)
59 * inotify_dev->mutex (protects inotify_device and watches->d_list) 44 * inotify_handle->mutex (protects inotify_handle and watches->h_list)
45 *
46 * The inode->inotify_mutex and inotify_handle->mutex and held during execution
47 * of a caller's event handler. Thus, the caller must not hold any locks
48 * taken in their event handler while calling any of the published inotify
49 * interfaces.
60 */ 50 */
61 51
62/* 52/*
63 * Lifetimes of the three main data structures--inotify_device, inode, and 53 * Lifetimes of the three main data structures--inotify_handle, inode, and
64 * inotify_watch--are managed by reference count. 54 * inotify_watch--are managed by reference count.
65 * 55 *
66 * inotify_device: Lifetime is from inotify_init() until release. Additional 56 * inotify_handle: Lifetime is from inotify_init() to inotify_destroy().
67 * references can bump the count via get_inotify_dev() and drop the count via 57 * Additional references can bump the count via get_inotify_handle() and drop
68 * put_inotify_dev(). 58 * the count via put_inotify_handle().
69 * 59 *
70 * inotify_watch: Lifetime is from create_watch() to destory_watch(). 60 * inotify_watch: for inotify's purposes, lifetime is from inotify_add_watch()
71 * Additional references can bump the count via get_inotify_watch() and drop 61 * to remove_watch_no_event(). Additional references can bump the count via
72 * the count via put_inotify_watch(). 62 * get_inotify_watch() and drop the count via put_inotify_watch(). The caller
63 * is reponsible for the final put after receiving IN_IGNORED, or when using
64 * IN_ONESHOT after receiving the first event. Inotify does the final put if
65 * inotify_destroy() is called.
73 * 66 *
74 * inode: Pinned so long as the inode is associated with a watch, from 67 * inode: Pinned so long as the inode is associated with a watch, from
75 * create_watch() to put_inotify_watch(). 68 * inotify_add_watch() to the final put_inotify_watch().
76 */ 69 */
77 70
78/* 71/*
79 * struct inotify_device - represents an inotify instance 72 * struct inotify_handle - represents an inotify instance
80 * 73 *
81 * This structure is protected by the mutex 'mutex'. 74 * This structure is protected by the mutex 'mutex'.
82 */ 75 */
83struct inotify_device { 76struct inotify_handle {
84 wait_queue_head_t wq; /* wait queue for i/o */
85 struct idr idr; /* idr mapping wd -> watch */ 77 struct idr idr; /* idr mapping wd -> watch */
86 struct mutex mutex; /* protects this bad boy */ 78 struct mutex mutex; /* protects this bad boy */
87 struct list_head events; /* list of queued events */
88 struct list_head watches; /* list of watches */ 79 struct list_head watches; /* list of watches */
89 atomic_t count; /* reference count */ 80 atomic_t count; /* reference count */
90 struct user_struct *user; /* user who opened this dev */
91 unsigned int queue_size; /* size of the queue (bytes) */
92 unsigned int event_count; /* number of pending events */
93 unsigned int max_events; /* maximum number of events */
94 u32 last_wd; /* the last wd allocated */ 81 u32 last_wd; /* the last wd allocated */
82 const struct inotify_operations *in_ops; /* inotify caller operations */
95}; 83};
96 84
97/* 85static inline void get_inotify_handle(struct inotify_handle *ih)
98 * struct inotify_kernel_event - An inotify event, originating from a watch and
99 * queued for user-space. A list of these is attached to each instance of the
100 * device. In read(), this list is walked and all events that can fit in the
101 * buffer are returned.
102 *
103 * Protected by dev->mutex of the device in which we are queued.
104 */
105struct inotify_kernel_event {
106 struct inotify_event event; /* the user-space event */
107 struct list_head list; /* entry in inotify_device's list */
108 char *name; /* filename, if any */
109};
110
111/*
112 * struct inotify_watch - represents a watch request on a specific inode
113 *
114 * d_list is protected by dev->mutex of the associated watch->dev.
115 * i_list and mask are protected by inode->inotify_mutex of the associated inode.
116 * dev, inode, and wd are never written to once the watch is created.
117 */
118struct inotify_watch {
119 struct list_head d_list; /* entry in inotify_device's list */
120 struct list_head i_list; /* entry in inode's list */
121 atomic_t count; /* reference count */
122 struct inotify_device *dev; /* associated device */
123 struct inode *inode; /* associated inode */
124 s32 wd; /* watch descriptor */
125 u32 mask; /* event mask for this watch */
126};
127
128#ifdef CONFIG_SYSCTL
129
130#include <linux/sysctl.h>
131
132static int zero;
133
134ctl_table inotify_table[] = {
135 {
136 .ctl_name = INOTIFY_MAX_USER_INSTANCES,
137 .procname = "max_user_instances",
138 .data = &inotify_max_user_instances,
139 .maxlen = sizeof(int),
140 .mode = 0644,
141 .proc_handler = &proc_dointvec_minmax,
142 .strategy = &sysctl_intvec,
143 .extra1 = &zero,
144 },
145 {
146 .ctl_name = INOTIFY_MAX_USER_WATCHES,
147 .procname = "max_user_watches",
148 .data = &inotify_max_user_watches,
149 .maxlen = sizeof(int),
150 .mode = 0644,
151 .proc_handler = &proc_dointvec_minmax,
152 .strategy = &sysctl_intvec,
153 .extra1 = &zero,
154 },
155 {
156 .ctl_name = INOTIFY_MAX_QUEUED_EVENTS,
157 .procname = "max_queued_events",
158 .data = &inotify_max_queued_events,
159 .maxlen = sizeof(int),
160 .mode = 0644,
161 .proc_handler = &proc_dointvec_minmax,
162 .strategy = &sysctl_intvec,
163 .extra1 = &zero
164 },
165 { .ctl_name = 0 }
166};
167#endif /* CONFIG_SYSCTL */
168
169static inline void get_inotify_dev(struct inotify_device *dev)
170{ 86{
171 atomic_inc(&dev->count); 87 atomic_inc(&ih->count);
172} 88}
173 89
174static inline void put_inotify_dev(struct inotify_device *dev) 90static inline void put_inotify_handle(struct inotify_handle *ih)
175{ 91{
176 if (atomic_dec_and_test(&dev->count)) { 92 if (atomic_dec_and_test(&ih->count)) {
177 atomic_dec(&dev->user->inotify_devs); 93 idr_destroy(&ih->idr);
178 free_uid(dev->user); 94 kfree(ih);
179 idr_destroy(&dev->idr);
180 kfree(dev);
181 } 95 }
182} 96}
183 97
184static inline void get_inotify_watch(struct inotify_watch *watch) 98/**
99 * get_inotify_watch - grab a reference to an inotify_watch
100 * @watch: watch to grab
101 */
102void get_inotify_watch(struct inotify_watch *watch)
185{ 103{
186 atomic_inc(&watch->count); 104 atomic_inc(&watch->count);
187} 105}
106EXPORT_SYMBOL_GPL(get_inotify_watch);
188 107
189/* 108/**
190 * put_inotify_watch - decrements the ref count on a given watch. cleans up 109 * put_inotify_watch - decrements the ref count on a given watch. cleans up
191 * the watch and its references if the count reaches zero. 110 * watch references if the count reaches zero. inotify_watch is freed by
111 * inotify callers via the destroy_watch() op.
112 * @watch: watch to release
192 */ 113 */
193static inline void put_inotify_watch(struct inotify_watch *watch) 114void put_inotify_watch(struct inotify_watch *watch)
194{ 115{
195 if (atomic_dec_and_test(&watch->count)) { 116 if (atomic_dec_and_test(&watch->count)) {
196 put_inotify_dev(watch->dev); 117 struct inotify_handle *ih = watch->ih;
197 iput(watch->inode);
198 kmem_cache_free(watch_cachep, watch);
199 }
200}
201
202/*
203 * kernel_event - create a new kernel event with the given parameters
204 *
205 * This function can sleep.
206 */
207static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
208 const char *name)
209{
210 struct inotify_kernel_event *kevent;
211
212 kevent = kmem_cache_alloc(event_cachep, GFP_KERNEL);
213 if (unlikely(!kevent))
214 return NULL;
215
216 /* we hand this out to user-space, so zero it just in case */
217 memset(&kevent->event, 0, sizeof(struct inotify_event));
218
219 kevent->event.wd = wd;
220 kevent->event.mask = mask;
221 kevent->event.cookie = cookie;
222
223 INIT_LIST_HEAD(&kevent->list);
224
225 if (name) {
226 size_t len, rem, event_size = sizeof(struct inotify_event);
227
228 /*
229 * We need to pad the filename so as to properly align an
230 * array of inotify_event structures. Because the structure is
231 * small and the common case is a small filename, we just round
232 * up to the next multiple of the structure's sizeof. This is
233 * simple and safe for all architectures.
234 */
235 len = strlen(name) + 1;
236 rem = event_size - len;
237 if (len > event_size) {
238 rem = event_size - (len % event_size);
239 if (len % event_size == 0)
240 rem = 0;
241 }
242
243 kevent->name = kmalloc(len + rem, GFP_KERNEL);
244 if (unlikely(!kevent->name)) {
245 kmem_cache_free(event_cachep, kevent);
246 return NULL;
247 }
248 memcpy(kevent->name, name, len);
249 if (rem)
250 memset(kevent->name + len, 0, rem);
251 kevent->event.len = len + rem;
252 } else {
253 kevent->event.len = 0;
254 kevent->name = NULL;
255 }
256
257 return kevent;
258}
259
260/*
261 * inotify_dev_get_event - return the next event in the given dev's queue
262 *
263 * Caller must hold dev->mutex.
264 */
265static inline struct inotify_kernel_event *
266inotify_dev_get_event(struct inotify_device *dev)
267{
268 return list_entry(dev->events.next, struct inotify_kernel_event, list);
269}
270
271/*
272 * inotify_dev_queue_event - add a new event to the given device
273 *
274 * Caller must hold dev->mutex. Can sleep (calls kernel_event()).
275 */
276static void inotify_dev_queue_event(struct inotify_device *dev,
277 struct inotify_watch *watch, u32 mask,
278 u32 cookie, const char *name)
279{
280 struct inotify_kernel_event *kevent, *last;
281
282 /* coalescing: drop this event if it is a dupe of the previous */
283 last = inotify_dev_get_event(dev);
284 if (last && last->event.mask == mask && last->event.wd == watch->wd &&
285 last->event.cookie == cookie) {
286 const char *lastname = last->name;
287
288 if (!name && !lastname)
289 return;
290 if (name && lastname && !strcmp(lastname, name))
291 return;
292 }
293
294 /* the queue overflowed and we already sent the Q_OVERFLOW event */
295 if (unlikely(dev->event_count > dev->max_events))
296 return;
297
298 /* if the queue overflows, we need to notify user space */
299 if (unlikely(dev->event_count == dev->max_events))
300 kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL);
301 else
302 kevent = kernel_event(watch->wd, mask, cookie, name);
303
304 if (unlikely(!kevent))
305 return;
306
307 /* queue the event and wake up anyone waiting */
308 dev->event_count++;
309 dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
310 list_add_tail(&kevent->list, &dev->events);
311 wake_up_interruptible(&dev->wq);
312}
313
314/*
315 * remove_kevent - cleans up and ultimately frees the given kevent
316 *
317 * Caller must hold dev->mutex.
318 */
319static void remove_kevent(struct inotify_device *dev,
320 struct inotify_kernel_event *kevent)
321{
322 list_del(&kevent->list);
323
324 dev->event_count--;
325 dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len;
326
327 kfree(kevent->name);
328 kmem_cache_free(event_cachep, kevent);
329}
330 118
331/* 119 iput(watch->inode);
332 * inotify_dev_event_dequeue - destroy an event on the given device 120 ih->in_ops->destroy_watch(watch);
333 * 121 put_inotify_handle(ih);
334 * Caller must hold dev->mutex.
335 */
336static void inotify_dev_event_dequeue(struct inotify_device *dev)
337{
338 if (!list_empty(&dev->events)) {
339 struct inotify_kernel_event *kevent;
340 kevent = inotify_dev_get_event(dev);
341 remove_kevent(dev, kevent);
342 } 122 }
343} 123}
124EXPORT_SYMBOL_GPL(put_inotify_watch);
344 125
345/* 126/*
346 * inotify_dev_get_wd - returns the next WD for use by the given dev 127 * inotify_handle_get_wd - returns the next WD for use by the given handle
347 * 128 *
348 * Callers must hold dev->mutex. This function can sleep. 129 * Callers must hold ih->mutex. This function can sleep.
349 */ 130 */
350static int inotify_dev_get_wd(struct inotify_device *dev, 131static int inotify_handle_get_wd(struct inotify_handle *ih,
351 struct inotify_watch *watch) 132 struct inotify_watch *watch)
352{ 133{
353 int ret; 134 int ret;
354 135
355 do { 136 do {
356 if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) 137 if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL)))
357 return -ENOSPC; 138 return -ENOSPC;
358 ret = idr_get_new_above(&dev->idr, watch, dev->last_wd+1, &watch->wd); 139 ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd);
359 } while (ret == -EAGAIN); 140 } while (ret == -EAGAIN);
360 141
361 return ret; 142 if (likely(!ret))
362} 143 ih->last_wd = watch->wd;
363 144
364/* 145 return ret;
365 * find_inode - resolve a user-given path to a specific inode and return a nd
366 */
367static int find_inode(const char __user *dirname, struct nameidata *nd,
368 unsigned flags)
369{
370 int error;
371
372 error = __user_walk(dirname, flags, nd);
373 if (error)
374 return error;
375 /* you can only watch an inode if you have read permissions on it */
376 error = vfs_permission(nd, MAY_READ);
377 if (error)
378 path_release(nd);
379 return error;
380} 146}
381 147
382/* 148/*
@@ -422,67 +188,18 @@ static void set_dentry_child_flags(struct inode *inode, int watched)
422} 188}
423 189
424/* 190/*
425 * create_watch - creates a watch on the given device. 191 * inotify_find_handle - find the watch associated with the given inode and
426 * 192 * handle
427 * Callers must hold dev->mutex. Calls inotify_dev_get_wd() so may sleep.
428 * Both 'dev' and 'inode' (by way of nameidata) need to be pinned.
429 */
430static struct inotify_watch *create_watch(struct inotify_device *dev,
431 u32 mask, struct inode *inode)
432{
433 struct inotify_watch *watch;
434 int ret;
435
436 if (atomic_read(&dev->user->inotify_watches) >=
437 inotify_max_user_watches)
438 return ERR_PTR(-ENOSPC);
439
440 watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL);
441 if (unlikely(!watch))
442 return ERR_PTR(-ENOMEM);
443
444 ret = inotify_dev_get_wd(dev, watch);
445 if (unlikely(ret)) {
446 kmem_cache_free(watch_cachep, watch);
447 return ERR_PTR(ret);
448 }
449
450 dev->last_wd = watch->wd;
451 watch->mask = mask;
452 atomic_set(&watch->count, 0);
453 INIT_LIST_HEAD(&watch->d_list);
454 INIT_LIST_HEAD(&watch->i_list);
455
456 /* save a reference to device and bump the count to make it official */
457 get_inotify_dev(dev);
458 watch->dev = dev;
459
460 /*
461 * Save a reference to the inode and bump the ref count to make it
462 * official. We hold a reference to nameidata, which makes this safe.
463 */
464 watch->inode = igrab(inode);
465
466 /* bump our own count, corresponding to our entry in dev->watches */
467 get_inotify_watch(watch);
468
469 atomic_inc(&dev->user->inotify_watches);
470
471 return watch;
472}
473
474/*
475 * inotify_find_dev - find the watch associated with the given inode and dev
476 * 193 *
477 * Callers must hold inode->inotify_mutex. 194 * Callers must hold inode->inotify_mutex.
478 */ 195 */
479static struct inotify_watch *inode_find_dev(struct inode *inode, 196static struct inotify_watch *inode_find_handle(struct inode *inode,
480 struct inotify_device *dev) 197 struct inotify_handle *ih)
481{ 198{
482 struct inotify_watch *watch; 199 struct inotify_watch *watch;
483 200
484 list_for_each_entry(watch, &inode->inotify_watches, i_list) { 201 list_for_each_entry(watch, &inode->inotify_watches, i_list) {
485 if (watch->dev == dev) 202 if (watch->ih == ih)
486 return watch; 203 return watch;
487 } 204 }
488 205
@@ -490,40 +207,40 @@ static struct inotify_watch *inode_find_dev(struct inode *inode,
490} 207}
491 208
492/* 209/*
493 * remove_watch_no_event - remove_watch() without the IN_IGNORED event. 210 * remove_watch_no_event - remove watch without the IN_IGNORED event.
211 *
212 * Callers must hold both inode->inotify_mutex and ih->mutex.
494 */ 213 */
495static void remove_watch_no_event(struct inotify_watch *watch, 214static void remove_watch_no_event(struct inotify_watch *watch,
496 struct inotify_device *dev) 215 struct inotify_handle *ih)
497{ 216{
498 list_del(&watch->i_list); 217 list_del(&watch->i_list);
499 list_del(&watch->d_list); 218 list_del(&watch->h_list);
500 219
501 if (!inotify_inode_watched(watch->inode)) 220 if (!inotify_inode_watched(watch->inode))
502 set_dentry_child_flags(watch->inode, 0); 221 set_dentry_child_flags(watch->inode, 0);
503 222
504 atomic_dec(&dev->user->inotify_watches); 223 idr_remove(&ih->idr, watch->wd);
505 idr_remove(&dev->idr, watch->wd);
506 put_inotify_watch(watch);
507} 224}
508 225
509/* 226/**
510 * remove_watch - Remove a watch from both the device and the inode. Sends 227 * inotify_remove_watch_locked - Remove a watch from both the handle and the
511 * the IN_IGNORED event to the given device signifying that the inode is no 228 * inode. Sends the IN_IGNORED event signifying that the inode is no longer
512 * longer watched. 229 * watched. May be invoked from a caller's event handler.
513 * 230 * @ih: inotify handle associated with watch
514 * Callers must hold both inode->inotify_mutex and dev->mutex. We drop a 231 * @watch: watch to remove
515 * reference to the inode before returning.
516 * 232 *
517 * The inode is not iput() so as to remain atomic. If the inode needs to be 233 * Callers must hold both inode->inotify_mutex and ih->mutex.
518 * iput(), the call returns one. Otherwise, it returns zero.
519 */ 234 */
520static void remove_watch(struct inotify_watch *watch,struct inotify_device *dev) 235void inotify_remove_watch_locked(struct inotify_handle *ih,
236 struct inotify_watch *watch)
521{ 237{
522 inotify_dev_queue_event(dev, watch, IN_IGNORED, 0, NULL); 238 remove_watch_no_event(watch, ih);
523 remove_watch_no_event(watch, dev); 239 ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL);
524} 240}
241EXPORT_SYMBOL_GPL(inotify_remove_watch_locked);
525 242
526/* Kernel API */ 243/* Kernel API for producing events */
527 244
528/* 245/*
529 * inotify_d_instantiate - instantiate dcache entry for inode 246 * inotify_d_instantiate - instantiate dcache entry for inode
@@ -563,9 +280,10 @@ void inotify_d_move(struct dentry *entry)
563 * @mask: event mask describing this event 280 * @mask: event mask describing this event
564 * @cookie: cookie for synchronization, or zero 281 * @cookie: cookie for synchronization, or zero
565 * @name: filename, if any 282 * @name: filename, if any
283 * @n_inode: inode associated with name
566 */ 284 */
567void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie, 285void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
568 const char *name) 286 const char *name, struct inode *n_inode)
569{ 287{
570 struct inotify_watch *watch, *next; 288 struct inotify_watch *watch, *next;
571 289
@@ -576,14 +294,13 @@ void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
576 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { 294 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
577 u32 watch_mask = watch->mask; 295 u32 watch_mask = watch->mask;
578 if (watch_mask & mask) { 296 if (watch_mask & mask) {
579 struct inotify_device *dev = watch->dev; 297 struct inotify_handle *ih= watch->ih;
580 get_inotify_watch(watch); 298 mutex_lock(&ih->mutex);
581 mutex_lock(&dev->mutex);
582 inotify_dev_queue_event(dev, watch, mask, cookie, name);
583 if (watch_mask & IN_ONESHOT) 299 if (watch_mask & IN_ONESHOT)
584 remove_watch_no_event(watch, dev); 300 remove_watch_no_event(watch, ih);
585 mutex_unlock(&dev->mutex); 301 ih->in_ops->handle_event(watch, watch->wd, mask, cookie,
586 put_inotify_watch(watch); 302 name, n_inode);
303 mutex_unlock(&ih->mutex);
587 } 304 }
588 } 305 }
589 mutex_unlock(&inode->inotify_mutex); 306 mutex_unlock(&inode->inotify_mutex);
@@ -613,7 +330,8 @@ void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
613 if (inotify_inode_watched(inode)) { 330 if (inotify_inode_watched(inode)) {
614 dget(parent); 331 dget(parent);
615 spin_unlock(&dentry->d_lock); 332 spin_unlock(&dentry->d_lock);
616 inotify_inode_queue_event(inode, mask, cookie, name); 333 inotify_inode_queue_event(inode, mask, cookie, name,
334 dentry->d_inode);
617 dput(parent); 335 dput(parent);
618 } else 336 } else
619 spin_unlock(&dentry->d_lock); 337 spin_unlock(&dentry->d_lock);
@@ -665,7 +383,7 @@ void inotify_unmount_inodes(struct list_head *list)
665 383
666 need_iput_tmp = need_iput; 384 need_iput_tmp = need_iput;
667 need_iput = NULL; 385 need_iput = NULL;
668 /* In case the remove_watch() drops a reference. */ 386 /* In case inotify_remove_watch_locked() drops a reference. */
669 if (inode != need_iput_tmp) 387 if (inode != need_iput_tmp)
670 __iget(inode); 388 __iget(inode);
671 else 389 else
@@ -694,11 +412,12 @@ void inotify_unmount_inodes(struct list_head *list)
694 mutex_lock(&inode->inotify_mutex); 412 mutex_lock(&inode->inotify_mutex);
695 watches = &inode->inotify_watches; 413 watches = &inode->inotify_watches;
696 list_for_each_entry_safe(watch, next_w, watches, i_list) { 414 list_for_each_entry_safe(watch, next_w, watches, i_list) {
697 struct inotify_device *dev = watch->dev; 415 struct inotify_handle *ih= watch->ih;
698 mutex_lock(&dev->mutex); 416 mutex_lock(&ih->mutex);
699 inotify_dev_queue_event(dev, watch, IN_UNMOUNT,0,NULL); 417 ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0,
700 remove_watch(watch, dev); 418 NULL, NULL);
701 mutex_unlock(&dev->mutex); 419 inotify_remove_watch_locked(ih, watch);
420 mutex_unlock(&ih->mutex);
702 } 421 }
703 mutex_unlock(&inode->inotify_mutex); 422 mutex_unlock(&inode->inotify_mutex);
704 iput(inode); 423 iput(inode);
@@ -718,432 +437,292 @@ void inotify_inode_is_dead(struct inode *inode)
718 437
719 mutex_lock(&inode->inotify_mutex); 438 mutex_lock(&inode->inotify_mutex);
720 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { 439 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
721 struct inotify_device *dev = watch->dev; 440 struct inotify_handle *ih = watch->ih;
722 mutex_lock(&dev->mutex); 441 mutex_lock(&ih->mutex);
723 remove_watch(watch, dev); 442 inotify_remove_watch_locked(ih, watch);
724 mutex_unlock(&dev->mutex); 443 mutex_unlock(&ih->mutex);
725 } 444 }
726 mutex_unlock(&inode->inotify_mutex); 445 mutex_unlock(&inode->inotify_mutex);
727} 446}
728EXPORT_SYMBOL_GPL(inotify_inode_is_dead); 447EXPORT_SYMBOL_GPL(inotify_inode_is_dead);
729 448
730/* Device Interface */ 449/* Kernel Consumer API */
731 450
732static unsigned int inotify_poll(struct file *file, poll_table *wait) 451/**
452 * inotify_init - allocate and initialize an inotify instance
453 * @ops: caller's inotify operations
454 */
455struct inotify_handle *inotify_init(const struct inotify_operations *ops)
733{ 456{
734 struct inotify_device *dev = file->private_data; 457 struct inotify_handle *ih;
735 int ret = 0;
736 458
737 poll_wait(file, &dev->wq, wait); 459 ih = kmalloc(sizeof(struct inotify_handle), GFP_KERNEL);
738 mutex_lock(&dev->mutex); 460 if (unlikely(!ih))
739 if (!list_empty(&dev->events)) 461 return ERR_PTR(-ENOMEM);
740 ret = POLLIN | POLLRDNORM;
741 mutex_unlock(&dev->mutex);
742 462
743 return ret; 463 idr_init(&ih->idr);
464 INIT_LIST_HEAD(&ih->watches);
465 mutex_init(&ih->mutex);
466 ih->last_wd = 0;
467 ih->in_ops = ops;
468 atomic_set(&ih->count, 0);
469 get_inotify_handle(ih);
470
471 return ih;
744} 472}
473EXPORT_SYMBOL_GPL(inotify_init);
745 474
746static ssize_t inotify_read(struct file *file, char __user *buf, 475/**
747 size_t count, loff_t *pos) 476 * inotify_init_watch - initialize an inotify watch
477 * @watch: watch to initialize
478 */
479void inotify_init_watch(struct inotify_watch *watch)
748{ 480{
749 size_t event_size = sizeof (struct inotify_event); 481 INIT_LIST_HEAD(&watch->h_list);
750 struct inotify_device *dev; 482 INIT_LIST_HEAD(&watch->i_list);
751 char __user *start; 483 atomic_set(&watch->count, 0);
752 int ret; 484 get_inotify_watch(watch); /* initial get */
753 DEFINE_WAIT(wait);
754
755 start = buf;
756 dev = file->private_data;
757
758 while (1) {
759 int events;
760
761 prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
762
763 mutex_lock(&dev->mutex);
764 events = !list_empty(&dev->events);
765 mutex_unlock(&dev->mutex);
766 if (events) {
767 ret = 0;
768 break;
769 }
770
771 if (file->f_flags & O_NONBLOCK) {
772 ret = -EAGAIN;
773 break;
774 }
775
776 if (signal_pending(current)) {
777 ret = -EINTR;
778 break;
779 }
780
781 schedule();
782 }
783
784 finish_wait(&dev->wq, &wait);
785 if (ret)
786 return ret;
787
788 mutex_lock(&dev->mutex);
789 while (1) {
790 struct inotify_kernel_event *kevent;
791
792 ret = buf - start;
793 if (list_empty(&dev->events))
794 break;
795
796 kevent = inotify_dev_get_event(dev);
797 if (event_size + kevent->event.len > count)
798 break;
799
800 if (copy_to_user(buf, &kevent->event, event_size)) {
801 ret = -EFAULT;
802 break;
803 }
804 buf += event_size;
805 count -= event_size;
806
807 if (kevent->name) {
808 if (copy_to_user(buf, kevent->name, kevent->event.len)){
809 ret = -EFAULT;
810 break;
811 }
812 buf += kevent->event.len;
813 count -= kevent->event.len;
814 }
815
816 remove_kevent(dev, kevent);
817 }
818 mutex_unlock(&dev->mutex);
819
820 return ret;
821} 485}
486EXPORT_SYMBOL_GPL(inotify_init_watch);
822 487
823static int inotify_release(struct inode *ignored, struct file *file) 488/**
489 * inotify_destroy - clean up and destroy an inotify instance
490 * @ih: inotify handle
491 */
492void inotify_destroy(struct inotify_handle *ih)
824{ 493{
825 struct inotify_device *dev = file->private_data;
826
827 /* 494 /*
828 * Destroy all of the watches on this device. Unfortunately, not very 495 * Destroy all of the watches for this handle. Unfortunately, not very
829 * pretty. We cannot do a simple iteration over the list, because we 496 * pretty. We cannot do a simple iteration over the list, because we
830 * do not know the inode until we iterate to the watch. But we need to 497 * do not know the inode until we iterate to the watch. But we need to
831 * hold inode->inotify_mutex before dev->mutex. The following works. 498 * hold inode->inotify_mutex before ih->mutex. The following works.
832 */ 499 */
833 while (1) { 500 while (1) {
834 struct inotify_watch *watch; 501 struct inotify_watch *watch;
835 struct list_head *watches; 502 struct list_head *watches;
836 struct inode *inode; 503 struct inode *inode;
837 504
838 mutex_lock(&dev->mutex); 505 mutex_lock(&ih->mutex);
839 watches = &dev->watches; 506 watches = &ih->watches;
840 if (list_empty(watches)) { 507 if (list_empty(watches)) {
841 mutex_unlock(&dev->mutex); 508 mutex_unlock(&ih->mutex);
842 break; 509 break;
843 } 510 }
844 watch = list_entry(watches->next, struct inotify_watch, d_list); 511 watch = list_entry(watches->next, struct inotify_watch, h_list);
845 get_inotify_watch(watch); 512 get_inotify_watch(watch);
846 mutex_unlock(&dev->mutex); 513 mutex_unlock(&ih->mutex);
847 514
848 inode = watch->inode; 515 inode = watch->inode;
849 mutex_lock(&inode->inotify_mutex); 516 mutex_lock(&inode->inotify_mutex);
850 mutex_lock(&dev->mutex); 517 mutex_lock(&ih->mutex);
851 518
852 /* make sure we didn't race with another list removal */ 519 /* make sure we didn't race with another list removal */
853 if (likely(idr_find(&dev->idr, watch->wd))) 520 if (likely(idr_find(&ih->idr, watch->wd))) {
854 remove_watch_no_event(watch, dev); 521 remove_watch_no_event(watch, ih);
522 put_inotify_watch(watch);
523 }
855 524
856 mutex_unlock(&dev->mutex); 525 mutex_unlock(&ih->mutex);
857 mutex_unlock(&inode->inotify_mutex); 526 mutex_unlock(&inode->inotify_mutex);
858 put_inotify_watch(watch); 527 put_inotify_watch(watch);
859 } 528 }
860 529
861 /* destroy all of the events on this device */ 530 /* free this handle: the put matching the get in inotify_init() */
862 mutex_lock(&dev->mutex); 531 put_inotify_handle(ih);
863 while (!list_empty(&dev->events))
864 inotify_dev_event_dequeue(dev);
865 mutex_unlock(&dev->mutex);
866
867 /* free this device: the put matching the get in inotify_init() */
868 put_inotify_dev(dev);
869
870 return 0;
871} 532}
533EXPORT_SYMBOL_GPL(inotify_destroy);
872 534
873/* 535/**
874 * inotify_ignore - remove a given wd from this inotify instance. 536 * inotify_find_watch - find an existing watch for an (ih,inode) pair
537 * @ih: inotify handle
538 * @inode: inode to watch
539 * @watchp: pointer to existing inotify_watch
875 * 540 *
876 * Can sleep. 541 * Caller must pin given inode (via nameidata).
877 */ 542 */
878static int inotify_ignore(struct inotify_device *dev, s32 wd) 543s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
544 struct inotify_watch **watchp)
879{ 545{
880 struct inotify_watch *watch; 546 struct inotify_watch *old;
881 struct inode *inode; 547 int ret = -ENOENT;
882
883 mutex_lock(&dev->mutex);
884 watch = idr_find(&dev->idr, wd);
885 if (unlikely(!watch)) {
886 mutex_unlock(&dev->mutex);
887 return -EINVAL;
888 }
889 get_inotify_watch(watch);
890 inode = watch->inode;
891 mutex_unlock(&dev->mutex);
892 548
893 mutex_lock(&inode->inotify_mutex); 549 mutex_lock(&inode->inotify_mutex);
894 mutex_lock(&dev->mutex); 550 mutex_lock(&ih->mutex);
895 551
896 /* make sure that we did not race */ 552 old = inode_find_handle(inode, ih);
897 if (likely(idr_find(&dev->idr, wd) == watch)) 553 if (unlikely(old)) {
898 remove_watch(watch, dev); 554 get_inotify_watch(old); /* caller must put watch */
555 *watchp = old;
556 ret = old->wd;
557 }
899 558
900 mutex_unlock(&dev->mutex); 559 mutex_unlock(&ih->mutex);
901 mutex_unlock(&inode->inotify_mutex); 560 mutex_unlock(&inode->inotify_mutex);
902 put_inotify_watch(watch);
903 561
904 return 0; 562 return ret;
905} 563}
564EXPORT_SYMBOL_GPL(inotify_find_watch);
906 565
907static long inotify_ioctl(struct file *file, unsigned int cmd, 566/**
908 unsigned long arg) 567 * inotify_find_update_watch - find and update the mask of an existing watch
568 * @ih: inotify handle
569 * @inode: inode's watch to update
570 * @mask: mask of events to watch
571 *
572 * Caller must pin given inode (via nameidata).
573 */
574s32 inotify_find_update_watch(struct inotify_handle *ih, struct inode *inode,
575 u32 mask)
909{ 576{
910 struct inotify_device *dev; 577 struct inotify_watch *old;
911 void __user *p; 578 int mask_add = 0;
912 int ret = -ENOTTY; 579 int ret;
913
914 dev = file->private_data;
915 p = (void __user *) arg;
916
917 switch (cmd) {
918 case FIONREAD:
919 ret = put_user(dev->queue_size, (int __user *) p);
920 break;
921 }
922
923 return ret;
924}
925 580
926static const struct file_operations inotify_fops = { 581 if (mask & IN_MASK_ADD)
927 .poll = inotify_poll, 582 mask_add = 1;
928 .read = inotify_read,
929 .release = inotify_release,
930 .unlocked_ioctl = inotify_ioctl,
931 .compat_ioctl = inotify_ioctl,
932};
933 583
934asmlinkage long sys_inotify_init(void) 584 /* don't allow invalid bits: we don't want flags set */
935{ 585 mask &= IN_ALL_EVENTS | IN_ONESHOT;
936 struct inotify_device *dev; 586 if (unlikely(!mask))
937 struct user_struct *user; 587 return -EINVAL;
938 struct file *filp;
939 int fd, ret;
940
941 fd = get_unused_fd();
942 if (fd < 0)
943 return fd;
944
945 filp = get_empty_filp();
946 if (!filp) {
947 ret = -ENFILE;
948 goto out_put_fd;
949 }
950 588
951 user = get_uid(current->user); 589 mutex_lock(&inode->inotify_mutex);
952 if (unlikely(atomic_read(&user->inotify_devs) >= 590 mutex_lock(&ih->mutex);
953 inotify_max_user_instances)) {
954 ret = -EMFILE;
955 goto out_free_uid;
956 }
957 591
958 dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL); 592 /*
959 if (unlikely(!dev)) { 593 * Handle the case of re-adding a watch on an (inode,ih) pair that we
960 ret = -ENOMEM; 594 * are already watching. We just update the mask and return its wd.
961 goto out_free_uid; 595 */
596 old = inode_find_handle(inode, ih);
597 if (unlikely(!old)) {
598 ret = -ENOENT;
599 goto out;
962 } 600 }
963 601
964 filp->f_op = &inotify_fops; 602 if (mask_add)
965 filp->f_vfsmnt = mntget(inotify_mnt); 603 old->mask |= mask;
966 filp->f_dentry = dget(inotify_mnt->mnt_root); 604 else
967 filp->f_mapping = filp->f_dentry->d_inode->i_mapping; 605 old->mask = mask;
968 filp->f_mode = FMODE_READ; 606 ret = old->wd;
969 filp->f_flags = O_RDONLY; 607out:
970 filp->private_data = dev; 608 mutex_unlock(&ih->mutex);
971 609 mutex_unlock(&inode->inotify_mutex);
972 idr_init(&dev->idr);
973 INIT_LIST_HEAD(&dev->events);
974 INIT_LIST_HEAD(&dev->watches);
975 init_waitqueue_head(&dev->wq);
976 mutex_init(&dev->mutex);
977 dev->event_count = 0;
978 dev->queue_size = 0;
979 dev->max_events = inotify_max_queued_events;
980 dev->user = user;
981 dev->last_wd = 0;
982 atomic_set(&dev->count, 0);
983
984 get_inotify_dev(dev);
985 atomic_inc(&user->inotify_devs);
986 fd_install(fd, filp);
987
988 return fd;
989out_free_uid:
990 free_uid(user);
991 put_filp(filp);
992out_put_fd:
993 put_unused_fd(fd);
994 return ret; 610 return ret;
995} 611}
612EXPORT_SYMBOL_GPL(inotify_find_update_watch);
996 613
997asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) 614/**
615 * inotify_add_watch - add a watch to an inotify instance
616 * @ih: inotify handle
617 * @watch: caller allocated watch structure
618 * @inode: inode to watch
619 * @mask: mask of events to watch
620 *
621 * Caller must pin given inode (via nameidata).
622 * Caller must ensure it only calls inotify_add_watch() once per watch.
623 * Calls inotify_handle_get_wd() so may sleep.
624 */
625s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch,
626 struct inode *inode, u32 mask)
998{ 627{
999 struct inotify_watch *watch, *old; 628 int ret = 0;
1000 struct inode *inode;
1001 struct inotify_device *dev;
1002 struct nameidata nd;
1003 struct file *filp;
1004 int ret, fput_needed;
1005 int mask_add = 0;
1006 unsigned flags = 0;
1007
1008 filp = fget_light(fd, &fput_needed);
1009 if (unlikely(!filp))
1010 return -EBADF;
1011
1012 /* verify that this is indeed an inotify instance */
1013 if (unlikely(filp->f_op != &inotify_fops)) {
1014 ret = -EINVAL;
1015 goto fput_and_out;
1016 }
1017
1018 if (!(mask & IN_DONT_FOLLOW))
1019 flags |= LOOKUP_FOLLOW;
1020 if (mask & IN_ONLYDIR)
1021 flags |= LOOKUP_DIRECTORY;
1022
1023 ret = find_inode(path, &nd, flags);
1024 if (unlikely(ret))
1025 goto fput_and_out;
1026 629
1027 /* inode held in place by reference to nd; dev by fget on fd */ 630 /* don't allow invalid bits: we don't want flags set */
1028 inode = nd.dentry->d_inode; 631 mask &= IN_ALL_EVENTS | IN_ONESHOT;
1029 dev = filp->private_data; 632 if (unlikely(!mask))
633 return -EINVAL;
634 watch->mask = mask;
1030 635
1031 mutex_lock(&inode->inotify_mutex); 636 mutex_lock(&inode->inotify_mutex);
1032 mutex_lock(&dev->mutex); 637 mutex_lock(&ih->mutex);
1033
1034 if (mask & IN_MASK_ADD)
1035 mask_add = 1;
1036 638
1037 /* don't let user-space set invalid bits: we don't want flags set */ 639 /* Initialize a new watch */
1038 mask &= IN_ALL_EVENTS | IN_ONESHOT; 640 ret = inotify_handle_get_wd(ih, watch);
1039 if (unlikely(!mask)) { 641 if (unlikely(ret))
1040 ret = -EINVAL;
1041 goto out; 642 goto out;
1042 } 643 ret = watch->wd;
644
645 /* save a reference to handle and bump the count to make it official */
646 get_inotify_handle(ih);
647 watch->ih = ih;
1043 648
1044 /* 649 /*
1045 * Handle the case of re-adding a watch on an (inode,dev) pair that we 650 * Save a reference to the inode and bump the ref count to make it
1046 * are already watching. We just update the mask and return its wd. 651 * official. We hold a reference to nameidata, which makes this safe.
1047 */ 652 */
1048 old = inode_find_dev(inode, dev); 653 watch->inode = igrab(inode);
1049 if (unlikely(old)) {
1050 if (mask_add)
1051 old->mask |= mask;
1052 else
1053 old->mask = mask;
1054 ret = old->wd;
1055 goto out;
1056 }
1057
1058 watch = create_watch(dev, mask, inode);
1059 if (unlikely(IS_ERR(watch))) {
1060 ret = PTR_ERR(watch);
1061 goto out;
1062 }
1063 654
1064 if (!inotify_inode_watched(inode)) 655 if (!inotify_inode_watched(inode))
1065 set_dentry_child_flags(inode, 1); 656 set_dentry_child_flags(inode, 1);
1066 657
1067 /* Add the watch to the device's and the inode's list */ 658 /* Add the watch to the handle's and the inode's list */
1068 list_add(&watch->d_list, &dev->watches); 659 list_add(&watch->h_list, &ih->watches);
1069 list_add(&watch->i_list, &inode->inotify_watches); 660 list_add(&watch->i_list, &inode->inotify_watches);
1070 ret = watch->wd;
1071out: 661out:
1072 mutex_unlock(&dev->mutex); 662 mutex_unlock(&ih->mutex);
1073 mutex_unlock(&inode->inotify_mutex); 663 mutex_unlock(&inode->inotify_mutex);
1074 path_release(&nd);
1075fput_and_out:
1076 fput_light(filp, fput_needed);
1077 return ret; 664 return ret;
1078} 665}
666EXPORT_SYMBOL_GPL(inotify_add_watch);
1079 667
1080asmlinkage long sys_inotify_rm_watch(int fd, u32 wd) 668/**
669 * inotify_rm_wd - remove a watch from an inotify instance
670 * @ih: inotify handle
671 * @wd: watch descriptor to remove
672 *
673 * Can sleep.
674 */
675int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
1081{ 676{
1082 struct file *filp; 677 struct inotify_watch *watch;
1083 struct inotify_device *dev; 678 struct inode *inode;
1084 int ret, fput_needed;
1085
1086 filp = fget_light(fd, &fput_needed);
1087 if (unlikely(!filp))
1088 return -EBADF;
1089 679
1090 /* verify that this is indeed an inotify instance */ 680 mutex_lock(&ih->mutex);
1091 if (unlikely(filp->f_op != &inotify_fops)) { 681 watch = idr_find(&ih->idr, wd);
1092 ret = -EINVAL; 682 if (unlikely(!watch)) {
1093 goto out; 683 mutex_unlock(&ih->mutex);
684 return -EINVAL;
1094 } 685 }
686 get_inotify_watch(watch);
687 inode = watch->inode;
688 mutex_unlock(&ih->mutex);
1095 689
1096 dev = filp->private_data; 690 mutex_lock(&inode->inotify_mutex);
1097 ret = inotify_ignore(dev, wd); 691 mutex_lock(&ih->mutex);
1098 692
1099out: 693 /* make sure that we did not race */
1100 fput_light(filp, fput_needed); 694 if (likely(idr_find(&ih->idr, wd) == watch))
1101 return ret; 695 inotify_remove_watch_locked(ih, watch);
696
697 mutex_unlock(&ih->mutex);
698 mutex_unlock(&inode->inotify_mutex);
699 put_inotify_watch(watch);
700
701 return 0;
1102} 702}
703EXPORT_SYMBOL_GPL(inotify_rm_wd);
1103 704
1104static struct super_block * 705/**
1105inotify_get_sb(struct file_system_type *fs_type, int flags, 706 * inotify_rm_watch - remove a watch from an inotify instance
1106 const char *dev_name, void *data) 707 * @ih: inotify handle
708 * @watch: watch to remove
709 *
710 * Can sleep.
711 */
712int inotify_rm_watch(struct inotify_handle *ih,
713 struct inotify_watch *watch)
1107{ 714{
1108 return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA); 715 return inotify_rm_wd(ih, watch->wd);
1109} 716}
1110 717EXPORT_SYMBOL_GPL(inotify_rm_watch);
1111static struct file_system_type inotify_fs_type = {
1112 .name = "inotifyfs",
1113 .get_sb = inotify_get_sb,
1114 .kill_sb = kill_anon_super,
1115};
1116 718
1117/* 719/*
1118 * inotify_setup - Our initialization function. Note that we cannnot return 720 * inotify_setup - core initialization function
1119 * error because we have compiled-in VFS hooks. So an (unlikely) failure here
1120 * must result in panic().
1121 */ 721 */
1122static int __init inotify_setup(void) 722static int __init inotify_setup(void)
1123{ 723{
1124 int ret;
1125
1126 ret = register_filesystem(&inotify_fs_type);
1127 if (unlikely(ret))
1128 panic("inotify: register_filesystem returned %d!\n", ret);
1129
1130 inotify_mnt = kern_mount(&inotify_fs_type);
1131 if (IS_ERR(inotify_mnt))
1132 panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt));
1133
1134 inotify_max_queued_events = 16384;
1135 inotify_max_user_instances = 128;
1136 inotify_max_user_watches = 8192;
1137
1138 atomic_set(&inotify_cookie, 0); 724 atomic_set(&inotify_cookie, 0);
1139 725
1140 watch_cachep = kmem_cache_create("inotify_watch_cache",
1141 sizeof(struct inotify_watch),
1142 0, SLAB_PANIC, NULL, NULL);
1143 event_cachep = kmem_cache_create("inotify_event_cache",
1144 sizeof(struct inotify_kernel_event),
1145 0, SLAB_PANIC, NULL, NULL);
1146
1147 return 0; 726 return 0;
1148} 727}
1149 728
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
new file mode 100644
index 000000000000..9e9931e2badd
--- /dev/null
+++ b/fs/inotify_user.c
@@ -0,0 +1,719 @@
1/*
2 * fs/inotify_user.c - inotify support for userspace
3 *
4 * Authors:
5 * John McCutchan <ttb@tentacle.dhs.org>
6 * Robert Love <rml@novell.com>
7 *
8 * Copyright (C) 2005 John McCutchan
9 * Copyright 2006 Hewlett-Packard Development Company, L.P.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2, or (at your option) any
14 * later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 */
21
22#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/slab.h>
25#include <linux/fs.h>
26#include <linux/file.h>
27#include <linux/mount.h>
28#include <linux/namei.h>
29#include <linux/poll.h>
30#include <linux/init.h>
31#include <linux/list.h>
32#include <linux/inotify.h>
33#include <linux/syscalls.h>
34
35#include <asm/ioctls.h>
36
37static kmem_cache_t *watch_cachep __read_mostly;
38static kmem_cache_t *event_cachep __read_mostly;
39
40static struct vfsmount *inotify_mnt __read_mostly;
41
42/* these are configurable via /proc/sys/fs/inotify/ */
43int inotify_max_user_instances __read_mostly;
44int inotify_max_user_watches __read_mostly;
45int inotify_max_queued_events __read_mostly;
46
47/*
48 * Lock ordering:
49 *
50 * inotify_dev->up_mutex (ensures we don't re-add the same watch)
51 * inode->inotify_mutex (protects inode's watch list)
52 * inotify_handle->mutex (protects inotify_handle's watch list)
53 * inotify_dev->ev_mutex (protects device's event queue)
54 */
55
56/*
57 * Lifetimes of the main data structures:
58 *
59 * inotify_device: Lifetime is managed by reference count, from
60 * sys_inotify_init() until release. Additional references can bump the count
61 * via get_inotify_dev() and drop the count via put_inotify_dev().
62 *
63 * inotify_user_watch: Lifetime is from create_watch() to the receipt of an
64 * IN_IGNORED event from inotify, or when using IN_ONESHOT, to receipt of the
65 * first event, or to inotify_destroy().
66 */
67
68/*
69 * struct inotify_device - represents an inotify instance
70 *
71 * This structure is protected by the mutex 'mutex'.
72 */
73struct inotify_device {
74 wait_queue_head_t wq; /* wait queue for i/o */
75 struct mutex ev_mutex; /* protects event queue */
76 struct mutex up_mutex; /* synchronizes watch updates */
77 struct list_head events; /* list of queued events */
78 atomic_t count; /* reference count */
79 struct user_struct *user; /* user who opened this dev */
80 struct inotify_handle *ih; /* inotify handle */
81 unsigned int queue_size; /* size of the queue (bytes) */
82 unsigned int event_count; /* number of pending events */
83 unsigned int max_events; /* maximum number of events */
84};
85
86/*
87 * struct inotify_kernel_event - An inotify event, originating from a watch and
88 * queued for user-space. A list of these is attached to each instance of the
89 * device. In read(), this list is walked and all events that can fit in the
90 * buffer are returned.
91 *
92 * Protected by dev->ev_mutex of the device in which we are queued.
93 */
94struct inotify_kernel_event {
95 struct inotify_event event; /* the user-space event */
96 struct list_head list; /* entry in inotify_device's list */
97 char *name; /* filename, if any */
98};
99
100/*
101 * struct inotify_user_watch - our version of an inotify_watch, we add
102 * a reference to the associated inotify_device.
103 */
104struct inotify_user_watch {
105 struct inotify_device *dev; /* associated device */
106 struct inotify_watch wdata; /* inotify watch data */
107};
108
109#ifdef CONFIG_SYSCTL
110
111#include <linux/sysctl.h>
112
113static int zero;
114
115ctl_table inotify_table[] = {
116 {
117 .ctl_name = INOTIFY_MAX_USER_INSTANCES,
118 .procname = "max_user_instances",
119 .data = &inotify_max_user_instances,
120 .maxlen = sizeof(int),
121 .mode = 0644,
122 .proc_handler = &proc_dointvec_minmax,
123 .strategy = &sysctl_intvec,
124 .extra1 = &zero,
125 },
126 {
127 .ctl_name = INOTIFY_MAX_USER_WATCHES,
128 .procname = "max_user_watches",
129 .data = &inotify_max_user_watches,
130 .maxlen = sizeof(int),
131 .mode = 0644,
132 .proc_handler = &proc_dointvec_minmax,
133 .strategy = &sysctl_intvec,
134 .extra1 = &zero,
135 },
136 {
137 .ctl_name = INOTIFY_MAX_QUEUED_EVENTS,
138 .procname = "max_queued_events",
139 .data = &inotify_max_queued_events,
140 .maxlen = sizeof(int),
141 .mode = 0644,
142 .proc_handler = &proc_dointvec_minmax,
143 .strategy = &sysctl_intvec,
144 .extra1 = &zero
145 },
146 { .ctl_name = 0 }
147};
148#endif /* CONFIG_SYSCTL */
149
150static inline void get_inotify_dev(struct inotify_device *dev)
151{
152 atomic_inc(&dev->count);
153}
154
155static inline void put_inotify_dev(struct inotify_device *dev)
156{
157 if (atomic_dec_and_test(&dev->count)) {
158 atomic_dec(&dev->user->inotify_devs);
159 free_uid(dev->user);
160 kfree(dev);
161 }
162}
163
164/*
165 * free_inotify_user_watch - cleans up the watch and its references
166 */
167static void free_inotify_user_watch(struct inotify_watch *w)
168{
169 struct inotify_user_watch *watch;
170 struct inotify_device *dev;
171
172 watch = container_of(w, struct inotify_user_watch, wdata);
173 dev = watch->dev;
174
175 atomic_dec(&dev->user->inotify_watches);
176 put_inotify_dev(dev);
177 kmem_cache_free(watch_cachep, watch);
178}
179
180/*
181 * kernel_event - create a new kernel event with the given parameters
182 *
183 * This function can sleep.
184 */
185static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
186 const char *name)
187{
188 struct inotify_kernel_event *kevent;
189
190 kevent = kmem_cache_alloc(event_cachep, GFP_KERNEL);
191 if (unlikely(!kevent))
192 return NULL;
193
194 /* we hand this out to user-space, so zero it just in case */
195 memset(&kevent->event, 0, sizeof(struct inotify_event));
196
197 kevent->event.wd = wd;
198 kevent->event.mask = mask;
199 kevent->event.cookie = cookie;
200
201 INIT_LIST_HEAD(&kevent->list);
202
203 if (name) {
204 size_t len, rem, event_size = sizeof(struct inotify_event);
205
206 /*
207 * We need to pad the filename so as to properly align an
208 * array of inotify_event structures. Because the structure is
209 * small and the common case is a small filename, we just round
210 * up to the next multiple of the structure's sizeof. This is
211 * simple and safe for all architectures.
212 */
213 len = strlen(name) + 1;
214 rem = event_size - len;
215 if (len > event_size) {
216 rem = event_size - (len % event_size);
217 if (len % event_size == 0)
218 rem = 0;
219 }
220
221 kevent->name = kmalloc(len + rem, GFP_KERNEL);
222 if (unlikely(!kevent->name)) {
223 kmem_cache_free(event_cachep, kevent);
224 return NULL;
225 }
226 memcpy(kevent->name, name, len);
227 if (rem)
228 memset(kevent->name + len, 0, rem);
229 kevent->event.len = len + rem;
230 } else {
231 kevent->event.len = 0;
232 kevent->name = NULL;
233 }
234
235 return kevent;
236}
237
238/*
239 * inotify_dev_get_event - return the next event in the given dev's queue
240 *
241 * Caller must hold dev->ev_mutex.
242 */
243static inline struct inotify_kernel_event *
244inotify_dev_get_event(struct inotify_device *dev)
245{
246 return list_entry(dev->events.next, struct inotify_kernel_event, list);
247}
248
249/*
250 * inotify_dev_queue_event - event handler registered with core inotify, adds
251 * a new event to the given device
252 *
253 * Can sleep (calls kernel_event()).
254 */
255static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask,
256 u32 cookie, const char *name,
257 struct inode *ignored)
258{
259 struct inotify_user_watch *watch;
260 struct inotify_device *dev;
261 struct inotify_kernel_event *kevent, *last;
262
263 watch = container_of(w, struct inotify_user_watch, wdata);
264 dev = watch->dev;
265
266 mutex_lock(&dev->ev_mutex);
267
268 /* we can safely put the watch as we don't reference it while
269 * generating the event
270 */
271 if (mask & IN_IGNORED || mask & IN_ONESHOT)
272 put_inotify_watch(w); /* final put */
273
274 /* coalescing: drop this event if it is a dupe of the previous */
275 last = inotify_dev_get_event(dev);
276 if (last && last->event.mask == mask && last->event.wd == wd &&
277 last->event.cookie == cookie) {
278 const char *lastname = last->name;
279
280 if (!name && !lastname)
281 goto out;
282 if (name && lastname && !strcmp(lastname, name))
283 goto out;
284 }
285
286 /* the queue overflowed and we already sent the Q_OVERFLOW event */
287 if (unlikely(dev->event_count > dev->max_events))
288 goto out;
289
290 /* if the queue overflows, we need to notify user space */
291 if (unlikely(dev->event_count == dev->max_events))
292 kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL);
293 else
294 kevent = kernel_event(wd, mask, cookie, name);
295
296 if (unlikely(!kevent))
297 goto out;
298
299 /* queue the event and wake up anyone waiting */
300 dev->event_count++;
301 dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
302 list_add_tail(&kevent->list, &dev->events);
303 wake_up_interruptible(&dev->wq);
304
305out:
306 mutex_unlock(&dev->ev_mutex);
307}
308
309/*
310 * remove_kevent - cleans up and ultimately frees the given kevent
311 *
312 * Caller must hold dev->ev_mutex.
313 */
314static void remove_kevent(struct inotify_device *dev,
315 struct inotify_kernel_event *kevent)
316{
317 list_del(&kevent->list);
318
319 dev->event_count--;
320 dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len;
321
322 kfree(kevent->name);
323 kmem_cache_free(event_cachep, kevent);
324}
325
326/*
327 * inotify_dev_event_dequeue - destroy an event on the given device
328 *
329 * Caller must hold dev->ev_mutex.
330 */
331static void inotify_dev_event_dequeue(struct inotify_device *dev)
332{
333 if (!list_empty(&dev->events)) {
334 struct inotify_kernel_event *kevent;
335 kevent = inotify_dev_get_event(dev);
336 remove_kevent(dev, kevent);
337 }
338}
339
340/*
341 * find_inode - resolve a user-given path to a specific inode and return a nd
342 */
343static int find_inode(const char __user *dirname, struct nameidata *nd,
344 unsigned flags)
345{
346 int error;
347
348 error = __user_walk(dirname, flags, nd);
349 if (error)
350 return error;
351 /* you can only watch an inode if you have read permissions on it */
352 error = vfs_permission(nd, MAY_READ);
353 if (error)
354 path_release(nd);
355 return error;
356}
357
358/*
359 * create_watch - creates a watch on the given device.
360 *
361 * Callers must hold dev->up_mutex.
362 */
363static int create_watch(struct inotify_device *dev, struct inode *inode,
364 u32 mask)
365{
366 struct inotify_user_watch *watch;
367 int ret;
368
369 if (atomic_read(&dev->user->inotify_watches) >=
370 inotify_max_user_watches)
371 return -ENOSPC;
372
373 watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL);
374 if (unlikely(!watch))
375 return -ENOMEM;
376
377 /* save a reference to device and bump the count to make it official */
378 get_inotify_dev(dev);
379 watch->dev = dev;
380
381 atomic_inc(&dev->user->inotify_watches);
382
383 inotify_init_watch(&watch->wdata);
384 ret = inotify_add_watch(dev->ih, &watch->wdata, inode, mask);
385 if (ret < 0)
386 free_inotify_user_watch(&watch->wdata);
387
388 return ret;
389}
390
391/* Device Interface */
392
393static unsigned int inotify_poll(struct file *file, poll_table *wait)
394{
395 struct inotify_device *dev = file->private_data;
396 int ret = 0;
397
398 poll_wait(file, &dev->wq, wait);
399 mutex_lock(&dev->ev_mutex);
400 if (!list_empty(&dev->events))
401 ret = POLLIN | POLLRDNORM;
402 mutex_unlock(&dev->ev_mutex);
403
404 return ret;
405}
406
407static ssize_t inotify_read(struct file *file, char __user *buf,
408 size_t count, loff_t *pos)
409{
410 size_t event_size = sizeof (struct inotify_event);
411 struct inotify_device *dev;
412 char __user *start;
413 int ret;
414 DEFINE_WAIT(wait);
415
416 start = buf;
417 dev = file->private_data;
418
419 while (1) {
420 int events;
421
422 prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
423
424 mutex_lock(&dev->ev_mutex);
425 events = !list_empty(&dev->events);
426 mutex_unlock(&dev->ev_mutex);
427 if (events) {
428 ret = 0;
429 break;
430 }
431
432 if (file->f_flags & O_NONBLOCK) {
433 ret = -EAGAIN;
434 break;
435 }
436
437 if (signal_pending(current)) {
438 ret = -EINTR;
439 break;
440 }
441
442 schedule();
443 }
444
445 finish_wait(&dev->wq, &wait);
446 if (ret)
447 return ret;
448
449 mutex_lock(&dev->ev_mutex);
450 while (1) {
451 struct inotify_kernel_event *kevent;
452
453 ret = buf - start;
454 if (list_empty(&dev->events))
455 break;
456
457 kevent = inotify_dev_get_event(dev);
458 if (event_size + kevent->event.len > count)
459 break;
460
461 if (copy_to_user(buf, &kevent->event, event_size)) {
462 ret = -EFAULT;
463 break;
464 }
465 buf += event_size;
466 count -= event_size;
467
468 if (kevent->name) {
469 if (copy_to_user(buf, kevent->name, kevent->event.len)){
470 ret = -EFAULT;
471 break;
472 }
473 buf += kevent->event.len;
474 count -= kevent->event.len;
475 }
476
477 remove_kevent(dev, kevent);
478 }
479 mutex_unlock(&dev->ev_mutex);
480
481 return ret;
482}
483
484static int inotify_release(struct inode *ignored, struct file *file)
485{
486 struct inotify_device *dev = file->private_data;
487
488 inotify_destroy(dev->ih);
489
490 /* destroy all of the events on this device */
491 mutex_lock(&dev->ev_mutex);
492 while (!list_empty(&dev->events))
493 inotify_dev_event_dequeue(dev);
494 mutex_unlock(&dev->ev_mutex);
495
496 /* free this device: the put matching the get in inotify_init() */
497 put_inotify_dev(dev);
498
499 return 0;
500}
501
502static long inotify_ioctl(struct file *file, unsigned int cmd,
503 unsigned long arg)
504{
505 struct inotify_device *dev;
506 void __user *p;
507 int ret = -ENOTTY;
508
509 dev = file->private_data;
510 p = (void __user *) arg;
511
512 switch (cmd) {
513 case FIONREAD:
514 ret = put_user(dev->queue_size, (int __user *) p);
515 break;
516 }
517
518 return ret;
519}
520
521static const struct file_operations inotify_fops = {
522 .poll = inotify_poll,
523 .read = inotify_read,
524 .release = inotify_release,
525 .unlocked_ioctl = inotify_ioctl,
526 .compat_ioctl = inotify_ioctl,
527};
528
529static const struct inotify_operations inotify_user_ops = {
530 .handle_event = inotify_dev_queue_event,
531 .destroy_watch = free_inotify_user_watch,
532};
533
534asmlinkage long sys_inotify_init(void)
535{
536 struct inotify_device *dev;
537 struct inotify_handle *ih;
538 struct user_struct *user;
539 struct file *filp;
540 int fd, ret;
541
542 fd = get_unused_fd();
543 if (fd < 0)
544 return fd;
545
546 filp = get_empty_filp();
547 if (!filp) {
548 ret = -ENFILE;
549 goto out_put_fd;
550 }
551
552 user = get_uid(current->user);
553 if (unlikely(atomic_read(&user->inotify_devs) >=
554 inotify_max_user_instances)) {
555 ret = -EMFILE;
556 goto out_free_uid;
557 }
558
559 dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL);
560 if (unlikely(!dev)) {
561 ret = -ENOMEM;
562 goto out_free_uid;
563 }
564
565 ih = inotify_init(&inotify_user_ops);
566 if (unlikely(IS_ERR(ih))) {
567 ret = PTR_ERR(ih);
568 goto out_free_dev;
569 }
570 dev->ih = ih;
571
572 filp->f_op = &inotify_fops;
573 filp->f_vfsmnt = mntget(inotify_mnt);
574 filp->f_dentry = dget(inotify_mnt->mnt_root);
575 filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
576 filp->f_mode = FMODE_READ;
577 filp->f_flags = O_RDONLY;
578 filp->private_data = dev;
579
580 INIT_LIST_HEAD(&dev->events);
581 init_waitqueue_head(&dev->wq);
582 mutex_init(&dev->ev_mutex);
583 mutex_init(&dev->up_mutex);
584 dev->event_count = 0;
585 dev->queue_size = 0;
586 dev->max_events = inotify_max_queued_events;
587 dev->user = user;
588 atomic_set(&dev->count, 0);
589
590 get_inotify_dev(dev);
591 atomic_inc(&user->inotify_devs);
592 fd_install(fd, filp);
593
594 return fd;
595out_free_dev:
596 kfree(dev);
597out_free_uid:
598 free_uid(user);
599 put_filp(filp);
600out_put_fd:
601 put_unused_fd(fd);
602 return ret;
603}
604
605asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
606{
607 struct inode *inode;
608 struct inotify_device *dev;
609 struct nameidata nd;
610 struct file *filp;
611 int ret, fput_needed;
612 unsigned flags = 0;
613
614 filp = fget_light(fd, &fput_needed);
615 if (unlikely(!filp))
616 return -EBADF;
617
618 /* verify that this is indeed an inotify instance */
619 if (unlikely(filp->f_op != &inotify_fops)) {
620 ret = -EINVAL;
621 goto fput_and_out;
622 }
623
624 if (!(mask & IN_DONT_FOLLOW))
625 flags |= LOOKUP_FOLLOW;
626 if (mask & IN_ONLYDIR)
627 flags |= LOOKUP_DIRECTORY;
628
629 ret = find_inode(path, &nd, flags);
630 if (unlikely(ret))
631 goto fput_and_out;
632
633 /* inode held in place by reference to nd; dev by fget on fd */
634 inode = nd.dentry->d_inode;
635 dev = filp->private_data;
636
637 mutex_lock(&dev->up_mutex);
638 ret = inotify_find_update_watch(dev->ih, inode, mask);
639 if (ret == -ENOENT)
640 ret = create_watch(dev, inode, mask);
641 mutex_unlock(&dev->up_mutex);
642
643 path_release(&nd);
644fput_and_out:
645 fput_light(filp, fput_needed);
646 return ret;
647}
648
649asmlinkage long sys_inotify_rm_watch(int fd, u32 wd)
650{
651 struct file *filp;
652 struct inotify_device *dev;
653 int ret, fput_needed;
654
655 filp = fget_light(fd, &fput_needed);
656 if (unlikely(!filp))
657 return -EBADF;
658
659 /* verify that this is indeed an inotify instance */
660 if (unlikely(filp->f_op != &inotify_fops)) {
661 ret = -EINVAL;
662 goto out;
663 }
664
665 dev = filp->private_data;
666
667 /* we free our watch data when we get IN_IGNORED */
668 ret = inotify_rm_wd(dev->ih, wd);
669
670out:
671 fput_light(filp, fput_needed);
672 return ret;
673}
674
675static struct super_block *
676inotify_get_sb(struct file_system_type *fs_type, int flags,
677 const char *dev_name, void *data)
678{
679 return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA);
680}
681
682static struct file_system_type inotify_fs_type = {
683 .name = "inotifyfs",
684 .get_sb = inotify_get_sb,
685 .kill_sb = kill_anon_super,
686};
687
688/*
689 * inotify_user_setup - Our initialization function. Note that we cannnot return
690 * error because we have compiled-in VFS hooks. So an (unlikely) failure here
691 * must result in panic().
692 */
693static int __init inotify_user_setup(void)
694{
695 int ret;
696
697 ret = register_filesystem(&inotify_fs_type);
698 if (unlikely(ret))
699 panic("inotify: register_filesystem returned %d!\n", ret);
700
701 inotify_mnt = kern_mount(&inotify_fs_type);
702 if (IS_ERR(inotify_mnt))
703 panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt));
704
705 inotify_max_queued_events = 16384;
706 inotify_max_user_instances = 128;
707 inotify_max_user_watches = 8192;
708
709 watch_cachep = kmem_cache_create("inotify_watch_cache",
710 sizeof(struct inotify_user_watch),
711 0, SLAB_PANIC, NULL, NULL);
712 event_cachep = kmem_cache_create("inotify_event_cache",
713 sizeof(struct inotify_kernel_event),
714 0, SLAB_PANIC, NULL, NULL);
715
716 return 0;
717}
718
719module_init(inotify_user_setup);
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 0ef207dfaf6f..5371a403130a 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -247,7 +247,7 @@ flash_safe_read(struct mtd_info *mtd, loff_t from,
247 D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n", 247 D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",
248 mtd, (unsigned int) from, buf, count)); 248 mtd, (unsigned int) from, buf, count));
249 249
250 res = MTD_READ(mtd, from, count, &retlen, buf); 250 res = mtd->read(mtd, from, count, &retlen, buf);
251 if (retlen != count) { 251 if (retlen != count) {
252 panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res); 252 panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);
253 } 253 }
@@ -262,7 +262,7 @@ flash_read_u32(struct mtd_info *mtd, loff_t from)
262 __u32 ret; 262 __u32 ret;
263 int res; 263 int res;
264 264
265 res = MTD_READ(mtd, from, 4, &retlen, (unsigned char *)&ret); 265 res = mtd->read(mtd, from, 4, &retlen, (unsigned char *)&ret);
266 if (retlen != 4) { 266 if (retlen != 4) {
267 printk("Didn't read all bytes in flash_read_u32(). Returned %d\n", res); 267 printk("Didn't read all bytes in flash_read_u32(). Returned %d\n", res);
268 return 0; 268 return 0;
@@ -282,7 +282,7 @@ flash_safe_write(struct mtd_info *mtd, loff_t to,
282 D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n", 282 D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n",
283 mtd, (unsigned int) to, buf, count)); 283 mtd, (unsigned int) to, buf, count));
284 284
285 res = MTD_WRITE(mtd, to, count, &retlen, buf); 285 res = mtd->write(mtd, to, count, &retlen, buf);
286 if (retlen != count) { 286 if (retlen != count) {
287 printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res); 287 printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);
288 } 288 }
@@ -300,9 +300,9 @@ flash_safe_writev(struct mtd_info *mtd, const struct kvec *vecs,
300 300
301 D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n", 301 D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n",
302 mtd, (unsigned int) to, vecs)); 302 mtd, (unsigned int) to, vecs));
303 303
304 if (mtd->writev) { 304 if (mtd->writev) {
305 res = MTD_WRITEV(mtd, vecs, iovec_cnt, to, &retlen); 305 res = mtd->writev(mtd, vecs, iovec_cnt, to, &retlen);
306 return res ? res : retlen; 306 return res ? res : retlen;
307 } 307 }
308 /* Not implemented writev. Repeatedly use write - on the not so 308 /* Not implemented writev. Repeatedly use write - on the not so
@@ -312,7 +312,8 @@ flash_safe_writev(struct mtd_info *mtd, const struct kvec *vecs,
312 retlen=0; 312 retlen=0;
313 313
314 for (i=0; !res && i<iovec_cnt; i++) { 314 for (i=0; !res && i<iovec_cnt; i++) {
315 res = MTD_WRITE(mtd, to, vecs[i].iov_len, &retlen_a, vecs[i].iov_base); 315 res = mtd->write(mtd, to, vecs[i].iov_len, &retlen_a,
316 vecs[i].iov_base);
316 if (retlen_a != vecs[i].iov_len) { 317 if (retlen_a != vecs[i].iov_len) {
317 printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res); 318 printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res);
318 if (i != iovec_cnt-1) 319 if (i != iovec_cnt-1)
@@ -393,7 +394,7 @@ flash_erase_region(struct mtd_info *mtd, loff_t start,
393 set_current_state(TASK_UNINTERRUPTIBLE); 394 set_current_state(TASK_UNINTERRUPTIBLE);
394 add_wait_queue(&wait_q, &wait); 395 add_wait_queue(&wait_q, &wait);
395 396
396 if (MTD_ERASE(mtd, erase) < 0) { 397 if (mtd->erase(mtd, erase) < 0) {
397 set_current_state(TASK_RUNNING); 398 set_current_state(TASK_RUNNING);
398 remove_wait_queue(&wait_q, &wait); 399 remove_wait_queue(&wait_q, &wait);
399 kfree(erase); 400 kfree(erase);
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index 77dc5561a04e..7f28ee0bd132 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -12,6 +12,9 @@ jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
12jffs2-y += super.o debug.o 12jffs2-y += super.o debug.o
13 13
14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o 14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
15jffs2-$(CONFIG_JFFS2_FS_XATTR) += xattr.o xattr_trusted.o xattr_user.o
16jffs2-$(CONFIG_JFFS2_FS_SECURITY) += security.o
17jffs2-$(CONFIG_JFFS2_FS_POSIX_ACL) += acl.o
15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 18jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
16jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o 19jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
17jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o 20jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
index b7943439b6ec..c8f0bd64e53e 100644
--- a/fs/jffs2/README.Locking
+++ b/fs/jffs2/README.Locking
@@ -150,3 +150,24 @@ the buffer.
150 150
151Ordering constraints: 151Ordering constraints:
152 Lock wbuf_sem last, after the alloc_sem or and f->sem. 152 Lock wbuf_sem last, after the alloc_sem or and f->sem.
153
154
155 c->xattr_sem
156 ------------
157
158This read/write semaphore protects against concurrent access to the
159xattr related objects which include stuff in superblock and ic->xref.
160In read-only path, write-semaphore is too much exclusion. It's enough
161by read-semaphore. But you must hold write-semaphore when updating,
162creating or deleting any xattr related object.
163
164Once xattr_sem released, there would be no assurance for the existence
165of those objects. Thus, a series of processes is often required to retry,
166when updating such a object is necessary under holding read semaphore.
167For example, do_jffs2_getxattr() holds read-semaphore to scan xref and
168xdatum at first. But it retries this process with holding write-semaphore
169after release read-semaphore, if it's necessary to load name/value pair
170from medium.
171
172Ordering constraints:
173 Lock xattr_sem last, after the alloc_sem.
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
new file mode 100644
index 000000000000..320dd48b834e
--- /dev/null
+++ b/fs/jffs2/acl.c
@@ -0,0 +1,485 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/fs.h>
14#include <linux/time.h>
15#include <linux/crc32.h>
16#include <linux/jffs2.h>
17#include <linux/xattr.h>
18#include <linux/posix_acl_xattr.h>
19#include <linux/mtd/mtd.h>
20#include "nodelist.h"
21
22static size_t jffs2_acl_size(int count)
23{
24 if (count <= 4) {
25 return sizeof(struct jffs2_acl_header)
26 + count * sizeof(struct jffs2_acl_entry_short);
27 } else {
28 return sizeof(struct jffs2_acl_header)
29 + 4 * sizeof(struct jffs2_acl_entry_short)
30 + (count - 4) * sizeof(struct jffs2_acl_entry);
31 }
32}
33
34static int jffs2_acl_count(size_t size)
35{
36 size_t s;
37
38 size -= sizeof(struct jffs2_acl_header);
39 s = size - 4 * sizeof(struct jffs2_acl_entry_short);
40 if (s < 0) {
41 if (size % sizeof(struct jffs2_acl_entry_short))
42 return -1;
43 return size / sizeof(struct jffs2_acl_entry_short);
44 } else {
45 if (s % sizeof(struct jffs2_acl_entry))
46 return -1;
47 return s / sizeof(struct jffs2_acl_entry) + 4;
48 }
49}
50
51static struct posix_acl *jffs2_acl_from_medium(void *value, size_t size)
52{
53 void *end = value + size;
54 struct jffs2_acl_header *header = value;
55 struct jffs2_acl_entry *entry;
56 struct posix_acl *acl;
57 uint32_t ver;
58 int i, count;
59
60 if (!value)
61 return NULL;
62 if (size < sizeof(struct jffs2_acl_header))
63 return ERR_PTR(-EINVAL);
64 ver = je32_to_cpu(header->a_version);
65 if (ver != JFFS2_ACL_VERSION) {
66 JFFS2_WARNING("Invalid ACL version. (=%u)\n", ver);
67 return ERR_PTR(-EINVAL);
68 }
69
70 value += sizeof(struct jffs2_acl_header);
71 count = jffs2_acl_count(size);
72 if (count < 0)
73 return ERR_PTR(-EINVAL);
74 if (count == 0)
75 return NULL;
76
77 acl = posix_acl_alloc(count, GFP_KERNEL);
78 if (!acl)
79 return ERR_PTR(-ENOMEM);
80
81 for (i=0; i < count; i++) {
82 entry = value;
83 if (value + sizeof(struct jffs2_acl_entry_short) > end)
84 goto fail;
85 acl->a_entries[i].e_tag = je16_to_cpu(entry->e_tag);
86 acl->a_entries[i].e_perm = je16_to_cpu(entry->e_perm);
87 switch (acl->a_entries[i].e_tag) {
88 case ACL_USER_OBJ:
89 case ACL_GROUP_OBJ:
90 case ACL_MASK:
91 case ACL_OTHER:
92 value += sizeof(struct jffs2_acl_entry_short);
93 acl->a_entries[i].e_id = ACL_UNDEFINED_ID;
94 break;
95
96 case ACL_USER:
97 case ACL_GROUP:
98 value += sizeof(struct jffs2_acl_entry);
99 if (value > end)
100 goto fail;
101 acl->a_entries[i].e_id = je32_to_cpu(entry->e_id);
102 break;
103
104 default:
105 goto fail;
106 }
107 }
108 if (value != end)
109 goto fail;
110 return acl;
111 fail:
112 posix_acl_release(acl);
113 return ERR_PTR(-EINVAL);
114}
115
116static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
117{
118 struct jffs2_acl_header *header;
119 struct jffs2_acl_entry *entry;
120 void *e;
121 size_t i;
122
123 *size = jffs2_acl_size(acl->a_count);
124 header = kmalloc(sizeof(*header) + acl->a_count * sizeof(*entry), GFP_KERNEL);
125 if (!header)
126 return ERR_PTR(-ENOMEM);
127 header->a_version = cpu_to_je32(JFFS2_ACL_VERSION);
128 e = header + 1;
129 for (i=0; i < acl->a_count; i++) {
130 entry = e;
131 entry->e_tag = cpu_to_je16(acl->a_entries[i].e_tag);
132 entry->e_perm = cpu_to_je16(acl->a_entries[i].e_perm);
133 switch(acl->a_entries[i].e_tag) {
134 case ACL_USER:
135 case ACL_GROUP:
136 entry->e_id = cpu_to_je32(acl->a_entries[i].e_id);
137 e += sizeof(struct jffs2_acl_entry);
138 break;
139
140 case ACL_USER_OBJ:
141 case ACL_GROUP_OBJ:
142 case ACL_MASK:
143 case ACL_OTHER:
144 e += sizeof(struct jffs2_acl_entry_short);
145 break;
146
147 default:
148 goto fail;
149 }
150 }
151 return header;
152 fail:
153 kfree(header);
154 return ERR_PTR(-EINVAL);
155}
156
157static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
158{
159 struct posix_acl *acl = JFFS2_ACL_NOT_CACHED;
160
161 spin_lock(&inode->i_lock);
162 if (*i_acl != JFFS2_ACL_NOT_CACHED)
163 acl = posix_acl_dup(*i_acl);
164 spin_unlock(&inode->i_lock);
165 return acl;
166}
167
168static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl)
169{
170 spin_lock(&inode->i_lock);
171 if (*i_acl != JFFS2_ACL_NOT_CACHED)
172 posix_acl_release(*i_acl);
173 *i_acl = posix_acl_dup(acl);
174 spin_unlock(&inode->i_lock);
175}
176
177static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
178{
179 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
180 struct posix_acl *acl;
181 char *value = NULL;
182 int rc, xprefix;
183
184 switch (type) {
185 case ACL_TYPE_ACCESS:
186 acl = jffs2_iget_acl(inode, &f->i_acl_access);
187 if (acl != JFFS2_ACL_NOT_CACHED)
188 return acl;
189 xprefix = JFFS2_XPREFIX_ACL_ACCESS;
190 break;
191 case ACL_TYPE_DEFAULT:
192 acl = jffs2_iget_acl(inode, &f->i_acl_default);
193 if (acl != JFFS2_ACL_NOT_CACHED)
194 return acl;
195 xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
196 break;
197 default:
198 return ERR_PTR(-EINVAL);
199 }
200 rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
201 if (rc > 0) {
202 value = kmalloc(rc, GFP_KERNEL);
203 if (!value)
204 return ERR_PTR(-ENOMEM);
205 rc = do_jffs2_getxattr(inode, xprefix, "", value, rc);
206 }
207 if (rc > 0) {
208 acl = jffs2_acl_from_medium(value, rc);
209 } else if (rc == -ENODATA || rc == -ENOSYS) {
210 acl = NULL;
211 } else {
212 acl = ERR_PTR(rc);
213 }
214 if (value)
215 kfree(value);
216 if (!IS_ERR(acl)) {
217 switch (type) {
218 case ACL_TYPE_ACCESS:
219 jffs2_iset_acl(inode, &f->i_acl_access, acl);
220 break;
221 case ACL_TYPE_DEFAULT:
222 jffs2_iset_acl(inode, &f->i_acl_default, acl);
223 break;
224 }
225 }
226 return acl;
227}
228
229static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
230{
231 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
232 size_t size = 0;
233 char *value = NULL;
234 int rc, xprefix;
235
236 if (S_ISLNK(inode->i_mode))
237 return -EOPNOTSUPP;
238
239 switch (type) {
240 case ACL_TYPE_ACCESS:
241 xprefix = JFFS2_XPREFIX_ACL_ACCESS;
242 if (acl) {
243 mode_t mode = inode->i_mode;
244 rc = posix_acl_equiv_mode(acl, &mode);
245 if (rc < 0)
246 return rc;
247 if (inode->i_mode != mode) {
248 inode->i_mode = mode;
249 jffs2_dirty_inode(inode);
250 }
251 if (rc == 0)
252 acl = NULL;
253 }
254 break;
255 case ACL_TYPE_DEFAULT:
256 xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
257 if (!S_ISDIR(inode->i_mode))
258 return acl ? -EACCES : 0;
259 break;
260 default:
261 return -EINVAL;
262 }
263 if (acl) {
264 value = jffs2_acl_to_medium(acl, &size);
265 if (IS_ERR(value))
266 return PTR_ERR(value);
267 }
268
269 rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
270 if (value)
271 kfree(value);
272 if (!rc) {
273 switch(type) {
274 case ACL_TYPE_ACCESS:
275 jffs2_iset_acl(inode, &f->i_acl_access, acl);
276 break;
277 case ACL_TYPE_DEFAULT:
278 jffs2_iset_acl(inode, &f->i_acl_default, acl);
279 break;
280 }
281 }
282 return rc;
283}
284
285static int jffs2_check_acl(struct inode *inode, int mask)
286{
287 struct posix_acl *acl;
288 int rc;
289
290 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
291 if (IS_ERR(acl))
292 return PTR_ERR(acl);
293 if (acl) {
294 rc = posix_acl_permission(inode, acl, mask);
295 posix_acl_release(acl);
296 return rc;
297 }
298 return -EAGAIN;
299}
300
301int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
302{
303 return generic_permission(inode, mask, jffs2_check_acl);
304}
305
306int jffs2_init_acl(struct inode *inode, struct inode *dir)
307{
308 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
309 struct posix_acl *acl = NULL, *clone;
310 mode_t mode;
311 int rc = 0;
312
313 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
314 f->i_acl_default = JFFS2_ACL_NOT_CACHED;
315 if (!S_ISLNK(inode->i_mode)) {
316 acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT);
317 if (IS_ERR(acl))
318 return PTR_ERR(acl);
319 if (!acl)
320 inode->i_mode &= ~current->fs->umask;
321 }
322 if (acl) {
323 if (S_ISDIR(inode->i_mode)) {
324 rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
325 if (rc)
326 goto cleanup;
327 }
328 clone = posix_acl_clone(acl, GFP_KERNEL);
329 rc = -ENOMEM;
330 if (!clone)
331 goto cleanup;
332 mode = inode->i_mode;
333 rc = posix_acl_create_masq(clone, &mode);
334 if (rc >= 0) {
335 inode->i_mode = mode;
336 if (rc > 0)
337 rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
338 }
339 posix_acl_release(clone);
340 }
341 cleanup:
342 posix_acl_release(acl);
343 return rc;
344}
345
346void jffs2_clear_acl(struct inode *inode)
347{
348 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
349
350 if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
351 posix_acl_release(f->i_acl_access);
352 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
353 }
354 if (f->i_acl_default && f->i_acl_default != JFFS2_ACL_NOT_CACHED) {
355 posix_acl_release(f->i_acl_default);
356 f->i_acl_default = JFFS2_ACL_NOT_CACHED;
357 }
358}
359
360int jffs2_acl_chmod(struct inode *inode)
361{
362 struct posix_acl *acl, *clone;
363 int rc;
364
365 if (S_ISLNK(inode->i_mode))
366 return -EOPNOTSUPP;
367 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
368 if (IS_ERR(acl) || !acl)
369 return PTR_ERR(acl);
370 clone = posix_acl_clone(acl, GFP_KERNEL);
371 posix_acl_release(acl);
372 if (!clone)
373 return -ENOMEM;
374 rc = posix_acl_chmod_masq(clone, inode->i_mode);
375 if (!rc)
376 rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
377 posix_acl_release(clone);
378 return rc;
379}
380
381static size_t jffs2_acl_access_listxattr(struct inode *inode, char *list, size_t list_size,
382 const char *name, size_t name_len)
383{
384 const int retlen = sizeof(POSIX_ACL_XATTR_ACCESS);
385
386 if (list && retlen <= list_size)
387 strcpy(list, POSIX_ACL_XATTR_ACCESS);
388 return retlen;
389}
390
391static size_t jffs2_acl_default_listxattr(struct inode *inode, char *list, size_t list_size,
392 const char *name, size_t name_len)
393{
394 const int retlen = sizeof(POSIX_ACL_XATTR_DEFAULT);
395
396 if (list && retlen <= list_size)
397 strcpy(list, POSIX_ACL_XATTR_DEFAULT);
398 return retlen;
399}
400
401static int jffs2_acl_getxattr(struct inode *inode, int type, void *buffer, size_t size)
402{
403 struct posix_acl *acl;
404 int rc;
405
406 acl = jffs2_get_acl(inode, type);
407 if (IS_ERR(acl))
408 return PTR_ERR(acl);
409 if (!acl)
410 return -ENODATA;
411 rc = posix_acl_to_xattr(acl, buffer, size);
412 posix_acl_release(acl);
413
414 return rc;
415}
416
417static int jffs2_acl_access_getxattr(struct inode *inode, const char *name, void *buffer, size_t size)
418{
419 if (name[0] != '\0')
420 return -EINVAL;
421 return jffs2_acl_getxattr(inode, ACL_TYPE_ACCESS, buffer, size);
422}
423
424static int jffs2_acl_default_getxattr(struct inode *inode, const char *name, void *buffer, size_t size)
425{
426 if (name[0] != '\0')
427 return -EINVAL;
428 return jffs2_acl_getxattr(inode, ACL_TYPE_DEFAULT, buffer, size);
429}
430
431static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value, size_t size)
432{
433 struct posix_acl *acl;
434 int rc;
435
436 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
437 return -EPERM;
438
439 if (value) {
440 acl = posix_acl_from_xattr(value, size);
441 if (IS_ERR(acl))
442 return PTR_ERR(acl);
443 if (acl) {
444 rc = posix_acl_valid(acl);
445 if (rc)
446 goto out;
447 }
448 } else {
449 acl = NULL;
450 }
451 rc = jffs2_set_acl(inode, type, acl);
452 out:
453 posix_acl_release(acl);
454 return rc;
455}
456
457static int jffs2_acl_access_setxattr(struct inode *inode, const char *name,
458 const void *buffer, size_t size, int flags)
459{
460 if (name[0] != '\0')
461 return -EINVAL;
462 return jffs2_acl_setxattr(inode, ACL_TYPE_ACCESS, buffer, size);
463}
464
465static int jffs2_acl_default_setxattr(struct inode *inode, const char *name,
466 const void *buffer, size_t size, int flags)
467{
468 if (name[0] != '\0')
469 return -EINVAL;
470 return jffs2_acl_setxattr(inode, ACL_TYPE_DEFAULT, buffer, size);
471}
472
473struct xattr_handler jffs2_acl_access_xattr_handler = {
474 .prefix = POSIX_ACL_XATTR_ACCESS,
475 .list = jffs2_acl_access_listxattr,
476 .get = jffs2_acl_access_getxattr,
477 .set = jffs2_acl_access_setxattr,
478};
479
480struct xattr_handler jffs2_acl_default_xattr_handler = {
481 .prefix = POSIX_ACL_XATTR_DEFAULT,
482 .list = jffs2_acl_default_listxattr,
483 .get = jffs2_acl_default_getxattr,
484 .set = jffs2_acl_default_setxattr,
485};
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
new file mode 100644
index 000000000000..8893bd1a6ba7
--- /dev/null
+++ b/fs/jffs2/acl.h
@@ -0,0 +1,45 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11struct jffs2_acl_entry {
12 jint16_t e_tag;
13 jint16_t e_perm;
14 jint32_t e_id;
15};
16
17struct jffs2_acl_entry_short {
18 jint16_t e_tag;
19 jint16_t e_perm;
20};
21
22struct jffs2_acl_header {
23 jint32_t a_version;
24};
25
26#ifdef CONFIG_JFFS2_FS_POSIX_ACL
27
28#define JFFS2_ACL_NOT_CACHED ((void *)-1)
29
30extern int jffs2_permission(struct inode *, int, struct nameidata *);
31extern int jffs2_acl_chmod(struct inode *);
32extern int jffs2_init_acl(struct inode *, struct inode *);
33extern void jffs2_clear_acl(struct inode *);
34
35extern struct xattr_handler jffs2_acl_access_xattr_handler;
36extern struct xattr_handler jffs2_acl_default_xattr_handler;
37
38#else
39
40#define jffs2_permission NULL
41#define jffs2_acl_chmod(inode) (0)
42#define jffs2_init_acl(inode,dir) (0)
43#define jffs2_clear_acl(inode)
44
45#endif /* CONFIG_JFFS2_FS_POSIX_ACL */
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 70f7a896c04a..02826967ab58 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -160,6 +160,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
160 ic->scan_dents = NULL; 160 ic->scan_dents = NULL;
161 cond_resched(); 161 cond_resched();
162 } 162 }
163 jffs2_build_xattr_subsystem(c);
163 c->flags &= ~JFFS2_SB_FLAG_BUILDING; 164 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
164 165
165 dbg_fsbuild("FS build complete\n"); 166 dbg_fsbuild("FS build complete\n");
@@ -178,6 +179,7 @@ exit:
178 jffs2_free_full_dirent(fd); 179 jffs2_free_full_dirent(fd);
179 } 180 }
180 } 181 }
182 jffs2_clear_xattr_subsystem(c);
181 } 183 }
182 184
183 return ret; 185 return ret;
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index e7944e665b9f..7001ba26c067 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -412,7 +412,7 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
412 kfree(comprbuf); 412 kfree(comprbuf);
413} 413}
414 414
415int jffs2_compressors_init(void) 415int __init jffs2_compressors_init(void)
416{ 416{
417/* Registering compressors */ 417/* Registering compressors */
418#ifdef CONFIG_JFFS2_ZLIB 418#ifdef CONFIG_JFFS2_ZLIB
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
index a77e830d85c5..509b8b1c0811 100644
--- a/fs/jffs2/compr.h
+++ b/fs/jffs2/compr.h
@@ -23,8 +23,8 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/jffs2.h> 25#include <linux/jffs2.h>
26#include <linux/jffs2_fs_i.h> 26#include "jffs2_fs_i.h"
27#include <linux/jffs2_fs_sb.h> 27#include "jffs2_fs_sb.h"
28#include "nodelist.h" 28#include "nodelist.h"
29 29
30#define JFFS2_RUBINMIPS_PRIORITY 10 30#define JFFS2_RUBINMIPS_PRIORITY 10
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
index 1fe17de713e8..72b4fc13a106 100644
--- a/fs/jffs2/debug.c
+++ b/fs/jffs2/debug.c
@@ -192,13 +192,13 @@ __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
192 else 192 else
193 my_dirty_size += totlen; 193 my_dirty_size += totlen;
194 194
195 if ((!ref2->next_phys) != (ref2 == jeb->last_node)) { 195 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
196 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), last_node is at %#08x (mem %p).\n", 196 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
197 ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys, 197 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
198 ref_offset(jeb->last_node), jeb->last_node); 198 ref_offset(jeb->last_node), jeb->last_node);
199 goto error; 199 goto error;
200 } 200 }
201 ref2 = ref2->next_phys; 201 ref2 = ref_next(ref2);
202 } 202 }
203 203
204 if (my_used_size != jeb->used_size) { 204 if (my_used_size != jeb->used_size) {
@@ -268,9 +268,9 @@ __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
268 } 268 }
269 269
270 printk(JFFS2_DBG); 270 printk(JFFS2_DBG);
271 for (ref = jeb->first_node; ; ref = ref->next_phys) { 271 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
272 printk("%#08x(%#x)", ref_offset(ref), ref->__totlen); 272 printk("%#08x(%#x)", ref_offset(ref), ref->__totlen);
273 if (ref->next_phys) 273 if (ref_next(ref))
274 printk("->"); 274 printk("->");
275 else 275 else
276 break; 276 break;
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 162af6dfe292..5fa494a792b2 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -171,6 +171,12 @@
171#define dbg_memalloc(fmt, ...) 171#define dbg_memalloc(fmt, ...)
172#endif 172#endif
173 173
174/* Watch the XATTR subsystem */
175#ifdef JFFS2_DBG_XATTR_MESSAGES
176#define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
177#else
178#define dbg_xattr(fmt, ...)
179#endif
174 180
175/* "Sanity" checks */ 181/* "Sanity" checks */
176void 182void
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 8bc7a5018e40..edd8371fc6a5 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -17,8 +17,8 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/crc32.h> 18#include <linux/crc32.h>
19#include <linux/jffs2.h> 19#include <linux/jffs2.h>
20#include <linux/jffs2_fs_i.h> 20#include "jffs2_fs_i.h"
21#include <linux/jffs2_fs_sb.h> 21#include "jffs2_fs_sb.h"
22#include <linux/time.h> 22#include <linux/time.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
@@ -57,7 +57,12 @@ struct inode_operations jffs2_dir_inode_operations =
57 .rmdir = jffs2_rmdir, 57 .rmdir = jffs2_rmdir,
58 .mknod = jffs2_mknod, 58 .mknod = jffs2_mknod,
59 .rename = jffs2_rename, 59 .rename = jffs2_rename,
60 .permission = jffs2_permission,
60 .setattr = jffs2_setattr, 61 .setattr = jffs2_setattr,
62 .setxattr = jffs2_setxattr,
63 .getxattr = jffs2_getxattr,
64 .listxattr = jffs2_listxattr,
65 .removexattr = jffs2_removexattr
61}; 66};
62 67
63/***********************************************************************/ 68/***********************************************************************/
@@ -78,6 +83,9 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
78 83
79 D1(printk(KERN_DEBUG "jffs2_lookup()\n")); 84 D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
80 85
86 if (target->d_name.len > JFFS2_MAX_NAME_LEN)
87 return ERR_PTR(-ENAMETOOLONG);
88
81 dir_f = JFFS2_INODE_INFO(dir_i); 89 dir_f = JFFS2_INODE_INFO(dir_i);
82 c = JFFS2_SB_INFO(dir_i->i_sb); 90 c = JFFS2_SB_INFO(dir_i->i_sb);
83 91
@@ -206,12 +214,15 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
206 ret = jffs2_do_create(c, dir_f, f, ri, 214 ret = jffs2_do_create(c, dir_f, f, ri,
207 dentry->d_name.name, dentry->d_name.len); 215 dentry->d_name.name, dentry->d_name.len);
208 216
209 if (ret) { 217 if (ret)
210 make_bad_inode(inode); 218 goto fail;
211 iput(inode); 219
212 jffs2_free_raw_inode(ri); 220 ret = jffs2_init_security(inode, dir_i);
213 return ret; 221 if (ret)
214 } 222 goto fail;
223 ret = jffs2_init_acl(inode, dir_i);
224 if (ret)
225 goto fail;
215 226
216 dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); 227 dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
217 228
@@ -221,6 +232,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
221 D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", 232 D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
222 inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); 233 inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
223 return 0; 234 return 0;
235
236 fail:
237 make_bad_inode(inode);
238 iput(inode);
239 jffs2_free_raw_inode(ri);
240 return ret;
224} 241}
225 242
226/***********************************************************************/ 243/***********************************************************************/
@@ -291,7 +308,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
291 struct jffs2_full_dnode *fn; 308 struct jffs2_full_dnode *fn;
292 struct jffs2_full_dirent *fd; 309 struct jffs2_full_dirent *fd;
293 int namelen; 310 int namelen;
294 uint32_t alloclen, phys_ofs; 311 uint32_t alloclen;
295 int ret, targetlen = strlen(target); 312 int ret, targetlen = strlen(target);
296 313
297 /* FIXME: If you care. We'd need to use frags for the target 314 /* FIXME: If you care. We'd need to use frags for the target
@@ -310,8 +327,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
310 * Just the node will do for now, though 327 * Just the node will do for now, though
311 */ 328 */
312 namelen = dentry->d_name.len; 329 namelen = dentry->d_name.len;
313 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, 330 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen,
314 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 331 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
315 332
316 if (ret) { 333 if (ret) {
317 jffs2_free_raw_inode(ri); 334 jffs2_free_raw_inode(ri);
@@ -339,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
339 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen)); 356 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
340 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 357 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
341 358
342 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL); 359 fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL);
343 360
344 jffs2_free_raw_inode(ri); 361 jffs2_free_raw_inode(ri);
345 362
@@ -371,8 +388,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
371 up(&f->sem); 388 up(&f->sem);
372 389
373 jffs2_complete_reservation(c); 390 jffs2_complete_reservation(c);
374 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 391
375 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 392 ret = jffs2_init_security(inode, dir_i);
393 if (ret) {
394 jffs2_clear_inode(inode);
395 return ret;
396 }
397 ret = jffs2_init_acl(inode, dir_i);
398 if (ret) {
399 jffs2_clear_inode(inode);
400 return ret;
401 }
402
403 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
404 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
376 if (ret) { 405 if (ret) {
377 /* Eep. */ 406 /* Eep. */
378 jffs2_clear_inode(inode); 407 jffs2_clear_inode(inode);
@@ -404,7 +433,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
404 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 433 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
405 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); 434 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
406 435
407 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 436 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
408 437
409 if (IS_ERR(fd)) { 438 if (IS_ERR(fd)) {
410 /* dirent failed to write. Delete the inode normally 439 /* dirent failed to write. Delete the inode normally
@@ -442,7 +471,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
442 struct jffs2_full_dnode *fn; 471 struct jffs2_full_dnode *fn;
443 struct jffs2_full_dirent *fd; 472 struct jffs2_full_dirent *fd;
444 int namelen; 473 int namelen;
445 uint32_t alloclen, phys_ofs; 474 uint32_t alloclen;
446 int ret; 475 int ret;
447 476
448 mode |= S_IFDIR; 477 mode |= S_IFDIR;
@@ -457,8 +486,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
457 * Just the node will do for now, though 486 * Just the node will do for now, though
458 */ 487 */
459 namelen = dentry->d_name.len; 488 namelen = dentry->d_name.len;
460 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, 489 ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
461 JFFS2_SUMMARY_INODE_SIZE); 490 JFFS2_SUMMARY_INODE_SIZE);
462 491
463 if (ret) { 492 if (ret) {
464 jffs2_free_raw_inode(ri); 493 jffs2_free_raw_inode(ri);
@@ -483,7 +512,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
483 ri->data_crc = cpu_to_je32(0); 512 ri->data_crc = cpu_to_je32(0);
484 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 513 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
485 514
486 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 515 fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
487 516
488 jffs2_free_raw_inode(ri); 517 jffs2_free_raw_inode(ri);
489 518
@@ -501,8 +530,20 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
501 up(&f->sem); 530 up(&f->sem);
502 531
503 jffs2_complete_reservation(c); 532 jffs2_complete_reservation(c);
504 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 533
505 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 534 ret = jffs2_init_security(inode, dir_i);
535 if (ret) {
536 jffs2_clear_inode(inode);
537 return ret;
538 }
539 ret = jffs2_init_acl(inode, dir_i);
540 if (ret) {
541 jffs2_clear_inode(inode);
542 return ret;
543 }
544
545 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
546 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
506 if (ret) { 547 if (ret) {
507 /* Eep. */ 548 /* Eep. */
508 jffs2_clear_inode(inode); 549 jffs2_clear_inode(inode);
@@ -534,7 +575,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
534 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 575 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
535 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); 576 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
536 577
537 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 578 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
538 579
539 if (IS_ERR(fd)) { 580 if (IS_ERR(fd)) {
540 /* dirent failed to write. Delete the inode normally 581 /* dirent failed to write. Delete the inode normally
@@ -588,12 +629,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
588 struct jffs2_full_dnode *fn; 629 struct jffs2_full_dnode *fn;
589 struct jffs2_full_dirent *fd; 630 struct jffs2_full_dirent *fd;
590 int namelen; 631 int namelen;
591 jint16_t dev; 632 union jffs2_device_node dev;
592 int devlen = 0; 633 int devlen = 0;
593 uint32_t alloclen, phys_ofs; 634 uint32_t alloclen;
594 int ret; 635 int ret;
595 636
596 if (!old_valid_dev(rdev)) 637 if (!new_valid_dev(rdev))
597 return -EINVAL; 638 return -EINVAL;
598 639
599 ri = jffs2_alloc_raw_inode(); 640 ri = jffs2_alloc_raw_inode();
@@ -602,17 +643,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
602 643
603 c = JFFS2_SB_INFO(dir_i->i_sb); 644 c = JFFS2_SB_INFO(dir_i->i_sb);
604 645
605 if (S_ISBLK(mode) || S_ISCHR(mode)) { 646 if (S_ISBLK(mode) || S_ISCHR(mode))
606 dev = cpu_to_je16(old_encode_dev(rdev)); 647 devlen = jffs2_encode_dev(&dev, rdev);
607 devlen = sizeof(dev);
608 }
609 648
610 /* Try to reserve enough space for both node and dirent. 649 /* Try to reserve enough space for both node and dirent.
611 * Just the node will do for now, though 650 * Just the node will do for now, though
612 */ 651 */
613 namelen = dentry->d_name.len; 652 namelen = dentry->d_name.len;
614 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, 653 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen,
615 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 654 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
616 655
617 if (ret) { 656 if (ret) {
618 jffs2_free_raw_inode(ri); 657 jffs2_free_raw_inode(ri);
@@ -639,7 +678,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
639 ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); 678 ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
640 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 679 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
641 680
642 fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); 681 fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL);
643 682
644 jffs2_free_raw_inode(ri); 683 jffs2_free_raw_inode(ri);
645 684
@@ -657,8 +696,20 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
657 up(&f->sem); 696 up(&f->sem);
658 697
659 jffs2_complete_reservation(c); 698 jffs2_complete_reservation(c);
660 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 699
661 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 700 ret = jffs2_init_security(inode, dir_i);
701 if (ret) {
702 jffs2_clear_inode(inode);
703 return ret;
704 }
705 ret = jffs2_init_acl(inode, dir_i);
706 if (ret) {
707 jffs2_clear_inode(inode);
708 return ret;
709 }
710
711 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
712 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
662 if (ret) { 713 if (ret) {
663 /* Eep. */ 714 /* Eep. */
664 jffs2_clear_inode(inode); 715 jffs2_clear_inode(inode);
@@ -693,7 +744,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
693 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 744 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
694 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); 745 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
695 746
696 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); 747 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
697 748
698 if (IS_ERR(fd)) { 749 if (IS_ERR(fd)) {
699 /* dirent failed to write. Delete the inode normally 750 /* dirent failed to write. Delete the inode normally
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index dad68fdffe9e..1862e8bc101d 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -30,7 +30,6 @@ static void jffs2_erase_callback(struct erase_info *);
30#endif 30#endif
31static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); 31static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
32static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 32static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
33static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
34static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 33static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
35 34
36static void jffs2_erase_block(struct jffs2_sb_info *c, 35static void jffs2_erase_block(struct jffs2_sb_info *c,
@@ -136,7 +135,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
136 c->used_size -= jeb->used_size; 135 c->used_size -= jeb->used_size;
137 c->dirty_size -= jeb->dirty_size; 136 c->dirty_size -= jeb->dirty_size;
138 jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0; 137 jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
139 jffs2_free_all_node_refs(c, jeb); 138 jffs2_free_jeb_node_refs(c, jeb);
140 list_add(&jeb->list, &c->erasing_list); 139 list_add(&jeb->list, &c->erasing_list);
141 spin_unlock(&c->erase_completion_lock); 140 spin_unlock(&c->erase_completion_lock);
142 141
@@ -231,6 +230,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
231 at the end of the linked list. Stash it and continue 230 at the end of the linked list. Stash it and continue
232 from the beginning of the list */ 231 from the beginning of the list */
233 ic = (struct jffs2_inode_cache *)(*prev); 232 ic = (struct jffs2_inode_cache *)(*prev);
233 BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
234 prev = &ic->nodes; 234 prev = &ic->nodes;
235 continue; 235 continue;
236 } 236 }
@@ -283,22 +283,27 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
283 jffs2_del_ino_cache(c, ic); 283 jffs2_del_ino_cache(c, ic);
284} 284}
285 285
286static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 286void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
287{ 287{
288 struct jffs2_raw_node_ref *ref; 288 struct jffs2_raw_node_ref *block, *ref;
289 D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); 289 D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset));
290 while(jeb->first_node) {
291 ref = jeb->first_node;
292 jeb->first_node = ref->next_phys;
293 290
294 /* Remove from the inode-list */ 291 block = ref = jeb->first_node;
295 if (ref->next_in_ino) 292
293 while (ref) {
294 if (ref->flash_offset == REF_LINK_NODE) {
295 ref = ref->next_in_ino;
296 jffs2_free_refblock(block);
297 block = ref;
298 continue;
299 }
300 if (ref->flash_offset != REF_EMPTY_NODE && ref->next_in_ino)
296 jffs2_remove_node_refs_from_ino_list(c, ref, jeb); 301 jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
297 /* else it was a non-inode node or already removed, so don't bother */ 302 /* else it was a non-inode node or already removed, so don't bother */
298 303
299 jffs2_free_raw_node_ref(ref); 304 ref++;
300 } 305 }
301 jeb->last_node = NULL; 306 jeb->first_node = jeb->last_node = NULL;
302} 307}
303 308
304static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset) 309static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset)
@@ -351,7 +356,6 @@ fail:
351 356
352static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 357static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
353{ 358{
354 struct jffs2_raw_node_ref *marker_ref = NULL;
355 size_t retlen; 359 size_t retlen;
356 int ret; 360 int ret;
357 uint32_t bad_offset; 361 uint32_t bad_offset;
@@ -373,12 +377,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
373 goto filebad; 377 goto filebad;
374 } 378 }
375 379
376 jeb->first_node = jeb->last_node = NULL; 380 /* Everything else got zeroed before the erase */
377 jeb->free_size = c->sector_size; 381 jeb->free_size = c->sector_size;
378 jeb->used_size = 0;
379 jeb->dirty_size = 0;
380 jeb->wasted_size = 0;
381
382 } else { 382 } else {
383 383
384 struct kvec vecs[1]; 384 struct kvec vecs[1];
@@ -388,11 +388,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
388 .totlen = cpu_to_je32(c->cleanmarker_size) 388 .totlen = cpu_to_je32(c->cleanmarker_size)
389 }; 389 };
390 390
391 marker_ref = jffs2_alloc_raw_node_ref(); 391 jffs2_prealloc_raw_node_refs(c, jeb, 1);
392 if (!marker_ref) {
393 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n");
394 goto refile;
395 }
396 392
397 marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); 393 marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
398 394
@@ -408,21 +404,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
408 printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n", 404 printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
409 jeb->offset, sizeof(marker), retlen); 405 jeb->offset, sizeof(marker), retlen);
410 406
411 jffs2_free_raw_node_ref(marker_ref);
412 goto filebad; 407 goto filebad;
413 } 408 }
414 409
415 marker_ref->next_in_ino = NULL; 410 /* Everything else got zeroed before the erase */
416 marker_ref->next_phys = NULL; 411 jeb->free_size = c->sector_size;
417 marker_ref->flash_offset = jeb->offset | REF_NORMAL; 412 /* FIXME Special case for cleanmarker in empty block */
418 marker_ref->__totlen = c->cleanmarker_size; 413 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
419
420 jeb->first_node = jeb->last_node = marker_ref;
421
422 jeb->free_size = c->sector_size - c->cleanmarker_size;
423 jeb->used_size = c->cleanmarker_size;
424 jeb->dirty_size = 0;
425 jeb->wasted_size = 0;
426 } 414 }
427 415
428 spin_lock(&c->erase_completion_lock); 416 spin_lock(&c->erase_completion_lock);
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 9f4171213e58..bb8844f40e48 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -54,7 +54,12 @@ const struct file_operations jffs2_file_operations =
54 54
55struct inode_operations jffs2_file_inode_operations = 55struct inode_operations jffs2_file_inode_operations =
56{ 56{
57 .setattr = jffs2_setattr 57 .permission = jffs2_permission,
58 .setattr = jffs2_setattr,
59 .setxattr = jffs2_setxattr,
60 .getxattr = jffs2_getxattr,
61 .listxattr = jffs2_listxattr,
62 .removexattr = jffs2_removexattr
58}; 63};
59 64
60struct address_space_operations jffs2_file_address_operations = 65struct address_space_operations jffs2_file_address_operations =
@@ -129,13 +134,13 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
129 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 134 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
130 struct jffs2_raw_inode ri; 135 struct jffs2_raw_inode ri;
131 struct jffs2_full_dnode *fn; 136 struct jffs2_full_dnode *fn;
132 uint32_t phys_ofs, alloc_len; 137 uint32_t alloc_len;
133 138
134 D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", 139 D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
135 (unsigned int)inode->i_size, pageofs)); 140 (unsigned int)inode->i_size, pageofs));
136 141
137 ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, 142 ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
138 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 143 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
139 if (ret) 144 if (ret)
140 return ret; 145 return ret;
141 146
@@ -161,7 +166,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
161 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 166 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
162 ri.data_crc = cpu_to_je32(0); 167 ri.data_crc = cpu_to_je32(0);
163 168
164 fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 169 fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_NORMAL);
165 170
166 if (IS_ERR(fn)) { 171 if (IS_ERR(fn)) {
167 ret = PTR_ERR(fn); 172 ret = PTR_ERR(fn);
@@ -215,12 +220,20 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
215 D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", 220 D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
216 inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); 221 inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
217 222
218 if (!start && end == PAGE_CACHE_SIZE) { 223 if (end == PAGE_CACHE_SIZE) {
219 /* We need to avoid deadlock with page_cache_read() in 224 if (!start) {
220 jffs2_garbage_collect_pass(). So we have to mark the 225 /* We need to avoid deadlock with page_cache_read() in
221 page up to date, to prevent page_cache_read() from 226 jffs2_garbage_collect_pass(). So we have to mark the
222 trying to re-lock it. */ 227 page up to date, to prevent page_cache_read() from
223 SetPageUptodate(pg); 228 trying to re-lock it. */
229 SetPageUptodate(pg);
230 } else {
231 /* When writing out the end of a page, write out the
232 _whole_ page. This helps to reduce the number of
233 nodes in files which have many short writes, like
234 syslog files. */
235 start = aligned_start = 0;
236 }
224 } 237 }
225 238
226 ri = jffs2_alloc_raw_inode(); 239 ri = jffs2_alloc_raw_inode();
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 09e5d10b8840..7b6c24b14f85 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -33,11 +33,11 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
33 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 33 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
34 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 34 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
35 struct jffs2_raw_inode *ri; 35 struct jffs2_raw_inode *ri;
36 unsigned short dev; 36 union jffs2_device_node dev;
37 unsigned char *mdata = NULL; 37 unsigned char *mdata = NULL;
38 int mdatalen = 0; 38 int mdatalen = 0;
39 unsigned int ivalid; 39 unsigned int ivalid;
40 uint32_t phys_ofs, alloclen; 40 uint32_t alloclen;
41 int ret; 41 int ret;
42 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); 42 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
43 ret = inode_change_ok(inode, iattr); 43 ret = inode_change_ok(inode, iattr);
@@ -51,20 +51,24 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
51 it out again with the appropriate data attached */ 51 it out again with the appropriate data attached */
52 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { 52 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
53 /* For these, we don't actually need to read the old node */ 53 /* For these, we don't actually need to read the old node */
54 dev = old_encode_dev(inode->i_rdev); 54 mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
55 mdata = (char *)&dev; 55 mdata = (char *)&dev;
56 mdatalen = sizeof(dev);
57 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); 56 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
58 } else if (S_ISLNK(inode->i_mode)) { 57 } else if (S_ISLNK(inode->i_mode)) {
58 down(&f->sem);
59 mdatalen = f->metadata->size; 59 mdatalen = f->metadata->size;
60 mdata = kmalloc(f->metadata->size, GFP_USER); 60 mdata = kmalloc(f->metadata->size, GFP_USER);
61 if (!mdata) 61 if (!mdata) {
62 up(&f->sem);
62 return -ENOMEM; 63 return -ENOMEM;
64 }
63 ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); 65 ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
64 if (ret) { 66 if (ret) {
67 up(&f->sem);
65 kfree(mdata); 68 kfree(mdata);
66 return ret; 69 return ret;
67 } 70 }
71 up(&f->sem);
68 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); 72 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
69 } 73 }
70 74
@@ -75,8 +79,8 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
75 return -ENOMEM; 79 return -ENOMEM;
76 } 80 }
77 81
78 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, 82 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen,
79 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 83 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
80 if (ret) { 84 if (ret) {
81 jffs2_free_raw_inode(ri); 85 jffs2_free_raw_inode(ri);
82 if (S_ISLNK(inode->i_mode & S_IFMT)) 86 if (S_ISLNK(inode->i_mode & S_IFMT))
@@ -127,7 +131,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
127 else 131 else
128 ri->data_crc = cpu_to_je32(0); 132 ri->data_crc = cpu_to_je32(0);
129 133
130 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL); 134 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, ALLOC_NORMAL);
131 if (S_ISLNK(inode->i_mode)) 135 if (S_ISLNK(inode->i_mode))
132 kfree(mdata); 136 kfree(mdata);
133 137
@@ -180,7 +184,12 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
180 184
181int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) 185int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
182{ 186{
183 return jffs2_do_setattr(dentry->d_inode, iattr); 187 int rc;
188
189 rc = jffs2_do_setattr(dentry->d_inode, iattr);
190 if (!rc && (iattr->ia_valid & ATTR_MODE))
191 rc = jffs2_acl_chmod(dentry->d_inode);
192 return rc;
184} 193}
185 194
186int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) 195int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
@@ -219,6 +228,7 @@ void jffs2_clear_inode (struct inode *inode)
219 228
220 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); 229 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
221 230
231 jffs2_xattr_delete_inode(c, f->inocache);
222 jffs2_do_clear_inode(c, f); 232 jffs2_do_clear_inode(c, f);
223} 233}
224 234
@@ -227,6 +237,8 @@ void jffs2_read_inode (struct inode *inode)
227 struct jffs2_inode_info *f; 237 struct jffs2_inode_info *f;
228 struct jffs2_sb_info *c; 238 struct jffs2_sb_info *c;
229 struct jffs2_raw_inode latest_node; 239 struct jffs2_raw_inode latest_node;
240 union jffs2_device_node jdev;
241 dev_t rdev = 0;
230 int ret; 242 int ret;
231 243
232 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); 244 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
@@ -258,7 +270,6 @@ void jffs2_read_inode (struct inode *inode)
258 inode->i_blocks = (inode->i_size + 511) >> 9; 270 inode->i_blocks = (inode->i_size + 511) >> 9;
259 271
260 switch (inode->i_mode & S_IFMT) { 272 switch (inode->i_mode & S_IFMT) {
261 jint16_t rdev;
262 273
263 case S_IFLNK: 274 case S_IFLNK:
264 inode->i_op = &jffs2_symlink_inode_operations; 275 inode->i_op = &jffs2_symlink_inode_operations;
@@ -292,8 +303,16 @@ void jffs2_read_inode (struct inode *inode)
292 case S_IFBLK: 303 case S_IFBLK:
293 case S_IFCHR: 304 case S_IFCHR:
294 /* Read the device numbers from the media */ 305 /* Read the device numbers from the media */
306 if (f->metadata->size != sizeof(jdev.old) &&
307 f->metadata->size != sizeof(jdev.new)) {
308 printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
309 up(&f->sem);
310 jffs2_do_clear_inode(c, f);
311 make_bad_inode(inode);
312 return;
313 }
295 D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); 314 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
296 if (jffs2_read_dnode(c, f, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) { 315 if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) {
297 /* Eep */ 316 /* Eep */
298 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); 317 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
299 up(&f->sem); 318 up(&f->sem);
@@ -301,12 +320,15 @@ void jffs2_read_inode (struct inode *inode)
301 make_bad_inode(inode); 320 make_bad_inode(inode);
302 return; 321 return;
303 } 322 }
323 if (f->metadata->size == sizeof(jdev.old))
324 rdev = old_decode_dev(je16_to_cpu(jdev.old));
325 else
326 rdev = new_decode_dev(je32_to_cpu(jdev.new));
304 327
305 case S_IFSOCK: 328 case S_IFSOCK:
306 case S_IFIFO: 329 case S_IFIFO:
307 inode->i_op = &jffs2_file_inode_operations; 330 inode->i_op = &jffs2_file_inode_operations;
308 init_special_inode(inode, inode->i_mode, 331 init_special_inode(inode, inode->i_mode, rdev);
309 old_decode_dev((je16_to_cpu(rdev))));
310 break; 332 break;
311 333
312 default: 334 default:
@@ -492,6 +514,8 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
492 } 514 }
493 memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *)); 515 memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
494 516
517 jffs2_init_xattr_subsystem(c);
518
495 if ((ret = jffs2_do_mount_fs(c))) 519 if ((ret = jffs2_do_mount_fs(c)))
496 goto out_inohash; 520 goto out_inohash;
497 521
@@ -526,6 +550,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
526 else 550 else
527 kfree(c->blocks); 551 kfree(c->blocks);
528 out_inohash: 552 out_inohash:
553 jffs2_clear_xattr_subsystem(c);
529 kfree(c->inocache_list); 554 kfree(c->inocache_list);
530 out_wbuf: 555 out_wbuf:
531 jffs2_flash_cleanup(c); 556 jffs2_flash_cleanup(c);
@@ -639,13 +664,6 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
639 return ret; 664 return ret;
640 } 665 }
641 666
642 /* add setups for other bizarre flashes here... */
643 if (jffs2_nor_ecc(c)) {
644 ret = jffs2_nor_ecc_flash_setup(c);
645 if (ret)
646 return ret;
647 }
648
649 /* and Dataflash */ 667 /* and Dataflash */
650 if (jffs2_dataflash(c)) { 668 if (jffs2_dataflash(c)) {
651 ret = jffs2_dataflash_setup(c); 669 ret = jffs2_dataflash_setup(c);
@@ -669,11 +687,6 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
669 jffs2_nand_flash_cleanup(c); 687 jffs2_nand_flash_cleanup(c);
670 } 688 }
671 689
672 /* add cleanups for other bizarre flashes here... */
673 if (jffs2_nor_ecc(c)) {
674 jffs2_nor_ecc_flash_cleanup(c);
675 }
676
677 /* and DataFlash */ 690 /* and DataFlash */
678 if (jffs2_dataflash(c)) { 691 if (jffs2_dataflash(c)) {
679 jffs2_dataflash_cleanup(c); 692 jffs2_dataflash_cleanup(c);
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index f9ffece453a3..477c526d638b 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -125,6 +125,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
125 struct jffs2_eraseblock *jeb; 125 struct jffs2_eraseblock *jeb;
126 struct jffs2_raw_node_ref *raw; 126 struct jffs2_raw_node_ref *raw;
127 int ret = 0, inum, nlink; 127 int ret = 0, inum, nlink;
128 int xattr = 0;
128 129
129 if (down_interruptible(&c->alloc_sem)) 130 if (down_interruptible(&c->alloc_sem))
130 return -EINTR; 131 return -EINTR;
@@ -138,7 +139,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
138 the node CRCs etc. Do it now. */ 139 the node CRCs etc. Do it now. */
139 140
140 /* checked_ino is protected by the alloc_sem */ 141 /* checked_ino is protected by the alloc_sem */
141 if (c->checked_ino > c->highest_ino) { 142 if (c->checked_ino > c->highest_ino && xattr) {
142 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", 143 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
143 c->unchecked_size); 144 c->unchecked_size);
144 jffs2_dbg_dump_block_lists_nolock(c); 145 jffs2_dbg_dump_block_lists_nolock(c);
@@ -148,6 +149,9 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
148 149
149 spin_unlock(&c->erase_completion_lock); 150 spin_unlock(&c->erase_completion_lock);
150 151
152 if (!xattr)
153 xattr = jffs2_verify_xattr(c);
154
151 spin_lock(&c->inocache_lock); 155 spin_lock(&c->inocache_lock);
152 156
153 ic = jffs2_get_ino_cache(c, c->checked_ino++); 157 ic = jffs2_get_ino_cache(c, c->checked_ino++);
@@ -181,6 +185,10 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
181 and trigger the BUG() above while we haven't yet 185 and trigger the BUG() above while we haven't yet
182 finished checking all its nodes */ 186 finished checking all its nodes */
183 D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); 187 D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
188 /* We need to come back again for the _same_ inode. We've
189 made no progress in this case, but that should be OK */
190 c->checked_ino--;
191
184 up(&c->alloc_sem); 192 up(&c->alloc_sem);
185 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 193 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
186 return 0; 194 return 0;
@@ -231,7 +239,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
231 239
232 while(ref_obsolete(raw)) { 240 while(ref_obsolete(raw)) {
233 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); 241 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
234 raw = raw->next_phys; 242 raw = ref_next(raw);
235 if (unlikely(!raw)) { 243 if (unlikely(!raw)) {
236 printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); 244 printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
237 printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", 245 printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
@@ -248,16 +256,37 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
248 256
249 if (!raw->next_in_ino) { 257 if (!raw->next_in_ino) {
250 /* Inode-less node. Clean marker, snapshot or something like that */ 258 /* Inode-less node. Clean marker, snapshot or something like that */
251 /* FIXME: If it's something that needs to be copied, including something
252 we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */
253 spin_unlock(&c->erase_completion_lock); 259 spin_unlock(&c->erase_completion_lock);
254 jffs2_mark_node_obsolete(c, raw); 260 if (ref_flags(raw) == REF_PRISTINE) {
261 /* It's an unknown node with JFFS2_FEATURE_RWCOMPAT_COPY */
262 jffs2_garbage_collect_pristine(c, NULL, raw);
263 } else {
264 /* Just mark it obsolete */
265 jffs2_mark_node_obsolete(c, raw);
266 }
255 up(&c->alloc_sem); 267 up(&c->alloc_sem);
256 goto eraseit_lock; 268 goto eraseit_lock;
257 } 269 }
258 270
259 ic = jffs2_raw_ref_to_ic(raw); 271 ic = jffs2_raw_ref_to_ic(raw);
260 272
273#ifdef CONFIG_JFFS2_FS_XATTR
274 /* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr.
275 * We can decide whether this node is inode or xattr by ic->class. */
276 if (ic->class == RAWNODE_CLASS_XATTR_DATUM
277 || ic->class == RAWNODE_CLASS_XATTR_REF) {
278 BUG_ON(raw->next_in_ino != (void *)ic);
279 spin_unlock(&c->erase_completion_lock);
280
281 if (ic->class == RAWNODE_CLASS_XATTR_DATUM) {
282 ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
283 } else {
284 ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
285 }
286 goto release_sem;
287 }
288#endif
289
261 /* We need to hold the inocache. Either the erase_completion_lock or 290 /* We need to hold the inocache. Either the erase_completion_lock or
262 the inocache_lock are sufficient; we trade down since the inocache_lock 291 the inocache_lock are sufficient; we trade down since the inocache_lock
263 causes less contention. */ 292 causes less contention. */
@@ -499,7 +528,6 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
499 struct jffs2_raw_node_ref *raw) 528 struct jffs2_raw_node_ref *raw)
500{ 529{
501 union jffs2_node_union *node; 530 union jffs2_node_union *node;
502 struct jffs2_raw_node_ref *nraw;
503 size_t retlen; 531 size_t retlen;
504 int ret; 532 int ret;
505 uint32_t phys_ofs, alloclen; 533 uint32_t phys_ofs, alloclen;
@@ -508,15 +536,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
508 536
509 D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw))); 537 D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
510 538
511 rawlen = ref_totlen(c, c->gcblock, raw); 539 alloclen = rawlen = ref_totlen(c, c->gcblock, raw);
512 540
513 /* Ask for a small amount of space (or the totlen if smaller) because we 541 /* Ask for a small amount of space (or the totlen if smaller) because we
514 don't want to force wastage of the end of a block if splitting would 542 don't want to force wastage of the end of a block if splitting would
515 work. */ 543 work. */
516 ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + 544 if (ic && alloclen > sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
517 JFFS2_MIN_DATA_LEN, rawlen), &phys_ofs, &alloclen, rawlen); 545 alloclen = sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN;
518 /* this is not the exact summary size of it, 546
519 it is only an upper estimation */ 547 ret = jffs2_reserve_space_gc(c, alloclen, &alloclen, rawlen);
548 /* 'rawlen' is not the exact summary size; it is only an upper estimation */
520 549
521 if (ret) 550 if (ret)
522 return ret; 551 return ret;
@@ -580,22 +609,17 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
580 } 609 }
581 break; 610 break;
582 default: 611 default:
583 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", 612 /* If it's inode-less, we don't _know_ what it is. Just copy it intact */
584 ref_offset(raw), je16_to_cpu(node->u.nodetype)); 613 if (ic) {
585 goto bail; 614 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
586 } 615 ref_offset(raw), je16_to_cpu(node->u.nodetype));
587 616 goto bail;
588 nraw = jffs2_alloc_raw_node_ref(); 617 }
589 if (!nraw) {
590 ret = -ENOMEM;
591 goto out_node;
592 } 618 }
593 619
594 /* OK, all the CRCs are good; this node can just be copied as-is. */ 620 /* OK, all the CRCs are good; this node can just be copied as-is. */
595 retry: 621 retry:
596 nraw->flash_offset = phys_ofs; 622 phys_ofs = write_ofs(c);
597 nraw->__totlen = rawlen;
598 nraw->next_phys = NULL;
599 623
600 ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); 624 ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
601 625
@@ -603,17 +627,11 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
603 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", 627 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
604 rawlen, phys_ofs, ret, retlen); 628 rawlen, phys_ofs, ret, retlen);
605 if (retlen) { 629 if (retlen) {
606 /* Doesn't belong to any inode */ 630 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL);
607 nraw->next_in_ino = NULL;
608
609 nraw->flash_offset |= REF_OBSOLETE;
610 jffs2_add_physical_node_ref(c, nraw);
611 jffs2_mark_node_obsolete(c, nraw);
612 } else { 631 } else {
613 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); 632 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", phys_ofs);
614 jffs2_free_raw_node_ref(nraw);
615 } 633 }
616 if (!retried && (nraw = jffs2_alloc_raw_node_ref())) { 634 if (!retried) {
617 /* Try to reallocate space and retry */ 635 /* Try to reallocate space and retry */
618 uint32_t dummy; 636 uint32_t dummy;
619 struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; 637 struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
@@ -625,7 +643,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
625 jffs2_dbg_acct_sanity_check(c,jeb); 643 jffs2_dbg_acct_sanity_check(c,jeb);
626 jffs2_dbg_acct_paranoia_check(c, jeb); 644 jffs2_dbg_acct_paranoia_check(c, jeb);
627 645
628 ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy, rawlen); 646 ret = jffs2_reserve_space_gc(c, rawlen, &dummy, rawlen);
629 /* this is not the exact summary size of it, 647 /* this is not the exact summary size of it,
630 it is only an upper estimation */ 648 it is only an upper estimation */
631 649
@@ -638,25 +656,13 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
638 goto retry; 656 goto retry;
639 } 657 }
640 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 658 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
641 jffs2_free_raw_node_ref(nraw);
642 } 659 }
643 660
644 jffs2_free_raw_node_ref(nraw);
645 if (!ret) 661 if (!ret)
646 ret = -EIO; 662 ret = -EIO;
647 goto out_node; 663 goto out_node;
648 } 664 }
649 nraw->flash_offset |= REF_PRISTINE; 665 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, rawlen, ic);
650 jffs2_add_physical_node_ref(c, nraw);
651
652 /* Link into per-inode list. This is safe because of the ic
653 state being INO_STATE_GC. Note that if we're doing this
654 for an inode which is in-core, the 'nraw' pointer is then
655 going to be fetched from ic->nodes by our caller. */
656 spin_lock(&c->erase_completion_lock);
657 nraw->next_in_ino = ic->nodes;
658 ic->nodes = nraw;
659 spin_unlock(&c->erase_completion_lock);
660 666
661 jffs2_mark_node_obsolete(c, raw); 667 jffs2_mark_node_obsolete(c, raw);
662 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); 668 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
@@ -675,19 +681,16 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
675 struct jffs2_full_dnode *new_fn; 681 struct jffs2_full_dnode *new_fn;
676 struct jffs2_raw_inode ri; 682 struct jffs2_raw_inode ri;
677 struct jffs2_node_frag *last_frag; 683 struct jffs2_node_frag *last_frag;
678 jint16_t dev; 684 union jffs2_device_node dev;
679 char *mdata = NULL, mdatalen = 0; 685 char *mdata = NULL, mdatalen = 0;
680 uint32_t alloclen, phys_ofs, ilen; 686 uint32_t alloclen, ilen;
681 int ret; 687 int ret;
682 688
683 if (S_ISBLK(JFFS2_F_I_MODE(f)) || 689 if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
684 S_ISCHR(JFFS2_F_I_MODE(f)) ) { 690 S_ISCHR(JFFS2_F_I_MODE(f)) ) {
685 /* For these, we don't actually need to read the old node */ 691 /* For these, we don't actually need to read the old node */
686 /* FIXME: for minor or major > 255. */ 692 mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f));
687 dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
688 JFFS2_F_I_RDEV_MIN(f)));
689 mdata = (char *)&dev; 693 mdata = (char *)&dev;
690 mdatalen = sizeof(dev);
691 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); 694 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
692 } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { 695 } else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
693 mdatalen = fn->size; 696 mdatalen = fn->size;
@@ -706,7 +709,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
706 709
707 } 710 }
708 711
709 ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, 712 ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &alloclen,
710 JFFS2_SUMMARY_INODE_SIZE); 713 JFFS2_SUMMARY_INODE_SIZE);
711 if (ret) { 714 if (ret) {
712 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", 715 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
@@ -744,7 +747,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
744 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 747 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
745 ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); 748 ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
746 749
747 new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, phys_ofs, ALLOC_GC); 750 new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, ALLOC_GC);
748 751
749 if (IS_ERR(new_fn)) { 752 if (IS_ERR(new_fn)) {
750 printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); 753 printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
@@ -765,7 +768,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
765{ 768{
766 struct jffs2_full_dirent *new_fd; 769 struct jffs2_full_dirent *new_fd;
767 struct jffs2_raw_dirent rd; 770 struct jffs2_raw_dirent rd;
768 uint32_t alloclen, phys_ofs; 771 uint32_t alloclen;
769 int ret; 772 int ret;
770 773
771 rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 774 rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -787,14 +790,14 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
787 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); 790 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
788 rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); 791 rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
789 792
790 ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen, 793 ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &alloclen,
791 JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize)); 794 JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize));
792 if (ret) { 795 if (ret) {
793 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", 796 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
794 sizeof(rd)+rd.nsize, ret); 797 sizeof(rd)+rd.nsize, ret);
795 return ret; 798 return ret;
796 } 799 }
797 new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC); 800 new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, ALLOC_GC);
798 801
799 if (IS_ERR(new_fd)) { 802 if (IS_ERR(new_fd)) {
800 printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); 803 printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd));
@@ -922,7 +925,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
922 struct jffs2_raw_inode ri; 925 struct jffs2_raw_inode ri;
923 struct jffs2_node_frag *frag; 926 struct jffs2_node_frag *frag;
924 struct jffs2_full_dnode *new_fn; 927 struct jffs2_full_dnode *new_fn;
925 uint32_t alloclen, phys_ofs, ilen; 928 uint32_t alloclen, ilen;
926 int ret; 929 int ret;
927 930
928 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", 931 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
@@ -1001,14 +1004,14 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
1001 ri.data_crc = cpu_to_je32(0); 1004 ri.data_crc = cpu_to_je32(0);
1002 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 1005 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
1003 1006
1004 ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen, 1007 ret = jffs2_reserve_space_gc(c, sizeof(ri), &alloclen,
1005 JFFS2_SUMMARY_INODE_SIZE); 1008 JFFS2_SUMMARY_INODE_SIZE);
1006 if (ret) { 1009 if (ret) {
1007 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", 1010 printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
1008 sizeof(ri), ret); 1011 sizeof(ri), ret);
1009 return ret; 1012 return ret;
1010 } 1013 }
1011 new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC); 1014 new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_GC);
1012 1015
1013 if (IS_ERR(new_fn)) { 1016 if (IS_ERR(new_fn)) {
1014 printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); 1017 printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn));
@@ -1070,7 +1073,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1070{ 1073{
1071 struct jffs2_full_dnode *new_fn; 1074 struct jffs2_full_dnode *new_fn;
1072 struct jffs2_raw_inode ri; 1075 struct jffs2_raw_inode ri;
1073 uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; 1076 uint32_t alloclen, offset, orig_end, orig_start;
1074 int ret = 0; 1077 int ret = 0;
1075 unsigned char *comprbuf = NULL, *writebuf; 1078 unsigned char *comprbuf = NULL, *writebuf;
1076 unsigned long pg; 1079 unsigned long pg;
@@ -1227,7 +1230,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1227 uint32_t cdatalen; 1230 uint32_t cdatalen;
1228 uint16_t comprtype = JFFS2_COMPR_NONE; 1231 uint16_t comprtype = JFFS2_COMPR_NONE;
1229 1232
1230 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, 1233 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN,
1231 &alloclen, JFFS2_SUMMARY_INODE_SIZE); 1234 &alloclen, JFFS2_SUMMARY_INODE_SIZE);
1232 1235
1233 if (ret) { 1236 if (ret) {
@@ -1264,7 +1267,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1264 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); 1267 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
1265 ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); 1268 ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
1266 1269
1267 new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); 1270 new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, ALLOC_GC);
1268 1271
1269 jffs2_free_comprbuf(comprbuf, writebuf); 1272 jffs2_free_comprbuf(comprbuf, writebuf);
1270 1273
diff --git a/fs/jffs2/histo.h b/fs/jffs2/histo.h
deleted file mode 100644
index 22a93a08210c..000000000000
--- a/fs/jffs2/histo.h
+++ /dev/null
@@ -1,3 +0,0 @@
1/* This file provides the bit-probabilities for the input file */
2#define BIT_DIVIDER 629
3static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */
diff --git a/include/linux/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h
index ad565bf9dcc1..2e0cc8e00b85 100644
--- a/include/linux/jffs2_fs_i.h
+++ b/fs/jffs2/jffs2_fs_i.h
@@ -5,6 +5,7 @@
5 5
6#include <linux/version.h> 6#include <linux/version.h>
7#include <linux/rbtree.h> 7#include <linux/rbtree.h>
8#include <linux/posix_acl.h>
8#include <asm/semaphore.h> 9#include <asm/semaphore.h>
9 10
10struct jffs2_inode_info { 11struct jffs2_inode_info {
@@ -45,6 +46,10 @@ struct jffs2_inode_info {
45 struct inode vfs_inode; 46 struct inode vfs_inode;
46#endif 47#endif
47#endif 48#endif
49#ifdef CONFIG_JFFS2_FS_POSIX_ACL
50 struct posix_acl *i_acl_access;
51 struct posix_acl *i_acl_default;
52#endif
48}; 53};
49 54
50#endif /* _JFFS2_FS_I */ 55#endif /* _JFFS2_FS_I */
diff --git a/include/linux/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 4bcfb5570221..935fec1b1201 100644
--- a/include/linux/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -100,6 +100,7 @@ struct jffs2_sb_info {
100#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 100#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
101 /* Write-behind buffer for NAND flash */ 101 /* Write-behind buffer for NAND flash */
102 unsigned char *wbuf; 102 unsigned char *wbuf;
103 unsigned char *oobbuf;
103 uint32_t wbuf_ofs; 104 uint32_t wbuf_ofs;
104 uint32_t wbuf_len; 105 uint32_t wbuf_len;
105 struct jffs2_inodirty *wbuf_inodes; 106 struct jffs2_inodirty *wbuf_inodes;
@@ -107,7 +108,7 @@ struct jffs2_sb_info {
107 struct rw_semaphore wbuf_sem; /* Protects the write buffer */ 108 struct rw_semaphore wbuf_sem; /* Protects the write buffer */
108 109
109 /* Information about out-of-band area usage... */ 110 /* Information about out-of-band area usage... */
110 struct nand_oobinfo *oobinfo; 111 struct nand_ecclayout *ecclayout;
111 uint32_t badblock_pos; 112 uint32_t badblock_pos;
112 uint32_t fsdata_pos; 113 uint32_t fsdata_pos;
113 uint32_t fsdata_len; 114 uint32_t fsdata_len;
@@ -115,6 +116,16 @@ struct jffs2_sb_info {
115 116
116 struct jffs2_summary *summary; /* Summary information */ 117 struct jffs2_summary *summary; /* Summary information */
117 118
119#ifdef CONFIG_JFFS2_FS_XATTR
120#define XATTRINDEX_HASHSIZE (57)
121 uint32_t highest_xid;
122 struct list_head xattrindex[XATTRINDEX_HASHSIZE];
123 struct list_head xattr_unchecked;
124 struct jffs2_xattr_ref *xref_temp;
125 struct rw_semaphore xattr_sem;
126 uint32_t xdatum_mem_usage;
127 uint32_t xdatum_mem_threshold;
128#endif
118 /* OS-private pointer for getting back to master superblock info */ 129 /* OS-private pointer for getting back to master superblock info */
119 void *os_priv; 130 void *os_priv;
120}; 131};
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 036cbd11c004..4889d0700c0e 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -26,6 +26,10 @@ static kmem_cache_t *tmp_dnode_info_slab;
26static kmem_cache_t *raw_node_ref_slab; 26static kmem_cache_t *raw_node_ref_slab;
27static kmem_cache_t *node_frag_slab; 27static kmem_cache_t *node_frag_slab;
28static kmem_cache_t *inode_cache_slab; 28static kmem_cache_t *inode_cache_slab;
29#ifdef CONFIG_JFFS2_FS_XATTR
30static kmem_cache_t *xattr_datum_cache;
31static kmem_cache_t *xattr_ref_cache;
32#endif
29 33
30int __init jffs2_create_slab_caches(void) 34int __init jffs2_create_slab_caches(void)
31{ 35{
@@ -53,8 +57,8 @@ int __init jffs2_create_slab_caches(void)
53 if (!tmp_dnode_info_slab) 57 if (!tmp_dnode_info_slab)
54 goto err; 58 goto err;
55 59
56 raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", 60 raw_node_ref_slab = kmem_cache_create("jffs2_refblock",
57 sizeof(struct jffs2_raw_node_ref), 61 sizeof(struct jffs2_raw_node_ref) * (REFS_PER_BLOCK + 1),
58 0, 0, NULL, NULL); 62 0, 0, NULL, NULL);
59 if (!raw_node_ref_slab) 63 if (!raw_node_ref_slab)
60 goto err; 64 goto err;
@@ -68,8 +72,24 @@ int __init jffs2_create_slab_caches(void)
68 inode_cache_slab = kmem_cache_create("jffs2_inode_cache", 72 inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
69 sizeof(struct jffs2_inode_cache), 73 sizeof(struct jffs2_inode_cache),
70 0, 0, NULL, NULL); 74 0, 0, NULL, NULL);
71 if (inode_cache_slab) 75 if (!inode_cache_slab)
72 return 0; 76 goto err;
77
78#ifdef CONFIG_JFFS2_FS_XATTR
79 xattr_datum_cache = kmem_cache_create("jffs2_xattr_datum",
80 sizeof(struct jffs2_xattr_datum),
81 0, 0, NULL, NULL);
82 if (!xattr_datum_cache)
83 goto err;
84
85 xattr_ref_cache = kmem_cache_create("jffs2_xattr_ref",
86 sizeof(struct jffs2_xattr_ref),
87 0, 0, NULL, NULL);
88 if (!xattr_ref_cache)
89 goto err;
90#endif
91
92 return 0;
73 err: 93 err:
74 jffs2_destroy_slab_caches(); 94 jffs2_destroy_slab_caches();
75 return -ENOMEM; 95 return -ENOMEM;
@@ -91,6 +111,12 @@ void jffs2_destroy_slab_caches(void)
91 kmem_cache_destroy(node_frag_slab); 111 kmem_cache_destroy(node_frag_slab);
92 if(inode_cache_slab) 112 if(inode_cache_slab)
93 kmem_cache_destroy(inode_cache_slab); 113 kmem_cache_destroy(inode_cache_slab);
114#ifdef CONFIG_JFFS2_FS_XATTR
115 if (xattr_datum_cache)
116 kmem_cache_destroy(xattr_datum_cache);
117 if (xattr_ref_cache)
118 kmem_cache_destroy(xattr_ref_cache);
119#endif
94} 120}
95 121
96struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) 122struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
@@ -164,15 +190,65 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
164 kmem_cache_free(tmp_dnode_info_slab, x); 190 kmem_cache_free(tmp_dnode_info_slab, x);
165} 191}
166 192
167struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) 193struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
168{ 194{
169 struct jffs2_raw_node_ref *ret; 195 struct jffs2_raw_node_ref *ret;
196
170 ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); 197 ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
171 dbg_memalloc("%p\n", ret); 198 if (ret) {
199 int i = 0;
200 for (i=0; i < REFS_PER_BLOCK; i++) {
201 ret[i].flash_offset = REF_EMPTY_NODE;
202 ret[i].next_in_ino = NULL;
203 }
204 ret[i].flash_offset = REF_LINK_NODE;
205 ret[i].next_in_ino = NULL;
206 }
172 return ret; 207 return ret;
173} 208}
174 209
175void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) 210int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c,
211 struct jffs2_eraseblock *jeb, int nr)
212{
213 struct jffs2_raw_node_ref **p, *ref;
214 int i = nr;
215
216 dbg_memalloc("%d\n", nr);
217
218 p = &jeb->last_node;
219 ref = *p;
220
221 dbg_memalloc("Reserving %d refs for block @0x%08x\n", nr, jeb->offset);
222
223 /* If jeb->last_node is really a valid node then skip over it */
224 if (ref && ref->flash_offset != REF_EMPTY_NODE)
225 ref++;
226
227 while (i) {
228 if (!ref) {
229 dbg_memalloc("Allocating new refblock linked from %p\n", p);
230 ref = *p = jffs2_alloc_refblock();
231 if (!ref)
232 return -ENOMEM;
233 }
234 if (ref->flash_offset == REF_LINK_NODE) {
235 p = &ref->next_in_ino;
236 ref = *p;
237 continue;
238 }
239 i--;
240 ref++;
241 }
242 jeb->allocated_refs = nr;
243
244 dbg_memalloc("Reserved %d refs for block @0x%08x, last_node is %p (%08x,%p)\n",
245 nr, jeb->offset, jeb->last_node, jeb->last_node->flash_offset,
246 jeb->last_node->next_in_ino);
247
248 return 0;
249}
250
251void jffs2_free_refblock(struct jffs2_raw_node_ref *x)
176{ 252{
177 dbg_memalloc("%p\n", x); 253 dbg_memalloc("%p\n", x);
178 kmem_cache_free(raw_node_ref_slab, x); 254 kmem_cache_free(raw_node_ref_slab, x);
@@ -205,3 +281,40 @@ void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
205 dbg_memalloc("%p\n", x); 281 dbg_memalloc("%p\n", x);
206 kmem_cache_free(inode_cache_slab, x); 282 kmem_cache_free(inode_cache_slab, x);
207} 283}
284
285#ifdef CONFIG_JFFS2_FS_XATTR
286struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
287{
288 struct jffs2_xattr_datum *xd;
289 xd = kmem_cache_alloc(xattr_datum_cache, GFP_KERNEL);
290 dbg_memalloc("%p\n", xd);
291
292 memset(xd, 0, sizeof(struct jffs2_xattr_datum));
293 xd->class = RAWNODE_CLASS_XATTR_DATUM;
294 INIT_LIST_HEAD(&xd->xindex);
295 return xd;
296}
297
298void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd)
299{
300 dbg_memalloc("%p\n", xd);
301 kmem_cache_free(xattr_datum_cache, xd);
302}
303
304struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
305{
306 struct jffs2_xattr_ref *ref;
307 ref = kmem_cache_alloc(xattr_ref_cache, GFP_KERNEL);
308 dbg_memalloc("%p\n", ref);
309
310 memset(ref, 0, sizeof(struct jffs2_xattr_ref));
311 ref->class = RAWNODE_CLASS_XATTR_REF;
312 return ref;
313}
314
315void jffs2_free_xattr_ref(struct jffs2_xattr_ref *ref)
316{
317 dbg_memalloc("%p\n", ref);
318 kmem_cache_free(xattr_ref_cache, ref);
319}
320#endif
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 1d46677afd17..927dfe42ba76 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -438,8 +438,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
438 if (c->mtd->point) { 438 if (c->mtd->point) {
439 err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); 439 err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
440 if (!err && retlen < tn->csize) { 440 if (!err && retlen < tn->csize) {
441 JFFS2_WARNING("MTD point returned len too short: %zu " 441 JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
442 "instead of %u.\n", retlen, tn->csize);
443 c->mtd->unpoint(c->mtd, buffer, ofs, len); 442 c->mtd->unpoint(c->mtd, buffer, ofs, len);
444 } else if (err) 443 } else if (err)
445 JFFS2_WARNING("MTD point failed: error code %d.\n", err); 444 JFFS2_WARNING("MTD point failed: error code %d.\n", err);
@@ -462,8 +461,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
462 } 461 }
463 462
464 if (retlen != len) { 463 if (retlen != len) {
465 JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", 464 JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len);
466 ofs, retlen, len);
467 err = -EIO; 465 err = -EIO;
468 goto free_out; 466 goto free_out;
469 } 467 }
@@ -940,6 +938,7 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
940 this = c->inocache_list[i]; 938 this = c->inocache_list[i];
941 while (this) { 939 while (this) {
942 next = this->next; 940 next = this->next;
941 jffs2_xattr_free_inode(c, this);
943 jffs2_free_inode_cache(this); 942 jffs2_free_inode_cache(this);
944 this = next; 943 this = next;
945 } 944 }
@@ -954,9 +953,13 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
954 953
955 for (i=0; i<c->nr_blocks; i++) { 954 for (i=0; i<c->nr_blocks; i++) {
956 this = c->blocks[i].first_node; 955 this = c->blocks[i].first_node;
957 while(this) { 956 while (this) {
958 next = this->next_phys; 957 if (this[REFS_PER_BLOCK].flash_offset == REF_LINK_NODE)
959 jffs2_free_raw_node_ref(this); 958 next = this[REFS_PER_BLOCK].next_in_ino;
959 else
960 next = NULL;
961
962 jffs2_free_refblock(this);
960 this = next; 963 this = next;
961 } 964 }
962 c->blocks[i].first_node = c->blocks[i].last_node = NULL; 965 c->blocks[i].first_node = c->blocks[i].last_node = NULL;
@@ -1047,3 +1050,169 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
1047 cond_resched(); 1050 cond_resched();
1048 } 1051 }
1049} 1052}
1053
1054struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
1055 struct jffs2_eraseblock *jeb,
1056 uint32_t ofs, uint32_t len,
1057 struct jffs2_inode_cache *ic)
1058{
1059 struct jffs2_raw_node_ref *ref;
1060
1061 BUG_ON(!jeb->allocated_refs);
1062 jeb->allocated_refs--;
1063
1064 ref = jeb->last_node;
1065
1066 dbg_noderef("Last node at %p is (%08x,%p)\n", ref, ref->flash_offset,
1067 ref->next_in_ino);
1068
1069 while (ref->flash_offset != REF_EMPTY_NODE) {
1070 if (ref->flash_offset == REF_LINK_NODE)
1071 ref = ref->next_in_ino;
1072 else
1073 ref++;
1074 }
1075
1076 dbg_noderef("New ref is %p (%08x becomes %08x,%p) len 0x%x\n", ref,
1077 ref->flash_offset, ofs, ref->next_in_ino, len);
1078
1079 ref->flash_offset = ofs;
1080
1081 if (!jeb->first_node) {
1082 jeb->first_node = ref;
1083 BUG_ON(ref_offset(ref) != jeb->offset);
1084 } else if (unlikely(ref_offset(ref) != jeb->offset + c->sector_size - jeb->free_size)) {
1085 uint32_t last_len = ref_totlen(c, jeb, jeb->last_node);
1086
1087 JFFS2_ERROR("Adding new ref %p at (0x%08x-0x%08x) not immediately after previous (0x%08x-0x%08x)\n",
1088 ref, ref_offset(ref), ref_offset(ref)+len,
1089 ref_offset(jeb->last_node),
1090 ref_offset(jeb->last_node)+last_len);
1091 BUG();
1092 }
1093 jeb->last_node = ref;
1094
1095 if (ic) {
1096 ref->next_in_ino = ic->nodes;
1097 ic->nodes = ref;
1098 } else {
1099 ref->next_in_ino = NULL;
1100 }
1101
1102 switch(ref_flags(ref)) {
1103 case REF_UNCHECKED:
1104 c->unchecked_size += len;
1105 jeb->unchecked_size += len;
1106 break;
1107
1108 case REF_NORMAL:
1109 case REF_PRISTINE:
1110 c->used_size += len;
1111 jeb->used_size += len;
1112 break;
1113
1114 case REF_OBSOLETE:
1115 c->dirty_size += len;
1116 jeb->dirty_size += len;
1117 break;
1118 }
1119 c->free_size -= len;
1120 jeb->free_size -= len;
1121
1122#ifdef TEST_TOTLEN
1123 /* Set (and test) __totlen field... for now */
1124 ref->__totlen = len;
1125 ref_totlen(c, jeb, ref);
1126#endif
1127 return ref;
1128}
1129
1130/* No locking, no reservation of 'ref'. Do not use on a live file system */
1131int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
1132 uint32_t size)
1133{
1134 if (!size)
1135 return 0;
1136 if (unlikely(size > jeb->free_size)) {
1137 printk(KERN_CRIT "Dirty space 0x%x larger then free_size 0x%x (wasted 0x%x)\n",
1138 size, jeb->free_size, jeb->wasted_size);
1139 BUG();
1140 }
1141 /* REF_EMPTY_NODE is !obsolete, so that works OK */
1142 if (jeb->last_node && ref_obsolete(jeb->last_node)) {
1143#ifdef TEST_TOTLEN
1144 jeb->last_node->__totlen += size;
1145#endif
1146 c->dirty_size += size;
1147 c->free_size -= size;
1148 jeb->dirty_size += size;
1149 jeb->free_size -= size;
1150 } else {
1151 uint32_t ofs = jeb->offset + c->sector_size - jeb->free_size;
1152 ofs |= REF_OBSOLETE;
1153
1154 jffs2_link_node_ref(c, jeb, ofs, size, NULL);
1155 }
1156
1157 return 0;
1158}
1159
1160/* Calculate totlen from surrounding nodes or eraseblock */
1161static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
1162 struct jffs2_eraseblock *jeb,
1163 struct jffs2_raw_node_ref *ref)
1164{
1165 uint32_t ref_end;
1166 struct jffs2_raw_node_ref *next_ref = ref_next(ref);
1167
1168 if (next_ref)
1169 ref_end = ref_offset(next_ref);
1170 else {
1171 if (!jeb)
1172 jeb = &c->blocks[ref->flash_offset / c->sector_size];
1173
1174 /* Last node in block. Use free_space */
1175 if (unlikely(ref != jeb->last_node)) {
1176 printk(KERN_CRIT "ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n",
1177 ref, ref_offset(ref), jeb->last_node, jeb->last_node?ref_offset(jeb->last_node):0);
1178 BUG();
1179 }
1180 ref_end = jeb->offset + c->sector_size - jeb->free_size;
1181 }
1182 return ref_end - ref_offset(ref);
1183}
1184
1185uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
1186 struct jffs2_raw_node_ref *ref)
1187{
1188 uint32_t ret;
1189
1190 ret = __ref_totlen(c, jeb, ref);
1191
1192#ifdef TEST_TOTLEN
1193 if (unlikely(ret != ref->__totlen)) {
1194 if (!jeb)
1195 jeb = &c->blocks[ref->flash_offset / c->sector_size];
1196
1197 printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
1198 ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
1199 ret, ref->__totlen);
1200 if (ref_next(ref)) {
1201 printk(KERN_CRIT "next %p (0x%08x-0x%08x)\n", ref_next(ref), ref_offset(ref_next(ref)),
1202 ref_offset(ref_next(ref))+ref->__totlen);
1203 } else
1204 printk(KERN_CRIT "No next ref. jeb->last_node is %p\n", jeb->last_node);
1205
1206 printk(KERN_CRIT "jeb->wasted_size %x, dirty_size %x, used_size %x, free_size %x\n", jeb->wasted_size, jeb->dirty_size, jeb->used_size, jeb->free_size);
1207
1208#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
1209 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
1210#endif
1211
1212 WARN_ON(1);
1213
1214 ret = ref->__totlen;
1215 }
1216#endif /* TEST_TOTLEN */
1217 return ret;
1218}
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 23a67bb3052f..b16c60bbcf6e 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -18,8 +18,10 @@
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/jffs2.h> 20#include <linux/jffs2.h>
21#include <linux/jffs2_fs_sb.h> 21#include "jffs2_fs_sb.h"
22#include <linux/jffs2_fs_i.h> 22#include "jffs2_fs_i.h"
23#include "xattr.h"
24#include "acl.h"
23#include "summary.h" 25#include "summary.h"
24 26
25#ifdef __ECOS 27#ifdef __ECOS
@@ -75,14 +77,50 @@
75struct jffs2_raw_node_ref 77struct jffs2_raw_node_ref
76{ 78{
77 struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref 79 struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
78 for this inode. If this is the last, it points to the inode_cache 80 for this object. If this _is_ the last, it points to the inode_cache,
79 for this inode instead. The inode_cache will have NULL in the first 81 xattr_ref or xattr_datum instead. The common part of those structures
80 word so you know when you've got there :) */ 82 has NULL in the first word. See jffs2_raw_ref_to_ic() below */
81 struct jffs2_raw_node_ref *next_phys;
82 uint32_t flash_offset; 83 uint32_t flash_offset;
84#define TEST_TOTLEN
85#ifdef TEST_TOTLEN
83 uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */ 86 uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
87#endif
84}; 88};
85 89
90#define REF_LINK_NODE ((int32_t)-1)
91#define REF_EMPTY_NODE ((int32_t)-2)
92
93/* Use blocks of about 256 bytes */
94#define REFS_PER_BLOCK ((255/sizeof(struct jffs2_raw_node_ref))-1)
95
96static inline struct jffs2_raw_node_ref *ref_next(struct jffs2_raw_node_ref *ref)
97{
98 ref++;
99
100 /* Link to another block of refs */
101 if (ref->flash_offset == REF_LINK_NODE) {
102 ref = ref->next_in_ino;
103 if (!ref)
104 return ref;
105 }
106
107 /* End of chain */
108 if (ref->flash_offset == REF_EMPTY_NODE)
109 return NULL;
110
111 return ref;
112}
113
114static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw)
115{
116 while(raw->next_in_ino)
117 raw = raw->next_in_ino;
118
119 /* NB. This can be a jffs2_xattr_datum or jffs2_xattr_ref and
120 not actually a jffs2_inode_cache. Check ->class */
121 return ((struct jffs2_inode_cache *)raw);
122}
123
86 /* flash_offset & 3 always has to be zero, because nodes are 124 /* flash_offset & 3 always has to be zero, because nodes are
87 always aligned at 4 bytes. So we have a couple of extra bits 125 always aligned at 4 bytes. So we have a couple of extra bits
88 to play with, which indicate the node's status; see below: */ 126 to play with, which indicate the node's status; see below: */
@@ -95,6 +133,11 @@ struct jffs2_raw_node_ref
95#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE) 133#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE)
96#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0) 134#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0)
97 135
136/* NB: REF_PRISTINE for an inode-less node (ref->next_in_ino == NULL) indicates
137 it is an unknown node of type JFFS2_NODETYPE_RWCOMPAT_COPY, so it'll get
138 copied. If you need to do anything different to GC inode-less nodes, then
139 you need to modify gc.c accordingly. */
140
98/* For each inode in the filesystem, we need to keep a record of 141/* For each inode in the filesystem, we need to keep a record of
99 nlink, because it would be a PITA to scan the whole directory tree 142 nlink, because it would be a PITA to scan the whole directory tree
100 at read_inode() time to calculate it, and to keep sufficient information 143 at read_inode() time to calculate it, and to keep sufficient information
@@ -103,15 +146,27 @@ struct jffs2_raw_node_ref
103 a pointer to the first physical node which is part of this inode, too. 146 a pointer to the first physical node which is part of this inode, too.
104*/ 147*/
105struct jffs2_inode_cache { 148struct jffs2_inode_cache {
149 /* First part of structure is shared with other objects which
150 can terminate the raw node refs' next_in_ino list -- which
151 currently struct jffs2_xattr_datum and struct jffs2_xattr_ref. */
152
106 struct jffs2_full_dirent *scan_dents; /* Used during scan to hold 153 struct jffs2_full_dirent *scan_dents; /* Used during scan to hold
107 temporary lists of dirents, and later must be set to 154 temporary lists of dirents, and later must be set to
108 NULL to mark the end of the raw_node_ref->next_in_ino 155 NULL to mark the end of the raw_node_ref->next_in_ino
109 chain. */ 156 chain. */
110 struct jffs2_inode_cache *next;
111 struct jffs2_raw_node_ref *nodes; 157 struct jffs2_raw_node_ref *nodes;
158 uint8_t class; /* It's used for identification */
159
160 /* end of shared structure */
161
162 uint8_t flags;
163 uint16_t state;
112 uint32_t ino; 164 uint32_t ino;
165 struct jffs2_inode_cache *next;
166#ifdef CONFIG_JFFS2_FS_XATTR
167 struct jffs2_xattr_ref *xref;
168#endif
113 int nlink; 169 int nlink;
114 int state;
115}; 170};
116 171
117/* Inode states for 'state' above. We need the 'GC' state to prevent 172/* Inode states for 'state' above. We need the 'GC' state to prevent
@@ -125,8 +180,16 @@ struct jffs2_inode_cache {
125#define INO_STATE_READING 5 /* In read_inode() */ 180#define INO_STATE_READING 5 /* In read_inode() */
126#define INO_STATE_CLEARING 6 /* In clear_inode() */ 181#define INO_STATE_CLEARING 6 /* In clear_inode() */
127 182
183#define INO_FLAGS_XATTR_CHECKED 0x01 /* has no duplicate xattr_ref */
184
185#define RAWNODE_CLASS_INODE_CACHE 0
186#define RAWNODE_CLASS_XATTR_DATUM 1
187#define RAWNODE_CLASS_XATTR_REF 2
188
128#define INOCACHE_HASHSIZE 128 189#define INOCACHE_HASHSIZE 128
129 190
191#define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size)
192
130/* 193/*
131 Larger representation of a raw node, kept in-core only when the 194 Larger representation of a raw node, kept in-core only when the
132 struct inode for this particular ino is instantiated. 195 struct inode for this particular ino is instantiated.
@@ -192,6 +255,7 @@ struct jffs2_eraseblock
192 uint32_t wasted_size; 255 uint32_t wasted_size;
193 uint32_t free_size; /* Note that sector_size - free_size 256 uint32_t free_size; /* Note that sector_size - free_size
194 is the address of the first free space */ 257 is the address of the first free space */
258 uint32_t allocated_refs;
195 struct jffs2_raw_node_ref *first_node; 259 struct jffs2_raw_node_ref *first_node;
196 struct jffs2_raw_node_ref *last_node; 260 struct jffs2_raw_node_ref *last_node;
197 261
@@ -203,57 +267,7 @@ static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
203 return ((c->flash_size / c->sector_size) * sizeof (struct jffs2_eraseblock)) > (128 * 1024); 267 return ((c->flash_size / c->sector_size) * sizeof (struct jffs2_eraseblock)) > (128 * 1024);
204} 268}
205 269
206/* Calculate totlen from surrounding nodes or eraseblock */ 270#define ref_totlen(a, b, c) __jffs2_ref_totlen((a), (b), (c))
207static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
208 struct jffs2_eraseblock *jeb,
209 struct jffs2_raw_node_ref *ref)
210{
211 uint32_t ref_end;
212
213 if (ref->next_phys)
214 ref_end = ref_offset(ref->next_phys);
215 else {
216 if (!jeb)
217 jeb = &c->blocks[ref->flash_offset / c->sector_size];
218
219 /* Last node in block. Use free_space */
220 BUG_ON(ref != jeb->last_node);
221 ref_end = jeb->offset + c->sector_size - jeb->free_size;
222 }
223 return ref_end - ref_offset(ref);
224}
225
226static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
227 struct jffs2_eraseblock *jeb,
228 struct jffs2_raw_node_ref *ref)
229{
230 uint32_t ret;
231
232#if CONFIG_JFFS2_FS_DEBUG > 0
233 if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
234 printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
235 jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
236 BUG();
237 }
238#endif
239
240#if 1
241 ret = ref->__totlen;
242#else
243 /* This doesn't actually work yet */
244 ret = __ref_totlen(c, jeb, ref);
245 if (ret != ref->__totlen) {
246 printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
247 ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
248 ret, ref->__totlen);
249 if (!jeb)
250 jeb = &c->blocks[ref->flash_offset / c->sector_size];
251 jffs2_dbg_dump_node_refs_nolock(c, jeb);
252 BUG();
253 }
254#endif
255 return ret;
256}
257 271
258#define ALLOC_NORMAL 0 /* Normal allocation */ 272#define ALLOC_NORMAL 0 /* Normal allocation */
259#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ 273#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
@@ -268,13 +282,15 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
268 282
269#define PAD(x) (((x)+3)&~3) 283#define PAD(x) (((x)+3)&~3)
270 284
271static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw) 285static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev)
272{ 286{
273 while(raw->next_in_ino) { 287 if (old_valid_dev(rdev)) {
274 raw = raw->next_in_ino; 288 jdev->old = cpu_to_je16(old_encode_dev(rdev));
289 return sizeof(jdev->old);
290 } else {
291 jdev->new = cpu_to_je32(new_encode_dev(rdev));
292 return sizeof(jdev->new);
275 } 293 }
276
277 return ((struct jffs2_inode_cache *)raw);
278} 294}
279 295
280static inline struct jffs2_node_frag *frag_first(struct rb_root *root) 296static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
@@ -299,7 +315,6 @@ static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
299 return rb_entry(node, struct jffs2_node_frag, rb); 315 return rb_entry(node, struct jffs2_node_frag, rb);
300} 316}
301 317
302#define rb_parent(rb) ((rb)->rb_parent)
303#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) 318#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
304#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) 319#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
305#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb) 320#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb)
@@ -324,28 +339,44 @@ void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *t
324int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); 339int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
325void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); 340void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
326int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); 341int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
342struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
343 struct jffs2_eraseblock *jeb,
344 uint32_t ofs, uint32_t len,
345 struct jffs2_inode_cache *ic);
346extern uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c,
347 struct jffs2_eraseblock *jeb,
348 struct jffs2_raw_node_ref *ref);
327 349
328/* nodemgmt.c */ 350/* nodemgmt.c */
329int jffs2_thread_should_wake(struct jffs2_sb_info *c); 351int jffs2_thread_should_wake(struct jffs2_sb_info *c);
330int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 352int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
331 uint32_t *len, int prio, uint32_t sumsize); 353 uint32_t *len, int prio, uint32_t sumsize);
332int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 354int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
333 uint32_t *len, uint32_t sumsize); 355 uint32_t *len, uint32_t sumsize);
334int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new); 356struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
357 uint32_t ofs, uint32_t len,
358 struct jffs2_inode_cache *ic);
335void jffs2_complete_reservation(struct jffs2_sb_info *c); 359void jffs2_complete_reservation(struct jffs2_sb_info *c);
336void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); 360void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
337 361
338/* write.c */ 362/* write.c */
339int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); 363int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
340 364
341struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode); 365struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
342struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode); 366 struct jffs2_raw_inode *ri, const unsigned char *data,
367 uint32_t datalen, int alloc_mode);
368struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
369 struct jffs2_raw_dirent *rd, const unsigned char *name,
370 uint32_t namelen, int alloc_mode);
343int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 371int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
344 struct jffs2_raw_inode *ri, unsigned char *buf, 372 struct jffs2_raw_inode *ri, unsigned char *buf,
345 uint32_t offset, uint32_t writelen, uint32_t *retlen); 373 uint32_t offset, uint32_t writelen, uint32_t *retlen);
346int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen); 374int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f,
347int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f, uint32_t time); 375 struct jffs2_raw_inode *ri, const char *name, int namelen);
348int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time); 376int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name,
377 int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
378int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino,
379 uint8_t type, const char *name, int namelen, uint32_t time);
349 380
350 381
351/* readinode.c */ 382/* readinode.c */
@@ -368,12 +399,19 @@ struct jffs2_raw_inode *jffs2_alloc_raw_inode(void);
368void jffs2_free_raw_inode(struct jffs2_raw_inode *); 399void jffs2_free_raw_inode(struct jffs2_raw_inode *);
369struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void); 400struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void);
370void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *); 401void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *);
371struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void); 402int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c,
372void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *); 403 struct jffs2_eraseblock *jeb, int nr);
404void jffs2_free_refblock(struct jffs2_raw_node_ref *);
373struct jffs2_node_frag *jffs2_alloc_node_frag(void); 405struct jffs2_node_frag *jffs2_alloc_node_frag(void);
374void jffs2_free_node_frag(struct jffs2_node_frag *); 406void jffs2_free_node_frag(struct jffs2_node_frag *);
375struct jffs2_inode_cache *jffs2_alloc_inode_cache(void); 407struct jffs2_inode_cache *jffs2_alloc_inode_cache(void);
376void jffs2_free_inode_cache(struct jffs2_inode_cache *); 408void jffs2_free_inode_cache(struct jffs2_inode_cache *);
409#ifdef CONFIG_JFFS2_FS_XATTR
410struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void);
411void jffs2_free_xattr_datum(struct jffs2_xattr_datum *);
412struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void);
413void jffs2_free_xattr_ref(struct jffs2_xattr_ref *);
414#endif
377 415
378/* gc.c */ 416/* gc.c */
379int jffs2_garbage_collect_pass(struct jffs2_sb_info *c); 417int jffs2_garbage_collect_pass(struct jffs2_sb_info *c);
@@ -393,12 +431,14 @@ int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
393 uint32_t ofs, uint32_t len); 431 uint32_t ofs, uint32_t len);
394struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); 432struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
395int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 433int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
434int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size);
396 435
397/* build.c */ 436/* build.c */
398int jffs2_do_mount_fs(struct jffs2_sb_info *c); 437int jffs2_do_mount_fs(struct jffs2_sb_info *c);
399 438
400/* erase.c */ 439/* erase.c */
401void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); 440void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
441void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
402 442
403#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 443#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
404/* wbuf.c */ 444/* wbuf.c */
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 49127a1f0458..8bedfd2ff689 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -23,13 +23,12 @@
23 * jffs2_reserve_space - request physical space to write nodes to flash 23 * jffs2_reserve_space - request physical space to write nodes to flash
24 * @c: superblock info 24 * @c: superblock info
25 * @minsize: Minimum acceptable size of allocation 25 * @minsize: Minimum acceptable size of allocation
26 * @ofs: Returned value of node offset
27 * @len: Returned value of allocation length 26 * @len: Returned value of allocation length
28 * @prio: Allocation type - ALLOC_{NORMAL,DELETION} 27 * @prio: Allocation type - ALLOC_{NORMAL,DELETION}
29 * 28 *
30 * Requests a block of physical space on the flash. Returns zero for success 29 * Requests a block of physical space on the flash. Returns zero for success
31 * and puts 'ofs' and 'len' into the appriopriate place, or returns -ENOSPC 30 * and puts 'len' into the appropriate place, or returns -ENOSPC or other
32 * or other error if appropriate. 31 * error if appropriate. Doesn't return len since that's
33 * 32 *
34 * If it returns zero, jffs2_reserve_space() also downs the per-filesystem 33 * If it returns zero, jffs2_reserve_space() also downs the per-filesystem
35 * allocation semaphore, to prevent more than one allocation from being 34 * allocation semaphore, to prevent more than one allocation from being
@@ -40,9 +39,9 @@
40 */ 39 */
41 40
42static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, 41static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
43 uint32_t *ofs, uint32_t *len, uint32_t sumsize); 42 uint32_t *len, uint32_t sumsize);
44 43
45int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 44int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
46 uint32_t *len, int prio, uint32_t sumsize) 45 uint32_t *len, int prio, uint32_t sumsize)
47{ 46{
48 int ret = -EAGAIN; 47 int ret = -EAGAIN;
@@ -132,19 +131,21 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
132 spin_lock(&c->erase_completion_lock); 131 spin_lock(&c->erase_completion_lock);
133 } 132 }
134 133
135 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); 134 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
136 if (ret) { 135 if (ret) {
137 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); 136 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
138 } 137 }
139 } 138 }
140 spin_unlock(&c->erase_completion_lock); 139 spin_unlock(&c->erase_completion_lock);
140 if (!ret)
141 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
141 if (ret) 142 if (ret)
142 up(&c->alloc_sem); 143 up(&c->alloc_sem);
143 return ret; 144 return ret;
144} 145}
145 146
146int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 147int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
147 uint32_t *len, uint32_t sumsize) 148 uint32_t *len, uint32_t sumsize)
148{ 149{
149 int ret = -EAGAIN; 150 int ret = -EAGAIN;
150 minsize = PAD(minsize); 151 minsize = PAD(minsize);
@@ -153,12 +154,15 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
153 154
154 spin_lock(&c->erase_completion_lock); 155 spin_lock(&c->erase_completion_lock);
155 while(ret == -EAGAIN) { 156 while(ret == -EAGAIN) {
156 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); 157 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
157 if (ret) { 158 if (ret) {
158 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); 159 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
159 } 160 }
160 } 161 }
161 spin_unlock(&c->erase_completion_lock); 162 spin_unlock(&c->erase_completion_lock);
163 if (!ret)
164 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
165
162 return ret; 166 return ret;
163} 167}
164 168
@@ -259,10 +263,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
259} 263}
260 264
261/* Called with alloc sem _and_ erase_completion_lock */ 265/* Called with alloc sem _and_ erase_completion_lock */
262static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize) 266static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
267 uint32_t *len, uint32_t sumsize)
263{ 268{
264 struct jffs2_eraseblock *jeb = c->nextblock; 269 struct jffs2_eraseblock *jeb = c->nextblock;
265 uint32_t reserved_size; /* for summary information at the end of the jeb */ 270 uint32_t reserved_size; /* for summary information at the end of the jeb */
266 int ret; 271 int ret;
267 272
268 restart: 273 restart:
@@ -312,6 +317,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
312 } 317 }
313 } else { 318 } else {
314 if (jeb && minsize > jeb->free_size) { 319 if (jeb && minsize > jeb->free_size) {
320 uint32_t waste;
321
315 /* Skip the end of this block and file it as having some dirty space */ 322 /* Skip the end of this block and file it as having some dirty space */
316 /* If there's a pending write to it, flush now */ 323 /* If there's a pending write to it, flush now */
317 324
@@ -324,10 +331,26 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
324 goto restart; 331 goto restart;
325 } 332 }
326 333
327 c->wasted_size += jeb->free_size; 334 spin_unlock(&c->erase_completion_lock);
328 c->free_size -= jeb->free_size; 335
329 jeb->wasted_size += jeb->free_size; 336 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
330 jeb->free_size = 0; 337 if (ret)
338 return ret;
339 /* Just lock it again and continue. Nothing much can change because
340 we hold c->alloc_sem anyway. In fact, it's not entirely clear why
341 we hold c->erase_completion_lock in the majority of this function...
342 but that's a question for another (more caffeine-rich) day. */
343 spin_lock(&c->erase_completion_lock);
344
345 waste = jeb->free_size;
346 jffs2_link_node_ref(c, jeb,
347 (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
348 waste, NULL);
349 /* FIXME: that made it count as dirty. Convert to wasted */
350 jeb->dirty_size -= waste;
351 c->dirty_size -= waste;
352 jeb->wasted_size += waste;
353 c->wasted_size += waste;
331 354
332 jffs2_close_nextblock(c, jeb); 355 jffs2_close_nextblock(c, jeb);
333 jeb = NULL; 356 jeb = NULL;
@@ -349,7 +372,6 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
349 } 372 }
350 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has 373 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
351 enough space */ 374 enough space */
352 *ofs = jeb->offset + (c->sector_size - jeb->free_size);
353 *len = jeb->free_size - reserved_size; 375 *len = jeb->free_size - reserved_size;
354 376
355 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && 377 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
@@ -365,7 +387,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
365 spin_lock(&c->erase_completion_lock); 387 spin_lock(&c->erase_completion_lock);
366 } 388 }
367 389
368 D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs)); 390 D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n",
391 *len, jeb->offset + (c->sector_size - jeb->free_size)));
369 return 0; 392 return 0;
370} 393}
371 394
@@ -374,7 +397,6 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
374 * @c: superblock info 397 * @c: superblock info
375 * @new: new node reference to add 398 * @new: new node reference to add
376 * @len: length of this physical node 399 * @len: length of this physical node
377 * @dirty: dirty flag for new node
378 * 400 *
379 * Should only be used to report nodes for which space has been allocated 401 * Should only be used to report nodes for which space has been allocated
380 * by jffs2_reserve_space. 402 * by jffs2_reserve_space.
@@ -382,42 +404,30 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
382 * Must be called with the alloc_sem held. 404 * Must be called with the alloc_sem held.
383 */ 405 */
384 406
385int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new) 407struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
408 uint32_t ofs, uint32_t len,
409 struct jffs2_inode_cache *ic)
386{ 410{
387 struct jffs2_eraseblock *jeb; 411 struct jffs2_eraseblock *jeb;
388 uint32_t len; 412 struct jffs2_raw_node_ref *new;
389 413
390 jeb = &c->blocks[new->flash_offset / c->sector_size]; 414 jeb = &c->blocks[ofs / c->sector_size];
391 len = ref_totlen(c, jeb, new);
392 415
393 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); 416 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n",
417 ofs & ~3, ofs & 3, len));
394#if 1 418#if 1
395 /* we could get some obsolete nodes after nextblock was refiled 419 /* Allow non-obsolete nodes only to be added at the end of c->nextblock,
396 in wbuf.c */ 420 if c->nextblock is set. Note that wbuf.c will file obsolete nodes
397 if ((c->nextblock || !ref_obsolete(new)) 421 even after refiling c->nextblock */
398 &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) { 422 if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
423 && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
399 printk(KERN_WARNING "argh. node added in wrong place\n"); 424 printk(KERN_WARNING "argh. node added in wrong place\n");
400 jffs2_free_raw_node_ref(new); 425 return ERR_PTR(-EINVAL);
401 return -EINVAL;
402 } 426 }
403#endif 427#endif
404 spin_lock(&c->erase_completion_lock); 428 spin_lock(&c->erase_completion_lock);
405 429
406 if (!jeb->first_node) 430 new = jffs2_link_node_ref(c, jeb, ofs, len, ic);
407 jeb->first_node = new;
408 if (jeb->last_node)
409 jeb->last_node->next_phys = new;
410 jeb->last_node = new;
411
412 jeb->free_size -= len;
413 c->free_size -= len;
414 if (ref_obsolete(new)) {
415 jeb->dirty_size += len;
416 c->dirty_size += len;
417 } else {
418 jeb->used_size += len;
419 c->used_size += len;
420 }
421 431
422 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { 432 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
423 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ 433 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
@@ -438,7 +448,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
438 448
439 spin_unlock(&c->erase_completion_lock); 449 spin_unlock(&c->erase_completion_lock);
440 450
441 return 0; 451 return new;
442} 452}
443 453
444 454
@@ -470,8 +480,9 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
470 struct jffs2_unknown_node n; 480 struct jffs2_unknown_node n;
471 int ret, addedsize; 481 int ret, addedsize;
472 size_t retlen; 482 size_t retlen;
483 uint32_t freed_len;
473 484
474 if(!ref) { 485 if(unlikely(!ref)) {
475 printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); 486 printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
476 return; 487 return;
477 } 488 }
@@ -499,32 +510,34 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
499 510
500 spin_lock(&c->erase_completion_lock); 511 spin_lock(&c->erase_completion_lock);
501 512
513 freed_len = ref_totlen(c, jeb, ref);
514
502 if (ref_flags(ref) == REF_UNCHECKED) { 515 if (ref_flags(ref) == REF_UNCHECKED) {
503 D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) { 516 D1(if (unlikely(jeb->unchecked_size < freed_len)) {
504 printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", 517 printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
505 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); 518 freed_len, blocknr, ref->flash_offset, jeb->used_size);
506 BUG(); 519 BUG();
507 }) 520 })
508 D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); 521 D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), freed_len));
509 jeb->unchecked_size -= ref_totlen(c, jeb, ref); 522 jeb->unchecked_size -= freed_len;
510 c->unchecked_size -= ref_totlen(c, jeb, ref); 523 c->unchecked_size -= freed_len;
511 } else { 524 } else {
512 D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) { 525 D1(if (unlikely(jeb->used_size < freed_len)) {
513 printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", 526 printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
514 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); 527 freed_len, blocknr, ref->flash_offset, jeb->used_size);
515 BUG(); 528 BUG();
516 }) 529 })
517 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); 530 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), freed_len));
518 jeb->used_size -= ref_totlen(c, jeb, ref); 531 jeb->used_size -= freed_len;
519 c->used_size -= ref_totlen(c, jeb, ref); 532 c->used_size -= freed_len;
520 } 533 }
521 534
522 // Take care, that wasted size is taken into concern 535 // Take care, that wasted size is taken into concern
523 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { 536 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + freed_len)) && jeb != c->nextblock) {
524 D1(printk(KERN_DEBUG "Dirtying\n")); 537 D1(printk("Dirtying\n"));
525 addedsize = ref_totlen(c, jeb, ref); 538 addedsize = freed_len;
526 jeb->dirty_size += ref_totlen(c, jeb, ref); 539 jeb->dirty_size += freed_len;
527 c->dirty_size += ref_totlen(c, jeb, ref); 540 c->dirty_size += freed_len;
528 541
529 /* Convert wasted space to dirty, if not a bad block */ 542 /* Convert wasted space to dirty, if not a bad block */
530 if (jeb->wasted_size) { 543 if (jeb->wasted_size) {
@@ -543,10 +556,10 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
543 } 556 }
544 } 557 }
545 } else { 558 } else {
546 D1(printk(KERN_DEBUG "Wasting\n")); 559 D1(printk("Wasting\n"));
547 addedsize = 0; 560 addedsize = 0;
548 jeb->wasted_size += ref_totlen(c, jeb, ref); 561 jeb->wasted_size += freed_len;
549 c->wasted_size += ref_totlen(c, jeb, ref); 562 c->wasted_size += freed_len;
550 } 563 }
551 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; 564 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
552 565
@@ -622,7 +635,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
622 /* The erase_free_sem is locked, and has been since before we marked the node obsolete 635 /* The erase_free_sem is locked, and has been since before we marked the node obsolete
623 and potentially put its eraseblock onto the erase_pending_list. Thus, we know that 636 and potentially put its eraseblock onto the erase_pending_list. Thus, we know that
624 the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet 637 the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet
625 by jffs2_free_all_node_refs() in erase.c. Which is nice. */ 638 by jffs2_free_jeb_node_refs() in erase.c. Which is nice. */
626 639
627 D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref))); 640 D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
628 ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); 641 ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
@@ -634,8 +647,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
634 printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); 647 printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
635 goto out_erase_sem; 648 goto out_erase_sem;
636 } 649 }
637 if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) { 650 if (PAD(je32_to_cpu(n.totlen)) != PAD(freed_len)) {
638 printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref)); 651 printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), freed_len);
639 goto out_erase_sem; 652 goto out_erase_sem;
640 } 653 }
641 if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) { 654 if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
@@ -671,6 +684,10 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
671 spin_lock(&c->erase_completion_lock); 684 spin_lock(&c->erase_completion_lock);
672 685
673 ic = jffs2_raw_ref_to_ic(ref); 686 ic = jffs2_raw_ref_to_ic(ref);
687 /* It seems we should never call jffs2_mark_node_obsolete() for
688 XATTR nodes.... yet. Make sure we notice if/when we change
689 that :) */
690 BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
674 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino)) 691 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
675 ; 692 ;
676 693
@@ -683,51 +700,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
683 spin_unlock(&c->erase_completion_lock); 700 spin_unlock(&c->erase_completion_lock);
684 } 701 }
685 702
686
687 /* Merge with the next node in the physical list, if there is one
688 and if it's also obsolete and if it doesn't belong to any inode */
689 if (ref->next_phys && ref_obsolete(ref->next_phys) &&
690 !ref->next_phys->next_in_ino) {
691 struct jffs2_raw_node_ref *n = ref->next_phys;
692
693 spin_lock(&c->erase_completion_lock);
694
695 ref->__totlen += n->__totlen;
696 ref->next_phys = n->next_phys;
697 if (jeb->last_node == n) jeb->last_node = ref;
698 if (jeb->gc_node == n) {
699 /* gc will be happy continuing gc on this node */
700 jeb->gc_node=ref;
701 }
702 spin_unlock(&c->erase_completion_lock);
703
704 jffs2_free_raw_node_ref(n);
705 }
706
707 /* Also merge with the previous node in the list, if there is one
708 and that one is obsolete */
709 if (ref != jeb->first_node ) {
710 struct jffs2_raw_node_ref *p = jeb->first_node;
711
712 spin_lock(&c->erase_completion_lock);
713
714 while (p->next_phys != ref)
715 p = p->next_phys;
716
717 if (ref_obsolete(p) && !ref->next_in_ino) {
718 p->__totlen += ref->__totlen;
719 if (jeb->last_node == ref) {
720 jeb->last_node = p;
721 }
722 if (jeb->gc_node == ref) {
723 /* gc will be happy continuing gc on this node */
724 jeb->gc_node=p;
725 }
726 p->next_phys = ref->next_phys;
727 jffs2_free_raw_node_ref(ref);
728 }
729 spin_unlock(&c->erase_completion_lock);
730 }
731 out_erase_sem: 703 out_erase_sem:
732 up(&c->erase_free_sem); 704 up(&c->erase_free_sem);
733} 705}
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d307cf548625..cd4021bcb944 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -31,9 +31,7 @@ struct kvec;
31#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) 31#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) 32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) 33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
34 34#define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev)
35#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
36#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
37 35
38#define ITIME(sec) ((struct timespec){sec, 0}) 36#define ITIME(sec) ((struct timespec){sec, 0})
39#define I_SEC(tv) ((tv).tv_sec) 37#define I_SEC(tv) ((tv).tv_sec)
@@ -60,6 +58,10 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
60 f->target = NULL; 58 f->target = NULL;
61 f->flags = 0; 59 f->flags = 0;
62 f->usercompr = 0; 60 f->usercompr = 0;
61#ifdef CONFIG_JFFS2_FS_POSIX_ACL
62 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
63 f->i_acl_default = JFFS2_ACL_NOT_CACHED;
64#endif
63} 65}
64 66
65 67
@@ -90,13 +92,10 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
90#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e) 92#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
91#define jffs2_wbuf_timeout NULL 93#define jffs2_wbuf_timeout NULL
92#define jffs2_wbuf_process NULL 94#define jffs2_wbuf_process NULL
93#define jffs2_nor_ecc(c) (0)
94#define jffs2_dataflash(c) (0) 95#define jffs2_dataflash(c) (0)
95#define jffs2_nor_wbuf_flash(c) (0)
96#define jffs2_nor_ecc_flash_setup(c) (0)
97#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
98#define jffs2_dataflash_setup(c) (0) 96#define jffs2_dataflash_setup(c) (0)
99#define jffs2_dataflash_cleanup(c) do {} while (0) 97#define jffs2_dataflash_cleanup(c) do {} while (0)
98#define jffs2_nor_wbuf_flash(c) (0)
100#define jffs2_nor_wbuf_flash_setup(c) (0) 99#define jffs2_nor_wbuf_flash_setup(c) (0)
101#define jffs2_nor_wbuf_flash_cleanup(c) do {} while (0) 100#define jffs2_nor_wbuf_flash_cleanup(c) do {} while (0)
102 101
@@ -107,9 +106,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
107#ifdef CONFIG_JFFS2_SUMMARY 106#ifdef CONFIG_JFFS2_SUMMARY
108#define jffs2_can_mark_obsolete(c) (0) 107#define jffs2_can_mark_obsolete(c) (0)
109#else 108#else
110#define jffs2_can_mark_obsolete(c) \ 109#define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE))
111 ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_ECC|MTD_PROGRAM_REGIONS))) || \
112 c->mtd->type == MTD_RAM)
113#endif 110#endif
114 111
115#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) 112#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
@@ -133,15 +130,11 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
133int jffs2_nand_flash_setup(struct jffs2_sb_info *c); 130int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
134void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); 131void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
135 132
136#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC))
137int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c);
138void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
139
140#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH) 133#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
141int jffs2_dataflash_setup(struct jffs2_sb_info *c); 134int jffs2_dataflash_setup(struct jffs2_sb_info *c);
142void jffs2_dataflash_cleanup(struct jffs2_sb_info *c); 135void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
143 136
144#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_PROGRAM_REGIONS)) 137#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && ! (c->mtd->flags & MTD_BIT_WRITEABLE))
145int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c); 138int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c);
146void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c); 139void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c);
147 140
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index f1695642d0f7..5fec012b02ed 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -66,7 +66,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
66 jffs2_free_full_dnode(tn->fn); 66 jffs2_free_full_dnode(tn->fn);
67 jffs2_free_tmp_dnode_info(tn); 67 jffs2_free_tmp_dnode_info(tn);
68 68
69 this = this->rb_parent; 69 this = rb_parent(this);
70 if (!this) 70 if (!this)
71 break; 71 break;
72 72
@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
116 uint32_t *latest_mctime, uint32_t *mctime_ver) 116 uint32_t *latest_mctime, uint32_t *mctime_ver)
117{ 117{
118 struct jffs2_full_dirent *fd; 118 struct jffs2_full_dirent *fd;
119 uint32_t crc;
119 120
120 /* The direntry nodes are checked during the flash scanning */
121 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
122 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 121 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
123 BUG_ON(ref_obsolete(ref)); 122 BUG_ON(ref_obsolete(ref));
124 123
125 /* Sanity check */ 124 crc = crc32(0, rd, sizeof(*rd) - 8);
126 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 125 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
127 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 126 JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
128 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 127 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
129 return 1; 128 return 1;
130 } 129 }
131 130
131 /* If we've never checked the CRCs on this node, check them now */
132 if (ref_flags(ref) == REF_UNCHECKED) {
133 struct jffs2_eraseblock *jeb;
134 int len;
135
136 /* Sanity check */
137 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
138 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
139 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
140 return 1;
141 }
142
143 jeb = &c->blocks[ref->flash_offset / c->sector_size];
144 len = ref_totlen(c, jeb, ref);
145
146 spin_lock(&c->erase_completion_lock);
147 jeb->used_size += len;
148 jeb->unchecked_size -= len;
149 c->used_size += len;
150 c->unchecked_size -= len;
151 ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
152 spin_unlock(&c->erase_completion_lock);
153 }
154
132 fd = jffs2_alloc_full_dirent(rd->nsize + 1); 155 fd = jffs2_alloc_full_dirent(rd->nsize + 1);
133 if (unlikely(!fd)) 156 if (unlikely(!fd))
134 return -ENOMEM; 157 return -ENOMEM;
@@ -198,13 +221,21 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
198 struct jffs2_tmp_dnode_info *tn; 221 struct jffs2_tmp_dnode_info *tn;
199 uint32_t len, csize; 222 uint32_t len, csize;
200 int ret = 1; 223 int ret = 1;
224 uint32_t crc;
201 225
202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 226 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
203 BUG_ON(ref_obsolete(ref)); 227 BUG_ON(ref_obsolete(ref));
204 228
229 crc = crc32(0, rd, sizeof(*rd) - 8);
230 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
231 JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n",
232 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
233 return 1;
234 }
235
205 tn = jffs2_alloc_tmp_dnode_info(); 236 tn = jffs2_alloc_tmp_dnode_info();
206 if (!tn) { 237 if (!tn) {
207 JFFS2_ERROR("failed to allocate tn (%d bytes).\n", sizeof(*tn)); 238 JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn));
208 return -ENOMEM; 239 return -ENOMEM;
209 } 240 }
210 241
@@ -213,14 +244,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
213 244
214 /* If we've never checked the CRCs on this node, check them now */ 245 /* If we've never checked the CRCs on this node, check them now */
215 if (ref_flags(ref) == REF_UNCHECKED) { 246 if (ref_flags(ref) == REF_UNCHECKED) {
216 uint32_t crc;
217
218 crc = crc32(0, rd, sizeof(*rd) - 8);
219 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
220 JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
222 goto free_out;
223 }
224 247
225 /* Sanity checks */ 248 /* Sanity checks */
226 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 249 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
@@ -343,7 +366,7 @@ free_out:
343 * Helper function for jffs2_get_inode_nodes(). 366 * Helper function for jffs2_get_inode_nodes().
344 * It is called every time an unknown node is found. 367 * It is called every time an unknown node is found.
345 * 368 *
346 * Returns: 0 on succes; 369 * Returns: 0 on success;
347 * 1 if the node should be marked obsolete; 370 * 1 if the node should be marked obsolete;
348 * negative error code on failure. 371 * negative error code on failure.
349 */ 372 */
@@ -354,37 +377,30 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re
354 377
355 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); 378 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
356 379
357 if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) { 380 switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
358 /* Hmmm. This should have been caught at scan time. */
359 JFFS2_NOTICE("node header CRC failed at %#08x. But it must have been OK earlier.\n", ref_offset(ref));
360 jffs2_dbg_dump_node(c, ref_offset(ref));
361 return 1;
362 } else {
363 switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
364 381
365 case JFFS2_FEATURE_INCOMPAT: 382 case JFFS2_FEATURE_INCOMPAT:
366 JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n", 383 JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n",
367 je16_to_cpu(un->nodetype), ref_offset(ref)); 384 je16_to_cpu(un->nodetype), ref_offset(ref));
368 /* EEP */ 385 /* EEP */
369 BUG(); 386 BUG();
370 break; 387 break;
371 388
372 case JFFS2_FEATURE_ROCOMPAT: 389 case JFFS2_FEATURE_ROCOMPAT:
373 JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n", 390 JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n",
374 je16_to_cpu(un->nodetype), ref_offset(ref)); 391 je16_to_cpu(un->nodetype), ref_offset(ref));
375 BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); 392 BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
376 break; 393 break;
377 394
378 case JFFS2_FEATURE_RWCOMPAT_COPY: 395 case JFFS2_FEATURE_RWCOMPAT_COPY:
379 JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n", 396 JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
380 je16_to_cpu(un->nodetype), ref_offset(ref)); 397 je16_to_cpu(un->nodetype), ref_offset(ref));
381 break; 398 break;
382 399
383 case JFFS2_FEATURE_RWCOMPAT_DELETE: 400 case JFFS2_FEATURE_RWCOMPAT_DELETE:
384 JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", 401 JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
385 je16_to_cpu(un->nodetype), ref_offset(ref)); 402 je16_to_cpu(un->nodetype), ref_offset(ref));
386 return 1; 403 return 1;
387 }
388 } 404 }
389 405
390 return 0; 406 return 0;
@@ -434,7 +450,7 @@ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
434 } 450 }
435 451
436 if (retlen < len) { 452 if (retlen < len) {
437 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", 453 JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n",
438 offs, retlen, len); 454 offs, retlen, len);
439 return -EIO; 455 return -EIO;
440 } 456 }
@@ -542,13 +558,25 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
542 } 558 }
543 559
544 if (retlen < len) { 560 if (retlen < len) {
545 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len); 561 JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", ref_offset(ref), retlen, len);
546 err = -EIO; 562 err = -EIO;
547 goto free_out; 563 goto free_out;
548 } 564 }
549 565
550 node = (union jffs2_node_union *)bufstart; 566 node = (union jffs2_node_union *)bufstart;
551 567
568 /* No need to mask in the valid bit; it shouldn't be invalid */
569 if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) {
570 JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n",
571 ref_offset(ref), je16_to_cpu(node->u.magic),
572 je16_to_cpu(node->u.nodetype),
573 je32_to_cpu(node->u.totlen),
574 je32_to_cpu(node->u.hdr_crc));
575 jffs2_dbg_dump_node(c, ref_offset(ref));
576 jffs2_mark_node_obsolete(c, ref);
577 goto cont;
578 }
579
552 switch (je16_to_cpu(node->u.nodetype)) { 580 switch (je16_to_cpu(node->u.nodetype)) {
553 581
554 case JFFS2_NODETYPE_DIRENT: 582 case JFFS2_NODETYPE_DIRENT:
@@ -606,6 +634,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
606 goto free_out; 634 goto free_out;
607 635
608 } 636 }
637 cont:
609 spin_lock(&c->erase_completion_lock); 638 spin_lock(&c->erase_completion_lock);
610 } 639 }
611 640
@@ -679,12 +708,12 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
679 jffs2_mark_node_obsolete(c, fn->raw); 708 jffs2_mark_node_obsolete(c, fn->raw);
680 709
681 BUG_ON(rb->rb_left); 710 BUG_ON(rb->rb_left);
682 if (rb->rb_parent && rb->rb_parent->rb_left == rb) { 711 if (rb_parent(rb) && rb_parent(rb)->rb_left == rb) {
683 /* We were then left-hand child of our parent. We need 712 /* We were then left-hand child of our parent. We need
684 * to move our own right-hand child into our place. */ 713 * to move our own right-hand child into our place. */
685 repl_rb = rb->rb_right; 714 repl_rb = rb->rb_right;
686 if (repl_rb) 715 if (repl_rb)
687 repl_rb->rb_parent = rb->rb_parent; 716 rb_set_parent(repl_rb, rb_parent(rb));
688 } else 717 } else
689 repl_rb = NULL; 718 repl_rb = NULL;
690 719
@@ -692,14 +721,14 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
692 721
693 /* Remove the spent tn from the tree; don't bother rebalancing 722 /* Remove the spent tn from the tree; don't bother rebalancing
694 * but put our right-hand child in our own place. */ 723 * but put our right-hand child in our own place. */
695 if (tn->rb.rb_parent) { 724 if (rb_parent(&tn->rb)) {
696 if (tn->rb.rb_parent->rb_left == &tn->rb) 725 if (rb_parent(&tn->rb)->rb_left == &tn->rb)
697 tn->rb.rb_parent->rb_left = repl_rb; 726 rb_parent(&tn->rb)->rb_left = repl_rb;
698 else if (tn->rb.rb_parent->rb_right == &tn->rb) 727 else if (rb_parent(&tn->rb)->rb_right == &tn->rb)
699 tn->rb.rb_parent->rb_right = repl_rb; 728 rb_parent(&tn->rb)->rb_right = repl_rb;
700 else BUG(); 729 else BUG();
701 } else if (tn->rb.rb_right) 730 } else if (tn->rb.rb_right)
702 tn->rb.rb_right->rb_parent = NULL; 731 rb_set_parent(tn->rb.rb_right, NULL);
703 732
704 jffs2_free_tmp_dnode_info(tn); 733 jffs2_free_tmp_dnode_info(tn);
705 if (ret) { 734 if (ret) {
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index cf55b221fc2b..61618080b86f 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -65,6 +65,28 @@ static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
65 return DEFAULT_EMPTY_SCAN_SIZE; 65 return DEFAULT_EMPTY_SCAN_SIZE;
66} 66}
67 67
68static int file_dirty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
69{
70 int ret;
71
72 if ((ret = jffs2_prealloc_raw_node_refs(c, jeb, 1)))
73 return ret;
74 if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size)))
75 return ret;
76 /* Turned wasted size into dirty, since we apparently
77 think it's recoverable now. */
78 jeb->dirty_size += jeb->wasted_size;
79 c->dirty_size += jeb->wasted_size;
80 c->wasted_size -= jeb->wasted_size;
81 jeb->wasted_size = 0;
82 if (VERYDIRTY(c, jeb->dirty_size)) {
83 list_add(&jeb->list, &c->very_dirty_list);
84 } else {
85 list_add(&jeb->list, &c->dirty_list);
86 }
87 return 0;
88}
89
68int jffs2_scan_medium(struct jffs2_sb_info *c) 90int jffs2_scan_medium(struct jffs2_sb_info *c)
69{ 91{
70 int i, ret; 92 int i, ret;
@@ -170,34 +192,20 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
170 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { 192 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
171 /* Better candidate for the next writes to go to */ 193 /* Better candidate for the next writes to go to */
172 if (c->nextblock) { 194 if (c->nextblock) {
173 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 195 ret = file_dirty(c, c->nextblock);
174 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 196 if (ret)
175 c->free_size -= c->nextblock->free_size; 197 return ret;
176 c->wasted_size -= c->nextblock->wasted_size;
177 c->nextblock->free_size = c->nextblock->wasted_size = 0;
178 if (VERYDIRTY(c, c->nextblock->dirty_size)) {
179 list_add(&c->nextblock->list, &c->very_dirty_list);
180 } else {
181 list_add(&c->nextblock->list, &c->dirty_list);
182 }
183 /* deleting summary information of the old nextblock */ 198 /* deleting summary information of the old nextblock */
184 jffs2_sum_reset_collected(c->summary); 199 jffs2_sum_reset_collected(c->summary);
185 } 200 }
186 /* update collected summary infromation for the current nextblock */ 201 /* update collected summary information for the current nextblock */
187 jffs2_sum_move_collected(c, s); 202 jffs2_sum_move_collected(c, s);
188 D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset)); 203 D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));
189 c->nextblock = jeb; 204 c->nextblock = jeb;
190 } else { 205 } else {
191 jeb->dirty_size += jeb->free_size + jeb->wasted_size; 206 ret = file_dirty(c, jeb);
192 c->dirty_size += jeb->free_size + jeb->wasted_size; 207 if (ret)
193 c->free_size -= jeb->free_size; 208 return ret;
194 c->wasted_size -= jeb->wasted_size;
195 jeb->free_size = jeb->wasted_size = 0;
196 if (VERYDIRTY(c, jeb->dirty_size)) {
197 list_add(&jeb->list, &c->very_dirty_list);
198 } else {
199 list_add(&jeb->list, &c->dirty_list);
200 }
201 } 209 }
202 break; 210 break;
203 211
@@ -222,9 +230,6 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
222 } 230 }
223 } 231 }
224 232
225 if (jffs2_sum_active() && s)
226 kfree(s);
227
228 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ 233 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
229 if (c->nextblock && (c->nextblock->dirty_size)) { 234 if (c->nextblock && (c->nextblock->dirty_size)) {
230 c->nextblock->wasted_size += c->nextblock->dirty_size; 235 c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -242,11 +247,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
242 247
243 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", 248 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
244 skip)); 249 skip));
245 c->nextblock->wasted_size += skip; 250 jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
246 c->wasted_size += skip; 251 jffs2_scan_dirty_space(c, c->nextblock, skip);
247
248 c->nextblock->free_size -= skip;
249 c->free_size -= skip;
250 } 252 }
251#endif 253#endif
252 if (c->nr_erasing_blocks) { 254 if (c->nr_erasing_blocks) {
@@ -266,6 +268,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
266 else 268 else
267 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); 269 c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
268#endif 270#endif
271 if (s)
272 kfree(s);
273
269 return ret; 274 return ret;
270} 275}
271 276
@@ -290,7 +295,7 @@ int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
290int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 295int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
291{ 296{
292 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 297 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
293 && (!jeb->first_node || !jeb->first_node->next_phys) ) 298 && (!jeb->first_node || !ref_next(jeb->first_node)) )
294 return BLK_STATE_CLEANMARKER; 299 return BLK_STATE_CLEANMARKER;
295 300
296 /* move blocks with max 4 byte dirty space to cleanlist */ 301 /* move blocks with max 4 byte dirty space to cleanlist */
@@ -306,11 +311,119 @@ int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *je
306 return BLK_STATE_ALLDIRTY; 311 return BLK_STATE_ALLDIRTY;
307} 312}
308 313
314#ifdef CONFIG_JFFS2_FS_XATTR
315static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
316 struct jffs2_raw_xattr *rx, uint32_t ofs,
317 struct jffs2_summary *s)
318{
319 struct jffs2_xattr_datum *xd;
320 uint32_t totlen, crc;
321 int err;
322
323 crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4);
324 if (crc != je32_to_cpu(rx->node_crc)) {
325 if (je32_to_cpu(rx->node_crc) != 0xffffffff)
326 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
327 ofs, je32_to_cpu(rx->node_crc), crc);
328 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
329 return err;
330 return 0;
331 }
332
333 totlen = PAD(sizeof(*rx) + rx->name_len + 1 + je16_to_cpu(rx->value_len));
334 if (totlen != je32_to_cpu(rx->totlen)) {
335 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
336 ofs, je32_to_cpu(rx->totlen), totlen);
337 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
338 return err;
339 return 0;
340 }
341
342 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version));
343 if (IS_ERR(xd)) {
344 if (PTR_ERR(xd) == -EEXIST) {
345 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen)))))
346 return err;
347 return 0;
348 }
349 return PTR_ERR(xd);
350 }
351 xd->xprefix = rx->xprefix;
352 xd->name_len = rx->name_len;
353 xd->value_len = je16_to_cpu(rx->value_len);
354 xd->data_crc = je32_to_cpu(rx->data_crc);
355
356 xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL);
357 /* FIXME */ xd->node->next_in_ino = (void *)xd;
358
359 if (jffs2_sum_active())
360 jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
361 dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n",
362 ofs, xd->xid, xd->version);
363 return 0;
364}
365
366static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
367 struct jffs2_raw_xref *rr, uint32_t ofs,
368 struct jffs2_summary *s)
369{
370 struct jffs2_xattr_ref *ref;
371 uint32_t crc;
372 int err;
373
374 crc = crc32(0, rr, sizeof(*rr) - 4);
375 if (crc != je32_to_cpu(rr->node_crc)) {
376 if (je32_to_cpu(rr->node_crc) != 0xffffffff)
377 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
378 ofs, je32_to_cpu(rr->node_crc), crc);
379 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))
380 return err;
381 return 0;
382 }
383
384 if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) {
385 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%zd\n",
386 ofs, je32_to_cpu(rr->totlen),
387 PAD(sizeof(struct jffs2_raw_xref)));
388 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rr->totlen))))
389 return err;
390 return 0;
391 }
392
393 ref = jffs2_alloc_xattr_ref();
394 if (!ref)
395 return -ENOMEM;
396
397 /* BEFORE jffs2_build_xattr_subsystem() called,
398 * ref->xid is used to store 32bit xid, xd is not used
399 * ref->ino is used to store 32bit inode-number, ic is not used
400 * Thoes variables are declared as union, thus using those
401 * are exclusive. In a similar way, ref->next is temporarily
402 * used to chain all xattr_ref object. It's re-chained to
403 * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.
404 */
405 ref->ino = je32_to_cpu(rr->ino);
406 ref->xid = je32_to_cpu(rr->xid);
407 ref->next = c->xref_temp;
408 c->xref_temp = ref;
409
410 ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL);
411 /* FIXME */ ref->node->next_in_ino = (void *)ref;
412
413 if (jffs2_sum_active())
414 jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
415 dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n",
416 ofs, ref->xid, ref->ino);
417 return 0;
418}
419#endif
420
421/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into
422 the flash, XIP-style */
309static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 423static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
310 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) { 424 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
311 struct jffs2_unknown_node *node; 425 struct jffs2_unknown_node *node;
312 struct jffs2_unknown_node crcnode; 426 struct jffs2_unknown_node crcnode;
313 struct jffs2_sum_marker *sm;
314 uint32_t ofs, prevofs; 427 uint32_t ofs, prevofs;
315 uint32_t hdr_crc, buf_ofs, buf_len; 428 uint32_t hdr_crc, buf_ofs, buf_len;
316 int err; 429 int err;
@@ -344,44 +457,75 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
344#endif 457#endif
345 458
346 if (jffs2_sum_active()) { 459 if (jffs2_sum_active()) {
347 sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL); 460 struct jffs2_sum_marker *sm;
348 if (!sm) { 461 void *sumptr = NULL;
349 return -ENOMEM; 462 uint32_t sumlen;
350 } 463
351 464 if (!buf_size) {
352 err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size - 465 /* XIP case. Just look, point at the summary if it's there */
353 sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker)); 466 sm = (void *)buf + c->sector_size - sizeof(*sm);
354 if (err) { 467 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {
355 kfree(sm); 468 sumptr = buf + je32_to_cpu(sm->offset);
356 return err; 469 sumlen = c->sector_size - je32_to_cpu(sm->offset);
357 } 470 }
358 471 } else {
359 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) { 472 /* If NAND flash, read a whole page of it. Else just the end */
360 err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random); 473 if (c->wbuf_pagesize)
361 if (err) { 474 buf_len = c->wbuf_pagesize;
362 kfree(sm); 475 else
476 buf_len = sizeof(*sm);
477
478 /* Read as much as we want into the _end_ of the preallocated buffer */
479 err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
480 jeb->offset + c->sector_size - buf_len,
481 buf_len);
482 if (err)
363 return err; 483 return err;
484
485 sm = (void *)buf + buf_size - sizeof(*sm);
486 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {
487 sumlen = c->sector_size - je32_to_cpu(sm->offset);
488 sumptr = buf + buf_size - sumlen;
489
490 /* Now, make sure the summary itself is available */
491 if (sumlen > buf_size) {
492 /* Need to kmalloc for this. */
493 sumptr = kmalloc(sumlen, GFP_KERNEL);
494 if (!sumptr)
495 return -ENOMEM;
496 memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len);
497 }
498 if (buf_len < sumlen) {
499 /* Need to read more so that the entire summary node is present */
500 err = jffs2_fill_scan_buf(c, sumptr,
501 jeb->offset + c->sector_size - sumlen,
502 sumlen - buf_len);
503 if (err)
504 return err;
505 }
364 } 506 }
507
365 } 508 }
366 509
367 kfree(sm); 510 if (sumptr) {
511 err = jffs2_sum_scan_sumnode(c, jeb, sumptr, sumlen, &pseudo_random);
368 512
369 ofs = jeb->offset; 513 if (buf_size && sumlen > buf_size)
370 prevofs = jeb->offset - 1; 514 kfree(sumptr);
515 /* If it returns with a real error, bail.
516 If it returns positive, that's a block classification
517 (i.e. BLK_STATE_xxx) so return that too.
518 If it returns zero, fall through to full scan. */
519 if (err)
520 return err;
521 }
371 } 522 }
372 523
373 buf_ofs = jeb->offset; 524 buf_ofs = jeb->offset;
374 525
375 if (!buf_size) { 526 if (!buf_size) {
527 /* This is the XIP case -- we're reading _directly_ from the flash chip */
376 buf_len = c->sector_size; 528 buf_len = c->sector_size;
377
378 if (jffs2_sum_active()) {
379 /* must reread because of summary test */
380 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
381 if (err)
382 return err;
383 }
384
385 } else { 529 } else {
386 buf_len = EMPTY_SCAN_SIZE(c->sector_size); 530 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
387 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 531 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
@@ -418,7 +562,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
418 if (ofs) { 562 if (ofs) {
419 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, 563 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
420 jeb->offset + ofs)); 564 jeb->offset + ofs));
421 DIRTY_SPACE(ofs); 565 if ((err = jffs2_prealloc_raw_node_refs(c, jeb, 1)))
566 return err;
567 if ((err = jffs2_scan_dirty_space(c, jeb, ofs)))
568 return err;
422 } 569 }
423 570
424 /* Now ofs is a complete physical flash offset as it always was... */ 571 /* Now ofs is a complete physical flash offset as it always was... */
@@ -433,6 +580,11 @@ scan_more:
433 580
434 jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 581 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
435 582
583 /* Make sure there are node refs available for use */
584 err = jffs2_prealloc_raw_node_refs(c, jeb, 2);
585 if (err)
586 return err;
587
436 cond_resched(); 588 cond_resched();
437 589
438 if (ofs & 3) { 590 if (ofs & 3) {
@@ -442,7 +594,8 @@ scan_more:
442 } 594 }
443 if (ofs == prevofs) { 595 if (ofs == prevofs) {
444 printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); 596 printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);
445 DIRTY_SPACE(4); 597 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
598 return err;
446 ofs += 4; 599 ofs += 4;
447 continue; 600 continue;
448 } 601 }
@@ -451,7 +604,8 @@ scan_more:
451 if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { 604 if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
452 D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), 605 D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),
453 jeb->offset, c->sector_size, ofs, sizeof(*node))); 606 jeb->offset, c->sector_size, ofs, sizeof(*node)));
454 DIRTY_SPACE((jeb->offset + c->sector_size)-ofs); 607 if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs)))
608 return err;
455 break; 609 break;
456 } 610 }
457 611
@@ -481,7 +635,8 @@ scan_more:
481 if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { 635 if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {
482 printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", 636 printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
483 empty_start, ofs); 637 empty_start, ofs);
484 DIRTY_SPACE(ofs-empty_start); 638 if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))
639 return err;
485 goto scan_more; 640 goto scan_more;
486 } 641 }
487 642
@@ -494,7 +649,7 @@ scan_more:
494 /* If we're only checking the beginning of a block with a cleanmarker, 649 /* If we're only checking the beginning of a block with a cleanmarker,
495 bail now */ 650 bail now */
496 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 651 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
497 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { 652 c->cleanmarker_size && !jeb->dirty_size && !ref_next(jeb->first_node)) {
498 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); 653 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
499 return BLK_STATE_CLEANMARKER; 654 return BLK_STATE_CLEANMARKER;
500 } 655 }
@@ -518,20 +673,23 @@ scan_more:
518 673
519 if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { 674 if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
520 printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); 675 printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
521 DIRTY_SPACE(4); 676 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
677 return err;
522 ofs += 4; 678 ofs += 4;
523 continue; 679 continue;
524 } 680 }
525 if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { 681 if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
526 D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); 682 D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
527 DIRTY_SPACE(4); 683 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
684 return err;
528 ofs += 4; 685 ofs += 4;
529 continue; 686 continue;
530 } 687 }
531 if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { 688 if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {
532 printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); 689 printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
533 printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); 690 printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
534 DIRTY_SPACE(4); 691 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
692 return err;
535 ofs += 4; 693 ofs += 4;
536 continue; 694 continue;
537 } 695 }
@@ -540,7 +698,8 @@ scan_more:
540 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", 698 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
541 JFFS2_MAGIC_BITMASK, ofs, 699 JFFS2_MAGIC_BITMASK, ofs,
542 je16_to_cpu(node->magic)); 700 je16_to_cpu(node->magic));
543 DIRTY_SPACE(4); 701 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
702 return err;
544 ofs += 4; 703 ofs += 4;
545 continue; 704 continue;
546 } 705 }
@@ -557,7 +716,8 @@ scan_more:
557 je32_to_cpu(node->totlen), 716 je32_to_cpu(node->totlen),
558 je32_to_cpu(node->hdr_crc), 717 je32_to_cpu(node->hdr_crc),
559 hdr_crc); 718 hdr_crc);
560 DIRTY_SPACE(4); 719 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
720 return err;
561 ofs += 4; 721 ofs += 4;
562 continue; 722 continue;
563 } 723 }
@@ -568,7 +728,8 @@ scan_more:
568 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", 728 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
569 ofs, je32_to_cpu(node->totlen)); 729 ofs, je32_to_cpu(node->totlen));
570 printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); 730 printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
571 DIRTY_SPACE(4); 731 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
732 return err;
572 ofs += 4; 733 ofs += 4;
573 continue; 734 continue;
574 } 735 }
@@ -576,7 +737,8 @@ scan_more:
576 if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { 737 if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {
577 /* Wheee. This is an obsoleted node */ 738 /* Wheee. This is an obsoleted node */
578 D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); 739 D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));
579 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 740 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
741 return err;
580 ofs += PAD(je32_to_cpu(node->totlen)); 742 ofs += PAD(je32_to_cpu(node->totlen));
581 continue; 743 continue;
582 } 744 }
@@ -614,30 +776,59 @@ scan_more:
614 ofs += PAD(je32_to_cpu(node->totlen)); 776 ofs += PAD(je32_to_cpu(node->totlen));
615 break; 777 break;
616 778
779#ifdef CONFIG_JFFS2_FS_XATTR
780 case JFFS2_NODETYPE_XATTR:
781 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
782 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
783 D1(printk(KERN_DEBUG "Fewer than %d bytes (xattr node)"
784 " left to end of buf. Reading 0x%x at 0x%08x\n",
785 je32_to_cpu(node->totlen), buf_len, ofs));
786 err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
787 if (err)
788 return err;
789 buf_ofs = ofs;
790 node = (void *)buf;
791 }
792 err = jffs2_scan_xattr_node(c, jeb, (void *)node, ofs, s);
793 if (err)
794 return err;
795 ofs += PAD(je32_to_cpu(node->totlen));
796 break;
797 case JFFS2_NODETYPE_XREF:
798 if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
799 buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
800 D1(printk(KERN_DEBUG "Fewer than %d bytes (xref node)"
801 " left to end of buf. Reading 0x%x at 0x%08x\n",
802 je32_to_cpu(node->totlen), buf_len, ofs));
803 err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
804 if (err)
805 return err;
806 buf_ofs = ofs;
807 node = (void *)buf;
808 }
809 err = jffs2_scan_xref_node(c, jeb, (void *)node, ofs, s);
810 if (err)
811 return err;
812 ofs += PAD(je32_to_cpu(node->totlen));
813 break;
814#endif /* CONFIG_JFFS2_FS_XATTR */
815
617 case JFFS2_NODETYPE_CLEANMARKER: 816 case JFFS2_NODETYPE_CLEANMARKER:
618 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); 817 D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
619 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { 818 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
620 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 819 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
621 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); 820 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
622 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 821 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node)))))
822 return err;
623 ofs += PAD(sizeof(struct jffs2_unknown_node)); 823 ofs += PAD(sizeof(struct jffs2_unknown_node));
624 } else if (jeb->first_node) { 824 } else if (jeb->first_node) {
625 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); 825 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
626 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 826 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node)))))
827 return err;
627 ofs += PAD(sizeof(struct jffs2_unknown_node)); 828 ofs += PAD(sizeof(struct jffs2_unknown_node));
628 } else { 829 } else {
629 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 830 jffs2_link_node_ref(c, jeb, ofs | REF_NORMAL, c->cleanmarker_size, NULL);
630 if (!marker_ref) {
631 printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");
632 return -ENOMEM;
633 }
634 marker_ref->next_in_ino = NULL;
635 marker_ref->next_phys = NULL;
636 marker_ref->flash_offset = ofs | REF_NORMAL;
637 marker_ref->__totlen = c->cleanmarker_size;
638 jeb->first_node = jeb->last_node = marker_ref;
639 831
640 USED_SPACE(PAD(c->cleanmarker_size));
641 ofs += PAD(c->cleanmarker_size); 832 ofs += PAD(c->cleanmarker_size);
642 } 833 }
643 break; 834 break;
@@ -645,7 +836,8 @@ scan_more:
645 case JFFS2_NODETYPE_PADDING: 836 case JFFS2_NODETYPE_PADDING:
646 if (jffs2_sum_active()) 837 if (jffs2_sum_active())
647 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen)); 838 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
648 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 839 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
840 return err;
649 ofs += PAD(je32_to_cpu(node->totlen)); 841 ofs += PAD(je32_to_cpu(node->totlen));
650 break; 842 break;
651 843
@@ -656,7 +848,8 @@ scan_more:
656 c->flags |= JFFS2_SB_FLAG_RO; 848 c->flags |= JFFS2_SB_FLAG_RO;
657 if (!(jffs2_is_readonly(c))) 849 if (!(jffs2_is_readonly(c)))
658 return -EROFS; 850 return -EROFS;
659 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 851 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
852 return err;
660 ofs += PAD(je32_to_cpu(node->totlen)); 853 ofs += PAD(je32_to_cpu(node->totlen));
661 break; 854 break;
662 855
@@ -666,15 +859,21 @@ scan_more:
666 859
667 case JFFS2_FEATURE_RWCOMPAT_DELETE: 860 case JFFS2_FEATURE_RWCOMPAT_DELETE:
668 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); 861 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
669 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 862 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
863 return err;
670 ofs += PAD(je32_to_cpu(node->totlen)); 864 ofs += PAD(je32_to_cpu(node->totlen));
671 break; 865 break;
672 866
673 case JFFS2_FEATURE_RWCOMPAT_COPY: 867 case JFFS2_FEATURE_RWCOMPAT_COPY: {
674 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); 868 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
675 USED_SPACE(PAD(je32_to_cpu(node->totlen))); 869
870 jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(node->totlen)), NULL);
871
872 /* We can't summarise nodes we don't grok */
873 jffs2_sum_disable_collecting(s);
676 ofs += PAD(je32_to_cpu(node->totlen)); 874 ofs += PAD(je32_to_cpu(node->totlen));
677 break; 875 break;
876 }
678 } 877 }
679 } 878 }
680 } 879 }
@@ -687,9 +886,9 @@ scan_more:
687 } 886 }
688 } 887 }
689 888
690 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, 889 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n",
691 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); 890 jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size));
692 891
693 /* mark_node_obsolete can add to wasted !! */ 892 /* mark_node_obsolete can add to wasted !! */
694 if (jeb->wasted_size) { 893 if (jeb->wasted_size) {
695 jeb->dirty_size += jeb->wasted_size; 894 jeb->dirty_size += jeb->wasted_size;
@@ -730,9 +929,9 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin
730static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 929static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
731 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) 930 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
732{ 931{
733 struct jffs2_raw_node_ref *raw;
734 struct jffs2_inode_cache *ic; 932 struct jffs2_inode_cache *ic;
735 uint32_t ino = je32_to_cpu(ri->ino); 933 uint32_t ino = je32_to_cpu(ri->ino);
934 int err;
736 935
737 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); 936 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
738 937
@@ -745,12 +944,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
745 Which means that the _full_ amount of time to get to proper write mode with GC 944 Which means that the _full_ amount of time to get to proper write mode with GC
746 operational may actually be _longer_ than before. Sucks to be me. */ 945 operational may actually be _longer_ than before. Sucks to be me. */
747 946
748 raw = jffs2_alloc_raw_node_ref();
749 if (!raw) {
750 printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
751 return -ENOMEM;
752 }
753
754 ic = jffs2_get_ino_cache(c, ino); 947 ic = jffs2_get_ino_cache(c, ino);
755 if (!ic) { 948 if (!ic) {
756 /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the 949 /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the
@@ -762,30 +955,17 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
762 printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 955 printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
763 ofs, je32_to_cpu(ri->node_crc), crc); 956 ofs, je32_to_cpu(ri->node_crc), crc);
764 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ 957 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
765 DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen))); 958 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen)))))
766 jffs2_free_raw_node_ref(raw); 959 return err;
767 return 0; 960 return 0;
768 } 961 }
769 ic = jffs2_scan_make_ino_cache(c, ino); 962 ic = jffs2_scan_make_ino_cache(c, ino);
770 if (!ic) { 963 if (!ic)
771 jffs2_free_raw_node_ref(raw);
772 return -ENOMEM; 964 return -ENOMEM;
773 }
774 } 965 }
775 966
776 /* Wheee. It worked */ 967 /* Wheee. It worked */
777 968 jffs2_link_node_ref(c, jeb, ofs | REF_UNCHECKED, PAD(je32_to_cpu(ri->totlen)), ic);
778 raw->flash_offset = ofs | REF_UNCHECKED;
779 raw->__totlen = PAD(je32_to_cpu(ri->totlen));
780 raw->next_phys = NULL;
781 raw->next_in_ino = ic->nodes;
782
783 ic->nodes = raw;
784 if (!jeb->first_node)
785 jeb->first_node = raw;
786 if (jeb->last_node)
787 jeb->last_node->next_phys = raw;
788 jeb->last_node = raw;
789 969
790 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 970 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
791 je32_to_cpu(ri->ino), je32_to_cpu(ri->version), 971 je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
@@ -794,8 +974,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
794 974
795 pseudo_random += je32_to_cpu(ri->version); 975 pseudo_random += je32_to_cpu(ri->version);
796 976
797 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
798
799 if (jffs2_sum_active()) { 977 if (jffs2_sum_active()) {
800 jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset); 978 jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset);
801 } 979 }
@@ -806,10 +984,10 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
806static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 984static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
807 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s) 985 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
808{ 986{
809 struct jffs2_raw_node_ref *raw;
810 struct jffs2_full_dirent *fd; 987 struct jffs2_full_dirent *fd;
811 struct jffs2_inode_cache *ic; 988 struct jffs2_inode_cache *ic;
812 uint32_t crc; 989 uint32_t crc;
990 int err;
813 991
814 D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs)); 992 D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs));
815 993
@@ -821,7 +999,8 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
821 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 999 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
822 ofs, je32_to_cpu(rd->node_crc), crc); 1000 ofs, je32_to_cpu(rd->node_crc), crc);
823 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ 1001 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
824 DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); 1002 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rd->totlen)))))
1003 return err;
825 return 0; 1004 return 0;
826 } 1005 }
827 1006
@@ -842,40 +1021,23 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
842 jffs2_free_full_dirent(fd); 1021 jffs2_free_full_dirent(fd);
843 /* FIXME: Why do we believe totlen? */ 1022 /* FIXME: Why do we believe totlen? */
844 /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */ 1023 /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
845 DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); 1024 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rd->totlen)))))
1025 return err;
846 return 0; 1026 return 0;
847 } 1027 }
848 raw = jffs2_alloc_raw_node_ref();
849 if (!raw) {
850 jffs2_free_full_dirent(fd);
851 printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
852 return -ENOMEM;
853 }
854 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); 1028 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino));
855 if (!ic) { 1029 if (!ic) {
856 jffs2_free_full_dirent(fd); 1030 jffs2_free_full_dirent(fd);
857 jffs2_free_raw_node_ref(raw);
858 return -ENOMEM; 1031 return -ENOMEM;
859 } 1032 }
860 1033
861 raw->__totlen = PAD(je32_to_cpu(rd->totlen)); 1034 fd->raw = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rd->totlen)), ic);
862 raw->flash_offset = ofs | REF_PRISTINE;
863 raw->next_phys = NULL;
864 raw->next_in_ino = ic->nodes;
865 ic->nodes = raw;
866 if (!jeb->first_node)
867 jeb->first_node = raw;
868 if (jeb->last_node)
869 jeb->last_node->next_phys = raw;
870 jeb->last_node = raw;
871 1035
872 fd->raw = raw;
873 fd->next = NULL; 1036 fd->next = NULL;
874 fd->version = je32_to_cpu(rd->version); 1037 fd->version = je32_to_cpu(rd->version);
875 fd->ino = je32_to_cpu(rd->ino); 1038 fd->ino = je32_to_cpu(rd->ino);
876 fd->nhash = full_name_hash(fd->name, rd->nsize); 1039 fd->nhash = full_name_hash(fd->name, rd->nsize);
877 fd->type = rd->type; 1040 fd->type = rd->type;
878 USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
879 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 1041 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
880 1042
881 if (jffs2_sum_active()) { 1043 if (jffs2_sum_active()) {
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
new file mode 100644
index 000000000000..52a9894a6364
--- /dev/null
+++ b/fs/jffs2/security.c
@@ -0,0 +1,82 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/fs.h>
14#include <linux/time.h>
15#include <linux/pagemap.h>
16#include <linux/highmem.h>
17#include <linux/crc32.h>
18#include <linux/jffs2.h>
19#include <linux/xattr.h>
20#include <linux/mtd/mtd.h>
21#include <linux/security.h>
22#include "nodelist.h"
23
24/* ---- Initial Security Label Attachment -------------- */
25int jffs2_init_security(struct inode *inode, struct inode *dir)
26{
27 int rc;
28 size_t len;
29 void *value;
30 char *name;
31
32 rc = security_inode_init_security(inode, dir, &name, &value, &len);
33 if (rc) {
34 if (rc == -EOPNOTSUPP)
35 return 0;
36 return rc;
37 }
38 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
39
40 kfree(name);
41 kfree(value);
42 return rc;
43}
44
45/* ---- XATTR Handler for "security.*" ----------------- */
46static int jffs2_security_getxattr(struct inode *inode, const char *name,
47 void *buffer, size_t size)
48{
49 if (!strcmp(name, ""))
50 return -EINVAL;
51
52 return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size);
53}
54
55static int jffs2_security_setxattr(struct inode *inode, const char *name, const void *buffer,
56 size_t size, int flags)
57{
58 if (!strcmp(name, ""))
59 return -EINVAL;
60
61 return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size, flags);
62}
63
64static size_t jffs2_security_listxattr(struct inode *inode, char *list, size_t list_size,
65 const char *name, size_t name_len)
66{
67 size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
68
69 if (list && retlen <= list_size) {
70 strcpy(list, XATTR_SECURITY_PREFIX);
71 strcpy(list + XATTR_SECURITY_PREFIX_LEN, name);
72 }
73
74 return retlen;
75}
76
77struct xattr_handler jffs2_security_xattr_handler = {
78 .prefix = XATTR_SECURITY_PREFIX,
79 .list = jffs2_security_listxattr,
80 .set = jffs2_security_setxattr,
81 .get = jffs2_security_getxattr
82};
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index fb9cec61fcf2..0b02fc79e4d1 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -5,6 +5,7 @@
5 * Zoltan Sogor <weth@inf.u-szeged.hu>, 5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>, 6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary 7 * University of Szeged, Hungary
8 * 2005 KaiGai Kohei <kaigai@ak.jp.nec.com>
8 * 9 *
9 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
10 * 11 *
@@ -81,6 +82,19 @@ static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
81 dbg_summary("dirent (%u) added to summary\n", 82 dbg_summary("dirent (%u) added to summary\n",
82 je32_to_cpu(item->d.ino)); 83 je32_to_cpu(item->d.ino));
83 break; 84 break;
85#ifdef CONFIG_JFFS2_FS_XATTR
86 case JFFS2_NODETYPE_XATTR:
87 s->sum_size += JFFS2_SUMMARY_XATTR_SIZE;
88 s->sum_num++;
89 dbg_summary("xattr (xid=%u, version=%u) added to summary\n",
90 je32_to_cpu(item->x.xid), je32_to_cpu(item->x.version));
91 break;
92 case JFFS2_NODETYPE_XREF:
93 s->sum_size += JFFS2_SUMMARY_XREF_SIZE;
94 s->sum_num++;
95 dbg_summary("xref added to summary\n");
96 break;
97#endif
84 default: 98 default:
85 JFFS2_WARNING("UNKNOWN node type %u\n", 99 JFFS2_WARNING("UNKNOWN node type %u\n",
86 je16_to_cpu(item->u.nodetype)); 100 je16_to_cpu(item->u.nodetype));
@@ -141,6 +155,40 @@ int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *r
141 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); 155 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
142} 156}
143 157
158#ifdef CONFIG_JFFS2_FS_XATTR
159int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs)
160{
161 struct jffs2_sum_xattr_mem *temp;
162
163 temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
164 if (!temp)
165 return -ENOMEM;
166
167 temp->nodetype = rx->nodetype;
168 temp->xid = rx->xid;
169 temp->version = rx->version;
170 temp->offset = cpu_to_je32(ofs);
171 temp->totlen = rx->totlen;
172 temp->next = NULL;
173
174 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
175}
176
177int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs)
178{
179 struct jffs2_sum_xref_mem *temp;
180
181 temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
182 if (!temp)
183 return -ENOMEM;
184
185 temp->nodetype = rr->nodetype;
186 temp->offset = cpu_to_je32(ofs);
187 temp->next = NULL;
188
189 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
190}
191#endif
144/* Cleanup every collected summary information */ 192/* Cleanup every collected summary information */
145 193
146static void jffs2_sum_clean_collected(struct jffs2_summary *s) 194static void jffs2_sum_clean_collected(struct jffs2_summary *s)
@@ -259,7 +307,40 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
259 307
260 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); 308 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
261 } 309 }
310#ifdef CONFIG_JFFS2_FS_XATTR
311 case JFFS2_NODETYPE_XATTR: {
312 struct jffs2_sum_xattr_mem *temp;
313 if (je32_to_cpu(node->x.version) == 0xffffffff)
314 return 0;
315 temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
316 if (!temp)
317 goto no_mem;
318
319 temp->nodetype = node->x.nodetype;
320 temp->xid = node->x.xid;
321 temp->version = node->x.version;
322 temp->totlen = node->x.totlen;
323 temp->offset = cpu_to_je32(ofs);
324 temp->next = NULL;
325
326 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
327 }
328 case JFFS2_NODETYPE_XREF: {
329 struct jffs2_sum_xref_mem *temp;
330
331 if (je32_to_cpu(node->r.ino) == 0xffffffff
332 && je32_to_cpu(node->r.xid) == 0xffffffff)
333 return 0;
334 temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
335 if (!temp)
336 goto no_mem;
337 temp->nodetype = node->r.nodetype;
338 temp->offset = cpu_to_je32(ofs);
339 temp->next = NULL;
262 340
341 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
342 }
343#endif
263 case JFFS2_NODETYPE_PADDING: 344 case JFFS2_NODETYPE_PADDING:
264 dbg_summary("node PADDING\n"); 345 dbg_summary("node PADDING\n");
265 c->summary->sum_padded += je32_to_cpu(node->u.totlen); 346 c->summary->sum_padded += je32_to_cpu(node->u.totlen);
@@ -288,23 +369,41 @@ no_mem:
288 return -ENOMEM; 369 return -ENOMEM;
289} 370}
290 371
372static struct jffs2_raw_node_ref *sum_link_node_ref(struct jffs2_sb_info *c,
373 struct jffs2_eraseblock *jeb,
374 uint32_t ofs, uint32_t len,
375 struct jffs2_inode_cache *ic)
376{
377 /* If there was a gap, mark it dirty */
378 if ((ofs & ~3) > c->sector_size - jeb->free_size) {
379 /* Ew. Summary doesn't actually tell us explicitly about dirty space */
380 jffs2_scan_dirty_space(c, jeb, (ofs & ~3) - (c->sector_size - jeb->free_size));
381 }
382
383 return jffs2_link_node_ref(c, jeb, jeb->offset + ofs, len, ic);
384}
291 385
292/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */ 386/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
293 387
294static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 388static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
295 struct jffs2_raw_summary *summary, uint32_t *pseudo_random) 389 struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
296{ 390{
297 struct jffs2_raw_node_ref *raw;
298 struct jffs2_inode_cache *ic; 391 struct jffs2_inode_cache *ic;
299 struct jffs2_full_dirent *fd; 392 struct jffs2_full_dirent *fd;
300 void *sp; 393 void *sp;
301 int i, ino; 394 int i, ino;
395 int err;
302 396
303 sp = summary->sum; 397 sp = summary->sum;
304 398
305 for (i=0; i<je32_to_cpu(summary->sum_num); i++) { 399 for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
306 dbg_summary("processing summary index %d\n", i); 400 dbg_summary("processing summary index %d\n", i);
307 401
402 /* Make sure there's a spare ref for dirty space */
403 err = jffs2_prealloc_raw_node_refs(c, jeb, 2);
404 if (err)
405 return err;
406
308 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { 407 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
309 case JFFS2_NODETYPE_INODE: { 408 case JFFS2_NODETYPE_INODE: {
310 struct jffs2_sum_inode_flash *spi; 409 struct jffs2_sum_inode_flash *spi;
@@ -312,38 +411,20 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
312 411
313 ino = je32_to_cpu(spi->inode); 412 ino = je32_to_cpu(spi->inode);
314 413
315 dbg_summary("Inode at 0x%08x\n", 414 dbg_summary("Inode at 0x%08x-0x%08x\n",
316 jeb->offset + je32_to_cpu(spi->offset)); 415 jeb->offset + je32_to_cpu(spi->offset),
317 416 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spi->totlen));
318 raw = jffs2_alloc_raw_node_ref();
319 if (!raw) {
320 JFFS2_NOTICE("allocation of node reference failed\n");
321 kfree(summary);
322 return -ENOMEM;
323 }
324 417
325 ic = jffs2_scan_make_ino_cache(c, ino); 418 ic = jffs2_scan_make_ino_cache(c, ino);
326 if (!ic) { 419 if (!ic) {
327 JFFS2_NOTICE("scan_make_ino_cache failed\n"); 420 JFFS2_NOTICE("scan_make_ino_cache failed\n");
328 jffs2_free_raw_node_ref(raw);
329 kfree(summary);
330 return -ENOMEM; 421 return -ENOMEM;
331 } 422 }
332 423
333 raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED; 424 sum_link_node_ref(c, jeb, je32_to_cpu(spi->offset) | REF_UNCHECKED,
334 raw->__totlen = PAD(je32_to_cpu(spi->totlen)); 425 PAD(je32_to_cpu(spi->totlen)), ic);
335 raw->next_phys = NULL;
336 raw->next_in_ino = ic->nodes;
337
338 ic->nodes = raw;
339 if (!jeb->first_node)
340 jeb->first_node = raw;
341 if (jeb->last_node)
342 jeb->last_node->next_phys = raw;
343 jeb->last_node = raw;
344 *pseudo_random += je32_to_cpu(spi->version);
345 426
346 UNCHECKED_SPACE(PAD(je32_to_cpu(spi->totlen))); 427 *pseudo_random += je32_to_cpu(spi->version);
347 428
348 sp += JFFS2_SUMMARY_INODE_SIZE; 429 sp += JFFS2_SUMMARY_INODE_SIZE;
349 430
@@ -354,52 +435,33 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
354 struct jffs2_sum_dirent_flash *spd; 435 struct jffs2_sum_dirent_flash *spd;
355 spd = sp; 436 spd = sp;
356 437
357 dbg_summary("Dirent at 0x%08x\n", 438 dbg_summary("Dirent at 0x%08x-0x%08x\n",
358 jeb->offset + je32_to_cpu(spd->offset)); 439 jeb->offset + je32_to_cpu(spd->offset),
440 jeb->offset + je32_to_cpu(spd->offset) + je32_to_cpu(spd->totlen));
441
359 442
360 fd = jffs2_alloc_full_dirent(spd->nsize+1); 443 fd = jffs2_alloc_full_dirent(spd->nsize+1);
361 if (!fd) { 444 if (!fd)
362 kfree(summary);
363 return -ENOMEM; 445 return -ENOMEM;
364 }
365 446
366 memcpy(&fd->name, spd->name, spd->nsize); 447 memcpy(&fd->name, spd->name, spd->nsize);
367 fd->name[spd->nsize] = 0; 448 fd->name[spd->nsize] = 0;
368 449
369 raw = jffs2_alloc_raw_node_ref();
370 if (!raw) {
371 jffs2_free_full_dirent(fd);
372 JFFS2_NOTICE("allocation of node reference failed\n");
373 kfree(summary);
374 return -ENOMEM;
375 }
376
377 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino)); 450 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
378 if (!ic) { 451 if (!ic) {
379 jffs2_free_full_dirent(fd); 452 jffs2_free_full_dirent(fd);
380 jffs2_free_raw_node_ref(raw);
381 kfree(summary);
382 return -ENOMEM; 453 return -ENOMEM;
383 } 454 }
384 455
385 raw->__totlen = PAD(je32_to_cpu(spd->totlen)); 456 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_UNCHECKED,
386 raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE; 457 PAD(je32_to_cpu(spd->totlen)), ic);
387 raw->next_phys = NULL; 458
388 raw->next_in_ino = ic->nodes;
389 ic->nodes = raw;
390 if (!jeb->first_node)
391 jeb->first_node = raw;
392 if (jeb->last_node)
393 jeb->last_node->next_phys = raw;
394 jeb->last_node = raw;
395
396 fd->raw = raw;
397 fd->next = NULL; 459 fd->next = NULL;
398 fd->version = je32_to_cpu(spd->version); 460 fd->version = je32_to_cpu(spd->version);
399 fd->ino = je32_to_cpu(spd->ino); 461 fd->ino = je32_to_cpu(spd->ino);
400 fd->nhash = full_name_hash(fd->name, spd->nsize); 462 fd->nhash = full_name_hash(fd->name, spd->nsize);
401 fd->type = spd->type; 463 fd->type = spd->type;
402 USED_SPACE(PAD(je32_to_cpu(spd->totlen))); 464
403 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 465 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
404 466
405 *pseudo_random += je32_to_cpu(spd->version); 467 *pseudo_random += je32_to_cpu(spd->version);
@@ -408,48 +470,105 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
408 470
409 break; 471 break;
410 } 472 }
473#ifdef CONFIG_JFFS2_FS_XATTR
474 case JFFS2_NODETYPE_XATTR: {
475 struct jffs2_xattr_datum *xd;
476 struct jffs2_sum_xattr_flash *spx;
477
478 spx = (struct jffs2_sum_xattr_flash *)sp;
479 dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n",
480 jeb->offset + je32_to_cpu(spx->offset),
481 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),
482 je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
483
484 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
485 je32_to_cpu(spx->version));
486 if (IS_ERR(xd)) {
487 if (PTR_ERR(xd) == -EEXIST) {
488 /* a newer version of xd exists */
489 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen))))
490 return err;
491 sp += JFFS2_SUMMARY_XATTR_SIZE;
492 break;
493 }
494 JFFS2_NOTICE("allocation of xattr_datum failed\n");
495 return PTR_ERR(xd);
496 }
497
498 xd->node = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
499 PAD(je32_to_cpu(spx->totlen)), NULL);
500 /* FIXME */ xd->node->next_in_ino = (void *)xd;
501
502 *pseudo_random += je32_to_cpu(spx->xid);
503 sp += JFFS2_SUMMARY_XATTR_SIZE;
504
505 break;
506 }
507 case JFFS2_NODETYPE_XREF: {
508 struct jffs2_xattr_ref *ref;
509 struct jffs2_sum_xref_flash *spr;
510
511 spr = (struct jffs2_sum_xref_flash *)sp;
512 dbg_summary("xref at %#08x-%#08x\n",
513 jeb->offset + je32_to_cpu(spr->offset),
514 jeb->offset + je32_to_cpu(spr->offset) +
515 (uint32_t)PAD(sizeof(struct jffs2_raw_xref)));
516
517 ref = jffs2_alloc_xattr_ref();
518 if (!ref) {
519 JFFS2_NOTICE("allocation of xattr_datum failed\n");
520 return -ENOMEM;
521 }
522 ref->ino = 0xfffffffe;
523 ref->xid = 0xfffffffd;
524 ref->next = c->xref_temp;
525 c->xref_temp = ref;
411 526
527 ref->node = sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,
528 PAD(sizeof(struct jffs2_raw_xref)), NULL);
529 /* FIXME */ ref->node->next_in_ino = (void *)ref;
530
531 *pseudo_random += ref->node->flash_offset;
532 sp += JFFS2_SUMMARY_XREF_SIZE;
533
534 break;
535 }
536#endif
412 default : { 537 default : {
413 JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); 538 uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);
414 kfree(summary); 539 JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);
415 return -EIO; 540 if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT)
541 return -EIO;
542
543 /* For compatible node types, just fall back to the full scan */
544 c->wasted_size -= jeb->wasted_size;
545 c->free_size += c->sector_size - jeb->free_size;
546 c->used_size -= jeb->used_size;
547 c->dirty_size -= jeb->dirty_size;
548 jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0;
549 jeb->free_size = c->sector_size;
550
551 jffs2_free_jeb_node_refs(c, jeb);
552 return -ENOTRECOVERABLE;
416 } 553 }
417 } 554 }
418 } 555 }
419
420 kfree(summary);
421 return 0; 556 return 0;
422} 557}
423 558
424/* Process the summary node - called from jffs2_scan_eraseblock() */ 559/* Process the summary node - called from jffs2_scan_eraseblock() */
425
426int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 560int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
427 uint32_t ofs, uint32_t *pseudo_random) 561 struct jffs2_raw_summary *summary, uint32_t sumsize,
562 uint32_t *pseudo_random)
428{ 563{
429 struct jffs2_unknown_node crcnode; 564 struct jffs2_unknown_node crcnode;
430 struct jffs2_raw_node_ref *cache_ref; 565 int ret, ofs;
431 struct jffs2_raw_summary *summary;
432 int ret, sumsize;
433 uint32_t crc; 566 uint32_t crc;
434 567
435 sumsize = c->sector_size - ofs; 568 ofs = c->sector_size - sumsize;
436 ofs += jeb->offset;
437 569
438 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", 570 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
439 jeb->offset, ofs, sumsize); 571 jeb->offset, jeb->offset + ofs, sumsize);
440
441 summary = kmalloc(sumsize, GFP_KERNEL);
442
443 if (!summary) {
444 return -ENOMEM;
445 }
446
447 ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
448
449 if (ret) {
450 kfree(summary);
451 return ret;
452 }
453 572
454 /* OK, now check for node validity and CRC */ 573 /* OK, now check for node validity and CRC */
455 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 574 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -486,66 +605,49 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
486 605
487 dbg_summary("Summary : CLEANMARKER node \n"); 606 dbg_summary("Summary : CLEANMARKER node \n");
488 607
608 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
609 if (ret)
610 return ret;
611
489 if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) { 612 if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
490 dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n", 613 dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
491 je32_to_cpu(summary->cln_mkr), c->cleanmarker_size); 614 je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
492 UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr))); 615 if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
616 return ret;
493 } else if (jeb->first_node) { 617 } else if (jeb->first_node) {
494 dbg_summary("CLEANMARKER node not first node in block " 618 dbg_summary("CLEANMARKER node not first node in block "
495 "(0x%08x)\n", jeb->offset); 619 "(0x%08x)\n", jeb->offset);
496 UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr))); 620 if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
621 return ret;
497 } else { 622 } else {
498 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 623 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL,
499 624 je32_to_cpu(summary->cln_mkr), NULL);
500 if (!marker_ref) {
501 JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
502 kfree(summary);
503 return -ENOMEM;
504 }
505
506 marker_ref->next_in_ino = NULL;
507 marker_ref->next_phys = NULL;
508 marker_ref->flash_offset = jeb->offset | REF_NORMAL;
509 marker_ref->__totlen = je32_to_cpu(summary->cln_mkr);
510 jeb->first_node = jeb->last_node = marker_ref;
511
512 USED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
513 } 625 }
514 } 626 }
515 627
516 if (je32_to_cpu(summary->padded)) {
517 DIRTY_SPACE(je32_to_cpu(summary->padded));
518 }
519
520 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); 628 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
629 /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full
630 scan of this eraseblock. So return zero */
631 if (ret == -ENOTRECOVERABLE)
632 return 0;
521 if (ret) 633 if (ret)
522 return ret; 634 return ret; /* real error */
523 635
524 /* for PARANOIA_CHECK */ 636 /* for PARANOIA_CHECK */
525 cache_ref = jffs2_alloc_raw_node_ref(); 637 ret = jffs2_prealloc_raw_node_refs(c, jeb, 2);
526 638 if (ret)
527 if (!cache_ref) { 639 return ret;
528 JFFS2_NOTICE("Failed to allocate node ref for cache\n");
529 return -ENOMEM;
530 }
531
532 cache_ref->next_in_ino = NULL;
533 cache_ref->next_phys = NULL;
534 cache_ref->flash_offset = ofs | REF_NORMAL;
535 cache_ref->__totlen = sumsize;
536
537 if (!jeb->first_node)
538 jeb->first_node = cache_ref;
539 if (jeb->last_node)
540 jeb->last_node->next_phys = cache_ref;
541 jeb->last_node = cache_ref;
542 640
543 USED_SPACE(sumsize); 641 sum_link_node_ref(c, jeb, ofs | REF_NORMAL, sumsize, NULL);
544 642
545 jeb->wasted_size += jeb->free_size; 643 if (unlikely(jeb->free_size)) {
546 c->wasted_size += jeb->free_size; 644 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
547 c->free_size -= jeb->free_size; 645 jeb->free_size, jeb->offset);
548 jeb->free_size = 0; 646 jeb->wasted_size += jeb->free_size;
647 c->wasted_size += jeb->free_size;
648 c->free_size -= jeb->free_size;
649 jeb->free_size = 0;
650 }
549 651
550 return jffs2_scan_classify_jeb(c, jeb); 652 return jffs2_scan_classify_jeb(c, jeb);
551 653
@@ -564,6 +666,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
564 union jffs2_sum_mem *temp; 666 union jffs2_sum_mem *temp;
565 struct jffs2_sum_marker *sm; 667 struct jffs2_sum_marker *sm;
566 struct kvec vecs[2]; 668 struct kvec vecs[2];
669 uint32_t sum_ofs;
567 void *wpage; 670 void *wpage;
568 int ret; 671 int ret;
569 size_t retlen; 672 size_t retlen;
@@ -581,16 +684,17 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
581 wpage = c->summary->sum_buf; 684 wpage = c->summary->sum_buf;
582 685
583 while (c->summary->sum_num) { 686 while (c->summary->sum_num) {
687 temp = c->summary->sum_list_head;
584 688
585 switch (je16_to_cpu(c->summary->sum_list_head->u.nodetype)) { 689 switch (je16_to_cpu(temp->u.nodetype)) {
586 case JFFS2_NODETYPE_INODE: { 690 case JFFS2_NODETYPE_INODE: {
587 struct jffs2_sum_inode_flash *sino_ptr = wpage; 691 struct jffs2_sum_inode_flash *sino_ptr = wpage;
588 692
589 sino_ptr->nodetype = c->summary->sum_list_head->i.nodetype; 693 sino_ptr->nodetype = temp->i.nodetype;
590 sino_ptr->inode = c->summary->sum_list_head->i.inode; 694 sino_ptr->inode = temp->i.inode;
591 sino_ptr->version = c->summary->sum_list_head->i.version; 695 sino_ptr->version = temp->i.version;
592 sino_ptr->offset = c->summary->sum_list_head->i.offset; 696 sino_ptr->offset = temp->i.offset;
593 sino_ptr->totlen = c->summary->sum_list_head->i.totlen; 697 sino_ptr->totlen = temp->i.totlen;
594 698
595 wpage += JFFS2_SUMMARY_INODE_SIZE; 699 wpage += JFFS2_SUMMARY_INODE_SIZE;
596 700
@@ -600,30 +704,60 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
600 case JFFS2_NODETYPE_DIRENT: { 704 case JFFS2_NODETYPE_DIRENT: {
601 struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage; 705 struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage;
602 706
603 sdrnt_ptr->nodetype = c->summary->sum_list_head->d.nodetype; 707 sdrnt_ptr->nodetype = temp->d.nodetype;
604 sdrnt_ptr->totlen = c->summary->sum_list_head->d.totlen; 708 sdrnt_ptr->totlen = temp->d.totlen;
605 sdrnt_ptr->offset = c->summary->sum_list_head->d.offset; 709 sdrnt_ptr->offset = temp->d.offset;
606 sdrnt_ptr->pino = c->summary->sum_list_head->d.pino; 710 sdrnt_ptr->pino = temp->d.pino;
607 sdrnt_ptr->version = c->summary->sum_list_head->d.version; 711 sdrnt_ptr->version = temp->d.version;
608 sdrnt_ptr->ino = c->summary->sum_list_head->d.ino; 712 sdrnt_ptr->ino = temp->d.ino;
609 sdrnt_ptr->nsize = c->summary->sum_list_head->d.nsize; 713 sdrnt_ptr->nsize = temp->d.nsize;
610 sdrnt_ptr->type = c->summary->sum_list_head->d.type; 714 sdrnt_ptr->type = temp->d.type;
611 715
612 memcpy(sdrnt_ptr->name, c->summary->sum_list_head->d.name, 716 memcpy(sdrnt_ptr->name, temp->d.name,
613 c->summary->sum_list_head->d.nsize); 717 temp->d.nsize);
614 718
615 wpage += JFFS2_SUMMARY_DIRENT_SIZE(c->summary->sum_list_head->d.nsize); 719 wpage += JFFS2_SUMMARY_DIRENT_SIZE(temp->d.nsize);
616 720
617 break; 721 break;
618 } 722 }
723#ifdef CONFIG_JFFS2_FS_XATTR
724 case JFFS2_NODETYPE_XATTR: {
725 struct jffs2_sum_xattr_flash *sxattr_ptr = wpage;
726
727 temp = c->summary->sum_list_head;
728 sxattr_ptr->nodetype = temp->x.nodetype;
729 sxattr_ptr->xid = temp->x.xid;
730 sxattr_ptr->version = temp->x.version;
731 sxattr_ptr->offset = temp->x.offset;
732 sxattr_ptr->totlen = temp->x.totlen;
733
734 wpage += JFFS2_SUMMARY_XATTR_SIZE;
735 break;
736 }
737 case JFFS2_NODETYPE_XREF: {
738 struct jffs2_sum_xref_flash *sxref_ptr = wpage;
619 739
740 temp = c->summary->sum_list_head;
741 sxref_ptr->nodetype = temp->r.nodetype;
742 sxref_ptr->offset = temp->r.offset;
743
744 wpage += JFFS2_SUMMARY_XREF_SIZE;
745 break;
746 }
747#endif
620 default : { 748 default : {
621 BUG(); /* unknown node in summary information */ 749 if ((je16_to_cpu(temp->u.nodetype) & JFFS2_COMPAT_MASK)
750 == JFFS2_FEATURE_RWCOMPAT_COPY) {
751 dbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n",
752 je16_to_cpu(temp->u.nodetype));
753 jffs2_sum_disable_collecting(c->summary);
754 } else {
755 BUG(); /* unknown node in summary information */
756 }
622 } 757 }
623 } 758 }
624 759
625 temp = c->summary->sum_list_head; 760 c->summary->sum_list_head = temp->u.next;
626 c->summary->sum_list_head = c->summary->sum_list_head->u.next;
627 kfree(temp); 761 kfree(temp);
628 762
629 c->summary->sum_num--; 763 c->summary->sum_num--;
@@ -645,25 +779,34 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
645 vecs[1].iov_base = c->summary->sum_buf; 779 vecs[1].iov_base = c->summary->sum_buf;
646 vecs[1].iov_len = datasize; 780 vecs[1].iov_len = datasize;
647 781
648 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n", 782 sum_ofs = jeb->offset + c->sector_size - jeb->free_size;
649 jeb->offset + c->sector_size - jeb->free_size);
650 783
651 spin_unlock(&c->erase_completion_lock); 784 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
652 ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size - 785 sum_ofs);
653 jeb->free_size, &retlen, 0);
654 spin_lock(&c->erase_completion_lock);
655 786
787 ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0);
656 788
657 if (ret || (retlen != infosize)) { 789 if (ret || (retlen != infosize)) {
658 JFFS2_WARNING("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 790
659 infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen); 791 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
792 infosize, sum_ofs, ret, retlen);
793
794 if (retlen) {
795 /* Waste remaining space */
796 spin_lock(&c->erase_completion_lock);
797 jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL);
798 spin_unlock(&c->erase_completion_lock);
799 }
660 800
661 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; 801 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
662 WASTED_SPACE(infosize);
663 802
664 return 1; 803 return 0;
665 } 804 }
666 805
806 spin_lock(&c->erase_completion_lock);
807 jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL);
808 spin_unlock(&c->erase_completion_lock);
809
667 return 0; 810 return 0;
668} 811}
669 812
@@ -671,13 +814,16 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
671 814
672int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) 815int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
673{ 816{
674 struct jffs2_raw_node_ref *summary_ref; 817 int datasize, infosize, padsize;
675 int datasize, infosize, padsize, ret;
676 struct jffs2_eraseblock *jeb; 818 struct jffs2_eraseblock *jeb;
819 int ret;
677 820
678 dbg_summary("called\n"); 821 dbg_summary("called\n");
679 822
823 spin_unlock(&c->erase_completion_lock);
824
680 jeb = c->nextblock; 825 jeb = c->nextblock;
826 jffs2_prealloc_raw_node_refs(c, jeb, 1);
681 827
682 if (!c->summary->sum_num || !c->summary->sum_list_head) { 828 if (!c->summary->sum_num || !c->summary->sum_list_head) {
683 JFFS2_WARNING("Empty summary info!!!\n"); 829 JFFS2_WARNING("Empty summary info!!!\n");
@@ -696,35 +842,11 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
696 jffs2_sum_disable_collecting(c->summary); 842 jffs2_sum_disable_collecting(c->summary);
697 843
698 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize); 844 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
845 spin_lock(&c->erase_completion_lock);
699 return 0; 846 return 0;
700 } 847 }
701 848
702 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); 849 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
703 if (ret)
704 return 0; /* can't write out summary, block is marked as NOSUM_SIZE */
705
706 /* for ACCT_PARANOIA_CHECK */
707 spin_unlock(&c->erase_completion_lock);
708 summary_ref = jffs2_alloc_raw_node_ref();
709 spin_lock(&c->erase_completion_lock); 850 spin_lock(&c->erase_completion_lock);
710 851 return ret;
711 if (!summary_ref) {
712 JFFS2_NOTICE("Failed to allocate node ref for summary\n");
713 return -ENOMEM;
714 }
715
716 summary_ref->next_in_ino = NULL;
717 summary_ref->next_phys = NULL;
718 summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
719 summary_ref->__totlen = infosize;
720
721 if (!jeb->first_node)
722 jeb->first_node = summary_ref;
723 if (jeb->last_node)
724 jeb->last_node->next_phys = summary_ref;
725 jeb->last_node = summary_ref;
726
727 USED_SPACE(infosize);
728
729 return 0;
730} 852}
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
index b7a678be1709..6bf1f6aa4552 100644
--- a/fs/jffs2/summary.h
+++ b/fs/jffs2/summary.h
@@ -18,23 +18,6 @@
18#include <linux/uio.h> 18#include <linux/uio.h>
19#include <linux/jffs2.h> 19#include <linux/jffs2.h>
20 20
21#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
22 c->free_size -= _x; c->dirty_size += _x; \
23 jeb->free_size -= _x ; jeb->dirty_size += _x; \
24 }while(0)
25#define USED_SPACE(x) do { typeof(x) _x = (x); \
26 c->free_size -= _x; c->used_size += _x; \
27 jeb->free_size -= _x ; jeb->used_size += _x; \
28 }while(0)
29#define WASTED_SPACE(x) do { typeof(x) _x = (x); \
30 c->free_size -= _x; c->wasted_size += _x; \
31 jeb->free_size -= _x ; jeb->wasted_size += _x; \
32 }while(0)
33#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
34 c->free_size -= _x; c->unchecked_size += _x; \
35 jeb->free_size -= _x ; jeb->unchecked_size += _x; \
36 }while(0)
37
38#define BLK_STATE_ALLFF 0 21#define BLK_STATE_ALLFF 0
39#define BLK_STATE_CLEAN 1 22#define BLK_STATE_CLEAN 1
40#define BLK_STATE_PARTDIRTY 2 23#define BLK_STATE_PARTDIRTY 2
@@ -45,6 +28,8 @@
45#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff 28#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff
46#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash)) 29#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash))
47#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x)) 30#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x))
31#define JFFS2_SUMMARY_XATTR_SIZE (sizeof(struct jffs2_sum_xattr_flash))
32#define JFFS2_SUMMARY_XREF_SIZE (sizeof(struct jffs2_sum_xref_flash))
48 33
49/* Summary structures used on flash */ 34/* Summary structures used on flash */
50 35
@@ -75,11 +60,28 @@ struct jffs2_sum_dirent_flash
75 uint8_t name[0]; /* dirent name */ 60 uint8_t name[0]; /* dirent name */
76} __attribute__((packed)); 61} __attribute__((packed));
77 62
63struct jffs2_sum_xattr_flash
64{
65 jint16_t nodetype; /* == JFFS2_NODETYPE_XATR */
66 jint32_t xid; /* xattr identifier */
67 jint32_t version; /* version number */
68 jint32_t offset; /* offset on jeb */
69 jint32_t totlen; /* node length */
70} __attribute__((packed));
71
72struct jffs2_sum_xref_flash
73{
74 jint16_t nodetype; /* == JFFS2_NODETYPE_XREF */
75 jint32_t offset; /* offset on jeb */
76} __attribute__((packed));
77
78union jffs2_sum_flash 78union jffs2_sum_flash
79{ 79{
80 struct jffs2_sum_unknown_flash u; 80 struct jffs2_sum_unknown_flash u;
81 struct jffs2_sum_inode_flash i; 81 struct jffs2_sum_inode_flash i;
82 struct jffs2_sum_dirent_flash d; 82 struct jffs2_sum_dirent_flash d;
83 struct jffs2_sum_xattr_flash x;
84 struct jffs2_sum_xref_flash r;
83}; 85};
84 86
85/* Summary structures used in the memory */ 87/* Summary structures used in the memory */
@@ -114,11 +116,30 @@ struct jffs2_sum_dirent_mem
114 uint8_t name[0]; /* dirent name */ 116 uint8_t name[0]; /* dirent name */
115} __attribute__((packed)); 117} __attribute__((packed));
116 118
119struct jffs2_sum_xattr_mem
120{
121 union jffs2_sum_mem *next;
122 jint16_t nodetype;
123 jint32_t xid;
124 jint32_t version;
125 jint32_t offset;
126 jint32_t totlen;
127} __attribute__((packed));
128
129struct jffs2_sum_xref_mem
130{
131 union jffs2_sum_mem *next;
132 jint16_t nodetype;
133 jint32_t offset;
134} __attribute__((packed));
135
117union jffs2_sum_mem 136union jffs2_sum_mem
118{ 137{
119 struct jffs2_sum_unknown_mem u; 138 struct jffs2_sum_unknown_mem u;
120 struct jffs2_sum_inode_mem i; 139 struct jffs2_sum_inode_mem i;
121 struct jffs2_sum_dirent_mem d; 140 struct jffs2_sum_dirent_mem d;
141 struct jffs2_sum_xattr_mem x;
142 struct jffs2_sum_xref_mem r;
122}; 143};
123 144
124/* Summary related information stored in superblock */ 145/* Summary related information stored in superblock */
@@ -159,8 +180,11 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c);
159int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size); 180int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size);
160int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs); 181int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs);
161int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs); 182int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs);
183int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs);
184int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs);
162int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 185int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
163 uint32_t ofs, uint32_t *pseudo_random); 186 struct jffs2_raw_summary *summary, uint32_t sumlen,
187 uint32_t *pseudo_random);
164 188
165#else /* SUMMARY DISABLED */ 189#else /* SUMMARY DISABLED */
166 190
@@ -176,7 +200,9 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
176#define jffs2_sum_add_padding_mem(a,b) 200#define jffs2_sum_add_padding_mem(a,b)
177#define jffs2_sum_add_inode_mem(a,b,c) 201#define jffs2_sum_add_inode_mem(a,b,c)
178#define jffs2_sum_add_dirent_mem(a,b,c) 202#define jffs2_sum_add_dirent_mem(a,b,c)
179#define jffs2_sum_scan_sumnode(a,b,c,d) (0) 203#define jffs2_sum_add_xattr_mem(a,b,c)
204#define jffs2_sum_add_xref_mem(a,b,c)
205#define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
180 206
181#endif /* CONFIG_JFFS2_SUMMARY */ 207#endif /* CONFIG_JFFS2_SUMMARY */
182 208
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index ffd8e84b22cc..9d0521451f59 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -151,7 +151,10 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
151 151
152 sb->s_op = &jffs2_super_operations; 152 sb->s_op = &jffs2_super_operations;
153 sb->s_flags = flags | MS_NOATIME; 153 sb->s_flags = flags | MS_NOATIME;
154 154 sb->s_xattr = jffs2_xattr_handlers;
155#ifdef CONFIG_JFFS2_FS_POSIX_ACL
156 sb->s_flags |= MS_POSIXACL;
157#endif
155 ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); 158 ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
156 159
157 if (ret) { 160 if (ret) {
@@ -293,6 +296,7 @@ static void jffs2_put_super (struct super_block *sb)
293 kfree(c->blocks); 296 kfree(c->blocks);
294 jffs2_flash_cleanup(c); 297 jffs2_flash_cleanup(c);
295 kfree(c->inocache_list); 298 kfree(c->inocache_list);
299 jffs2_clear_xattr_subsystem(c);
296 if (c->mtd->sync) 300 if (c->mtd->sync)
297 c->mtd->sync(c->mtd); 301 c->mtd->sync(c->mtd);
298 302
@@ -320,6 +324,18 @@ static int __init init_jffs2_fs(void)
320{ 324{
321 int ret; 325 int ret;
322 326
327 /* Paranoia checks for on-medium structures. If we ask GCC
328 to pack them with __attribute__((packed)) then it _also_
329 assumes that they're not aligned -- so it emits crappy
330 code on some architectures. Ideally we want an attribute
331 which means just 'no padding', without the alignment
332 thing. But GCC doesn't have that -- we have to just
333 hope the structs are the right sizes, instead. */
334 BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
335 BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
336 BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
337 BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
338
323 printk(KERN_INFO "JFFS2 version 2.2." 339 printk(KERN_INFO "JFFS2 version 2.2."
324#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 340#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
325 " (NAND)" 341 " (NAND)"
@@ -327,7 +343,7 @@ static int __init init_jffs2_fs(void)
327#ifdef CONFIG_JFFS2_SUMMARY 343#ifdef CONFIG_JFFS2_SUMMARY
328 " (SUMMARY) " 344 " (SUMMARY) "
329#endif 345#endif
330 " (C) 2001-2003 Red Hat, Inc.\n"); 346 " (C) 2001-2006 Red Hat, Inc.\n");
331 347
332 jffs2_inode_cachep = kmem_cache_create("jffs2_i", 348 jffs2_inode_cachep = kmem_cache_create("jffs2_i",
333 sizeof(struct jffs2_inode_info), 349 sizeof(struct jffs2_inode_info),
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index d55754fe8925..fc211b6e9b03 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -24,7 +24,12 @@ struct inode_operations jffs2_symlink_inode_operations =
24{ 24{
25 .readlink = generic_readlink, 25 .readlink = generic_readlink,
26 .follow_link = jffs2_follow_link, 26 .follow_link = jffs2_follow_link,
27 .setattr = jffs2_setattr 27 .permission = jffs2_permission,
28 .setattr = jffs2_setattr,
29 .setxattr = jffs2_setxattr,
30 .getxattr = jffs2_getxattr,
31 .listxattr = jffs2_listxattr,
32 .removexattr = jffs2_removexattr
28}; 33};
29 34
30static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 35static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 4cebf0e57c46..a7f153f79ecb 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -156,69 +156,130 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
156 jffs2_erase_pending_trigger(c); 156 jffs2_erase_pending_trigger(c);
157 } 157 }
158 158
159 /* Adjust its size counts accordingly */ 159 if (!jffs2_prealloc_raw_node_refs(c, jeb, 1)) {
160 c->wasted_size += jeb->free_size; 160 uint32_t oldfree = jeb->free_size;
161 c->free_size -= jeb->free_size; 161
162 jeb->wasted_size += jeb->free_size; 162 jffs2_link_node_ref(c, jeb,
163 jeb->free_size = 0; 163 (jeb->offset+c->sector_size-oldfree) | REF_OBSOLETE,
164 oldfree, NULL);
165 /* convert to wasted */
166 c->wasted_size += oldfree;
167 jeb->wasted_size += oldfree;
168 c->dirty_size -= oldfree;
169 jeb->dirty_size -= oldfree;
170 }
164 171
165 jffs2_dbg_dump_block_lists_nolock(c); 172 jffs2_dbg_dump_block_lists_nolock(c);
166 jffs2_dbg_acct_sanity_check_nolock(c,jeb); 173 jffs2_dbg_acct_sanity_check_nolock(c,jeb);
167 jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 174 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
168} 175}
169 176
177static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info *c,
178 struct jffs2_inode_info *f,
179 struct jffs2_raw_node_ref *raw,
180 union jffs2_node_union *node)
181{
182 struct jffs2_node_frag *frag;
183 struct jffs2_full_dirent *fd;
184
185 dbg_noderef("incore_replace_raw: node at %p is {%04x,%04x}\n",
186 node, je16_to_cpu(node->u.magic), je16_to_cpu(node->u.nodetype));
187
188 BUG_ON(je16_to_cpu(node->u.magic) != 0x1985 &&
189 je16_to_cpu(node->u.magic) != 0);
190
191 switch (je16_to_cpu(node->u.nodetype)) {
192 case JFFS2_NODETYPE_INODE:
193 if (f->metadata && f->metadata->raw == raw) {
194 dbg_noderef("Will replace ->raw in f->metadata at %p\n", f->metadata);
195 return &f->metadata->raw;
196 }
197 frag = jffs2_lookup_node_frag(&f->fragtree, je32_to_cpu(node->i.offset));
198 BUG_ON(!frag);
199 /* Find a frag which refers to the full_dnode we want to modify */
200 while (!frag->node || frag->node->raw != raw) {
201 frag = frag_next(frag);
202 BUG_ON(!frag);
203 }
204 dbg_noderef("Will replace ->raw in full_dnode at %p\n", frag->node);
205 return &frag->node->raw;
206
207 case JFFS2_NODETYPE_DIRENT:
208 for (fd = f->dents; fd; fd = fd->next) {
209 if (fd->raw == raw) {
210 dbg_noderef("Will replace ->raw in full_dirent at %p\n", fd);
211 return &fd->raw;
212 }
213 }
214 BUG();
215
216 default:
217 dbg_noderef("Don't care about replacing raw for nodetype %x\n",
218 je16_to_cpu(node->u.nodetype));
219 break;
220 }
221 return NULL;
222}
223
170/* Recover from failure to write wbuf. Recover the nodes up to the 224/* Recover from failure to write wbuf. Recover the nodes up to the
171 * wbuf, not the one which we were starting to try to write. */ 225 * wbuf, not the one which we were starting to try to write. */
172 226
173static void jffs2_wbuf_recover(struct jffs2_sb_info *c) 227static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
174{ 228{
175 struct jffs2_eraseblock *jeb, *new_jeb; 229 struct jffs2_eraseblock *jeb, *new_jeb;
176 struct jffs2_raw_node_ref **first_raw, **raw; 230 struct jffs2_raw_node_ref *raw, *next, *first_raw = NULL;
177 size_t retlen; 231 size_t retlen;
178 int ret; 232 int ret;
233 int nr_refile = 0;
179 unsigned char *buf; 234 unsigned char *buf;
180 uint32_t start, end, ofs, len; 235 uint32_t start, end, ofs, len;
181 236
182 spin_lock(&c->erase_completion_lock);
183
184 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 237 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
185 238
239 spin_lock(&c->erase_completion_lock);
186 jffs2_block_refile(c, jeb, REFILE_NOTEMPTY); 240 jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
241 spin_unlock(&c->erase_completion_lock);
242
243 BUG_ON(!ref_obsolete(jeb->last_node));
187 244
188 /* Find the first node to be recovered, by skipping over every 245 /* Find the first node to be recovered, by skipping over every
189 node which ends before the wbuf starts, or which is obsolete. */ 246 node which ends before the wbuf starts, or which is obsolete. */
190 first_raw = &jeb->first_node; 247 for (next = raw = jeb->first_node; next; raw = next) {
191 while (*first_raw && 248 next = ref_next(raw);
192 (ref_obsolete(*first_raw) || 249
193 (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) { 250 if (ref_obsolete(raw) ||
194 D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n", 251 (next && ref_offset(next) <= c->wbuf_ofs)) {
195 ref_offset(*first_raw), ref_flags(*first_raw), 252 dbg_noderef("Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
196 (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)), 253 ref_offset(raw), ref_flags(raw),
197 c->wbuf_ofs)); 254 (ref_offset(raw) + ref_totlen(c, jeb, raw)),
198 first_raw = &(*first_raw)->next_phys; 255 c->wbuf_ofs);
256 continue;
257 }
258 dbg_noderef("First node to be recovered is at 0x%08x(%d)-0x%08x\n",
259 ref_offset(raw), ref_flags(raw),
260 (ref_offset(raw) + ref_totlen(c, jeb, raw)));
261
262 first_raw = raw;
263 break;
199 } 264 }
200 265
201 if (!*first_raw) { 266 if (!first_raw) {
202 /* All nodes were obsolete. Nothing to recover. */ 267 /* All nodes were obsolete. Nothing to recover. */
203 D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n")); 268 D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n"));
204 spin_unlock(&c->erase_completion_lock); 269 c->wbuf_len = 0;
205 return; 270 return;
206 } 271 }
207 272
208 start = ref_offset(*first_raw); 273 start = ref_offset(first_raw);
209 end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw); 274 end = ref_offset(jeb->last_node);
210 275 nr_refile = 1;
211 /* Find the last node to be recovered */
212 raw = first_raw;
213 while ((*raw)) {
214 if (!ref_obsolete(*raw))
215 end = ref_offset(*raw) + ref_totlen(c, jeb, *raw);
216 276
217 raw = &(*raw)->next_phys; 277 /* Count the number of refs which need to be copied */
218 } 278 while ((raw = ref_next(raw)) != jeb->last_node)
219 spin_unlock(&c->erase_completion_lock); 279 nr_refile++;
220 280
221 D1(printk(KERN_DEBUG "wbuf recover %08x-%08x\n", start, end)); 281 dbg_noderef("wbuf recover %08x-%08x (%d bytes in %d nodes)\n",
282 start, end, end - start, nr_refile);
222 283
223 buf = NULL; 284 buf = NULL;
224 if (start < c->wbuf_ofs) { 285 if (start < c->wbuf_ofs) {
@@ -233,28 +294,37 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
233 } 294 }
234 295
235 /* Do the read... */ 296 /* Do the read... */
236 if (jffs2_cleanmarker_oob(c)) 297 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
237 ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
238 else
239 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
240 298
241 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) { 299 /* ECC recovered ? */
242 /* ECC recovered */ 300 if ((ret == -EUCLEAN || ret == -EBADMSG) &&
301 (retlen == c->wbuf_ofs - start))
243 ret = 0; 302 ret = 0;
244 } 303
245 if (ret || retlen != c->wbuf_ofs - start) { 304 if (ret || retlen != c->wbuf_ofs - start) {
246 printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n"); 305 printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n");
247 306
248 kfree(buf); 307 kfree(buf);
249 buf = NULL; 308 buf = NULL;
250 read_failed: 309 read_failed:
251 first_raw = &(*first_raw)->next_phys; 310 first_raw = ref_next(first_raw);
311 nr_refile--;
312 while (first_raw && ref_obsolete(first_raw)) {
313 first_raw = ref_next(first_raw);
314 nr_refile--;
315 }
316
252 /* If this was the only node to be recovered, give up */ 317 /* If this was the only node to be recovered, give up */
253 if (!(*first_raw)) 318 if (!first_raw) {
319 c->wbuf_len = 0;
254 return; 320 return;
321 }
255 322
256 /* It wasn't. Go on and try to recover nodes complete in the wbuf */ 323 /* It wasn't. Go on and try to recover nodes complete in the wbuf */
257 start = ref_offset(*first_raw); 324 start = ref_offset(first_raw);
325 dbg_noderef("wbuf now recover %08x-%08x (%d bytes in %d nodes)\n",
326 start, end, end - start, nr_refile);
327
258 } else { 328 } else {
259 /* Read succeeded. Copy the remaining data from the wbuf */ 329 /* Read succeeded. Copy the remaining data from the wbuf */
260 memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs); 330 memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs);
@@ -263,14 +333,23 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
263 /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards. 333 /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards.
264 Either 'buf' contains the data, or we find it in the wbuf */ 334 Either 'buf' contains the data, or we find it in the wbuf */
265 335
266
267 /* ... and get an allocation of space from a shiny new block instead */ 336 /* ... and get an allocation of space from a shiny new block instead */
268 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len, JFFS2_SUMMARY_NOSUM_SIZE); 337 ret = jffs2_reserve_space_gc(c, end-start, &len, JFFS2_SUMMARY_NOSUM_SIZE);
269 if (ret) { 338 if (ret) {
270 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); 339 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
271 kfree(buf); 340 kfree(buf);
272 return; 341 return;
273 } 342 }
343
344 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile);
345 if (ret) {
346 printk(KERN_WARNING "Failed to allocate node refs for wbuf recovery. Data loss ensues.\n");
347 kfree(buf);
348 return;
349 }
350
351 ofs = write_ofs(c);
352
274 if (end-start >= c->wbuf_pagesize) { 353 if (end-start >= c->wbuf_pagesize) {
275 /* Need to do another write immediately, but it's possible 354 /* Need to do another write immediately, but it's possible
276 that this is just because the wbuf itself is completely 355 that this is just because the wbuf itself is completely
@@ -288,36 +367,22 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
288 if (breakme++ == 20) { 367 if (breakme++ == 20) {
289 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs); 368 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);
290 breakme = 0; 369 breakme = 0;
291 c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 370 c->mtd->write(c->mtd, ofs, towrite, &retlen,
292 brokenbuf, NULL, c->oobinfo); 371 brokenbuf);
293 ret = -EIO; 372 ret = -EIO;
294 } else 373 } else
295#endif 374#endif
296 if (jffs2_cleanmarker_oob(c)) 375 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen,
297 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 376 rewrite_buf);
298 rewrite_buf, NULL, c->oobinfo);
299 else
300 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);
301 377
302 if (ret || retlen != towrite) { 378 if (ret || retlen != towrite) {
303 /* Argh. We tried. Really we did. */ 379 /* Argh. We tried. Really we did. */
304 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); 380 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
305 kfree(buf); 381 kfree(buf);
306 382
307 if (retlen) { 383 if (retlen)
308 struct jffs2_raw_node_ref *raw2; 384 jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, ref_totlen(c, jeb, first_raw), NULL);
309
310 raw2 = jffs2_alloc_raw_node_ref();
311 if (!raw2)
312 return;
313 385
314 raw2->flash_offset = ofs | REF_OBSOLETE;
315 raw2->__totlen = ref_totlen(c, jeb, *first_raw);
316 raw2->next_phys = NULL;
317 raw2->next_in_ino = NULL;
318
319 jffs2_add_physical_node_ref(c, raw2);
320 }
321 return; 386 return;
322 } 387 }
323 printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs); 388 printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs);
@@ -326,12 +391,10 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
326 c->wbuf_ofs = ofs + towrite; 391 c->wbuf_ofs = ofs + towrite;
327 memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len); 392 memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
328 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */ 393 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
329 kfree(buf);
330 } else { 394 } else {
331 /* OK, now we're left with the dregs in whichever buffer we're using */ 395 /* OK, now we're left with the dregs in whichever buffer we're using */
332 if (buf) { 396 if (buf) {
333 memcpy(c->wbuf, buf, end-start); 397 memcpy(c->wbuf, buf, end-start);
334 kfree(buf);
335 } else { 398 } else {
336 memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start); 399 memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start);
337 } 400 }
@@ -343,62 +406,111 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
343 new_jeb = &c->blocks[ofs / c->sector_size]; 406 new_jeb = &c->blocks[ofs / c->sector_size];
344 407
345 spin_lock(&c->erase_completion_lock); 408 spin_lock(&c->erase_completion_lock);
346 if (new_jeb->first_node) { 409 for (raw = first_raw; raw != jeb->last_node; raw = ref_next(raw)) {
347 /* Odd, but possible with ST flash later maybe */ 410 uint32_t rawlen = ref_totlen(c, jeb, raw);
348 new_jeb->last_node->next_phys = *first_raw; 411 struct jffs2_inode_cache *ic;
349 } else { 412 struct jffs2_raw_node_ref *new_ref;
350 new_jeb->first_node = *first_raw; 413 struct jffs2_raw_node_ref **adjust_ref = NULL;
351 } 414 struct jffs2_inode_info *f = NULL;
352
353 raw = first_raw;
354 while (*raw) {
355 uint32_t rawlen = ref_totlen(c, jeb, *raw);
356 415
357 D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n", 416 D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n",
358 rawlen, ref_offset(*raw), ref_flags(*raw), ofs)); 417 rawlen, ref_offset(raw), ref_flags(raw), ofs));
418
419 ic = jffs2_raw_ref_to_ic(raw);
420
421 /* Ick. This XATTR mess should be fixed shortly... */
422 if (ic && ic->class == RAWNODE_CLASS_XATTR_DATUM) {
423 struct jffs2_xattr_datum *xd = (void *)ic;
424 BUG_ON(xd->node != raw);
425 adjust_ref = &xd->node;
426 raw->next_in_ino = NULL;
427 ic = NULL;
428 } else if (ic && ic->class == RAWNODE_CLASS_XATTR_REF) {
429 struct jffs2_xattr_datum *xr = (void *)ic;
430 BUG_ON(xr->node != raw);
431 adjust_ref = &xr->node;
432 raw->next_in_ino = NULL;
433 ic = NULL;
434 } else if (ic && ic->class == RAWNODE_CLASS_INODE_CACHE) {
435 struct jffs2_raw_node_ref **p = &ic->nodes;
436
437 /* Remove the old node from the per-inode list */
438 while (*p && *p != (void *)ic) {
439 if (*p == raw) {
440 (*p) = (raw->next_in_ino);
441 raw->next_in_ino = NULL;
442 break;
443 }
444 p = &((*p)->next_in_ino);
445 }
359 446
360 if (ref_obsolete(*raw)) { 447 if (ic->state == INO_STATE_PRESENT && !ref_obsolete(raw)) {
361 /* Shouldn't really happen much */ 448 /* If it's an in-core inode, then we have to adjust any
362 new_jeb->dirty_size += rawlen; 449 full_dirent or full_dnode structure to point to the
363 new_jeb->free_size -= rawlen; 450 new version instead of the old */
364 c->dirty_size += rawlen; 451 f = jffs2_gc_fetch_inode(c, ic->ino, ic->nlink);
365 } else { 452 if (IS_ERR(f)) {
366 new_jeb->used_size += rawlen; 453 /* Should never happen; it _must_ be present */
367 new_jeb->free_size -= rawlen; 454 JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n",
455 ic->ino, PTR_ERR(f));
456 BUG();
457 }
458 /* We don't lock f->sem. There's a number of ways we could
459 end up in here with it already being locked, and nobody's
460 going to modify it on us anyway because we hold the
461 alloc_sem. We're only changing one ->raw pointer too,
462 which we can get away with without upsetting readers. */
463 adjust_ref = jffs2_incore_replace_raw(c, f, raw,
464 (void *)(buf?:c->wbuf) + (ref_offset(raw) - start));
465 } else if (unlikely(ic->state != INO_STATE_PRESENT &&
466 ic->state != INO_STATE_CHECKEDABSENT &&
467 ic->state != INO_STATE_GC)) {
468 JFFS2_ERROR("Inode #%u is in strange state %d!\n", ic->ino, ic->state);
469 BUG();
470 }
471 }
472
473 new_ref = jffs2_link_node_ref(c, new_jeb, ofs | ref_flags(raw), rawlen, ic);
474
475 if (adjust_ref) {
476 BUG_ON(*adjust_ref != raw);
477 *adjust_ref = new_ref;
478 }
479 if (f)
480 jffs2_gc_release_inode(c, f);
481
482 if (!ref_obsolete(raw)) {
368 jeb->dirty_size += rawlen; 483 jeb->dirty_size += rawlen;
369 jeb->used_size -= rawlen; 484 jeb->used_size -= rawlen;
370 c->dirty_size += rawlen; 485 c->dirty_size += rawlen;
486 c->used_size -= rawlen;
487 raw->flash_offset = ref_offset(raw) | REF_OBSOLETE;
488 BUG_ON(raw->next_in_ino);
371 } 489 }
372 c->free_size -= rawlen;
373 (*raw)->flash_offset = ofs | ref_flags(*raw);
374 ofs += rawlen; 490 ofs += rawlen;
375 new_jeb->last_node = *raw;
376
377 raw = &(*raw)->next_phys;
378 } 491 }
379 492
493 kfree(buf);
494
380 /* Fix up the original jeb now it's on the bad_list */ 495 /* Fix up the original jeb now it's on the bad_list */
381 *first_raw = NULL; 496 if (first_raw == jeb->first_node) {
382 if (first_raw == &jeb->first_node) {
383 jeb->last_node = NULL;
384 D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset)); 497 D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset));
385 list_del(&jeb->list); 498 list_del(&jeb->list);
386 list_add(&jeb->list, &c->erase_pending_list); 499 list_add(&jeb->list, &c->erase_pending_list);
387 c->nr_erasing_blocks++; 500 c->nr_erasing_blocks++;
388 jffs2_erase_pending_trigger(c); 501 jffs2_erase_pending_trigger(c);
389 } 502 }
390 else
391 jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
392 503
393 jffs2_dbg_acct_sanity_check_nolock(c, jeb); 504 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
394 jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 505 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
395 506
396 jffs2_dbg_acct_sanity_check_nolock(c, new_jeb); 507 jffs2_dbg_acct_sanity_check_nolock(c, new_jeb);
397 jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb); 508 jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb);
398 509
399 spin_unlock(&c->erase_completion_lock); 510 spin_unlock(&c->erase_completion_lock);
400 511
401 D1(printk(KERN_DEBUG "wbuf recovery completed OK\n")); 512 D1(printk(KERN_DEBUG "wbuf recovery completed OK. wbuf_ofs 0x%08x, len 0x%x\n", c->wbuf_ofs, c->wbuf_len));
513
402} 514}
403 515
404/* Meaning of pad argument: 516/* Meaning of pad argument:
@@ -412,6 +524,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
412 524
413static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) 525static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
414{ 526{
527 struct jffs2_eraseblock *wbuf_jeb;
415 int ret; 528 int ret;
416 size_t retlen; 529 size_t retlen;
417 530
@@ -429,6 +542,10 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
429 if (!c->wbuf_len) /* already checked c->wbuf above */ 542 if (!c->wbuf_len) /* already checked c->wbuf above */
430 return 0; 543 return 0;
431 544
545 wbuf_jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
546 if (jffs2_prealloc_raw_node_refs(c, wbuf_jeb, c->nextblock->allocated_refs + 1))
547 return -ENOMEM;
548
432 /* claim remaining space on the page 549 /* claim remaining space on the page
433 this happens, if we have a change to a new block, 550 this happens, if we have a change to a new block,
434 or if fsync forces us to flush the writebuffer. 551 or if fsync forces us to flush the writebuffer.
@@ -458,15 +575,12 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
458 if (breakme++ == 20) { 575 if (breakme++ == 20) {
459 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs); 576 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);
460 breakme = 0; 577 breakme = 0;
461 c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, 578 c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen,
462 &retlen, brokenbuf, NULL, c->oobinfo); 579 brokenbuf);
463 ret = -EIO; 580 ret = -EIO;
464 } else 581 } else
465#endif 582#endif
466 583
467 if (jffs2_cleanmarker_oob(c))
468 ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
469 else
470 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf); 584 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);
471 585
472 if (ret || retlen != c->wbuf_pagesize) { 586 if (ret || retlen != c->wbuf_pagesize) {
@@ -483,32 +597,34 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
483 return ret; 597 return ret;
484 } 598 }
485 599
486 spin_lock(&c->erase_completion_lock);
487
488 /* Adjust free size of the block if we padded. */ 600 /* Adjust free size of the block if we padded. */
489 if (pad) { 601 if (pad) {
490 struct jffs2_eraseblock *jeb; 602 uint32_t waste = c->wbuf_pagesize - c->wbuf_len;
491
492 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
493 603
494 D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n", 604 D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
495 (jeb==c->nextblock)?"next":"", jeb->offset)); 605 (wbuf_jeb==c->nextblock)?"next":"", wbuf_jeb->offset));
496 606
497 /* wbuf_pagesize - wbuf_len is the amount of space that's to be 607 /* wbuf_pagesize - wbuf_len is the amount of space that's to be
498 padded. If there is less free space in the block than that, 608 padded. If there is less free space in the block than that,
499 something screwed up */ 609 something screwed up */
500 if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) { 610 if (wbuf_jeb->free_size < waste) {
501 printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n", 611 printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",
502 c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize-c->wbuf_len); 612 c->wbuf_ofs, c->wbuf_len, waste);
503 printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n", 613 printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",
504 jeb->offset, jeb->free_size); 614 wbuf_jeb->offset, wbuf_jeb->free_size);
505 BUG(); 615 BUG();
506 } 616 }
507 jeb->free_size -= (c->wbuf_pagesize - c->wbuf_len); 617
508 c->free_size -= (c->wbuf_pagesize - c->wbuf_len); 618 spin_lock(&c->erase_completion_lock);
509 jeb->wasted_size += (c->wbuf_pagesize - c->wbuf_len); 619
510 c->wasted_size += (c->wbuf_pagesize - c->wbuf_len); 620 jffs2_link_node_ref(c, wbuf_jeb, (c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE, waste, NULL);
511 } 621 /* FIXME: that made it count as dirty. Convert to wasted */
622 wbuf_jeb->dirty_size -= waste;
623 c->dirty_size -= waste;
624 wbuf_jeb->wasted_size += waste;
625 c->wasted_size += waste;
626 } else
627 spin_lock(&c->erase_completion_lock);
512 628
513 /* Stick any now-obsoleted blocks on the erase_pending_list */ 629 /* Stick any now-obsoleted blocks on the erase_pending_list */
514 jffs2_refile_wbuf_blocks(c); 630 jffs2_refile_wbuf_blocks(c);
@@ -603,20 +719,30 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
603 719
604 return ret; 720 return ret;
605} 721}
606int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) 722
723static size_t jffs2_fill_wbuf(struct jffs2_sb_info *c, const uint8_t *buf,
724 size_t len)
607{ 725{
608 struct kvec outvecs[3]; 726 if (len && !c->wbuf_len && (len >= c->wbuf_pagesize))
609 uint32_t totlen = 0; 727 return 0;
610 uint32_t split_ofs = 0; 728
611 uint32_t old_totlen; 729 if (len > (c->wbuf_pagesize - c->wbuf_len))
612 int ret, splitvec = -1; 730 len = c->wbuf_pagesize - c->wbuf_len;
613 int invec, outvec; 731 memcpy(c->wbuf + c->wbuf_len, buf, len);
614 size_t wbuf_retlen; 732 c->wbuf_len += (uint32_t) len;
615 unsigned char *wbuf_ptr; 733 return len;
616 size_t donelen = 0; 734}
735
736int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs,
737 unsigned long count, loff_t to, size_t *retlen,
738 uint32_t ino)
739{
740 struct jffs2_eraseblock *jeb;
741 size_t wbuf_retlen, donelen = 0;
617 uint32_t outvec_to = to; 742 uint32_t outvec_to = to;
743 int ret, invec;
618 744
619 /* If not NAND flash, don't bother */ 745 /* If not writebuffered flash, don't bother */
620 if (!jffs2_is_writebuffered(c)) 746 if (!jffs2_is_writebuffered(c))
621 return jffs2_flash_direct_writev(c, invecs, count, to, retlen); 747 return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
622 748
@@ -629,34 +755,22 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
629 memset(c->wbuf,0xff,c->wbuf_pagesize); 755 memset(c->wbuf,0xff,c->wbuf_pagesize);
630 } 756 }
631 757
632 /* Fixup the wbuf if we are moving to a new eraseblock. The checks below 758 /*
633 fail for ECC'd NOR because cleanmarker == 16, so a block starts at 759 * Sanity checks on target address. It's permitted to write
634 xxx0010. */ 760 * at PAD(c->wbuf_len+c->wbuf_ofs), and it's permitted to
635 if (jffs2_nor_ecc(c)) { 761 * write at the beginning of a new erase block. Anything else,
636 if (((c->wbuf_ofs % c->sector_size) == 0) && !c->wbuf_len) { 762 * and you die. New block starts at xxx000c (0-b = block
637 c->wbuf_ofs = PAGE_DIV(to); 763 * header)
638 c->wbuf_len = PAGE_MOD(to); 764 */
639 memset(c->wbuf,0xff,c->wbuf_pagesize);
640 }
641 }
642
643 /* Sanity checks on target address.
644 It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
645 and it's permitted to write at the beginning of a new
646 erase block. Anything else, and you die.
647 New block starts at xxx000c (0-b = block header)
648 */
649 if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) { 765 if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
650 /* It's a write to a new block */ 766 /* It's a write to a new block */
651 if (c->wbuf_len) { 767 if (c->wbuf_len) {
652 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs)); 768 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx "
769 "causes flush of wbuf at 0x%08x\n",
770 (unsigned long)to, c->wbuf_ofs));
653 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); 771 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
654 if (ret) { 772 if (ret)
655 /* the underlying layer has to check wbuf_len to do the cleanup */ 773 goto outerr;
656 D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
657 *retlen = 0;
658 goto exit;
659 }
660 } 774 }
661 /* set pointer to new block */ 775 /* set pointer to new block */
662 c->wbuf_ofs = PAGE_DIV(to); 776 c->wbuf_ofs = PAGE_DIV(to);
@@ -665,165 +779,70 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
665 779
666 if (to != PAD(c->wbuf_ofs + c->wbuf_len)) { 780 if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
667 /* We're not writing immediately after the writebuffer. Bad. */ 781 /* We're not writing immediately after the writebuffer. Bad. */
668 printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write to %08lx\n", (unsigned long)to); 782 printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write "
783 "to %08lx\n", (unsigned long)to);
669 if (c->wbuf_len) 784 if (c->wbuf_len)
670 printk(KERN_CRIT "wbuf was previously %08x-%08x\n", 785 printk(KERN_CRIT "wbuf was previously %08x-%08x\n",
671 c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len); 786 c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len);
672 BUG(); 787 BUG();
673 } 788 }
674 789
675 /* Note outvecs[3] above. We know count is never greater than 2 */ 790 /* adjust alignment offset */
676 if (count > 2) { 791 if (c->wbuf_len != PAGE_MOD(to)) {
677 printk(KERN_CRIT "jffs2_flash_writev(): count is %ld\n", count); 792 c->wbuf_len = PAGE_MOD(to);
678 BUG(); 793 /* take care of alignment to next page */
679 } 794 if (!c->wbuf_len) {
680 795 c->wbuf_len = c->wbuf_pagesize;
681 invec = 0; 796 ret = __jffs2_flush_wbuf(c, NOPAD);
682 outvec = 0; 797 if (ret)
683 798 goto outerr;
684 /* Fill writebuffer first, if already in use */
685 if (c->wbuf_len) {
686 uint32_t invec_ofs = 0;
687
688 /* adjust alignment offset */
689 if (c->wbuf_len != PAGE_MOD(to)) {
690 c->wbuf_len = PAGE_MOD(to);
691 /* take care of alignment to next page */
692 if (!c->wbuf_len)
693 c->wbuf_len = c->wbuf_pagesize;
694 }
695
696 while(c->wbuf_len < c->wbuf_pagesize) {
697 uint32_t thislen;
698
699 if (invec == count)
700 goto alldone;
701
702 thislen = c->wbuf_pagesize - c->wbuf_len;
703
704 if (thislen >= invecs[invec].iov_len)
705 thislen = invecs[invec].iov_len;
706
707 invec_ofs = thislen;
708
709 memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
710 c->wbuf_len += thislen;
711 donelen += thislen;
712 /* Get next invec, if actual did not fill the buffer */
713 if (c->wbuf_len < c->wbuf_pagesize)
714 invec++;
715 }
716
717 /* write buffer is full, flush buffer */
718 ret = __jffs2_flush_wbuf(c, NOPAD);
719 if (ret) {
720 /* the underlying layer has to check wbuf_len to do the cleanup */
721 D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
722 /* Retlen zero to make sure our caller doesn't mark the space dirty.
723 We've already done everything that's necessary */
724 *retlen = 0;
725 goto exit;
726 }
727 outvec_to += donelen;
728 c->wbuf_ofs = outvec_to;
729
730 /* All invecs done ? */
731 if (invec == count)
732 goto alldone;
733
734 /* Set up the first outvec, containing the remainder of the
735 invec we partially used */
736 if (invecs[invec].iov_len > invec_ofs) {
737 outvecs[0].iov_base = invecs[invec].iov_base+invec_ofs;
738 totlen = outvecs[0].iov_len = invecs[invec].iov_len-invec_ofs;
739 if (totlen > c->wbuf_pagesize) {
740 splitvec = outvec;
741 split_ofs = outvecs[0].iov_len - PAGE_MOD(totlen);
742 }
743 outvec++;
744 }
745 invec++;
746 }
747
748 /* OK, now we've flushed the wbuf and the start of the bits
749 we have been asked to write, now to write the rest.... */
750
751 /* totlen holds the amount of data still to be written */
752 old_totlen = totlen;
753 for ( ; invec < count; invec++,outvec++ ) {
754 outvecs[outvec].iov_base = invecs[invec].iov_base;
755 totlen += outvecs[outvec].iov_len = invecs[invec].iov_len;
756 if (PAGE_DIV(totlen) != PAGE_DIV(old_totlen)) {
757 splitvec = outvec;
758 split_ofs = outvecs[outvec].iov_len - PAGE_MOD(totlen);
759 old_totlen = totlen;
760 } 799 }
761 } 800 }
762 801
763 /* Now the outvecs array holds all the remaining data to write */ 802 for (invec = 0; invec < count; invec++) {
764 /* Up to splitvec,split_ofs is to be written immediately. The rest 803 int vlen = invecs[invec].iov_len;
765 goes into the (now-empty) wbuf */ 804 uint8_t *v = invecs[invec].iov_base;
766
767 if (splitvec != -1) {
768 uint32_t remainder;
769
770 remainder = outvecs[splitvec].iov_len - split_ofs;
771 outvecs[splitvec].iov_len = split_ofs;
772
773 /* We did cross a page boundary, so we write some now */
774 if (jffs2_cleanmarker_oob(c))
775 ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
776 else
777 ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
778
779 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
780 /* At this point we have no problem,
781 c->wbuf is empty. However refile nextblock to avoid
782 writing again to same address.
783 */
784 struct jffs2_eraseblock *jeb;
785 805
786 spin_lock(&c->erase_completion_lock); 806 wbuf_retlen = jffs2_fill_wbuf(c, v, vlen);
787 807
788 jeb = &c->blocks[outvec_to / c->sector_size]; 808 if (c->wbuf_len == c->wbuf_pagesize) {
789 jffs2_block_refile(c, jeb, REFILE_ANYWAY); 809 ret = __jffs2_flush_wbuf(c, NOPAD);
790 810 if (ret)
791 *retlen = 0; 811 goto outerr;
792 spin_unlock(&c->erase_completion_lock);
793 goto exit;
794 } 812 }
795 813 vlen -= wbuf_retlen;
814 outvec_to += wbuf_retlen;
796 donelen += wbuf_retlen; 815 donelen += wbuf_retlen;
797 c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen); 816 v += wbuf_retlen;
798 817
799 if (remainder) { 818 if (vlen >= c->wbuf_pagesize) {
800 outvecs[splitvec].iov_base += split_ofs; 819 ret = c->mtd->write(c->mtd, outvec_to, PAGE_DIV(vlen),
801 outvecs[splitvec].iov_len = remainder; 820 &wbuf_retlen, v);
802 } else { 821 if (ret < 0 || wbuf_retlen != PAGE_DIV(vlen))
803 splitvec++; 822 goto outfile;
823
824 vlen -= wbuf_retlen;
825 outvec_to += wbuf_retlen;
826 c->wbuf_ofs = outvec_to;
827 donelen += wbuf_retlen;
828 v += wbuf_retlen;
804 } 829 }
805 830
806 } else { 831 wbuf_retlen = jffs2_fill_wbuf(c, v, vlen);
807 splitvec = 0; 832 if (c->wbuf_len == c->wbuf_pagesize) {
808 } 833 ret = __jffs2_flush_wbuf(c, NOPAD);
809 834 if (ret)
810 /* Now splitvec points to the start of the bits we have to copy 835 goto outerr;
811 into the wbuf */ 836 }
812 wbuf_ptr = c->wbuf;
813 837
814 for ( ; splitvec < outvec; splitvec++) { 838 outvec_to += wbuf_retlen;
815 /* Don't copy the wbuf into itself */ 839 donelen += wbuf_retlen;
816 if (outvecs[splitvec].iov_base == c->wbuf)
817 continue;
818 memcpy(wbuf_ptr, outvecs[splitvec].iov_base, outvecs[splitvec].iov_len);
819 wbuf_ptr += outvecs[splitvec].iov_len;
820 donelen += outvecs[splitvec].iov_len;
821 } 840 }
822 c->wbuf_len = wbuf_ptr - c->wbuf;
823 841
824 /* If there's a remainder in the wbuf and it's a non-GC write, 842 /*
825 remember that the wbuf affects this ino */ 843 * If there's a remainder in the wbuf and it's a non-GC write,
826alldone: 844 * remember that the wbuf affects this ino
845 */
827 *retlen = donelen; 846 *retlen = donelen;
828 847
829 if (jffs2_sum_active()) { 848 if (jffs2_sum_active()) {
@@ -836,8 +855,24 @@ alldone:
836 jffs2_wbuf_dirties_inode(c, ino); 855 jffs2_wbuf_dirties_inode(c, ino);
837 856
838 ret = 0; 857 ret = 0;
858 up_write(&c->wbuf_sem);
859 return ret;
839 860
840exit: 861outfile:
862 /*
863 * At this point we have no problem, c->wbuf is empty. However
864 * refile nextblock to avoid writing again to same address.
865 */
866
867 spin_lock(&c->erase_completion_lock);
868
869 jeb = &c->blocks[outvec_to / c->sector_size];
870 jffs2_block_refile(c, jeb, REFILE_ANYWAY);
871
872 spin_unlock(&c->erase_completion_lock);
873
874outerr:
875 *retlen = 0;
841 up_write(&c->wbuf_sem); 876 up_write(&c->wbuf_sem);
842 return ret; 877 return ret;
843} 878}
@@ -846,7 +881,8 @@ exit:
846 * This is the entry for flash write. 881 * This is the entry for flash write.
847 * Check, if we work on NAND FLASH, if so build an kvec and write it via vritev 882 * Check, if we work on NAND FLASH, if so build an kvec and write it via vritev
848*/ 883*/
849int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf) 884int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
885 size_t *retlen, const u_char *buf)
850{ 886{
851 struct kvec vecs[1]; 887 struct kvec vecs[1];
852 888
@@ -871,25 +907,23 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
871 907
872 /* Read flash */ 908 /* Read flash */
873 down_read(&c->wbuf_sem); 909 down_read(&c->wbuf_sem);
874 if (jffs2_cleanmarker_oob(c)) 910 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
875 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo); 911
876 else 912 if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) {
877 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf); 913 if (ret == -EBADMSG)
878 914 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx)"
879 if ( (ret == -EBADMSG) && (*retlen == len) ) { 915 " returned ECC error\n", len, ofs);
880 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
881 len, ofs);
882 /* 916 /*
883 * We have the raw data without ECC correction in the buffer, maybe 917 * We have the raw data without ECC correction in the buffer,
884 * we are lucky and all data or parts are correct. We check the node. 918 * maybe we are lucky and all data or parts are correct. We
885 * If data are corrupted node check will sort it out. 919 * check the node. If data are corrupted node check will sort
886 * We keep this block, it will fail on write or erase and the we 920 * it out. We keep this block, it will fail on write or erase
887 * mark it bad. Or should we do that now? But we should give him a chance. 921 * and the we mark it bad. Or should we do that now? But we
888 * Maybe we had a system crash or power loss before the ecc write or 922 * should give him a chance. Maybe we had a system crash or
889 * a erase was completed. 923 * power loss before the ecc write or a erase was completed.
890 * So we return success. :) 924 * So we return success. :)
891 */ 925 */
892 ret = 0; 926 ret = 0;
893 } 927 }
894 928
895 /* if no writebuffer available or write buffer empty, return */ 929 /* if no writebuffer available or write buffer empty, return */
@@ -911,7 +945,7 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
911 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */ 945 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
912 if (orbf > len) /* is write beyond write buffer ? */ 946 if (orbf > len) /* is write beyond write buffer ? */
913 goto exit; 947 goto exit;
914 lwbf = len - orbf; /* number of bytes to copy */ 948 lwbf = len - orbf; /* number of bytes to copy */
915 if (lwbf > c->wbuf_len) 949 if (lwbf > c->wbuf_len)
916 lwbf = c->wbuf_len; 950 lwbf = c->wbuf_len;
917 } 951 }
@@ -923,158 +957,159 @@ exit:
923 return ret; 957 return ret;
924} 958}
925 959
960#define NR_OOB_SCAN_PAGES 4
961
926/* 962/*
927 * Check, if the out of band area is empty 963 * Check, if the out of band area is empty
928 */ 964 */
929int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int mode) 965int jffs2_check_oob_empty(struct jffs2_sb_info *c,
966 struct jffs2_eraseblock *jeb, int mode)
930{ 967{
931 unsigned char *buf; 968 int i, page, ret;
932 int ret = 0; 969 int oobsize = c->mtd->oobsize;
933 int i,len,page; 970 struct mtd_oob_ops ops;
934 size_t retlen; 971
935 int oob_size; 972 ops.len = NR_OOB_SCAN_PAGES * oobsize;
936 973 ops.ooblen = oobsize;
937 /* allocate a buffer for all oob data in this sector */ 974 ops.oobbuf = c->oobbuf;
938 oob_size = c->mtd->oobsize; 975 ops.ooboffs = 0;
939 len = 4 * oob_size; 976 ops.datbuf = NULL;
940 buf = kmalloc(len, GFP_KERNEL); 977 ops.mode = MTD_OOB_PLACE;
941 if (!buf) { 978
942 printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n"); 979 ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
943 return -ENOMEM;
944 }
945 /*
946 * if mode = 0, we scan for a total empty oob area, else we have
947 * to take care of the cleanmarker in the first page of the block
948 */
949 ret = jffs2_flash_read_oob(c, jeb->offset, len , &retlen, buf);
950 if (ret) { 980 if (ret) {
951 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); 981 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
952 goto out; 982 "failed %d for block at %08x\n", ret, jeb->offset));
983 return ret;
953 } 984 }
954 985
955 if (retlen < len) { 986 if (ops.retlen < ops.len) {
956 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read " 987 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
957 "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset)); 988 "returned short read (%zd bytes not %d) for block "
958 ret = -EIO; 989 "at %08x\n", ops.retlen, ops.len, jeb->offset));
959 goto out; 990 return -EIO;
960 } 991 }
961 992
962 /* Special check for first page */ 993 /* Special check for first page */
963 for(i = 0; i < oob_size ; i++) { 994 for(i = 0; i < oobsize ; i++) {
964 /* Yeah, we know about the cleanmarker. */ 995 /* Yeah, we know about the cleanmarker. */
965 if (mode && i >= c->fsdata_pos && 996 if (mode && i >= c->fsdata_pos &&
966 i < c->fsdata_pos + c->fsdata_len) 997 i < c->fsdata_pos + c->fsdata_len)
967 continue; 998 continue;
968 999
969 if (buf[i] != 0xFF) { 1000 if (ops.oobbuf[i] != 0xFF) {
970 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n", 1001 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for "
971 buf[i], i, jeb->offset)); 1002 "%08x\n", ops.oobbuf[i], i, jeb->offset));
972 ret = 1; 1003 return 1;
973 goto out;
974 } 1004 }
975 } 1005 }
976 1006
977 /* we know, we are aligned :) */ 1007 /* we know, we are aligned :) */
978 for (page = oob_size; page < len; page += sizeof(long)) { 1008 for (page = oobsize; page < ops.len; page += sizeof(long)) {
979 unsigned long dat = *(unsigned long *)(&buf[page]); 1009 long dat = *(long *)(&ops.oobbuf[page]);
980 if(dat != -1) { 1010 if(dat != -1)
981 ret = 1; 1011 return 1;
982 goto out;
983 }
984 } 1012 }
985 1013 return 0;
986out:
987 kfree(buf);
988
989 return ret;
990} 1014}
991 1015
992/* 1016/*
993* Scan for a valid cleanmarker and for bad blocks 1017 * Scan for a valid cleanmarker and for bad blocks
994* For virtual blocks (concatenated physical blocks) check the cleanmarker 1018 */
995* only in the first page of the first physical block, but scan for bad blocks in all 1019int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
996* physical blocks 1020 struct jffs2_eraseblock *jeb)
997*/
998int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
999{ 1021{
1000 struct jffs2_unknown_node n; 1022 struct jffs2_unknown_node n;
1001 unsigned char buf[2 * NAND_MAX_OOBSIZE]; 1023 struct mtd_oob_ops ops;
1002 unsigned char *p; 1024 int oobsize = c->mtd->oobsize;
1003 int ret, i, cnt, retval = 0; 1025 unsigned char *p,*b;
1004 size_t retlen, offset; 1026 int i, ret;
1005 int oob_size; 1027 size_t offset = jeb->offset;
1006 1028
1007 offset = jeb->offset; 1029 /* Check first if the block is bad. */
1008 oob_size = c->mtd->oobsize; 1030 if (c->mtd->block_isbad(c->mtd, offset)) {
1009 1031 D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker()"
1010 /* Loop through the physical blocks */ 1032 ": Bad block at %08x\n", jeb->offset));
1011 for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) { 1033 return 2;
1012 /* Check first if the block is bad. */ 1034 }
1013 if (c->mtd->block_isbad (c->mtd, offset)) {
1014 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x\n", jeb->offset));
1015 return 2;
1016 }
1017 /*
1018 * We read oob data from page 0 and 1 of the block.
1019 * page 0 contains cleanmarker and badblock info
1020 * page 1 contains failure count of this block
1021 */
1022 ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf);
1023 1035
1024 if (ret) { 1036 ops.len = oobsize;
1025 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); 1037 ops.ooblen = oobsize;
1026 return ret; 1038 ops.oobbuf = c->oobbuf;
1027 } 1039 ops.ooboffs = 0;
1028 if (retlen < (oob_size << 1)) { 1040 ops.datbuf = NULL;
1029 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset)); 1041 ops.mode = MTD_OOB_PLACE;
1030 return -EIO;
1031 }
1032 1042
1033 /* Check cleanmarker only on the first physical block */ 1043 ret = c->mtd->read_oob(c->mtd, offset, &ops);
1034 if (!cnt) { 1044 if (ret) {
1035 n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); 1045 D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1036 n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); 1046 "Read OOB failed %d for block at %08x\n",
1037 n.totlen = cpu_to_je32 (8); 1047 ret, jeb->offset));
1038 p = (unsigned char *) &n; 1048 return ret;
1049 }
1039 1050
1040 for (i = 0; i < c->fsdata_len; i++) { 1051 if (ops.retlen < ops.len) {
1041 if (buf[c->fsdata_pos + i] != p[i]) { 1052 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1042 retval = 1; 1053 "Read OOB return short read (%zd bytes not %d) "
1043 } 1054 "for block at %08x\n", ops.retlen, ops.len,
1044 } 1055 jeb->offset));
1045 D1(if (retval == 1) { 1056 return -EIO;
1046 printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset);
1047 printk(KERN_WARNING "OOB at %08x was ", offset);
1048 for (i=0; i < oob_size; i++) {
1049 printk("%02x ", buf[i]);
1050 }
1051 printk("\n");
1052 })
1053 }
1054 offset += c->mtd->erasesize;
1055 } 1057 }
1056 return retval; 1058
1059 n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
1060 n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
1061 n.totlen = cpu_to_je32 (8);
1062 p = (unsigned char *) &n;
1063 b = c->oobbuf + c->fsdata_pos;
1064
1065 for (i = c->fsdata_len; i; i--) {
1066 if (*b++ != *p++)
1067 ret = 1;
1068 }
1069
1070 D1(if (ret == 1) {
1071 printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1072 "Cleanmarker node not detected in block at %08x\n",
1073 offset);
1074 printk(KERN_WARNING "OOB at %08zx was ", offset);
1075 for (i=0; i < oobsize; i++)
1076 printk("%02x ", c->oobbuf[i]);
1077 printk("\n");
1078 });
1079 return ret;
1057} 1080}
1058 1081
1059int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 1082int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1083 struct jffs2_eraseblock *jeb)
1060{ 1084{
1061 struct jffs2_unknown_node n; 1085 struct jffs2_unknown_node n;
1062 int ret; 1086 int ret;
1063 size_t retlen; 1087 struct mtd_oob_ops ops;
1064 1088
1065 n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 1089 n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
1066 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); 1090 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
1067 n.totlen = cpu_to_je32(8); 1091 n.totlen = cpu_to_je32(8);
1068 1092
1069 ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n); 1093 ops.len = c->fsdata_len;
1094 ops.ooblen = c->fsdata_len;;
1095 ops.oobbuf = (uint8_t *)&n;
1096 ops.ooboffs = c->fsdata_pos;
1097 ops.datbuf = NULL;
1098 ops.mode = MTD_OOB_PLACE;
1099
1100 ret = c->mtd->write_oob(c->mtd, jeb->offset, &ops);
1070 1101
1071 if (ret) { 1102 if (ret) {
1072 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); 1103 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
1104 "Write failed for block at %08x: error %d\n",
1105 jeb->offset, ret));
1073 return ret; 1106 return ret;
1074 } 1107 }
1075 if (retlen != c->fsdata_len) { 1108 if (ops.retlen != ops.len) {
1076 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, c->fsdata_len)); 1109 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
1077 return ret; 1110 "Short write for block at %08x: %zd not %d\n",
1111 jeb->offset, ops.retlen, ops.len));
1112 return -EIO;
1078 } 1113 }
1079 return 0; 1114 return 0;
1080} 1115}
@@ -1108,18 +1143,9 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
1108 return 1; 1143 return 1;
1109} 1144}
1110 1145
1111#define NAND_JFFS2_OOB16_FSDALEN 8
1112
1113static struct nand_oobinfo jffs2_oobinfo_docecc = {
1114 .useecc = MTD_NANDECC_PLACE,
1115 .eccbytes = 6,
1116 .eccpos = {0,1,2,3,4,5}
1117};
1118
1119
1120static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) 1146static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
1121{ 1147{
1122 struct nand_oobinfo *oinfo = &c->mtd->oobinfo; 1148 struct nand_ecclayout *oinfo = c->mtd->ecclayout;
1123 1149
1124 /* Do this only, if we have an oob buffer */ 1150 /* Do this only, if we have an oob buffer */
1125 if (!c->mtd->oobsize) 1151 if (!c->mtd->oobsize)
@@ -1129,33 +1155,23 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
1129 c->cleanmarker_size = 0; 1155 c->cleanmarker_size = 0;
1130 1156
1131 /* Should we use autoplacement ? */ 1157 /* Should we use autoplacement ? */
1132 if (oinfo && oinfo->useecc == MTD_NANDECC_AUTOPLACE) { 1158 if (!oinfo) {
1133 D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); 1159 D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
1134 /* Get the position of the free bytes */ 1160 return -EINVAL;
1135 if (!oinfo->oobfree[0][1]) { 1161 }
1136 printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep. Autoplacement selected and no empty space in oob\n");
1137 return -ENOSPC;
1138 }
1139 c->fsdata_pos = oinfo->oobfree[0][0];
1140 c->fsdata_len = oinfo->oobfree[0][1];
1141 if (c->fsdata_len > 8)
1142 c->fsdata_len = 8;
1143 } else {
1144 /* This is just a legacy fallback and should go away soon */
1145 switch(c->mtd->ecctype) {
1146 case MTD_ECC_RS_DiskOnChip:
1147 printk(KERN_WARNING "JFFS2 using DiskOnChip hardware ECC without autoplacement. Fix it!\n");
1148 c->oobinfo = &jffs2_oobinfo_docecc;
1149 c->fsdata_pos = 6;
1150 c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
1151 c->badblock_pos = 15;
1152 break;
1153 1162
1154 default: 1163 D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n"));
1155 D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); 1164 /* Get the position of the free bytes */
1156 return -EINVAL; 1165 if (!oinfo->oobfree[0].length) {
1157 } 1166 printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep."
1167 " Autoplacement selected and no empty space in oob\n");
1168 return -ENOSPC;
1158 } 1169 }
1170 c->fsdata_pos = oinfo->oobfree[0].offset;
1171 c->fsdata_len = oinfo->oobfree[0].length;
1172 if (c->fsdata_len > 8)
1173 c->fsdata_len = 8;
1174
1159 return 0; 1175 return 0;
1160} 1176}
1161 1177
@@ -1165,13 +1181,17 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1165 1181
1166 /* Initialise write buffer */ 1182 /* Initialise write buffer */
1167 init_rwsem(&c->wbuf_sem); 1183 init_rwsem(&c->wbuf_sem);
1168 c->wbuf_pagesize = c->mtd->oobblock; 1184 c->wbuf_pagesize = c->mtd->writesize;
1169 c->wbuf_ofs = 0xFFFFFFFF; 1185 c->wbuf_ofs = 0xFFFFFFFF;
1170 1186
1171 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); 1187 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1172 if (!c->wbuf) 1188 if (!c->wbuf)
1173 return -ENOMEM; 1189 return -ENOMEM;
1174 1190
1191 c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->mtd->oobsize, GFP_KERNEL);
1192 if (!c->oobbuf)
1193 return -ENOMEM;
1194
1175 res = jffs2_nand_set_oobinfo(c); 1195 res = jffs2_nand_set_oobinfo(c);
1176 1196
1177#ifdef BREAKME 1197#ifdef BREAKME
@@ -1189,6 +1209,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
1189void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) 1209void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
1190{ 1210{
1191 kfree(c->wbuf); 1211 kfree(c->wbuf);
1212 kfree(c->oobbuf);
1192} 1213}
1193 1214
1194int jffs2_dataflash_setup(struct jffs2_sb_info *c) { 1215int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
@@ -1236,33 +1257,14 @@ void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
1236 kfree(c->wbuf); 1257 kfree(c->wbuf);
1237} 1258}
1238 1259
1239int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1240 /* Cleanmarker is actually larger on the flashes */
1241 c->cleanmarker_size = 16;
1242
1243 /* Initialize write buffer */
1244 init_rwsem(&c->wbuf_sem);
1245 c->wbuf_pagesize = c->mtd->eccsize;
1246 c->wbuf_ofs = 0xFFFFFFFF;
1247
1248 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1249 if (!c->wbuf)
1250 return -ENOMEM;
1251
1252 return 0;
1253}
1254
1255void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
1256 kfree(c->wbuf);
1257}
1258
1259int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { 1260int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
1260 /* Cleanmarker currently occupies a whole programming region */ 1261 /* Cleanmarker currently occupies whole programming regions,
1261 c->cleanmarker_size = MTD_PROGREGION_SIZE(c->mtd); 1262 * either one or 2 for 8Byte STMicro flashes. */
1263 c->cleanmarker_size = max(16u, c->mtd->writesize);
1262 1264
1263 /* Initialize write buffer */ 1265 /* Initialize write buffer */
1264 init_rwsem(&c->wbuf_sem); 1266 init_rwsem(&c->wbuf_sem);
1265 c->wbuf_pagesize = MTD_PROGREGION_SIZE(c->mtd); 1267 c->wbuf_pagesize = c->mtd->writesize;
1266 c->wbuf_ofs = 0xFFFFFFFF; 1268 c->wbuf_ofs = 0xFFFFFFFF;
1267 1269
1268 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); 1270 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 1342f0158e9b..67176792e138 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -37,7 +37,6 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
38 f->inocache->state = INO_STATE_PRESENT; 38 f->inocache->state = INO_STATE_PRESENT;
39 39
40
41 jffs2_add_ino_cache(c, f->inocache); 40 jffs2_add_ino_cache(c, f->inocache);
42 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); 41 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
43 ri->ino = cpu_to_je32(f->inocache->ino); 42 ri->ino = cpu_to_je32(f->inocache->ino);
@@ -57,12 +56,14 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
57/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, 56/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
58 write it to the flash, link it into the existing inode/fragment list */ 57 write it to the flash, link it into the existing inode/fragment list */
59 58
60struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode) 59struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
60 struct jffs2_raw_inode *ri, const unsigned char *data,
61 uint32_t datalen, int alloc_mode)
61 62
62{ 63{
63 struct jffs2_raw_node_ref *raw;
64 struct jffs2_full_dnode *fn; 64 struct jffs2_full_dnode *fn;
65 size_t retlen; 65 size_t retlen;
66 uint32_t flash_ofs;
66 struct kvec vecs[2]; 67 struct kvec vecs[2];
67 int ret; 68 int ret;
68 int retried = 0; 69 int retried = 0;
@@ -78,34 +79,21 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
78 vecs[1].iov_base = (unsigned char *)data; 79 vecs[1].iov_base = (unsigned char *)data;
79 vecs[1].iov_len = datalen; 80 vecs[1].iov_len = datalen;
80 81
81 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
82
83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 82 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
84 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); 83 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
85 } 84 }
86 raw = jffs2_alloc_raw_node_ref();
87 if (!raw)
88 return ERR_PTR(-ENOMEM);
89 85
90 fn = jffs2_alloc_full_dnode(); 86 fn = jffs2_alloc_full_dnode();
91 if (!fn) { 87 if (!fn)
92 jffs2_free_raw_node_ref(raw);
93 return ERR_PTR(-ENOMEM); 88 return ERR_PTR(-ENOMEM);
94 }
95
96 fn->ofs = je32_to_cpu(ri->offset);
97 fn->size = je32_to_cpu(ri->dsize);
98 fn->frags = 0;
99 89
100 /* check number of valid vecs */ 90 /* check number of valid vecs */
101 if (!datalen || !data) 91 if (!datalen || !data)
102 cnt = 1; 92 cnt = 1;
103 retry: 93 retry:
104 fn->raw = raw; 94 flash_ofs = write_ofs(c);
105 95
106 raw->flash_offset = flash_ofs; 96 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
107 raw->__totlen = PAD(sizeof(*ri)+datalen);
108 raw->next_phys = NULL;
109 97
110 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { 98 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
111 BUG_ON(!retried); 99 BUG_ON(!retried);
@@ -125,22 +113,16 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
125 113
126 /* Mark the space as dirtied */ 114 /* Mark the space as dirtied */
127 if (retlen) { 115 if (retlen) {
128 /* Doesn't belong to any inode */
129 raw->next_in_ino = NULL;
130
131 /* Don't change raw->size to match retlen. We may have 116 /* Don't change raw->size to match retlen. We may have
132 written the node header already, and only the data will 117 written the node header already, and only the data will
133 seem corrupted, in which case the scan would skip over 118 seem corrupted, in which case the scan would skip over
134 any node we write before the original intended end of 119 any node we write before the original intended end of
135 this node */ 120 this node */
136 raw->flash_offset |= REF_OBSOLETE; 121 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL);
137 jffs2_add_physical_node_ref(c, raw);
138 jffs2_mark_node_obsolete(c, raw);
139 } else { 122 } else {
140 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 123 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
141 jffs2_free_raw_node_ref(raw);
142 } 124 }
143 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { 125 if (!retried && alloc_mode != ALLOC_NORETRY) {
144 /* Try to reallocate space and retry */ 126 /* Try to reallocate space and retry */
145 uint32_t dummy; 127 uint32_t dummy;
146 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 128 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -153,19 +135,20 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
153 jffs2_dbg_acct_paranoia_check(c, jeb); 135 jffs2_dbg_acct_paranoia_check(c, jeb);
154 136
155 if (alloc_mode == ALLOC_GC) { 137 if (alloc_mode == ALLOC_GC) {
156 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, 138 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &dummy,
157 &dummy, JFFS2_SUMMARY_INODE_SIZE); 139 JFFS2_SUMMARY_INODE_SIZE);
158 } else { 140 } else {
159 /* Locking pain */ 141 /* Locking pain */
160 up(&f->sem); 142 up(&f->sem);
161 jffs2_complete_reservation(c); 143 jffs2_complete_reservation(c);
162 144
163 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, 145 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &dummy,
164 &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE); 146 alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
165 down(&f->sem); 147 down(&f->sem);
166 } 148 }
167 149
168 if (!ret) { 150 if (!ret) {
151 flash_ofs = write_ofs(c);
169 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 152 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
170 153
171 jffs2_dbg_acct_sanity_check(c,jeb); 154 jffs2_dbg_acct_sanity_check(c,jeb);
@@ -174,7 +157,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
174 goto retry; 157 goto retry;
175 } 158 }
176 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 159 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
177 jffs2_free_raw_node_ref(raw);
178 } 160 }
179 /* Release the full_dnode which is now useless, and return */ 161 /* Release the full_dnode which is now useless, and return */
180 jffs2_free_full_dnode(fn); 162 jffs2_free_full_dnode(fn);
@@ -188,20 +170,17 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
188 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 170 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
189 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 171 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
190 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { 172 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
191 raw->flash_offset |= REF_PRISTINE; 173 flash_ofs |= REF_PRISTINE;
192 } else { 174 } else {
193 raw->flash_offset |= REF_NORMAL; 175 flash_ofs |= REF_NORMAL;
194 } 176 }
195 jffs2_add_physical_node_ref(c, raw); 177 fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache);
196 178 fn->ofs = je32_to_cpu(ri->offset);
197 /* Link into per-inode list */ 179 fn->size = je32_to_cpu(ri->dsize);
198 spin_lock(&c->erase_completion_lock); 180 fn->frags = 0;
199 raw->next_in_ino = f->inocache->nodes;
200 f->inocache->nodes = raw;
201 spin_unlock(&c->erase_completion_lock);
202 181
203 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", 182 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
204 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), 183 flash_ofs & ~3, flash_ofs & 3, je32_to_cpu(ri->dsize),
205 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 184 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
206 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 185 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
207 186
@@ -212,12 +191,14 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
212 return fn; 191 return fn;
213} 192}
214 193
215struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode) 194struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
195 struct jffs2_raw_dirent *rd, const unsigned char *name,
196 uint32_t namelen, int alloc_mode)
216{ 197{
217 struct jffs2_raw_node_ref *raw;
218 struct jffs2_full_dirent *fd; 198 struct jffs2_full_dirent *fd;
219 size_t retlen; 199 size_t retlen;
220 struct kvec vecs[2]; 200 struct kvec vecs[2];
201 uint32_t flash_ofs;
221 int retried = 0; 202 int retried = 0;
222 int ret; 203 int ret;
223 204
@@ -228,26 +209,16 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
228 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 209 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
229 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 210 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
230 BUG(); 211 BUG();
231 } 212 });
232 );
233 213
234 vecs[0].iov_base = rd; 214 vecs[0].iov_base = rd;
235 vecs[0].iov_len = sizeof(*rd); 215 vecs[0].iov_len = sizeof(*rd);
236 vecs[1].iov_base = (unsigned char *)name; 216 vecs[1].iov_base = (unsigned char *)name;
237 vecs[1].iov_len = namelen; 217 vecs[1].iov_len = namelen;
238 218
239 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
240
241 raw = jffs2_alloc_raw_node_ref();
242
243 if (!raw)
244 return ERR_PTR(-ENOMEM);
245
246 fd = jffs2_alloc_full_dirent(namelen+1); 219 fd = jffs2_alloc_full_dirent(namelen+1);
247 if (!fd) { 220 if (!fd)
248 jffs2_free_raw_node_ref(raw);
249 return ERR_PTR(-ENOMEM); 221 return ERR_PTR(-ENOMEM);
250 }
251 222
252 fd->version = je32_to_cpu(rd->version); 223 fd->version = je32_to_cpu(rd->version);
253 fd->ino = je32_to_cpu(rd->ino); 224 fd->ino = je32_to_cpu(rd->ino);
@@ -257,11 +228,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
257 fd->name[namelen]=0; 228 fd->name[namelen]=0;
258 229
259 retry: 230 retry:
260 fd->raw = raw; 231 flash_ofs = write_ofs(c);
261 232
262 raw->flash_offset = flash_ofs; 233 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
263 raw->__totlen = PAD(sizeof(*rd)+namelen);
264 raw->next_phys = NULL;
265 234
266 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) { 235 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
267 BUG_ON(!retried); 236 BUG_ON(!retried);
@@ -280,15 +249,11 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
280 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 249 sizeof(*rd)+namelen, flash_ofs, ret, retlen);
281 /* Mark the space as dirtied */ 250 /* Mark the space as dirtied */
282 if (retlen) { 251 if (retlen) {
283 raw->next_in_ino = NULL; 252 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL);
284 raw->flash_offset |= REF_OBSOLETE;
285 jffs2_add_physical_node_ref(c, raw);
286 jffs2_mark_node_obsolete(c, raw);
287 } else { 253 } else {
288 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 254 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
289 jffs2_free_raw_node_ref(raw);
290 } 255 }
291 if (!retried && (raw = jffs2_alloc_raw_node_ref())) { 256 if (!retried) {
292 /* Try to reallocate space and retry */ 257 /* Try to reallocate space and retry */
293 uint32_t dummy; 258 uint32_t dummy;
294 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 259 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -301,39 +266,33 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
301 jffs2_dbg_acct_paranoia_check(c, jeb); 266 jffs2_dbg_acct_paranoia_check(c, jeb);
302 267
303 if (alloc_mode == ALLOC_GC) { 268 if (alloc_mode == ALLOC_GC) {
304 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, 269 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &dummy,
305 &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 270 JFFS2_SUMMARY_DIRENT_SIZE(namelen));
306 } else { 271 } else {
307 /* Locking pain */ 272 /* Locking pain */
308 up(&f->sem); 273 up(&f->sem);
309 jffs2_complete_reservation(c); 274 jffs2_complete_reservation(c);
310 275
311 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, 276 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &dummy,
312 &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 277 alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
313 down(&f->sem); 278 down(&f->sem);
314 } 279 }
315 280
316 if (!ret) { 281 if (!ret) {
282 flash_ofs = write_ofs(c);
317 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 283 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
318 jffs2_dbg_acct_sanity_check(c,jeb); 284 jffs2_dbg_acct_sanity_check(c,jeb);
319 jffs2_dbg_acct_paranoia_check(c, jeb); 285 jffs2_dbg_acct_paranoia_check(c, jeb);
320 goto retry; 286 goto retry;
321 } 287 }
322 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 288 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
323 jffs2_free_raw_node_ref(raw);
324 } 289 }
325 /* Release the full_dnode which is now useless, and return */ 290 /* Release the full_dnode which is now useless, and return */
326 jffs2_free_full_dirent(fd); 291 jffs2_free_full_dirent(fd);
327 return ERR_PTR(ret?ret:-EIO); 292 return ERR_PTR(ret?ret:-EIO);
328 } 293 }
329 /* Mark the space used */ 294 /* Mark the space used */
330 raw->flash_offset |= REF_PRISTINE; 295 fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache);
331 jffs2_add_physical_node_ref(c, raw);
332
333 spin_lock(&c->erase_completion_lock);
334 raw->next_in_ino = f->inocache->nodes;
335 f->inocache->nodes = raw;
336 spin_unlock(&c->erase_completion_lock);
337 296
338 if (retried) { 297 if (retried) {
339 jffs2_dbg_acct_sanity_check(c,NULL); 298 jffs2_dbg_acct_sanity_check(c,NULL);
@@ -359,14 +318,14 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
359 struct jffs2_full_dnode *fn; 318 struct jffs2_full_dnode *fn;
360 unsigned char *comprbuf = NULL; 319 unsigned char *comprbuf = NULL;
361 uint16_t comprtype = JFFS2_COMPR_NONE; 320 uint16_t comprtype = JFFS2_COMPR_NONE;
362 uint32_t phys_ofs, alloclen; 321 uint32_t alloclen;
363 uint32_t datalen, cdatalen; 322 uint32_t datalen, cdatalen;
364 int retried = 0; 323 int retried = 0;
365 324
366 retry: 325 retry:
367 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); 326 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
368 327
369 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, 328 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN,
370 &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 329 &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
371 if (ret) { 330 if (ret) {
372 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); 331 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
@@ -394,7 +353,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
394 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 353 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
395 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); 354 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
396 355
397 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY); 356 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
398 357
399 jffs2_free_comprbuf(comprbuf, buf); 358 jffs2_free_comprbuf(comprbuf, buf);
400 359
@@ -448,13 +407,13 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
448 struct jffs2_raw_dirent *rd; 407 struct jffs2_raw_dirent *rd;
449 struct jffs2_full_dnode *fn; 408 struct jffs2_full_dnode *fn;
450 struct jffs2_full_dirent *fd; 409 struct jffs2_full_dirent *fd;
451 uint32_t alloclen, phys_ofs; 410 uint32_t alloclen;
452 int ret; 411 int ret;
453 412
454 /* Try to reserve enough space for both node and dirent. 413 /* Try to reserve enough space for both node and dirent.
455 * Just the node will do for now, though 414 * Just the node will do for now, though
456 */ 415 */
457 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, 416 ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
458 JFFS2_SUMMARY_INODE_SIZE); 417 JFFS2_SUMMARY_INODE_SIZE);
459 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); 418 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
460 if (ret) { 419 if (ret) {
@@ -465,7 +424,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
465 ri->data_crc = cpu_to_je32(0); 424 ri->data_crc = cpu_to_je32(0);
466 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 425 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
467 426
468 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 427 fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
469 428
470 D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", 429 D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
471 jemode_to_cpu(ri->mode))); 430 jemode_to_cpu(ri->mode)));
@@ -484,7 +443,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
484 443
485 up(&f->sem); 444 up(&f->sem);
486 jffs2_complete_reservation(c); 445 jffs2_complete_reservation(c);
487 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 446 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
488 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 447 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
489 448
490 if (ret) { 449 if (ret) {
@@ -516,7 +475,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
516 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 475 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
517 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 476 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
518 477
519 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 478 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
520 479
521 jffs2_free_raw_dirent(rd); 480 jffs2_free_raw_dirent(rd);
522 481
@@ -545,7 +504,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
545{ 504{
546 struct jffs2_raw_dirent *rd; 505 struct jffs2_raw_dirent *rd;
547 struct jffs2_full_dirent *fd; 506 struct jffs2_full_dirent *fd;
548 uint32_t alloclen, phys_ofs; 507 uint32_t alloclen;
549 int ret; 508 int ret;
550 509
551 if (1 /* alternative branch needs testing */ || 510 if (1 /* alternative branch needs testing */ ||
@@ -556,7 +515,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
556 if (!rd) 515 if (!rd)
557 return -ENOMEM; 516 return -ENOMEM;
558 517
559 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 518 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
560 ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 519 ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
561 if (ret) { 520 if (ret) {
562 jffs2_free_raw_dirent(rd); 521 jffs2_free_raw_dirent(rd);
@@ -580,7 +539,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
580 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 539 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
581 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 540 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
582 541
583 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); 542 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION);
584 543
585 jffs2_free_raw_dirent(rd); 544 jffs2_free_raw_dirent(rd);
586 545
@@ -659,14 +618,14 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
659{ 618{
660 struct jffs2_raw_dirent *rd; 619 struct jffs2_raw_dirent *rd;
661 struct jffs2_full_dirent *fd; 620 struct jffs2_full_dirent *fd;
662 uint32_t alloclen, phys_ofs; 621 uint32_t alloclen;
663 int ret; 622 int ret;
664 623
665 rd = jffs2_alloc_raw_dirent(); 624 rd = jffs2_alloc_raw_dirent();
666 if (!rd) 625 if (!rd)
667 return -ENOMEM; 626 return -ENOMEM;
668 627
669 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 628 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
670 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 629 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
671 if (ret) { 630 if (ret) {
672 jffs2_free_raw_dirent(rd); 631 jffs2_free_raw_dirent(rd);
@@ -692,7 +651,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
692 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 651 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
693 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 652 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
694 653
695 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 654 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
696 655
697 jffs2_free_raw_dirent(rd); 656 jffs2_free_raw_dirent(rd);
698 657
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
new file mode 100644
index 000000000000..2d82e250be34
--- /dev/null
+++ b/fs/jffs2/xattr.c
@@ -0,0 +1,1238 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/fs.h>
14#include <linux/time.h>
15#include <linux/pagemap.h>
16#include <linux/highmem.h>
17#include <linux/crc32.h>
18#include <linux/jffs2.h>
19#include <linux/xattr.h>
20#include <linux/mtd/mtd.h>
21#include "nodelist.h"
22/* -------- xdatum related functions ----------------
23 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
24 * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
25 * the index of the xattr name/value pair cache (c->xattrindex).
26 * unload_xattr_datum(c, xd)
27 * is used to release xattr name/value pair and detach from c->xattrindex.
28 * reclaim_xattr_datum(c)
29 * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
30 * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold
31 * is hard coded as 32KiB.
32 * delete_xattr_datum_node(c, xd)
33 * is used to delete a jffs2 node is dominated by xdatum. When EBS(Erase Block Summary) is
34 * enabled, it overwrites the obsolete node by myself.
35 * delete_xattr_datum(c, xd)
36 * is used to delete jffs2_xattr_datum object. It must be called with 0-value of reference
37 * counter. (It means how many jffs2_xattr_ref object refers this xdatum.)
38 * do_verify_xattr_datum(c, xd)
39 * is used to load the xdatum informations without name/value pair from the medium.
40 * It's necessary once, because those informations are not collected during mounting
41 * process when EBS is enabled.
42 * 0 will be returned, if success. An negative return value means recoverable error, and
43 * positive return value means unrecoverable error. Thus, caller must remove this xdatum
44 * and xref when it returned positive value.
45 * do_load_xattr_datum(c, xd)
46 * is used to load name/value pair from the medium.
47 * The meanings of return value is same as do_verify_xattr_datum().
48 * load_xattr_datum(c, xd)
49 * is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum().
50 * If xd need to call do_verify_xattr_datum() at first, it's called before calling
51 * do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum().
52 * save_xattr_datum(c, xd)
53 * is used to write xdatum to medium. xd->version will be incremented.
54 * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
55 * is used to create new xdatum and write to medium.
56 * -------------------------------------------------- */
57
58static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
59{
60 int name_len = strlen(xname);
61
62 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
63}
64
65static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
66{
67 /* must be called under down_write(xattr_sem) */
68 D1(dbg_xattr("%s: xid=%u, version=%u\n", __FUNCTION__, xd->xid, xd->version));
69 if (xd->xname) {
70 c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
71 kfree(xd->xname);
72 }
73
74 list_del_init(&xd->xindex);
75 xd->hashkey = 0;
76 xd->xname = NULL;
77 xd->xvalue = NULL;
78}
79
80static void reclaim_xattr_datum(struct jffs2_sb_info *c)
81{
82 /* must be called under down_write(xattr_sem) */
83 struct jffs2_xattr_datum *xd, *_xd;
84 uint32_t target, before;
85 static int index = 0;
86 int count;
87
88 if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
89 return;
90
91 before = c->xdatum_mem_usage;
92 target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */
93 for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
94 list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
95 if (xd->flags & JFFS2_XFLAGS_HOT) {
96 xd->flags &= ~JFFS2_XFLAGS_HOT;
97 } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
98 unload_xattr_datum(c, xd);
99 }
100 if (c->xdatum_mem_usage <= target)
101 goto out;
102 }
103 index = (index+1) % XATTRINDEX_HASHSIZE;
104 }
105 out:
106 JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
107 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
108}
109
110static void delete_xattr_datum_node(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
111{
112 /* must be called under down_write(xattr_sem) */
113 struct jffs2_raw_xattr rx;
114 size_t length;
115 int rc;
116
117 if (!xd->node) {
118 JFFS2_WARNING("xdatum (xid=%u) is removed twice.\n", xd->xid);
119 return;
120 }
121 if (jffs2_sum_active()) {
122 memset(&rx, 0xff, sizeof(struct jffs2_raw_xattr));
123 rc = jffs2_flash_read(c, ref_offset(xd->node),
124 sizeof(struct jffs2_unknown_node),
125 &length, (char *)&rx);
126 if (rc || length != sizeof(struct jffs2_unknown_node)) {
127 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
128 rc, sizeof(struct jffs2_unknown_node),
129 length, ref_offset(xd->node));
130 }
131 rc = jffs2_flash_write(c, ref_offset(xd->node), sizeof(rx),
132 &length, (char *)&rx);
133 if (rc || length != sizeof(struct jffs2_raw_xattr)) {
134 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu ar %#08x\n",
135 rc, sizeof(rx), length, ref_offset(xd->node));
136 }
137 }
138 spin_lock(&c->erase_completion_lock);
139 xd->node->next_in_ino = NULL;
140 spin_unlock(&c->erase_completion_lock);
141 jffs2_mark_node_obsolete(c, xd->node);
142 xd->node = NULL;
143}
144
145static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
146{
147 /* must be called under down_write(xattr_sem) */
148 BUG_ON(xd->refcnt);
149
150 unload_xattr_datum(c, xd);
151 if (xd->node) {
152 delete_xattr_datum_node(c, xd);
153 xd->node = NULL;
154 }
155 jffs2_free_xattr_datum(xd);
156}
157
158static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
159{
160 /* must be called under down_write(xattr_sem) */
161 struct jffs2_eraseblock *jeb;
162 struct jffs2_raw_xattr rx;
163 size_t readlen;
164 uint32_t crc, totlen;
165 int rc;
166
167 BUG_ON(!xd->node);
168 BUG_ON(ref_flags(xd->node) != REF_UNCHECKED);
169
170 rc = jffs2_flash_read(c, ref_offset(xd->node), sizeof(rx), &readlen, (char *)&rx);
171 if (rc || readlen != sizeof(rx)) {
172 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
173 rc, sizeof(rx), readlen, ref_offset(xd->node));
174 return rc ? rc : -EIO;
175 }
176 crc = crc32(0, &rx, sizeof(rx) - 4);
177 if (crc != je32_to_cpu(rx.node_crc)) {
178 if (je32_to_cpu(rx.node_crc) != 0xffffffff)
179 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
180 ref_offset(xd->node), je32_to_cpu(rx.hdr_crc), crc);
181 return EIO;
182 }
183 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
184 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
185 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
186 || je32_to_cpu(rx.totlen) != totlen
187 || je32_to_cpu(rx.xid) != xd->xid
188 || je32_to_cpu(rx.version) != xd->version) {
189 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
190 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
191 ref_offset(xd->node), je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
192 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
193 je32_to_cpu(rx.totlen), totlen,
194 je32_to_cpu(rx.xid), xd->xid,
195 je32_to_cpu(rx.version), xd->version);
196 return EIO;
197 }
198 xd->xprefix = rx.xprefix;
199 xd->name_len = rx.name_len;
200 xd->value_len = je16_to_cpu(rx.value_len);
201 xd->data_crc = je32_to_cpu(rx.data_crc);
202
203 /* This JFFS2_NODETYPE_XATTR node is checked */
204 jeb = &c->blocks[ref_offset(xd->node) / c->sector_size];
205 totlen = PAD(je32_to_cpu(rx.totlen));
206
207 spin_lock(&c->erase_completion_lock);
208 c->unchecked_size -= totlen; c->used_size += totlen;
209 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
210 xd->node->flash_offset = ref_offset(xd->node) | REF_PRISTINE;
211 spin_unlock(&c->erase_completion_lock);
212
213 /* unchecked xdatum is chained with c->xattr_unchecked */
214 list_del_init(&xd->xindex);
215
216 dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n",
217 xd->xid, xd->version);
218
219 return 0;
220}
221
222static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
223{
224 /* must be called under down_write(xattr_sem) */
225 char *data;
226 size_t readlen;
227 uint32_t crc, length;
228 int i, ret, retry = 0;
229
230 BUG_ON(!xd->node);
231 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
232 BUG_ON(!list_empty(&xd->xindex));
233 retry:
234 length = xd->name_len + 1 + xd->value_len;
235 data = kmalloc(length, GFP_KERNEL);
236 if (!data)
237 return -ENOMEM;
238
239 ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
240 length, &readlen, data);
241
242 if (ret || length!=readlen) {
243 JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
244 ret, length, readlen, ref_offset(xd->node));
245 kfree(data);
246 return ret ? ret : -EIO;
247 }
248
249 data[xd->name_len] = '\0';
250 crc = crc32(0, data, length);
251 if (crc != xd->data_crc) {
252 JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)"
253 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
254 ref_offset(xd->node), xd->data_crc, crc);
255 kfree(data);
256 return EIO;
257 }
258
259 xd->flags |= JFFS2_XFLAGS_HOT;
260 xd->xname = data;
261 xd->xvalue = data + xd->name_len+1;
262
263 c->xdatum_mem_usage += length;
264
265 xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
266 i = xd->hashkey % XATTRINDEX_HASHSIZE;
267 list_add(&xd->xindex, &c->xattrindex[i]);
268 if (!retry) {
269 retry = 1;
270 reclaim_xattr_datum(c);
271 if (!xd->xname)
272 goto retry;
273 }
274
275 dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
276 xd->xid, xd->xprefix, xd->xname);
277
278 return 0;
279}
280
281static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
282{
283 /* must be called under down_write(xattr_sem);
284 * rc < 0 : recoverable error, try again
285 * rc = 0 : success
286 * rc > 0 : Unrecoverable error, this node should be deleted.
287 */
288 int rc = 0;
289 BUG_ON(xd->xname);
290 if (!xd->node)
291 return EIO;
292 if (unlikely(ref_flags(xd->node) != REF_PRISTINE)) {
293 rc = do_verify_xattr_datum(c, xd);
294 if (rc > 0) {
295 list_del_init(&xd->xindex);
296 delete_xattr_datum_node(c, xd);
297 }
298 }
299 if (!rc)
300 rc = do_load_xattr_datum(c, xd);
301 return rc;
302}
303
304static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
305{
306 /* must be called under down_write(xattr_sem) */
307 struct jffs2_raw_node_ref *raw;
308 struct jffs2_raw_xattr rx;
309 struct kvec vecs[2];
310 size_t length;
311 int rc, totlen;
312 uint32_t phys_ofs = write_ofs(c);
313
314 BUG_ON(!xd->xname);
315
316 vecs[0].iov_base = &rx;
317 vecs[0].iov_len = PAD(sizeof(rx));
318 vecs[1].iov_base = xd->xname;
319 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
320 totlen = vecs[0].iov_len + vecs[1].iov_len;
321
322 /* Setup raw-xattr */
323 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
324 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
325 rx.totlen = cpu_to_je32(PAD(totlen));
326 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
327
328 rx.xid = cpu_to_je32(xd->xid);
329 rx.version = cpu_to_je32(++xd->version);
330 rx.xprefix = xd->xprefix;
331 rx.name_len = xd->name_len;
332 rx.value_len = cpu_to_je16(xd->value_len);
333 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
334 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
335
336 rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
337 if (rc || totlen != length) {
338 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
339 rc, totlen, length, phys_ofs);
340 rc = rc ? rc : -EIO;
341 if (length)
342 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
343
344 return rc;
345 }
346
347 /* success */
348 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), NULL);
349 /* FIXME */ raw->next_in_ino = (void *)xd;
350
351 if (xd->node)
352 delete_xattr_datum_node(c, xd);
353 xd->node = raw;
354
355 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
356 xd->xid, xd->version, xd->xprefix, xd->xname);
357
358 return 0;
359}
360
361static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
362 int xprefix, const char *xname,
363 const char *xvalue, int xsize)
364{
365 /* must be called under down_write(xattr_sem) */
366 struct jffs2_xattr_datum *xd;
367 uint32_t hashkey, name_len;
368 char *data;
369 int i, rc;
370
371 /* Search xattr_datum has same xname/xvalue by index */
372 hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
373 i = hashkey % XATTRINDEX_HASHSIZE;
374 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
375 if (xd->hashkey==hashkey
376 && xd->xprefix==xprefix
377 && xd->value_len==xsize
378 && !strcmp(xd->xname, xname)
379 && !memcmp(xd->xvalue, xvalue, xsize)) {
380 xd->refcnt++;
381 return xd;
382 }
383 }
384
385 /* Not found, Create NEW XATTR-Cache */
386 name_len = strlen(xname);
387
388 xd = jffs2_alloc_xattr_datum();
389 if (!xd)
390 return ERR_PTR(-ENOMEM);
391
392 data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
393 if (!data) {
394 jffs2_free_xattr_datum(xd);
395 return ERR_PTR(-ENOMEM);
396 }
397 strcpy(data, xname);
398 memcpy(data + name_len + 1, xvalue, xsize);
399
400 xd->refcnt = 1;
401 xd->xid = ++c->highest_xid;
402 xd->flags |= JFFS2_XFLAGS_HOT;
403 xd->xprefix = xprefix;
404
405 xd->hashkey = hashkey;
406 xd->xname = data;
407 xd->xvalue = data + name_len + 1;
408 xd->name_len = name_len;
409 xd->value_len = xsize;
410 xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
411
412 rc = save_xattr_datum(c, xd);
413 if (rc) {
414 kfree(xd->xname);
415 jffs2_free_xattr_datum(xd);
416 return ERR_PTR(rc);
417 }
418
419 /* Insert Hash Index */
420 i = hashkey % XATTRINDEX_HASHSIZE;
421 list_add(&xd->xindex, &c->xattrindex[i]);
422
423 c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
424 reclaim_xattr_datum(c);
425
426 return xd;
427}
428
429/* -------- xref related functions ------------------
430 * verify_xattr_ref(c, ref)
431 * is used to load xref information from medium. Because summary data does not
432 * contain xid/ino, it's necessary to verify once while mounting process.
433 * delete_xattr_ref_node(c, ref)
434 * is used to delete a jffs2 node is dominated by xref. When EBS is enabled,
435 * it overwrites the obsolete node by myself.
436 * delete_xattr_ref(c, ref)
437 * is used to delete jffs2_xattr_ref object. If the reference counter of xdatum
438 * is refered by this xref become 0, delete_xattr_datum() is called later.
439 * save_xattr_ref(c, ref)
440 * is used to write xref to medium.
441 * create_xattr_ref(c, ic, xd)
442 * is used to create a new xref and write to medium.
443 * jffs2_xattr_delete_inode(c, ic)
444 * is called to remove xrefs related to obsolete inode when inode is unlinked.
445 * jffs2_xattr_free_inode(c, ic)
446 * is called to release xattr related objects when unmounting.
447 * check_xattr_ref_inode(c, ic)
448 * is used to confirm inode does not have duplicate xattr name/value pair.
449 * -------------------------------------------------- */
450static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
451{
452 struct jffs2_eraseblock *jeb;
453 struct jffs2_raw_xref rr;
454 size_t readlen;
455 uint32_t crc, totlen;
456 int rc;
457
458 BUG_ON(ref_flags(ref->node) != REF_UNCHECKED);
459
460 rc = jffs2_flash_read(c, ref_offset(ref->node), sizeof(rr), &readlen, (char *)&rr);
461 if (rc || sizeof(rr) != readlen) {
462 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
463 rc, sizeof(rr), readlen, ref_offset(ref->node));
464 return rc ? rc : -EIO;
465 }
466 /* obsolete node */
467 crc = crc32(0, &rr, sizeof(rr) - 4);
468 if (crc != je32_to_cpu(rr.node_crc)) {
469 if (je32_to_cpu(rr.node_crc) != 0xffffffff)
470 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
471 ref_offset(ref->node), je32_to_cpu(rr.node_crc), crc);
472 return EIO;
473 }
474 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
475 || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
476 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
477 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
478 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
479 ref_offset(ref->node), je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
480 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
481 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
482 return EIO;
483 }
484 ref->ino = je32_to_cpu(rr.ino);
485 ref->xid = je32_to_cpu(rr.xid);
486
487 /* fixup superblock/eraseblock info */
488 jeb = &c->blocks[ref_offset(ref->node) / c->sector_size];
489 totlen = PAD(sizeof(rr));
490
491 spin_lock(&c->erase_completion_lock);
492 c->unchecked_size -= totlen; c->used_size += totlen;
493 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
494 ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE;
495 spin_unlock(&c->erase_completion_lock);
496
497 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
498 ref->ino, ref->xid, ref_offset(ref->node));
499 return 0;
500}
501
502static void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
503{
504 struct jffs2_raw_xref rr;
505 size_t length;
506 int rc;
507
508 if (jffs2_sum_active()) {
509 memset(&rr, 0xff, sizeof(rr));
510 rc = jffs2_flash_read(c, ref_offset(ref->node),
511 sizeof(struct jffs2_unknown_node),
512 &length, (char *)&rr);
513 if (rc || length != sizeof(struct jffs2_unknown_node)) {
514 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
515 rc, sizeof(struct jffs2_unknown_node),
516 length, ref_offset(ref->node));
517 }
518 rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
519 &length, (char *)&rr);
520 if (rc || length != sizeof(struct jffs2_raw_xref)) {
521 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu at %#08x\n",
522 rc, sizeof(rr), length, ref_offset(ref->node));
523 }
524 }
525 spin_lock(&c->erase_completion_lock);
526 ref->node->next_in_ino = NULL;
527 spin_unlock(&c->erase_completion_lock);
528 jffs2_mark_node_obsolete(c, ref->node);
529 ref->node = NULL;
530}
531
532static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
533{
534 /* must be called under down_write(xattr_sem) */
535 struct jffs2_xattr_datum *xd;
536
537 BUG_ON(!ref->node);
538 delete_xattr_ref_node(c, ref);
539
540 xd = ref->xd;
541 xd->refcnt--;
542 if (!xd->refcnt)
543 delete_xattr_datum(c, xd);
544 jffs2_free_xattr_ref(ref);
545}
546
547static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
548{
549 /* must be called under down_write(xattr_sem) */
550 struct jffs2_raw_node_ref *raw;
551 struct jffs2_raw_xref rr;
552 size_t length;
553 uint32_t phys_ofs = write_ofs(c);
554 int ret;
555
556 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
557 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
558 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
559 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
560
561 rr.ino = cpu_to_je32(ref->ic->ino);
562 rr.xid = cpu_to_je32(ref->xd->xid);
563 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
564
565 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
566 if (ret || sizeof(rr) != length) {
567 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
568 ret, sizeof(rr), length, phys_ofs);
569 ret = ret ? ret : -EIO;
570 if (length)
571 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
572
573 return ret;
574 }
575
576 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), NULL);
577 /* FIXME */ raw->next_in_ino = (void *)ref;
578 if (ref->node)
579 delete_xattr_ref_node(c, ref);
580 ref->node = raw;
581
582 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
583
584 return 0;
585}
586
587static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
588 struct jffs2_xattr_datum *xd)
589{
590 /* must be called under down_write(xattr_sem) */
591 struct jffs2_xattr_ref *ref;
592 int ret;
593
594 ref = jffs2_alloc_xattr_ref();
595 if (!ref)
596 return ERR_PTR(-ENOMEM);
597 ref->ic = ic;
598 ref->xd = xd;
599
600 ret = save_xattr_ref(c, ref);
601 if (ret) {
602 jffs2_free_xattr_ref(ref);
603 return ERR_PTR(ret);
604 }
605
606 /* Chain to inode */
607 ref->next = ic->xref;
608 ic->xref = ref;
609
610 return ref; /* success */
611}
612
613void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
614{
615 /* It's called from jffs2_clear_inode() on inode removing.
616 When an inode with XATTR is removed, those XATTRs must be removed. */
617 struct jffs2_xattr_ref *ref, *_ref;
618
619 if (!ic || ic->nlink > 0)
620 return;
621
622 down_write(&c->xattr_sem);
623 for (ref = ic->xref; ref; ref = _ref) {
624 _ref = ref->next;
625 delete_xattr_ref(c, ref);
626 }
627 ic->xref = NULL;
628 up_write(&c->xattr_sem);
629}
630
631void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
632{
633 /* It's called from jffs2_free_ino_caches() until unmounting FS. */
634 struct jffs2_xattr_datum *xd;
635 struct jffs2_xattr_ref *ref, *_ref;
636
637 down_write(&c->xattr_sem);
638 for (ref = ic->xref; ref; ref = _ref) {
639 _ref = ref->next;
640 xd = ref->xd;
641 xd->refcnt--;
642 if (!xd->refcnt) {
643 unload_xattr_datum(c, xd);
644 jffs2_free_xattr_datum(xd);
645 }
646 jffs2_free_xattr_ref(ref);
647 }
648 ic->xref = NULL;
649 up_write(&c->xattr_sem);
650}
651
652static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
653{
654 /* success of check_xattr_ref_inode() means taht inode (ic) dose not have
655 * duplicate name/value pairs. If duplicate name/value pair would be found,
656 * one will be removed.
657 */
658 struct jffs2_xattr_ref *ref, *cmp, **pref;
659 int rc = 0;
660
661 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
662 return 0;
663 down_write(&c->xattr_sem);
664 retry:
665 rc = 0;
666 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
667 if (!ref->xd->xname) {
668 rc = load_xattr_datum(c, ref->xd);
669 if (unlikely(rc > 0)) {
670 *pref = ref->next;
671 delete_xattr_ref(c, ref);
672 goto retry;
673 } else if (unlikely(rc < 0))
674 goto out;
675 }
676 for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) {
677 if (!cmp->xd->xname) {
678 ref->xd->flags |= JFFS2_XFLAGS_BIND;
679 rc = load_xattr_datum(c, cmp->xd);
680 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
681 if (unlikely(rc > 0)) {
682 *pref = cmp->next;
683 delete_xattr_ref(c, cmp);
684 goto retry;
685 } else if (unlikely(rc < 0))
686 goto out;
687 }
688 if (ref->xd->xprefix == cmp->xd->xprefix
689 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
690 *pref = cmp->next;
691 delete_xattr_ref(c, cmp);
692 goto retry;
693 }
694 }
695 }
696 ic->flags |= INO_FLAGS_XATTR_CHECKED;
697 out:
698 up_write(&c->xattr_sem);
699
700 return rc;
701}
702
703/* -------- xattr subsystem functions ---------------
704 * jffs2_init_xattr_subsystem(c)
705 * is used to initialize semaphore and list_head, and some variables.
706 * jffs2_find_xattr_datum(c, xid)
707 * is used to lookup xdatum while scanning process.
708 * jffs2_clear_xattr_subsystem(c)
709 * is used to release any xattr related objects.
710 * jffs2_build_xattr_subsystem(c)
711 * is used to associate xdatum and xref while super block building process.
712 * jffs2_setup_xattr_datum(c, xid, version)
713 * is used to insert xdatum while scanning process.
714 * -------------------------------------------------- */
715void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
716{
717 int i;
718
719 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
720 INIT_LIST_HEAD(&c->xattrindex[i]);
721 INIT_LIST_HEAD(&c->xattr_unchecked);
722 c->xref_temp = NULL;
723
724 init_rwsem(&c->xattr_sem);
725 c->xdatum_mem_usage = 0;
726 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */
727}
728
729static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
730{
731 struct jffs2_xattr_datum *xd;
732 int i = xid % XATTRINDEX_HASHSIZE;
733
734 /* It's only used in scanning/building process. */
735 BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
736
737 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
738 if (xd->xid==xid)
739 return xd;
740 }
741 return NULL;
742}
743
744void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
745{
746 struct jffs2_xattr_datum *xd, *_xd;
747 struct jffs2_xattr_ref *ref, *_ref;
748 int i;
749
750 for (ref=c->xref_temp; ref; ref = _ref) {
751 _ref = ref->next;
752 jffs2_free_xattr_ref(ref);
753 }
754 c->xref_temp = NULL;
755
756 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
758 list_del(&xd->xindex);
759 if (xd->xname)
760 kfree(xd->xname);
761 jffs2_free_xattr_datum(xd);
762 }
763 }
764}
765
766void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
767{
768 struct jffs2_xattr_ref *ref, *_ref;
769 struct jffs2_xattr_datum *xd, *_xd;
770 struct jffs2_inode_cache *ic;
771 int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0;
772
773 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
774
775 /* Phase.1 */
776 for (ref=c->xref_temp; ref; ref=_ref) {
777 _ref = ref->next;
778 /* checking REF_UNCHECKED nodes */
779 if (ref_flags(ref->node) != REF_PRISTINE) {
780 if (verify_xattr_ref(c, ref)) {
781 delete_xattr_ref_node(c, ref);
782 jffs2_free_xattr_ref(ref);
783 continue;
784 }
785 }
786 /* At this point, ref->xid and ref->ino contain XID and inode number.
787 ref->xd and ref->ic are not valid yet. */
788 xd = jffs2_find_xattr_datum(c, ref->xid);
789 ic = jffs2_get_ino_cache(c, ref->ino);
790 if (!xd || !ic) {
791 if (ref_flags(ref->node) != REF_UNCHECKED)
792 JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n",
793 ref->ino, ref->xid);
794 delete_xattr_ref_node(c, ref);
795 jffs2_free_xattr_ref(ref);
796 continue;
797 }
798 ref->xd = xd;
799 ref->ic = ic;
800 xd->refcnt++;
801 ref->next = ic->xref;
802 ic->xref = ref;
803 xref_count++;
804 }
805 c->xref_temp = NULL;
806 /* After this, ref->xid/ino are NEVER used. */
807
808 /* Phase.2 */
809 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
810 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
811 list_del_init(&xd->xindex);
812 if (!xd->refcnt) {
813 if (ref_flags(xd->node) != REF_UNCHECKED)
814 JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n",
815 xd->xid, xd->version, ref_offset(xd->node));
816 delete_xattr_datum(c, xd);
817 continue;
818 }
819 if (ref_flags(xd->node) != REF_PRISTINE) {
820 dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n",
821 xd->xid, ref_offset(xd->node));
822 list_add(&xd->xindex, &c->xattr_unchecked);
823 xdatum_unchecked_count++;
824 }
825 xdatum_count++;
826 }
827 }
828 /* build complete */
829 JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum (%u unchecked) and "
830 "%u of xref found.\n", xdatum_count, xdatum_unchecked_count, xref_count);
831}
832
833struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
834 uint32_t xid, uint32_t version)
835{
836 struct jffs2_xattr_datum *xd, *_xd;
837
838 _xd = jffs2_find_xattr_datum(c, xid);
839 if (_xd) {
840 dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n",
841 xid, version, _xd->version, ref_offset(_xd->node));
842 if (version < _xd->version)
843 return ERR_PTR(-EEXIST);
844 }
845 xd = jffs2_alloc_xattr_datum();
846 if (!xd)
847 return ERR_PTR(-ENOMEM);
848 xd->xid = xid;
849 xd->version = version;
850 if (xd->xid > c->highest_xid)
851 c->highest_xid = xd->xid;
852 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
853
854 if (_xd) {
855 list_del_init(&_xd->xindex);
856 delete_xattr_datum_node(c, _xd);
857 jffs2_free_xattr_datum(_xd);
858 }
859 return xd;
860}
861
862/* -------- xattr subsystem functions ---------------
863 * xprefix_to_handler(xprefix)
864 * is used to translate xprefix into xattr_handler.
865 * jffs2_listxattr(dentry, buffer, size)
866 * is an implementation of listxattr handler on jffs2.
867 * do_jffs2_getxattr(inode, xprefix, xname, buffer, size)
868 * is an implementation of getxattr handler on jffs2.
869 * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags)
870 * is an implementation of setxattr handler on jffs2.
871 * -------------------------------------------------- */
872struct xattr_handler *jffs2_xattr_handlers[] = {
873 &jffs2_user_xattr_handler,
874#ifdef CONFIG_JFFS2_FS_SECURITY
875 &jffs2_security_xattr_handler,
876#endif
877#ifdef CONFIG_JFFS2_FS_POSIX_ACL
878 &jffs2_acl_access_xattr_handler,
879 &jffs2_acl_default_xattr_handler,
880#endif
881 &jffs2_trusted_xattr_handler,
882 NULL
883};
884
885static struct xattr_handler *xprefix_to_handler(int xprefix) {
886 struct xattr_handler *ret;
887
888 switch (xprefix) {
889 case JFFS2_XPREFIX_USER:
890 ret = &jffs2_user_xattr_handler;
891 break;
892#ifdef CONFIG_JFFS2_FS_SECURITY
893 case JFFS2_XPREFIX_SECURITY:
894 ret = &jffs2_security_xattr_handler;
895 break;
896#endif
897#ifdef CONFIG_JFFS2_FS_POSIX_ACL
898 case JFFS2_XPREFIX_ACL_ACCESS:
899 ret = &jffs2_acl_access_xattr_handler;
900 break;
901 case JFFS2_XPREFIX_ACL_DEFAULT:
902 ret = &jffs2_acl_default_xattr_handler;
903 break;
904#endif
905 case JFFS2_XPREFIX_TRUSTED:
906 ret = &jffs2_trusted_xattr_handler;
907 break;
908 default:
909 ret = NULL;
910 break;
911 }
912 return ret;
913}
914
915ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
916{
917 struct inode *inode = dentry->d_inode;
918 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
919 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
920 struct jffs2_inode_cache *ic = f->inocache;
921 struct jffs2_xattr_ref *ref, **pref;
922 struct jffs2_xattr_datum *xd;
923 struct xattr_handler *xhandle;
924 ssize_t len, rc;
925 int retry = 0;
926
927 rc = check_xattr_ref_inode(c, ic);
928 if (unlikely(rc))
929 return rc;
930
931 down_read(&c->xattr_sem);
932 retry:
933 len = 0;
934 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
935 BUG_ON(ref->ic != ic);
936 xd = ref->xd;
937 if (!xd->xname) {
938 /* xdatum is unchached */
939 if (!retry) {
940 retry = 1;
941 up_read(&c->xattr_sem);
942 down_write(&c->xattr_sem);
943 goto retry;
944 } else {
945 rc = load_xattr_datum(c, xd);
946 if (unlikely(rc > 0)) {
947 *pref = ref->next;
948 delete_xattr_ref(c, ref);
949 goto retry;
950 } else if (unlikely(rc < 0))
951 goto out;
952 }
953 }
954 xhandle = xprefix_to_handler(xd->xprefix);
955 if (!xhandle)
956 continue;
957 if (buffer) {
958 rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
959 } else {
960 rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
961 }
962 if (rc < 0)
963 goto out;
964 len += rc;
965 }
966 rc = len;
967 out:
968 if (!retry) {
969 up_read(&c->xattr_sem);
970 } else {
971 up_write(&c->xattr_sem);
972 }
973 return rc;
974}
975
976int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
977 char *buffer, size_t size)
978{
979 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
980 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
981 struct jffs2_inode_cache *ic = f->inocache;
982 struct jffs2_xattr_datum *xd;
983 struct jffs2_xattr_ref *ref, **pref;
984 int rc, retry = 0;
985
986 rc = check_xattr_ref_inode(c, ic);
987 if (unlikely(rc))
988 return rc;
989
990 down_read(&c->xattr_sem);
991 retry:
992 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
993 BUG_ON(ref->ic!=ic);
994
995 xd = ref->xd;
996 if (xd->xprefix != xprefix)
997 continue;
998 if (!xd->xname) {
999 /* xdatum is unchached */
1000 if (!retry) {
1001 retry = 1;
1002 up_read(&c->xattr_sem);
1003 down_write(&c->xattr_sem);
1004 goto retry;
1005 } else {
1006 rc = load_xattr_datum(c, xd);
1007 if (unlikely(rc > 0)) {
1008 *pref = ref->next;
1009 delete_xattr_ref(c, ref);
1010 goto retry;
1011 } else if (unlikely(rc < 0)) {
1012 goto out;
1013 }
1014 }
1015 }
1016 if (!strcmp(xname, xd->xname)) {
1017 rc = xd->value_len;
1018 if (buffer) {
1019 if (size < rc) {
1020 rc = -ERANGE;
1021 } else {
1022 memcpy(buffer, xd->xvalue, rc);
1023 }
1024 }
1025 goto out;
1026 }
1027 }
1028 rc = -ENODATA;
1029 out:
1030 if (!retry) {
1031 up_read(&c->xattr_sem);
1032 } else {
1033 up_write(&c->xattr_sem);
1034 }
1035 return rc;
1036}
1037
1038int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1039 const char *buffer, size_t size, int flags)
1040{
1041 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1042 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1043 struct jffs2_inode_cache *ic = f->inocache;
1044 struct jffs2_xattr_datum *xd;
1045 struct jffs2_xattr_ref *ref, *newref, **pref;
1046 uint32_t length, request;
1047 int rc;
1048
1049 rc = check_xattr_ref_inode(c, ic);
1050 if (unlikely(rc))
1051 return rc;
1052
1053 request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
1054 rc = jffs2_reserve_space(c, request, &length,
1055 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
1056 if (rc) {
1057 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1058 return rc;
1059 }
1060
1061 /* Find existing xattr */
1062 down_write(&c->xattr_sem);
1063 retry:
1064 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1065 xd = ref->xd;
1066 if (xd->xprefix != xprefix)
1067 continue;
1068 if (!xd->xname) {
1069 rc = load_xattr_datum(c, xd);
1070 if (unlikely(rc > 0)) {
1071 *pref = ref->next;
1072 delete_xattr_ref(c, ref);
1073 goto retry;
1074 } else if (unlikely(rc < 0))
1075 goto out;
1076 }
1077 if (!strcmp(xd->xname, xname)) {
1078 if (flags & XATTR_CREATE) {
1079 rc = -EEXIST;
1080 goto out;
1081 }
1082 if (!buffer) {
1083 *pref = ref->next;
1084 delete_xattr_ref(c, ref);
1085 rc = 0;
1086 goto out;
1087 }
1088 goto found;
1089 }
1090 }
1091 /* not found */
1092 if (flags & XATTR_REPLACE) {
1093 rc = -ENODATA;
1094 goto out;
1095 }
1096 if (!buffer) {
1097 rc = -EINVAL;
1098 goto out;
1099 }
1100 found:
1101 xd = create_xattr_datum(c, xprefix, xname, buffer, size);
1102 if (IS_ERR(xd)) {
1103 rc = PTR_ERR(xd);
1104 goto out;
1105 }
1106 up_write(&c->xattr_sem);
1107 jffs2_complete_reservation(c);
1108
1109 /* create xattr_ref */
1110 request = PAD(sizeof(struct jffs2_raw_xref));
1111 rc = jffs2_reserve_space(c, request, &length,
1112 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1113 if (rc) {
1114 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1115 down_write(&c->xattr_sem);
1116 xd->refcnt--;
1117 if (!xd->refcnt)
1118 delete_xattr_datum(c, xd);
1119 up_write(&c->xattr_sem);
1120 return rc;
1121 }
1122 down_write(&c->xattr_sem);
1123 if (ref)
1124 *pref = ref->next;
1125 newref = create_xattr_ref(c, ic, xd);
1126 if (IS_ERR(newref)) {
1127 if (ref) {
1128 ref->next = ic->xref;
1129 ic->xref = ref;
1130 }
1131 rc = PTR_ERR(newref);
1132 xd->refcnt--;
1133 if (!xd->refcnt)
1134 delete_xattr_datum(c, xd);
1135 } else if (ref) {
1136 delete_xattr_ref(c, ref);
1137 }
1138 out:
1139 up_write(&c->xattr_sem);
1140 jffs2_complete_reservation(c);
1141 return rc;
1142}
1143
1144/* -------- garbage collector functions -------------
1145 * jffs2_garbage_collect_xattr_datum(c, xd)
1146 * is used to move xdatum into new node.
1147 * jffs2_garbage_collect_xattr_ref(c, ref)
1148 * is used to move xref into new node.
1149 * jffs2_verify_xattr(c)
1150 * is used to call do_verify_xattr_datum() before garbage collecting.
1151 * -------------------------------------------------- */
1152int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1153{
1154 uint32_t totlen, length, old_ofs;
1155 int rc = -EINVAL;
1156
1157 down_write(&c->xattr_sem);
1158 BUG_ON(!xd->node);
1159
1160 old_ofs = ref_offset(xd->node);
1161 totlen = ref_totlen(c, c->gcblock, xd->node);
1162 if (totlen < sizeof(struct jffs2_raw_xattr))
1163 goto out;
1164
1165 if (!xd->xname) {
1166 rc = load_xattr_datum(c, xd);
1167 if (unlikely(rc > 0)) {
1168 delete_xattr_datum_node(c, xd);
1169 rc = 0;
1170 goto out;
1171 } else if (unlikely(rc < 0))
1172 goto out;
1173 }
1174 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1175 if (rc || length < totlen) {
1176 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen);
1177 rc = rc ? rc : -EBADFD;
1178 goto out;
1179 }
1180 rc = save_xattr_datum(c, xd);
1181 if (!rc)
1182 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1183 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1184 out:
1185 up_write(&c->xattr_sem);
1186 return rc;
1187}
1188
1189
1190int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1191{
1192 uint32_t totlen, length, old_ofs;
1193 int rc = -EINVAL;
1194
1195 down_write(&c->xattr_sem);
1196 BUG_ON(!ref->node);
1197
1198 old_ofs = ref_offset(ref->node);
1199 totlen = ref_totlen(c, c->gcblock, ref->node);
1200 if (totlen != sizeof(struct jffs2_raw_xref))
1201 goto out;
1202
1203 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1204 if (rc || length < totlen) {
1205 JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n",
1206 __FUNCTION__, rc, totlen);
1207 rc = rc ? rc : -EBADFD;
1208 goto out;
1209 }
1210 rc = save_xattr_ref(c, ref);
1211 if (!rc)
1212 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1213 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1214 out:
1215 up_write(&c->xattr_sem);
1216 return rc;
1217}
1218
1219int jffs2_verify_xattr(struct jffs2_sb_info *c)
1220{
1221 struct jffs2_xattr_datum *xd, *_xd;
1222 int rc;
1223
1224 down_write(&c->xattr_sem);
1225 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1226 rc = do_verify_xattr_datum(c, xd);
1227 if (rc == 0) {
1228 list_del_init(&xd->xindex);
1229 break;
1230 } else if (rc > 0) {
1231 list_del_init(&xd->xindex);
1232 delete_xattr_datum_node(c, xd);
1233 }
1234 }
1235 up_write(&c->xattr_sem);
1236
1237 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1238}
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
new file mode 100644
index 000000000000..2c199856c582
--- /dev/null
+++ b/fs/jffs2/xattr.h
@@ -0,0 +1,116 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#ifndef _JFFS2_FS_XATTR_H_
12#define _JFFS2_FS_XATTR_H_
13
14#include <linux/xattr.h>
15#include <linux/list.h>
16
17#define JFFS2_XFLAGS_HOT (0x01) /* This datum is HOT */
18#define JFFS2_XFLAGS_BIND (0x02) /* This datum is not reclaimed */
19
20struct jffs2_xattr_datum
21{
22 void *always_null;
23 struct jffs2_raw_node_ref *node;
24 uint8_t class;
25 uint8_t flags;
26 uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */
27
28 struct list_head xindex; /* chained from c->xattrindex[n] */
29 uint32_t refcnt; /* # of xattr_ref refers this */
30 uint32_t xid;
31 uint32_t version;
32
33 uint32_t data_crc;
34 uint32_t hashkey;
35 char *xname; /* XATTR name without prefix */
36 uint32_t name_len; /* length of xname */
37 char *xvalue; /* XATTR value */
38 uint32_t value_len; /* length of xvalue */
39};
40
41struct jffs2_inode_cache;
42struct jffs2_xattr_ref
43{
44 void *always_null;
45 struct jffs2_raw_node_ref *node;
46 uint8_t class;
47 uint8_t flags; /* Currently unused */
48 u16 unused;
49
50 union {
51 struct jffs2_inode_cache *ic; /* reference to jffs2_inode_cache */
52 uint32_t ino; /* only used in scanning/building */
53 };
54 union {
55 struct jffs2_xattr_datum *xd; /* reference to jffs2_xattr_datum */
56 uint32_t xid; /* only used in sccanning/building */
57 };
58 struct jffs2_xattr_ref *next; /* chained from ic->xref_list */
59};
60
61#ifdef CONFIG_JFFS2_FS_XATTR
62
63extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
64extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
65extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
66
67extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
68 uint32_t xid, uint32_t version);
69
70extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
71extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
72
73extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd);
74extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref);
75extern int jffs2_verify_xattr(struct jffs2_sb_info *c);
76
77extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
78 char *buffer, size_t size);
79extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
80 const char *buffer, size_t size, int flags);
81
82extern struct xattr_handler *jffs2_xattr_handlers[];
83extern struct xattr_handler jffs2_user_xattr_handler;
84extern struct xattr_handler jffs2_trusted_xattr_handler;
85
86extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
87#define jffs2_getxattr generic_getxattr
88#define jffs2_setxattr generic_setxattr
89#define jffs2_removexattr generic_removexattr
90
91#else
92
93#define jffs2_init_xattr_subsystem(c)
94#define jffs2_build_xattr_subsystem(c)
95#define jffs2_clear_xattr_subsystem(c)
96
97#define jffs2_xattr_delete_inode(c, ic)
98#define jffs2_xattr_free_inode(c, ic)
99#define jffs2_verify_xattr(c) (1)
100
101#define jffs2_xattr_handlers NULL
102#define jffs2_listxattr NULL
103#define jffs2_getxattr NULL
104#define jffs2_setxattr NULL
105#define jffs2_removexattr NULL
106
107#endif /* CONFIG_JFFS2_FS_XATTR */
108
109#ifdef CONFIG_JFFS2_FS_SECURITY
110extern int jffs2_init_security(struct inode *inode, struct inode *dir);
111extern struct xattr_handler jffs2_security_xattr_handler;
112#else
113#define jffs2_init_security(inode,dir) (0)
114#endif /* CONFIG_JFFS2_FS_SECURITY */
115
116#endif /* _JFFS2_FS_XATTR_H_ */
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
new file mode 100644
index 000000000000..ed046e19dbfa
--- /dev/null
+++ b/fs/jffs2/xattr_trusted.c
@@ -0,0 +1,52 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/fs.h>
13#include <linux/jffs2.h>
14#include <linux/xattr.h>
15#include <linux/mtd/mtd.h>
16#include "nodelist.h"
17
18static int jffs2_trusted_getxattr(struct inode *inode, const char *name,
19 void *buffer, size_t size)
20{
21 if (!strcmp(name, ""))
22 return -EINVAL;
23 return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size);
24}
25
26static int jffs2_trusted_setxattr(struct inode *inode, const char *name, const void *buffer,
27 size_t size, int flags)
28{
29 if (!strcmp(name, ""))
30 return -EINVAL;
31 return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size, flags);
32}
33
34static size_t jffs2_trusted_listxattr(struct inode *inode, char *list, size_t list_size,
35 const char *name, size_t name_len)
36{
37 size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1;
38
39 if (list && retlen<=list_size) {
40 strcpy(list, XATTR_TRUSTED_PREFIX);
41 strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
42 }
43
44 return retlen;
45}
46
47struct xattr_handler jffs2_trusted_xattr_handler = {
48 .prefix = XATTR_TRUSTED_PREFIX,
49 .list = jffs2_trusted_listxattr,
50 .set = jffs2_trusted_setxattr,
51 .get = jffs2_trusted_getxattr
52};
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
new file mode 100644
index 000000000000..2f8e9aa01ea0
--- /dev/null
+++ b/fs/jffs2/xattr_user.c
@@ -0,0 +1,52 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2006 NEC Corporation
5 *
6 * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/fs.h>
13#include <linux/jffs2.h>
14#include <linux/xattr.h>
15#include <linux/mtd/mtd.h>
16#include "nodelist.h"
17
18static int jffs2_user_getxattr(struct inode *inode, const char *name,
19 void *buffer, size_t size)
20{
21 if (!strcmp(name, ""))
22 return -EINVAL;
23 return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size);
24}
25
26static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer,
27 size_t size, int flags)
28{
29 if (!strcmp(name, ""))
30 return -EINVAL;
31 return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size, flags);
32}
33
34static size_t jffs2_user_listxattr(struct inode *inode, char *list, size_t list_size,
35 const char *name, size_t name_len)
36{
37 size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
38
39 if (list && retlen <= list_size) {
40 strcpy(list, XATTR_USER_PREFIX);
41 strcpy(list + XATTR_USER_PREFIX_LEN, name);
42 }
43
44 return retlen;
45}
46
47struct xattr_handler jffs2_user_xattr_handler = {
48 .prefix = XATTR_USER_PREFIX,
49 .list = jffs2_user_listxattr,
50 .set = jffs2_user_setxattr,
51 .get = jffs2_user_getxattr
52};
diff --git a/fs/namei.c b/fs/namei.c
index d6e2ee251736..184fe4acf824 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1127,7 +1127,7 @@ out:
1127 if (likely(retval == 0)) { 1127 if (likely(retval == 0)) {
1128 if (unlikely(current->audit_context && nd && nd->dentry && 1128 if (unlikely(current->audit_context && nd && nd->dentry &&
1129 nd->dentry->d_inode)) 1129 nd->dentry->d_inode))
1130 audit_inode(name, nd->dentry->d_inode, flags); 1130 audit_inode(name, nd->dentry->d_inode);
1131 } 1131 }
1132out_fail: 1132out_fail:
1133 return retval; 1133 return retval;
diff --git a/fs/open.c b/fs/open.c
index 317b7c7f38a7..4f178acd4c09 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -633,7 +633,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
633 dentry = file->f_dentry; 633 dentry = file->f_dentry;
634 inode = dentry->d_inode; 634 inode = dentry->d_inode;
635 635
636 audit_inode(NULL, inode, 0); 636 audit_inode(NULL, inode);
637 637
638 err = -EROFS; 638 err = -EROFS;
639 if (IS_RDONLY(inode)) 639 if (IS_RDONLY(inode))
@@ -786,7 +786,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
786 if (file) { 786 if (file) {
787 struct dentry * dentry; 787 struct dentry * dentry;
788 dentry = file->f_dentry; 788 dentry = file->f_dentry;
789 audit_inode(NULL, dentry->d_inode, 0); 789 audit_inode(NULL, dentry->d_inode);
790 error = chown_common(dentry, user, group); 790 error = chown_common(dentry, user, group);
791 fput(file); 791 fput(file);
792 } 792 }
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6cc77dc3f3ff..6afff725a8c9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1019,8 +1019,8 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
1019 if (current != task) 1019 if (current != task)
1020 return -EPERM; 1020 return -EPERM;
1021 1021
1022 if (count > PAGE_SIZE) 1022 if (count >= PAGE_SIZE)
1023 count = PAGE_SIZE; 1023 count = PAGE_SIZE - 1;
1024 1024
1025 if (*ppos != 0) { 1025 if (*ppos != 0) {
1026 /* No partial writes. */ 1026 /* No partial writes. */
@@ -1033,6 +1033,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
1033 if (copy_from_user(page, buf, count)) 1033 if (copy_from_user(page, buf, count))
1034 goto out_free_page; 1034 goto out_free_page;
1035 1035
1036 page[count] = '\0';
1036 loginuid = simple_strtoul(page, &tmp, 10); 1037 loginuid = simple_strtoul(page, &tmp, 10);
1037 if (tmp == page) { 1038 if (tmp == page) {
1038 length = -EINVAL; 1039 length = -EINVAL;
diff --git a/fs/xattr.c b/fs/xattr.c
index e416190f5e9c..c32f15b5f60f 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -242,7 +242,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
242 if (!f) 242 if (!f)
243 return error; 243 return error;
244 dentry = f->f_dentry; 244 dentry = f->f_dentry;
245 audit_inode(NULL, dentry->d_inode, 0); 245 audit_inode(NULL, dentry->d_inode);
246 error = setxattr(dentry, name, value, size, flags); 246 error = setxattr(dentry, name, value, size, flags);
247 fput(f); 247 fput(f);
248 return error; 248 return error;
@@ -469,7 +469,7 @@ sys_fremovexattr(int fd, char __user *name)
469 if (!f) 469 if (!f)
470 return error; 470 return error;
471 dentry = f->f_dentry; 471 dentry = f->f_dentry;
472 audit_inode(NULL, dentry->d_inode, 0); 472 audit_inode(NULL, dentry->d_inode);
473 error = removexattr(dentry, name); 473 error = removexattr(dentry, name);
474 fput(f); 474 fput(f);
475 return error; 475 return error;
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 2e6d54569ee8..3c6a6205853a 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -49,7 +49,6 @@
49 49
50#ifdef __KERNEL__ 50#ifdef __KERNEL__
51 51
52#include <linux/config.h>
53#include <linux/string.h> 52#include <linux/string.h>
54#include <linux/kernel.h> 53#include <linux/kernel.h>
55#include <linux/ctype.h> 54#include <linux/ctype.h>
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index badf0277b1be..ef7d83a41470 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -2,7 +2,6 @@
2#define __ACPI_PROCESSOR_H 2#define __ACPI_PROCESSOR_H
3 3
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/config.h>
6 5
7#include <asm/acpi.h> 6#include <asm/acpi.h>
8 7
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 3f88715e811e..4b6ef7f21b93 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_BITOPS_H 1#ifndef _ALPHA_BITOPS_H
2#define _ALPHA_BITOPS_H 2#define _ALPHA_BITOPS_H
3 3
4#include <linux/config.h>
5#include <asm/compiler.h> 4#include <asm/compiler.h>
6 5
7/* 6/*
diff --git a/include/asm-alpha/cache.h b/include/asm-alpha/cache.h
index e6d4d1695e25..f199e69a5d0b 100644
--- a/include/asm-alpha/cache.h
+++ b/include/asm-alpha/cache.h
@@ -4,7 +4,6 @@
4#ifndef __ARCH_ALPHA_CACHE_H 4#ifndef __ARCH_ALPHA_CACHE_H
5#define __ARCH_ALPHA_CACHE_H 5#define __ARCH_ALPHA_CACHE_H
6 6
7#include <linux/config.h>
8 7
9/* Bytes per L1 (data) cache line. */ 8/* Bytes per L1 (data) cache line. */
10#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6) 9#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
diff --git a/include/asm-alpha/cacheflush.h b/include/asm-alpha/cacheflush.h
index 3fc6ef726d8c..805640b41078 100644
--- a/include/asm-alpha/cacheflush.h
+++ b/include/asm-alpha/cacheflush.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_CACHEFLUSH_H 1#ifndef _ALPHA_CACHEFLUSH_H
2#define _ALPHA_CACHEFLUSH_H 2#define _ALPHA_CACHEFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6 5
7/* Caches aren't brain-dead on the Alpha. */ 6/* Caches aren't brain-dead on the Alpha. */
diff --git a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h
index 3a70d68bfce8..9e0516c0ca27 100644
--- a/include/asm-alpha/core_cia.h
+++ b/include/asm-alpha/core_cia.h
@@ -4,7 +4,6 @@
4/* Define to experiment with fitting everything into one 512MB HAE window. */ 4/* Define to experiment with fitting everything into one 512MB HAE window. */
5#define CIA_ONE_HAE_WINDOW 1 5#define CIA_ONE_HAE_WINDOW 1
6 6
7#include <linux/config.h>
8#include <linux/types.h> 7#include <linux/types.h>
9#include <asm/compiler.h> 8#include <asm/compiler.h>
10 9
diff --git a/include/asm-alpha/core_t2.h b/include/asm-alpha/core_t2.h
index 5c1c40338c82..dba70c62a16c 100644
--- a/include/asm-alpha/core_t2.h
+++ b/include/asm-alpha/core_t2.h
@@ -1,7 +1,6 @@
1#ifndef __ALPHA_T2__H__ 1#ifndef __ALPHA_T2__H__
2#define __ALPHA_T2__H__ 2#define __ALPHA_T2__H__
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6#include <linux/spinlock.h> 5#include <linux/spinlock.h>
7#include <asm/compiler.h> 6#include <asm/compiler.h>
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 62d0d6681aa9..b9ff4d8cb33a 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_DMA_MAPPING_H 1#ifndef _ALPHA_DMA_MAPPING_H
2#define _ALPHA_DMA_MAPPING_H 2#define _ALPHA_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7 6
diff --git a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h
index 683afaa3deed..87cfdbdf08fc 100644
--- a/include/asm-alpha/dma.h
+++ b/include/asm-alpha/dma.h
@@ -18,7 +18,6 @@
18#ifndef _ASM_DMA_H 18#ifndef _ASM_DMA_H
19#define _ASM_DMA_H 19#define _ASM_DMA_H
20 20
21#include <linux/config.h>
22#include <linux/spinlock.h> 21#include <linux/spinlock.h>
23#include <asm/io.h> 22#include <asm/io.h>
24 23
diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h
index 289a00d51a90..e177d4180f83 100644
--- a/include/asm-alpha/floppy.h
+++ b/include/asm-alpha/floppy.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_ALPHA_FLOPPY_H 10#ifndef __ASM_ALPHA_FLOPPY_H
11#define __ASM_ALPHA_FLOPPY_H 11#define __ASM_ALPHA_FLOPPY_H
12 12
13#include <linux/config.h>
14 13
15#define fd_inb(port) inb_p(port) 14#define fd_inb(port) inb_p(port)
16#define fd_outb(value,port) outb_p(value,port) 15#define fd_outb(value,port) outb_p(value,port)
diff --git a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
index 7bb6a36c96a1..d953e234daa8 100644
--- a/include/asm-alpha/hardirq.h
+++ b/include/asm-alpha/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_HARDIRQ_H 1#ifndef _ALPHA_HARDIRQ_H
2#define _ALPHA_HARDIRQ_H 2#define _ALPHA_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/cache.h> 5#include <linux/cache.h>
7 6
diff --git a/include/asm-alpha/hw_irq.h b/include/asm-alpha/hw_irq.h
index a310b9efc906..ca9d43b63502 100644
--- a/include/asm-alpha/hw_irq.h
+++ b/include/asm-alpha/hw_irq.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_HW_IRQ_H 1#ifndef _ALPHA_HW_IRQ_H
2#define _ALPHA_HW_IRQ_H 2#define _ALPHA_HW_IRQ_H
3 3
4#include <linux/config.h>
5 4
6static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} 5static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
7 6
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 6126afe27380..2a5cc0b367ab 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17 16
18#define IDE_ARCH_OBSOLETE_DEFAULTS 17#define IDE_ARCH_OBSOLETE_DEFAULTS
19 18
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index 3ebbeee753e9..f5ae98c25d1f 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7#include <linux/kernel.h> 6#include <linux/kernel.h>
8#include <asm/compiler.h> 7#include <asm/compiler.h>
9#include <asm/system.h> 8#include <asm/system.h>
diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h
index 566db720000a..f6de033718a0 100644
--- a/include/asm-alpha/irq.h
+++ b/include/asm-alpha/irq.h
@@ -8,7 +8,6 @@
8 */ 8 */
9 9
10#include <linux/linkage.h> 10#include <linux/linkage.h>
11#include <linux/config.h>
12 11
13#if defined(CONFIG_ALPHA_GENERIC) 12#if defined(CONFIG_ALPHA_GENERIC)
14 13
diff --git a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h
index 3d10cd3ea75f..3e6735a34c57 100644
--- a/include/asm-alpha/kmap_types.h
+++ b/include/asm-alpha/kmap_types.h
@@ -3,7 +3,6 @@
3 3
4/* Dummy header just to define km_type. */ 4/* Dummy header just to define km_type. */
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_DEBUG_HIGHMEM 7#ifdef CONFIG_DEBUG_HIGHMEM
9# define D(n) __KM_FENCE_##n , 8# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-alpha/machvec.h b/include/asm-alpha/machvec.h
index ece166a203ec..aced22f91752 100644
--- a/include/asm-alpha/machvec.h
+++ b/include/asm-alpha/machvec.h
@@ -1,7 +1,6 @@
1#ifndef __ALPHA_MACHVEC_H 1#ifndef __ALPHA_MACHVEC_H
2#define __ALPHA_MACHVEC_H 1 2#define __ALPHA_MACHVEC_H 1
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7/* 6/*
diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h
index 0c017fc181c1..fe249e9d3360 100644
--- a/include/asm-alpha/mmu_context.h
+++ b/include/asm-alpha/mmu_context.h
@@ -7,7 +7,6 @@
7 * Copyright (C) 1996, Linus Torvalds 7 * Copyright (C) 1996, Linus Torvalds
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <asm/system.h> 10#include <asm/system.h>
12#include <asm/machvec.h> 11#include <asm/machvec.h>
13#include <asm/compiler.h> 12#include <asm/compiler.h>
diff --git a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
index 192d80c875b0..64d0ab98fcd8 100644
--- a/include/asm-alpha/mmzone.h
+++ b/include/asm-alpha/mmzone.h
@@ -5,7 +5,6 @@
5#ifndef _ASM_MMZONE_H_ 5#ifndef _ASM_MMZONE_H_
6#define _ASM_MMZONE_H_ 6#define _ASM_MMZONE_H_
7 7
8#include <linux/config.h>
9#include <asm/smp.h> 8#include <asm/smp.h>
10 9
11struct bootmem_data_t; /* stupid forward decl. */ 10struct bootmem_data_t; /* stupid forward decl. */
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h
index 61bcf70b5eac..8c7cd50d4eae 100644
--- a/include/asm-alpha/page.h
+++ b/include/asm-alpha/page.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_PAGE_H 1#ifndef _ALPHA_PAGE_H
2#define _ALPHA_PAGE_H 2#define _ALPHA_PAGE_H
3 3
4#include <linux/config.h>
5#include <asm/pal.h> 4#include <asm/pal.h>
6 5
7/* PAGE_SHIFT determines the page size */ 6/* PAGE_SHIFT determines the page size */
diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h
index 3ed0b3b02e52..214e7996346f 100644
--- a/include/asm-alpha/param.h
+++ b/include/asm-alpha/param.h
@@ -5,7 +5,6 @@
5 hardware ignores reprogramming. We also need userland buy-in to the 5 hardware ignores reprogramming. We also need userland buy-in to the
6 change in HZ, since this is visible in the wait4 resources etc. */ 6 change in HZ, since this is visible in the wait4 resources etc. */
7 7
8#include <linux/config.h>
9 8
10#ifndef HZ 9#ifndef HZ
11# ifndef CONFIG_ALPHA_RAWHIDE 10# ifndef CONFIG_ALPHA_RAWHIDE
diff --git a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h
index 308475642913..471864e8d4c3 100644
--- a/include/asm-alpha/pgalloc.h
+++ b/include/asm-alpha/pgalloc.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_PGALLOC_H 1#ifndef _ALPHA_PGALLOC_H
2#define _ALPHA_PGALLOC_H 2#define _ALPHA_PGALLOC_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <linux/mmzone.h> 5#include <linux/mmzone.h>
7 6
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index a985cd29b6db..93eaa58b7961 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -10,7 +10,6 @@
10 * This hopefully works with any standard Alpha page-size, as defined 10 * This hopefully works with any standard Alpha page-size, as defined
11 * in <asm/page.h> (currently 8192). 11 * in <asm/page.h> (currently 8192).
12 */ 12 */
13#include <linux/config.h>
14#include <linux/mmzone.h> 13#include <linux/mmzone.h>
15 14
16#include <asm/page.h> 15#include <asm/page.h>
diff --git a/include/asm-alpha/serial.h b/include/asm-alpha/serial.h
index 7e4b2987d453..9d263e8d8ccc 100644
--- a/include/asm-alpha/serial.h
+++ b/include/asm-alpha/serial.h
@@ -2,7 +2,6 @@
2 * include/asm-alpha/serial.h 2 * include/asm-alpha/serial.h
3 */ 3 */
4 4
5#include <linux/config.h>
6 5
7/* 6/*
8 * This assumes you have a 1.8432 MHz clock for your UART. 7 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
index e1432102be05..a1a1eca6be45 100644
--- a/include/asm-alpha/smp.h
+++ b/include/asm-alpha/smp.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SMP_H 1#ifndef __ASM_SMP_H
2#define __ASM_SMP_H 2#define __ASM_SMP_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/cpumask.h> 5#include <linux/cpumask.h>
7#include <linux/bitops.h> 6#include <linux/bitops.h>
diff --git a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
index 8197c69eff44..0c294c9b0c55 100644
--- a/include/asm-alpha/spinlock.h
+++ b/include/asm-alpha/spinlock.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_SPINLOCK_H 1#ifndef _ALPHA_SPINLOCK_H
2#define _ALPHA_SPINLOCK_H 2#define _ALPHA_SPINLOCK_H
3 3
4#include <linux/config.h>
5#include <asm/system.h> 4#include <asm/system.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <asm/current.h> 6#include <asm/current.h>
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index f3b7b1a59c56..03e9c0e5ed74 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -1,7 +1,6 @@
1#ifndef __ALPHA_SYSTEM_H 1#ifndef __ALPHA_SYSTEM_H
2#define __ALPHA_SYSTEM_H 2#define __ALPHA_SYSTEM_H
3 3
4#include <linux/config.h>
5#include <asm/pal.h> 4#include <asm/pal.h>
6#include <asm/page.h> 5#include <asm/page.h>
7#include <asm/barrier.h> 6#include <asm/barrier.h>
diff --git a/include/asm-alpha/tlbflush.h b/include/asm-alpha/tlbflush.h
index 9d484c1fdc82..1ca3ed3bd6d3 100644
--- a/include/asm-alpha/tlbflush.h
+++ b/include/asm-alpha/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _ALPHA_TLBFLUSH_H 1#ifndef _ALPHA_TLBFLUSH_H
2#define _ALPHA_TLBFLUSH_H 2#define _ALPHA_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/compiler.h> 5#include <asm/compiler.h>
7 6
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index ef25b6585119..bc6e6a9259dc 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -383,6 +383,8 @@
383#define __NR_inotify_add_watch 445 383#define __NR_inotify_add_watch 445
384#define __NR_inotify_rm_watch 446 384#define __NR_inotify_rm_watch 446
385 385
386#ifdef __KERNEL__
387
386#define NR_SYSCALLS 447 388#define NR_SYSCALLS 447
387 389
388#if defined(__GNUC__) 390#if defined(__GNUC__)
@@ -565,9 +567,8 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
565 _syscall_return(type); \ 567 _syscall_return(type); \
566} 568}
567 569
568#endif /* __LIBRARY__ && __GNUC__ */ 570#endif /* __GNUC__ */
569 571
570#ifdef __KERNEL__
571#define __ARCH_WANT_IPC_PARSE_VERSION 572#define __ARCH_WANT_IPC_PARSE_VERSION
572#define __ARCH_WANT_OLD_READDIR 573#define __ARCH_WANT_OLD_READDIR
573#define __ARCH_WANT_STAT64 574#define __ARCH_WANT_STAT64
@@ -578,7 +579,6 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
578#define __ARCH_WANT_SYS_OLD_GETRLIMIT 579#define __ARCH_WANT_SYS_OLD_GETRLIMIT
579#define __ARCH_WANT_SYS_OLDUMOUNT 580#define __ARCH_WANT_SYS_OLDUMOUNT
580#define __ARCH_WANT_SYS_SIGPENDING 581#define __ARCH_WANT_SYS_SIGPENDING
581#endif
582 582
583#ifdef __KERNEL_SYSCALLS__ 583#ifdef __KERNEL_SYSCALLS__
584 584
@@ -661,4 +661,5 @@ asmlinkage long sys_rt_sigaction(int sig,
661 661
662#define cond_syscall(x) asm(".weak\t" #x "\n" #x " = sys_ni_syscall") 662#define cond_syscall(x) asm(".weak\t" #x "\n" #x " = sys_ni_syscall")
663 663
664#endif /* __KERNEL__ */
664#endif /* _ALPHA_UNISTD_H */ 665#endif /* _ALPHA_UNISTD_H */
diff --git a/include/asm-arm/apm.h b/include/asm-arm/apm.h
index 3a50eb759c28..d09113b37e4a 100644
--- a/include/asm-arm/apm.h
+++ b/include/asm-arm/apm.h
@@ -13,7 +13,6 @@
13#ifndef ARM_ASM_SA1100_APM_H 13#ifndef ARM_ASM_SA1100_APM_H
14#define ARM_ASM_SA1100_APM_H 14#define ARM_ASM_SA1100_APM_H
15 15
16#include <linux/config.h>
17#include <linux/apm_bios.h> 16#include <linux/apm_bios.h>
18 17
19/* 18/*
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
index d8209f8911d6..24b51cccde8f 100644
--- a/include/asm-arm/arch-aaec2000/memory.h
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_ARCH_MEMORY_H 11#ifndef __ASM_ARCH_MEMORY_H
12#define __ASM_ARCH_MEMORY_H 12#define __ASM_ARCH_MEMORY_H
13 13
14#include <linux/config.h>
15 14
16#define PHYS_OFFSET UL(0xf0000000) 15#define PHYS_OFFSET UL(0xf0000000)
17 16
diff --git a/include/asm-arm/arch-cl7500/acornfb.h b/include/asm-arm/arch-cl7500/acornfb.h
index 3867231a4470..aea6330c9745 100644
--- a/include/asm-arm/arch-cl7500/acornfb.h
+++ b/include/asm-arm/arch-cl7500/acornfb.h
@@ -1,4 +1,3 @@
1#include <linux/config.h>
2#define acornfb_valid_pixrate(var) (var->pixclock >= 39325 && var->pixclock <= 40119) 1#define acornfb_valid_pixrate(var) (var->pixclock >= 39325 && var->pixclock <= 40119)
3 2
4static inline void 3static inline void
diff --git a/include/asm-arm/arch-clps711x/hardware.h b/include/asm-arm/arch-clps711x/hardware.h
index 1386871e1a5a..0fdbe72fff2a 100644
--- a/include/asm-arm/arch-clps711x/hardware.h
+++ b/include/asm-arm/arch-clps711x/hardware.h
@@ -22,7 +22,6 @@
22#ifndef __ASM_ARCH_HARDWARE_H 22#ifndef __ASM_ARCH_HARDWARE_H
23#define __ASM_ARCH_HARDWARE_H 23#define __ASM_ARCH_HARDWARE_H
24 24
25#include <linux/config.h>
26 25
27#define CLPS7111_VIRT_BASE 0xff000000 26#define CLPS7111_VIRT_BASE 0xff000000
28#define CLPS7111_BASE CLPS7111_VIRT_BASE 27#define CLPS7111_BASE CLPS7111_VIRT_BASE
diff --git a/include/asm-arm/arch-clps711x/memory.h b/include/asm-arm/arch-clps711x/memory.h
index 61d8717406ce..c6e8dcf674de 100644
--- a/include/asm-arm/arch-clps711x/memory.h
+++ b/include/asm-arm/arch-clps711x/memory.h
@@ -20,7 +20,6 @@
20#ifndef __ASM_ARCH_MEMORY_H 20#ifndef __ASM_ARCH_MEMORY_H
21#define __ASM_ARCH_MEMORY_H 21#define __ASM_ARCH_MEMORY_H
22 22
23#include <linux/config.h>
24 23
25/* 24/*
26 * Physical DRAM offset. 25 * Physical DRAM offset.
diff --git a/include/asm-arm/arch-clps711x/uncompress.h b/include/asm-arm/arch-clps711x/uncompress.h
index 07157b7e4b20..03d233ae87ce 100644
--- a/include/asm-arm/arch-clps711x/uncompress.h
+++ b/include/asm-arm/arch-clps711x/uncompress.h
@@ -17,7 +17,6 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#include <linux/config.h>
21#include <asm/arch/io.h> 20#include <asm/arch/io.h>
22#include <asm/hardware.h> 21#include <asm/hardware.h>
23#include <asm/hardware/clps7111.h> 22#include <asm/hardware/clps7111.h>
diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h
index ec51fe92483b..daad8ee2d194 100644
--- a/include/asm-arm/arch-ebsa285/hardware.h
+++ b/include/asm-arm/arch-ebsa285/hardware.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_ARCH_HARDWARE_H 12#ifndef __ASM_ARCH_HARDWARE_H
13#define __ASM_ARCH_HARDWARE_H 13#define __ASM_ARCH_HARDWARE_H
14 14
15#include <linux/config.h>
16#include <asm/arch/memory.h> 15#include <asm/arch/memory.h>
17 16
18#ifdef CONFIG_ARCH_FOOTBRIDGE 17#ifdef CONFIG_ARCH_FOOTBRIDGE
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
index 99181ffc7e27..cbd7ae64bcc9 100644
--- a/include/asm-arm/arch-ebsa285/memory.h
+++ b/include/asm-arm/arch-ebsa285/memory.h
@@ -19,7 +19,6 @@
19#ifndef __ASM_ARCH_MEMORY_H 19#ifndef __ASM_ARCH_MEMORY_H
20#define __ASM_ARCH_MEMORY_H 20#define __ASM_ARCH_MEMORY_H
21 21
22#include <linux/config.h>
23 22
24#if defined(CONFIG_FOOTBRIDGE_ADDIN) 23#if defined(CONFIG_FOOTBRIDGE_ADDIN)
25/* 24/*
diff --git a/include/asm-arm/arch-ebsa285/vmalloc.h b/include/asm-arm/arch-ebsa285/vmalloc.h
index d1ca955ce434..02598200997d 100644
--- a/include/asm-arm/arch-ebsa285/vmalloc.h
+++ b/include/asm-arm/arch-ebsa285/vmalloc.h
@@ -6,7 +6,6 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#ifdef CONFIG_ARCH_FOOTBRIDGE 10#ifdef CONFIG_ARCH_FOOTBRIDGE
12#define VMALLOC_END (PAGE_OFFSET + 0x30000000) 11#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
diff --git a/include/asm-arm/arch-integrator/smp.h b/include/asm-arm/arch-integrator/smp.h
index da6981efdc39..ab2c79bb9505 100644
--- a/include/asm-arm/arch-integrator/smp.h
+++ b/include/asm-arm/arch-integrator/smp.h
@@ -1,7 +1,6 @@
1#ifndef ASMARM_ARCH_SMP_H 1#ifndef ASMARM_ARCH_SMP_H
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <linux/config.h>
5 4
6#include <asm/hardware.h> 5#include <asm/hardware.h>
7#include <asm/io.h> 6#include <asm/io.h>
diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
index bc62f4b13235..e43ebd984745 100644
--- a/include/asm-arm/arch-iop3xx/memory.h
+++ b/include/asm-arm/arch-iop3xx/memory.h
@@ -5,7 +5,6 @@
5#ifndef __ASM_ARCH_MEMORY_H 5#ifndef __ASM_ARCH_MEMORY_H
6#define __ASM_ARCH_MEMORY_H 6#define __ASM_ARCH_MEMORY_H
7 7
8#include <linux/config.h>
9#include <asm/hardware.h> 8#include <asm/hardware.h>
10 9
11/* 10/*
diff --git a/include/asm-arm/arch-iop3xx/timex.h b/include/asm-arm/arch-iop3xx/timex.h
index 472badb451c4..14ca8d0f7b29 100644
--- a/include/asm-arm/arch-iop3xx/timex.h
+++ b/include/asm-arm/arch-iop3xx/timex.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * IOP3xx architecture timex specifications 4 * IOP3xx architecture timex specifications
5 */ 5 */
6#include <linux/config.h>
7#include <asm/hardware.h> 6#include <asm/hardware.h>
8 7
9#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244) 8#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
diff --git a/include/asm-arm/arch-iop3xx/uncompress.h b/include/asm-arm/arch-iop3xx/uncompress.h
index c98eb6254b1f..fbdd5af644fe 100644
--- a/include/asm-arm/arch-iop3xx/uncompress.h
+++ b/include/asm-arm/arch-iop3xx/uncompress.h
@@ -1,7 +1,6 @@
1/* 1/*
2 * linux/include/asm-arm/arch-iop3xx/uncompress.h 2 * linux/include/asm-arm/arch-iop3xx/uncompress.h
3 */ 3 */
4#include <linux/config.h>
5#include <asm/types.h> 4#include <asm/types.h>
6#include <asm/mach-types.h> 5#include <asm/mach-types.h>
7#include <linux/serial_reg.h> 6#include <linux/serial_reg.h>
diff --git a/include/asm-arm/arch-ixp4xx/dma.h b/include/asm-arm/arch-ixp4xx/dma.h
index b1a071ecebc8..789f7f53c357 100644
--- a/include/asm-arm/arch-ixp4xx/dma.h
+++ b/include/asm-arm/arch-ixp4xx/dma.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_ARCH_DMA_H 11#ifndef __ASM_ARCH_DMA_H
12#define __ASM_ARCH_DMA_H 12#define __ASM_ARCH_DMA_H
13 13
14#include <linux/config.h>
15#include <linux/device.h> 14#include <linux/device.h>
16#include <linux/pci.h> 15#include <linux/pci.h>
17#include <asm/page.h> 16#include <asm/page.h>
diff --git a/include/asm-arm/arch-lh7a40x/clocks.h b/include/asm-arm/arch-lh7a40x/clocks.h
new file mode 100644
index 000000000000..bee02fd8dab1
--- /dev/null
+++ b/include/asm-arm/arch-lh7a40x/clocks.h
@@ -0,0 +1,20 @@
1/* include/asm-arm/arch-lh7a40x/clocks.h
2 *
3 * Copyright (C) 2004 Marc Singer
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/config.h>
12
13#ifndef __ASM_ARCH_CLOCKS_H
14#define __ASM_ARCH_CLOCKS_H
15
16unsigned int fclkfreq_get (void);
17unsigned int hclkfreq_get (void);
18unsigned int pclkfreq_get (void);
19
20#endif /* _ASM_ARCH_CLOCKS_H */
diff --git a/include/asm-arm/arch-lh7a40x/constants.h b/include/asm-arm/arch-lh7a40x/constants.h
index 52c1cb9c39c6..51de96e87faf 100644
--- a/include/asm-arm/arch-lh7a40x/constants.h
+++ b/include/asm-arm/arch-lh7a40x/constants.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_ARCH_CONSTANTS_H 12#ifndef __ASM_ARCH_CONSTANTS_H
13#define __ASM_ARCH_CONSTANTS_H 13#define __ASM_ARCH_CONSTANTS_H
14 14
15#include <linux/config.h>
16 15
17/* Addressing constants */ 16/* Addressing constants */
18 17
@@ -29,8 +28,7 @@
29 28
30#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) 29#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
31 30
32# define IOBARRIER_PHYS 0xc0000000 /* Start of SDRAM */ 31# define IOBARRIER_PHYS 0x10000000 /* Second bank, fastest timing */
33/*# define IOBARRIER_PHYS 0x00000000 */ /* Start of flash */
34# define IOBARRIER_VIRT 0xf0000000 32# define IOBARRIER_VIRT 0xf0000000
35# define IOBARRIER_SIZE PAGE_SIZE 33# define IOBARRIER_SIZE PAGE_SIZE
36 34
@@ -53,6 +51,9 @@
53# define CPLD08_PHYS CPLDX_PHYS (0x08) 51# define CPLD08_PHYS CPLDX_PHYS (0x08)
54# define CPLD08_VIRT CPLDX_VIRT (0x08) 52# define CPLD08_VIRT CPLDX_VIRT (0x08)
55# define CPLD08_SIZE PAGE_SIZE 53# define CPLD08_SIZE PAGE_SIZE
54# define CPLD0A_PHYS CPLDX_PHYS (0x0a)
55# define CPLD0A_VIRT CPLDX_VIRT (0x0a)
56# define CPLD0A_SIZE PAGE_SIZE
56# define CPLD0C_PHYS CPLDX_PHYS (0x0c) 57# define CPLD0C_PHYS CPLDX_PHYS (0x0c)
57# define CPLD0C_VIRT CPLDX_VIRT (0x0c) 58# define CPLD0C_VIRT CPLDX_VIRT (0x0c)
58# define CPLD0C_SIZE PAGE_SIZE 59# define CPLD0C_SIZE PAGE_SIZE
@@ -84,5 +85,7 @@
84#define XTAL_IN 14745600 /* 14.7456 MHz crystal */ 85#define XTAL_IN 14745600 /* 14.7456 MHz crystal */
85#define PLL_CLOCK (XTAL_IN * 21) /* 309 MHz PLL clock */ 86#define PLL_CLOCK (XTAL_IN * 21) /* 309 MHz PLL clock */
86#define MAX_HCLK_KHZ 100000 /* HCLK max limit ~100MHz */ 87#define MAX_HCLK_KHZ 100000 /* HCLK max limit ~100MHz */
88#define HCLK (99993600)
89//#define HCLK (119808000)
87 90
88#endif /* __ASM_ARCH_CONSTANTS_H */ 91#endif /* __ASM_ARCH_CONSTANTS_H */
diff --git a/include/asm-arm/arch-lh7a40x/dma.h b/include/asm-arm/arch-lh7a40x/dma.h
index 15492e3253f6..a8cbd14bbf9d 100644
--- a/include/asm-arm/arch-lh7a40x/dma.h
+++ b/include/asm-arm/arch-lh7a40x/dma.h
@@ -1,9 +1,86 @@
1/* include/asm-arm/arch-lh7a40x/dma.h 1/* include/asm-arm/arch-lh7a40x/dma.h
2 * 2 *
3 * Copyright (C) 2003 Coastal Environmental Systems 3 * Copyright (C) 2005 Marc Singer
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation. 7 * version 2 as published by the Free Software Foundation.
8 * 8 *
9 */ 9 */
10
11typedef enum {
12 DMA_M2M0 = 0,
13 DMA_M2M1 = 1,
14 DMA_M2P0 = 2, /* Tx */
15 DMA_M2P1 = 3, /* Rx */
16 DMA_M2P2 = 4, /* Tx */
17 DMA_M2P3 = 5, /* Rx */
18 DMA_M2P4 = 6, /* Tx - AC97 */
19 DMA_M2P5 = 7, /* Rx - AC97 */
20 DMA_M2P6 = 8, /* Tx */
21 DMA_M2P7 = 9, /* Rx */
22} dma_device_t;
23
24#define DMA_LENGTH_MAX ((64*1024) - 4) /* bytes */
25
26#define DMAC_GCA __REG(DMAC_PHYS + 0x2b80)
27#define DMAC_GIR __REG(DMAC_PHYS + 0x2bc0)
28
29#define DMAC_GIR_MMI1 (1<<11)
30#define DMAC_GIR_MMI0 (1<<10)
31#define DMAC_GIR_MPI8 (1<<9)
32#define DMAC_GIR_MPI9 (1<<8)
33#define DMAC_GIR_MPI6 (1<<7)
34#define DMAC_GIR_MPI7 (1<<6)
35#define DMAC_GIR_MPI4 (1<<5)
36#define DMAC_GIR_MPI5 (1<<4)
37#define DMAC_GIR_MPI2 (1<<3)
38#define DMAC_GIR_MPI3 (1<<2)
39#define DMAC_GIR_MPI0 (1<<1)
40#define DMAC_GIR_MPI1 (1<<0)
41
42#define DMAC_M2P0 0x0000
43#define DMAC_M2P1 0x0040
44#define DMAC_M2P2 0x0080
45#define DMAC_M2P3 0x00c0
46#define DMAC_M2P4 0x0240
47#define DMAC_M2P5 0x0200
48#define DMAC_M2P6 0x02c0
49#define DMAC_M2P7 0x0280
50#define DMAC_M2P8 0x0340
51#define DMAC_M2P9 0x0300
52#define DMAC_M2M0 0x0100
53#define DMAC_M2M1 0x0140
54
55#define DMAC_P_PCONTROL(c) __REG(DMAC_PHYS + (c) + 0x00)
56#define DMAC_P_PINTERRUPT(c) __REG(DMAC_PHYS + (c) + 0x04)
57#define DMAC_P_PPALLOC(c) __REG(DMAC_PHYS + (c) + 0x08)
58#define DMAC_P_PSTATUS(c) __REG(DMAC_PHYS + (c) + 0x0c)
59#define DMAC_P_REMAIN(c) __REG(DMAC_PHYS + (c) + 0x14)
60#define DMAC_P_MAXCNT0(c) __REG(DMAC_PHYS + (c) + 0x20)
61#define DMAC_P_BASE0(c) __REG(DMAC_PHYS + (c) + 0x24)
62#define DMAC_P_CURRENT0(c) __REG(DMAC_PHYS + (c) + 0x28)
63#define DMAC_P_MAXCNT1(c) __REG(DMAC_PHYS + (c) + 0x30)
64#define DMAC_P_BASE1(c) __REG(DMAC_PHYS + (c) + 0x34)
65#define DMAC_P_CURRENT1(c) __REG(DMAC_PHYS + (c) + 0x38)
66
67#define DMAC_PCONTROL_ENABLE (1<<4)
68
69#define DMAC_PORT_USB 0
70#define DMAC_PORT_SDMMC 1
71#define DMAC_PORT_AC97_1 2
72#define DMAC_PORT_AC97_2 3
73#define DMAC_PORT_AC97_3 4
74#define DMAC_PORT_UART1 6
75#define DMAC_PORT_UART2 7
76#define DMAC_PORT_UART3 8
77
78#define DMAC_PSTATUS_CURRSTATE_SHIFT 4
79#define DMAC_PSTATUS_CURRSTATE_MASK 0x3
80
81#define DMAC_PSTATUS_NEXTBUF (1<<6)
82#define DMAC_PSTATUS_STALLRINT (1<<0)
83
84#define DMAC_INT_CHE (1<<3)
85#define DMAC_INT_NFB (1<<1)
86#define DMAC_INT_STALL (1<<0)
diff --git a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S
index a2f67c06d9c9..9fc7f4988124 100644
--- a/include/asm-arm/arch-lh7a40x/entry-macro.S
+++ b/include/asm-arm/arch-lh7a40x/entry-macro.S
@@ -10,11 +10,73 @@
10#include <asm/hardware.h> 10#include <asm/hardware.h>
11#include <asm/arch/irqs.h> 11#include <asm/arch/irqs.h>
12 12
13# if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) 13/* In order to allow there to be support for both of the processor
14# error "LH7A400 and LH7A404 are mutually exclusive" 14 classes at the same time, we make a hack here that isn't very
15# endif 15 pretty. At startup, the link pointed to with the
16 branch_irq_lh7a400 symbol is replaced with a NOP when the CPU is
17 detected as a lh7a404.
16 18
17# if defined (CONFIG_ARCH_LH7A400) 19 *** FIXME: we should clean this up so that there is only one
20 implementation for each CPU's design.
21
22*/
23
24#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
25
26 .macro disable_fiq
27 .endm
28
29 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
30
31branch_irq_lh7a400: b 1000f
32
33@ Implementation of the LH7A404 get_irqnr_and_base.
34
35 mov \irqnr, #0 @ VIC1 irq base
36 mov \base, #io_p2v(0x80000000) @ APB registers
37 add \base, \base, #0x8000
38 ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR
39 tst \tmp, #VA_VECTORED @ Direct vectored
40 bne 1002f
41 tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1
42 ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS
43 bne 1001f
44 add \base, \base, #(0xa000 - 0x8000)
45 ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR
46 tst \tmp, #VA_VECTORED @ Direct vectored
47 bne 1002f
48 ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS
49 mov \irqnr, #32 @ VIC2 irq base
50
511001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
52 bcs 1008f @ Bit set; irq found
53 add \irqnr, \irqnr, #1
54 bne 1001b @ Until no bits
55 b 1009f @ Nothing? Hmm.
561002: and \irqnr, \tmp, #0x3f @ Mask for valid bits
571008: movs \irqstat, #1 @ Force !Z
58 str \tmp, [\base, #0x0030] @ Clear vector
59 b 1009f
60
61@ Implementation of the LH7A400 get_irqnr_and_base.
62
631000: mov \irqnr, #0
64 mov \base, #io_p2v(0x80000000) @ APB registers
65 ldr \irqstat, [\base, #0x500] @ PIC INTSR
66
671001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry
68 bcs 1008f @ Bit set; irq found
69 add \irqnr, \irqnr, #1
70 bne 1001b @ Until no bits
71 b 1009f @ Nothing? Hmm.
721008: movs \irqstat, #1 @ Force !Z
73
741009:
75 .endm
76
77
78
79#elif defined (CONFIG_ARCH_LH7A400)
18 .macro disable_fiq 80 .macro disable_fiq
19 .endm 81 .endm
20 82
diff --git a/include/asm-arm/arch-lh7a40x/hardware.h b/include/asm-arm/arch-lh7a40x/hardware.h
index aeb07c162e25..e9ff74fd7939 100644
--- a/include/asm-arm/arch-lh7a40x/hardware.h
+++ b/include/asm-arm/arch-lh7a40x/hardware.h
@@ -13,6 +13,8 @@
13#ifndef __ASM_ARCH_HARDWARE_H 13#ifndef __ASM_ARCH_HARDWARE_H
14#define __ASM_ARCH_HARDWARE_H 14#define __ASM_ARCH_HARDWARE_H
15 15
16#include <asm/sizes.h> /* Added for the sake of amba-clcd driver */
17
16#define io_p2v(x) (0xf0000000 | (((x) & 0xfff00000) >> 4) | ((x) & 0x0000ffff)) 18#define io_p2v(x) (0xf0000000 | (((x) & 0xfff00000) >> 4) | ((x) & 0x0000ffff))
17#define io_v2p(x) ( (((x) & 0x0fff0000) << 4) | ((x) & 0x0000ffff)) 19#define io_v2p(x) ( (((x) & 0x0fff0000) << 4) | ((x) & 0x0000ffff))
18 20
@@ -53,6 +55,8 @@ typedef struct { volatile u8 offset[4096]; } __regbase8;
53 55
54#endif 56#endif
55 57
58#define MASK_AND_SET(v,m,s) (v) = ((v)&~(m))|(s)
59
56#include "registers.h" 60#include "registers.h"
57 61
58#endif /* _ASM_ARCH_HARDWARE_H */ 62#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-lh7a40x/irqs.h b/include/asm-arm/arch-lh7a40x/irqs.h
index f91f3e59f3ab..afe8c7cbad6a 100644
--- a/include/asm-arm/arch-lh7a40x/irqs.h
+++ b/include/asm-arm/arch-lh7a40x/irqs.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_ARCH_IRQS_H 18#ifndef __ASM_ARCH_IRQS_H
19#define __ASM_ARCH_IRQS_H 19#define __ASM_ARCH_IRQS_H
20 20
21#include <linux/config.h>
22 21
23#define FIQ_START 80 22#define FIQ_START 80
24 23
@@ -154,9 +153,10 @@
154#if !defined (IRQ_GPIO0INTR) 153#if !defined (IRQ_GPIO0INTR)
155# define IRQ_GPIO0INTR IRQ_GPIO0FIQ 154# define IRQ_GPIO0INTR IRQ_GPIO0FIQ
156#endif 155#endif
157#define IRQ_TICK IRQ_TINTR 156#define IRQ_TICK IRQ_TINTR
158#define IRQ_PCC1_RDY IRQ_GPIO6INTR /* PCCard 1 ready */ 157#define IRQ_PCC1_RDY IRQ_GPIO6INTR /* PCCard 1 ready */
159#define IRQ_PCC2_RDY IRQ_GPIO7INTR /* PCCard 2 ready */ 158#define IRQ_PCC2_RDY IRQ_GPIO7INTR /* PCCard 2 ready */
159#define IRQ_USB IRQ_USBINTR /* USB device */
160 160
161#ifdef CONFIG_MACH_KEV7A400 161#ifdef CONFIG_MACH_KEV7A400
162# define IRQ_TS IRQ_GPIOFIQ /* Touchscreen */ 162# define IRQ_TS IRQ_GPIOFIQ /* Touchscreen */
@@ -191,6 +191,10 @@
191# define IRQ_LPD7A400_TS IRQ_LPD7A40X_CPLD + 1 /* Touch screen */ 191# define IRQ_LPD7A400_TS IRQ_LPD7A40X_CPLD + 1 /* Touch screen */
192#endif 192#endif
193 193
194#if defined (CONFIG_MACH_LPD7A400)
195# define IRQ_TOUCH IRQ_LPD7A400_TS
196#endif
197
194#define NR_IRQS (NR_IRQ_CPU + NR_IRQ_BOARD) 198#define NR_IRQS (NR_IRQ_CPU + NR_IRQ_BOARD)
195 199
196#endif 200#endif
diff --git a/include/asm-arm/arch-lh7a40x/registers.h b/include/asm-arm/arch-lh7a40x/registers.h
index 2edb22e35450..b4f09b3e2d03 100644
--- a/include/asm-arm/arch-lh7a40x/registers.h
+++ b/include/asm-arm/arch-lh7a40x/registers.h
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <asm/arch/constants.h> 12#include <asm/arch/constants.h>
14 13
15#ifndef __ASM_ARCH_REGISTERS_H 14#ifndef __ASM_ARCH_REGISTERS_H
@@ -18,7 +17,7 @@
18 17
19 /* Physical register base addresses */ 18 /* Physical register base addresses */
20 19
21#define AC97_PHYS (0x80000000) /* AC97 Controller */ 20#define AC97C_PHYS (0x80000000) /* AC97 Controller */
22#define MMC_PHYS (0x80000100) /* Multimedia Card Controller */ 21#define MMC_PHYS (0x80000100) /* Multimedia Card Controller */
23#define USB_PHYS (0x80000200) /* USB Client */ 22#define USB_PHYS (0x80000200) /* USB Client */
24#define SCI_PHYS (0x80000300) /* Secure Card Interface */ 23#define SCI_PHYS (0x80000300) /* Secure Card Interface */
@@ -35,6 +34,8 @@
35#define RTC_PHYS (0x80000d00) /* Real-time Clock */ 34#define RTC_PHYS (0x80000d00) /* Real-time Clock */
36#define GPIO_PHYS (0x80000e00) /* General Purpose IO */ 35#define GPIO_PHYS (0x80000e00) /* General Purpose IO */
37#define BMI_PHYS (0x80000f00) /* Battery Monitor Interface */ 36#define BMI_PHYS (0x80000f00) /* Battery Monitor Interface */
37#define HRTFTC_PHYS (0x80001000) /* High-res TFT Controller (LH7A400) */
38#define ALI_PHYS (0x80001000) /* Advanced LCD Interface (LH7A404) */
38#define WDT_PHYS (0x80001400) /* Watchdog Timer */ 39#define WDT_PHYS (0x80001400) /* Watchdog Timer */
39#define SMC_PHYS (0x80002000) /* Static Memory Controller */ 40#define SMC_PHYS (0x80002000) /* Static Memory Controller */
40#define SDRC_PHYS (0x80002400) /* SDRAM Controller */ 41#define SDRC_PHYS (0x80002400) /* SDRAM Controller */
@@ -43,6 +44,7 @@
43 44
44 /* Physical registers of the LH7A404 */ 45 /* Physical registers of the LH7A404 */
45 46
47#define ADC_PHYS (0x80001300) /* A/D & Touchscreen Controller */
46#define VIC1_PHYS (0x80008000) /* Vectored Interrupt Controller 1 */ 48#define VIC1_PHYS (0x80008000) /* Vectored Interrupt Controller 1 */
47#define USBH_PHYS (0x80009000) /* USB OHCI host controller */ 49#define USBH_PHYS (0x80009000) /* USB OHCI host controller */
48#define VIC2_PHYS (0x8000a000) /* Vectored Interrupt Controller 2 */ 50#define VIC2_PHYS (0x8000a000) /* Vectored Interrupt Controller 2 */
@@ -53,10 +55,32 @@
53 55
54 /* Clock/State Controller register */ 56 /* Clock/State Controller register */
55 57
58#define CSC_PWRSR __REG(CSC_PHYS + 0x00) /* Reset register & ID */
56#define CSC_PWRCNT __REG(CSC_PHYS + 0x04) /* Power control */ 59#define CSC_PWRCNT __REG(CSC_PHYS + 0x04) /* Power control */
60#define CSC_CLKSET __REG(CSC_PHYS + 0x20) /* Clock speed control */
61#define CSC_USBDRESET __REG(CSC_PHYS + 0x4c) /* USB Device resets */
57 62
58#define CSC_PWRCNT_USBH_EN (1<<28) /* USB Host power enable */ 63#define CSC_PWRCNT_USBH_EN (1<<28) /* USB Host power enable */
59 64#define CSC_PWRCNT_DMAC_M2M1_EN (1<<27)
65#define CSC_PWRCNT_DMAC_M2M0_EN (1<<26)
66#define CSC_PWRCNT_DMAC_M2P8_EN (1<<25)
67#define CSC_PWRCNT_DMAC_M2P9_EN (1<<24)
68#define CSC_PWRCNT_DMAC_M2P6_EN (1<<23)
69#define CSC_PWRCNT_DMAC_M2P7_EN (1<<22)
70#define CSC_PWRCNT_DMAC_M2P4_EN (1<<21)
71#define CSC_PWRCNT_DMAC_M2P5_EN (1<<20)
72#define CSC_PWRCNT_DMAC_M2P2_EN (1<<19)
73#define CSC_PWRCNT_DMAC_M2P3_EN (1<<18)
74#define CSC_PWRCNT_DMAC_M2P0_EN (1<<17)
75#define CSC_PWRCNT_DMAC_M2P1_EN (1<<16)
76
77#define CSC_PWRSR_CHIPMAN_SHIFT (24)
78#define CSC_PWRSR_CHIPMAN_MASK (0xff)
79#define CSC_PWRSR_CHIPID_SHIFT (16)
80#define CSC_PWRSR_CHIPID_MASK (0xff)
81
82#define CSC_USBDRESET_APBRESETREG (1<<1)
83#define CSC_USBDRESET_IORESETREG (1<<0)
60 84
61 /* Interrupt Controller registers */ 85 /* Interrupt Controller registers */
62 86
@@ -109,6 +133,13 @@
109#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIO End-of-Interrupt */ 133#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIO End-of-Interrupt */
110#define GPIO_GPIOINTEN __REG(GPIO_PHYS + 0x58) /* GPIO Interrupt Enable */ 134#define GPIO_GPIOINTEN __REG(GPIO_PHYS + 0x58) /* GPIO Interrupt Enable */
111#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIO Interrupt Status */ 135#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIO Interrupt Status */
136#define GPIO_PINMUX __REG(GPIO_PHYS + 0x2c)
137#define GPIO_PADD __REG(GPIO_PHYS + 0x10)
138#define GPIO_PAD __REG(GPIO_PHYS + 0x00)
139#define GPIO_PCD __REG(GPIO_PHYS + 0x08)
140#define GPIO_PCDD __REG(GPIO_PHYS + 0x18)
141#define GPIO_PEDD __REG(GPIO_PHYS + 0x24)
142#define GPIO_PED __REG(GPIO_PHYS + 0x20)
112 143
113 144
114 /* Static Memory Controller registers */ 145 /* Static Memory Controller registers */
@@ -138,20 +169,21 @@
138#endif 169#endif
139 170
140#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) 171#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
141# define CPLD_CONTROL __REG8(CPLD02_PHYS)
142# define CPLD_SPI_DATA __REG8(CPLD06_PHYS)
143# define CPLD_SPI_CONTROL __REG8(CPLD08_PHYS)
144# define CPLD_SPI_EEPROM __REG8(CPLD0A_PHYS)
145# define CPLD_INTERRUPTS __REG8(CPLD0C_PHYS) /* IRQ mask/status */
146# define CPLD_BOOT_MODE __REG8(CPLD0E_PHYS)
147# define CPLD_FLASH __REG8(CPLD10_PHYS)
148# define CPLD_POWER_MGMT __REG8(CPLD12_PHYS)
149# define CPLD_REVISION __REG8(CPLD14_PHYS)
150# define CPLD_GPIO_EXT __REG8(CPLD16_PHYS)
151# define CPLD_GPIO_DATA __REG8(CPLD18_PHYS)
152# define CPLD_GPIO_DIR __REG8(CPLD1A_PHYS)
153#endif
154 172
173# define CPLD_CONTROL __REG16(CPLD02_PHYS)
174# define CPLD_SPI_DATA __REG16(CPLD06_PHYS)
175# define CPLD_SPI_CONTROL __REG16(CPLD08_PHYS)
176# define CPLD_SPI_EEPROM __REG16(CPLD0A_PHYS)
177# define CPLD_INTERRUPTS __REG16(CPLD0C_PHYS) /* IRQ mask/status */
178# define CPLD_BOOT_MODE __REG16(CPLD0E_PHYS)
179# define CPLD_FLASH __REG16(CPLD10_PHYS)
180# define CPLD_POWER_MGMT __REG16(CPLD12_PHYS)
181# define CPLD_REVISION __REG16(CPLD14_PHYS)
182# define CPLD_GPIO_EXT __REG16(CPLD16_PHYS)
183# define CPLD_GPIO_DATA __REG16(CPLD18_PHYS)
184# define CPLD_GPIO_DIR __REG16(CPLD1A_PHYS)
185
186#endif
155 187
156 /* Timer registers */ 188 /* Timer registers */
157 189
@@ -190,4 +222,3 @@
190 222
191 223
192#endif /* _ASM_ARCH_REGISTERS_H */ 224#endif /* _ASM_ARCH_REGISTERS_H */
193
diff --git a/include/asm-arm/arch-lh7a40x/ssp.h b/include/asm-arm/arch-lh7a40x/ssp.h
new file mode 100644
index 000000000000..132b1c4d5ce6
--- /dev/null
+++ b/include/asm-arm/arch-lh7a40x/ssp.h
@@ -0,0 +1,71 @@
1/* ssp.h
2 $Id$
3
4 written by Marc Singer
5 6 Dec 2004
6
7 Copyright (C) 2004 Marc Singer
8
9 -----------
10 DESCRIPTION
11 -----------
12
13 This SSP header is available throughout the kernel, for this
14 machine/architecture, because drivers that use it may be dispersed.
15
16 This file was cloned from the 7952x implementation. It would be
17 better to share them, but we're taking an easier approach for the
18 time being.
19
20*/
21
22#if !defined (__SSP_H__)
23# define __SSP_H__
24
25/* ----- Includes */
26
27/* ----- Types */
28
29struct ssp_driver {
30 int (*init) (void);
31 void (*exit) (void);
32 void (*acquire) (void);
33 void (*release) (void);
34 int (*configure) (int device, int mode, int speed,
35 int frame_size_write, int frame_size_read);
36 void (*chip_select) (int enable);
37 void (*set_callbacks) (void* handle,
38 irqreturn_t (*callback_tx)(void*),
39 irqreturn_t (*callback_rx)(void*));
40 void (*enable) (void);
41 void (*disable) (void);
42// int (*save_state) (void*);
43// void (*restore_state) (void*);
44 int (*read) (void);
45 int (*write) (u16 data);
46 int (*write_read) (u16 data);
47 void (*flush) (void);
48 void (*write_async) (void* pv, size_t cb);
49 size_t (*write_pos) (void);
50};
51
52 /* These modes are only available on the LH79524 */
53#define SSP_MODE_SPI (1)
54#define SSP_MODE_SSI (2)
55#define SSP_MODE_MICROWIRE (3)
56#define SSP_MODE_I2S (4)
57
58 /* CPLD SPI devices */
59#define DEVICE_EEPROM 0 /* Configuration eeprom */
60#define DEVICE_MAC 1 /* MAC eeprom (LPD79524) */
61#define DEVICE_CODEC 2 /* Audio codec */
62#define DEVICE_TOUCH 3 /* Touch screen (LPD79520) */
63
64/* ----- Globals */
65
66/* ----- Prototypes */
67
68//extern struct ssp_driver lh79520_i2s_driver;
69extern struct ssp_driver lh7a400_cpld_ssp_driver;
70
71#endif /* __SSP_H__ */
diff --git a/include/asm-arm/arch-lh7a40x/uncompress.h b/include/asm-arm/arch-lh7a40x/uncompress.h
index f8053346f608..3d1ce0426a33 100644
--- a/include/asm-arm/arch-lh7a40x/uncompress.h
+++ b/include/asm-arm/arch-lh7a40x/uncompress.h
@@ -16,7 +16,7 @@
16#ifndef UART_R_STATUS 16#ifndef UART_R_STATUS
17# define UART_R_STATUS (0x10) 17# define UART_R_STATUS (0x10)
18#endif 18#endif
19#define nTxRdy (0x20) /* Not TxReady (literally Tx FIFO full) */ 19#define nTxRdy (0x20) /* Not TxReady (literally Tx FIFO full) */
20 20
21 /* Access UART with physical addresses before MMU is setup */ 21 /* Access UART with physical addresses before MMU is setup */
22#define UART_STATUS (*(volatile unsigned long*) (UART2_PHYS + UART_R_STATUS)) 22#define UART_STATUS (*(volatile unsigned long*) (UART2_PHYS + UART_R_STATUS))
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
index 6d6240a4681c..dfdbf06fd646 100644
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -10,7 +10,6 @@
10#ifndef _OMAP_BOARD_H 10#ifndef _OMAP_BOARD_H
11#define _OMAP_BOARD_H 11#define _OMAP_BOARD_H
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15 14
16/* Different peripheral ids */ 15/* Different peripheral ids */
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 7909b729826c..c7d9e857795d 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -37,7 +37,6 @@
37#define __ASM_ARCH_OMAP_HARDWARE_H 37#define __ASM_ARCH_OMAP_HARDWARE_H
38 38
39#include <asm/sizes.h> 39#include <asm/sizes.h>
40#include <linux/config.h>
41#ifndef __ASSEMBLER__ 40#ifndef __ASSEMBLER__
42#include <asm/types.h> 41#include <asm/types.h>
43#include <asm/arch/cpu.h> 42#include <asm/arch/cpu.h>
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index 67970d1a2020..ac2bfa433f06 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -4,7 +4,6 @@
4 */ 4 */
5#ifndef __ASM_ARCH_SYSTEM_H 5#ifndef __ASM_ARCH_SYSTEM_H
6#define __ASM_ARCH_SYSTEM_H 6#define __ASM_ARCH_SYSTEM_H
7#include <linux/config.h>
8#include <linux/clk.h> 7#include <linux/clk.h>
9 8
10#include <asm/mach-types.h> 9#include <asm/mach-types.h>
diff --git a/include/asm-arm/arch-omap/uncompress.h b/include/asm-arm/arch-omap/uncompress.h
index ca2c8bec82e7..aca0adfef1b8 100644
--- a/include/asm-arm/arch-omap/uncompress.h
+++ b/include/asm-arm/arch-omap/uncompress.h
@@ -17,7 +17,6 @@
17 * kind, whether express or implied. 17 * kind, whether express or implied.
18 */ 18 */
19 19
20#include <linux/config.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <linux/serial_reg.h> 21#include <linux/serial_reg.h>
23#include <asm/arch/serial.h> 22#include <asm/arch/serial.h>
diff --git a/include/asm-arm/arch-pnx4008/clock.h b/include/asm-arm/arch-pnx4008/clock.h
new file mode 100644
index 000000000000..91ae0030fdf2
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/clock.h
@@ -0,0 +1,61 @@
1/*
2 * include/asm-arm/arch-pnx4008/clock.h
3 *
4 * Clock control driver for PNX4008 - header file
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#ifndef __PNX4008_CLOCK_H__
14#define __PNX4008_CLOCK_H__
15
16struct module;
17struct clk;
18
19#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
20#define HCLKDIVCTRL_REG (PWRMAN_VA_BASE + 0x40)
21#define PWRCTRL_REG (PWRMAN_VA_BASE + 0x44)
22#define PLLCTRL_REG (PWRMAN_VA_BASE + 0x48)
23#define OSC13CTRL_REG (PWRMAN_VA_BASE + 0x4c)
24#define SYSCLKCTRL_REG (PWRMAN_VA_BASE + 0x50)
25#define HCLKPLLCTRL_REG (PWRMAN_VA_BASE + 0x58)
26#define USBCTRL_REG (PWRMAN_VA_BASE + 0x64)
27#define SDRAMCLKCTRL_REG (PWRMAN_VA_BASE + 0x68)
28#define MSCTRL_REG (PWRMAN_VA_BASE + 0x80)
29#define BTCLKCTRL (PWRMAN_VA_BASE + 0x84)
30#define DUMCLKCTRL_REG (PWRMAN_VA_BASE + 0x90)
31#define I2CCLKCTRL_REG (PWRMAN_VA_BASE + 0xac)
32#define KEYCLKCTRL_REG (PWRMAN_VA_BASE + 0xb0)
33#define TSCLKCTRL_REG (PWRMAN_VA_BASE + 0xb4)
34#define PWMCLKCTRL_REG (PWRMAN_VA_BASE + 0xb8)
35#define SPICTRL_REG (PWRMAN_VA_BASE + 0xc4)
36#define FLASHCLKCTRL_REG (PWRMAN_VA_BASE + 0xc8)
37#define UART3CLK_REG (PWRMAN_VA_BASE + 0xd0)
38#define UARTCLKCTRL_REG (PWRMAN_VA_BASE + 0xe4)
39#define DMACLKCTRL_REG (PWRMAN_VA_BASE + 0xe8)
40#define AUTOCLK_CTRL (PWRMAN_VA_BASE + 0xec)
41#define JPEGCLKCTRL_REG (PWRMAN_VA_BASE + 0xfc)
42
43#define AUDIOCONFIG_VA_BASE IO_ADDRESS(PNX4008_AUDIOCONFIG_BASE)
44#define DSPPLLCTRL_REG (AUDIOCONFIG_VA_BASE + 0x60)
45#define DSPCLKCTRL_REG (AUDIOCONFIG_VA_BASE + 0x64)
46#define AUDIOCLKCTRL_REG (AUDIOCONFIG_VA_BASE + 0x68)
47#define AUDIOPLLCTRL_REG (AUDIOCONFIG_VA_BASE + 0x6C)
48
49#define USB_OTG_CLKCTRL_REG IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xff4)
50
51#define VFP9CLKCTRL_REG IO_ADDRESS(PNX4008_DEBUG_BASE)
52
53#define CLK_RATE_13MHZ 13000
54#define CLK_RATE_1MHZ 1000
55#define CLK_RATE_208MHZ 208000
56#define CLK_RATE_48MHZ 48000
57#define CLK_RATE_32KHZ 32
58
59#define PNX4008_UART_CLK CLK_RATE_13MHZ * 1000 /* in MHz */
60
61#endif
diff --git a/include/asm-arm/arch-pnx4008/debug-macro.S b/include/asm-arm/arch-pnx4008/debug-macro.S
new file mode 100644
index 000000000000..eb3839de389a
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/debug-macro.S
@@ -0,0 +1,27 @@
1/* linux/include/asm-arm/arch-pnx4008/debug-macro.S
2 *
3 * Debugging macro include header
4 *
5 * Copyright (C) 1994-1999 Russell King
6 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14 .macro addruart,rx
15 mrc p15, 0, \rx, c1, c0
16 tst \rx, #1 @ MMU enabled?
17 mov \rx, #0x00090000
18 addeq \rx, \rx, #0x40000000
19 addne \rx, \rx, #0xf4000000
20 .endm
21
22 .macro senduart,rd,rx
23 strb \rd, [\rx, #0x0]
24 .endm
25
26#define UART_SHIFT 2
27#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-pnx4008/dma.h b/include/asm-arm/arch-pnx4008/dma.h
new file mode 100644
index 000000000000..3aee1204795b
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/dma.h
@@ -0,0 +1,162 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/dma.h
3 *
4 * PNX4008 DMA header file
5 *
6 * Author: Vitaly Wool
7 * Copyright: MontaVista Software Inc. (c) 2005
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef __ASM_ARCH_DMA_H
15#define __ASM_ARCH_DMA_H
16
17#include "platform.h"
18
19#define MAX_DMA_ADDRESS 0xffffffff
20
21#define MAX_DMA_CHANNELS 8
22
23#define DMAC_BASE IO_ADDRESS(PNX4008_DMA_CONFIG_BASE)
24#define DMAC_INT_STAT (DMAC_BASE + 0x0000)
25#define DMAC_INT_TC_STAT (DMAC_BASE + 0x0004)
26#define DMAC_INT_TC_CLEAR (DMAC_BASE + 0x0008)
27#define DMAC_INT_ERR_STAT (DMAC_BASE + 0x000c)
28#define DMAC_INT_ERR_CLEAR (DMAC_BASE + 0x0010)
29#define DMAC_SOFT_SREQ (DMAC_BASE + 0x0024)
30#define DMAC_CONFIG (DMAC_BASE + 0x0030)
31#define DMAC_Cx_SRC_ADDR(c) (DMAC_BASE + 0x0100 + (c) * 0x20)
32#define DMAC_Cx_DEST_ADDR(c) (DMAC_BASE + 0x0104 + (c) * 0x20)
33#define DMAC_Cx_LLI(c) (DMAC_BASE + 0x0108 + (c) * 0x20)
34#define DMAC_Cx_CONTROL(c) (DMAC_BASE + 0x010c + (c) * 0x20)
35#define DMAC_Cx_CONFIG(c) (DMAC_BASE + 0x0110 + (c) * 0x20)
36
37enum {
38 WIDTH_BYTE = 0,
39 WIDTH_HWORD,
40 WIDTH_WORD
41};
42
43enum {
44 FC_MEM2MEM_DMA,
45 FC_MEM2PER_DMA,
46 FC_PER2MEM_DMA,
47 FC_PER2PER_DMA,
48 FC_PER2PER_DPER,
49 FC_MEM2PER_PER,
50 FC_PER2MEM_PER,
51 FC_PER2PER_SPER
52};
53
54enum {
55 DMA_INT_UNKNOWN = 0,
56 DMA_ERR_INT = 1,
57 DMA_TC_INT = 2,
58};
59
60enum {
61 DMA_BUFFER_ALLOCATED = 1,
62 DMA_HAS_LL = 2,
63};
64
65enum {
66 PER_CAM_DMA_1 = 0,
67 PER_NDF_FLASH = 1,
68 PER_MBX_SLAVE_FIFO = 2,
69 PER_SPI2_REC_XMIT = 3,
70 PER_MS_SD_RX_XMIT = 4,
71 PER_HS_UART_1_XMIT = 5,
72 PER_HS_UART_1_RX = 6,
73 PER_HS_UART_2_XMIT = 7,
74 PER_HS_UART_2_RX = 8,
75 PER_HS_UART_7_XMIT = 9,
76 PER_HS_UART_7_RX = 10,
77 PER_SPI1_REC_XMIT = 11,
78 PER_MLC_NDF_SREC = 12,
79 PER_CAM_DMA_2 = 13,
80 PER_PRNG_INFIFO = 14,
81 PER_PRNG_OUTFIFO = 15,
82};
83
84struct pnx4008_dma_ch_ctrl {
85 int tc_mask;
86 int cacheable;
87 int bufferable;
88 int priv_mode;
89 int di;
90 int si;
91 int dest_ahb1;
92 int src_ahb1;
93 int dwidth;
94 int swidth;
95 int dbsize;
96 int sbsize;
97 int tr_size;
98};
99
100struct pnx4008_dma_ch_config {
101 int halt;
102 int active;
103 int lock;
104 int itc;
105 int ie;
106 int flow_cntrl;
107 int dest_per;
108 int src_per;
109};
110
111struct pnx4008_dma_ll {
112 unsigned long src_addr;
113 unsigned long dest_addr;
114 u32 next_dma;
115 unsigned long ch_ctrl;
116 struct pnx4008_dma_ll *next;
117 int flags;
118 void *alloc_data;
119 int (*free) (void *);
120};
121
122struct pnx4008_dma_config {
123 int is_ll;
124 unsigned long src_addr;
125 unsigned long dest_addr;
126 unsigned long ch_ctrl;
127 unsigned long ch_cfg;
128 struct pnx4008_dma_ll *ll;
129 u32 ll_dma;
130 int flags;
131 void *alloc_data;
132 int (*free) (void *);
133};
134
135extern struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t *);
136extern void pnx4008_free_ll_entry(struct pnx4008_dma_ll *, dma_addr_t);
137extern void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll *);
138
139extern int pnx4008_request_channel(char *, int,
140 void (*)(int, int, void *, struct pt_regs *),
141 void *);
142extern void pnx4008_free_channel(int);
143extern int pnx4008_config_dma(int, int, int);
144extern int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl *,
145 unsigned long *);
146extern int pnx4008_dma_parse_control(unsigned long,
147 struct pnx4008_dma_ch_ctrl *);
148extern int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config *,
149 unsigned long *);
150extern int pnx4008_dma_parse_config(unsigned long,
151 struct pnx4008_dma_ch_config *);
152extern int pnx4008_config_channel(int, struct pnx4008_dma_config *);
153extern int pnx4008_channel_get_config(int, struct pnx4008_dma_config *);
154extern int pnx4008_dma_ch_enable(int);
155extern int pnx4008_dma_ch_disable(int);
156extern int pnx4008_dma_ch_enabled(int);
157extern void pnx4008_dma_split_head_entry(struct pnx4008_dma_config *,
158 struct pnx4008_dma_ch_ctrl *);
159extern void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll *,
160 struct pnx4008_dma_ch_ctrl *);
161
162#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-pnx4008/entry-macro.S b/include/asm-arm/arch-pnx4008/entry-macro.S
new file mode 100644
index 000000000000..c1c198e3680b
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/entry-macro.S
@@ -0,0 +1,121 @@
1/*
2 * include/asm-arm/arch-pnx4008/entry-macro.S
3 *
4 * Low-level IRQ helper macros for PNX4008-based platforms
5 *
6 * 2005-2006 (c) MontaVista Software, Inc.
7 * Author: Vitaly Wool <vwool@ru.mvista.com>
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include "platform.h"
14
15#define IO_BASE 0xF0000000
16#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
17
18#define INTRC_MASK 0x00
19#define INTRC_RAW_STAT 0x04
20#define INTRC_STAT 0x08
21#define INTRC_POLAR 0x0C
22#define INTRC_ACT_TYPE 0x10
23#define INTRC_TYPE 0x14
24
25#define SIC1_BASE_INT 32
26#define SIC2_BASE_INT 64
27
28 .macro disable_fiq
29 .endm
30
31 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
32/* decode the MIC interrupt numbers */
33 ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
34 ldr \irqstat, [\base, #INTRC_STAT]
35
36 cmp \irqstat,#1<<16
37 movhs \irqnr,#16
38 movlo \irqnr,#0
39 movhs \irqstat,\irqstat,lsr#16
40 cmp \irqstat,#1<<8
41 addhs \irqnr,\irqnr,#8
42 movhs \irqstat,\irqstat,lsr#8
43 cmp \irqstat,#1<<4
44 addhs \irqnr,\irqnr,#4
45 movhs \irqstat,\irqstat,lsr#4
46 cmp \irqstat,#1<<2
47 addhs \irqnr,\irqnr,#2
48 movhs \irqstat,\irqstat,lsr#2
49 cmp \irqstat,#1<<1
50 addhs \irqnr,\irqnr,#1
51
52/* was there an interrupt ? if not then drop out with EQ status */
53 teq \irqstat,#0
54 beq 1003f
55
56/* and now check for extended IRQ reasons */
57 cmp \irqnr,#1
58 bls 1003f
59 cmp \irqnr,#30
60 blo 1002f
61
62/* IRQ 31,30 : High priority cascade IRQ handle */
63/* read the correct SIC */
64/* decoding status after compare : eq is 30 (SIC1) , ne is 31 (SIC2) */
65/* set the base IRQ number */
66 ldreq \base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
67 moveq \irqnr,#SIC1_BASE_INT
68 ldrne \base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
69 movne \irqnr,#SIC2_BASE_INT
70 ldr \irqstat, [\base, #INTRC_STAT]
71 ldr \tmp, [\base, #INTRC_TYPE]
72/* and with inverted mask : low priority interrupts */
73 and \irqstat,\irqstat,\tmp
74 b 1004f
75
761003:
77/* IRQ 1,0 : Low priority cascade IRQ handle */
78/* read the correct SIC */
79/* decoding status after compare : eq is 1 (SIC2) , ne is 0 (SIC1)*/
80/* read the correct SIC */
81/* set the base IRQ number */
82 ldrne \base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
83 movne \irqnr,#SIC1_BASE_INT
84 ldreq \base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
85 moveq \irqnr,#SIC2_BASE_INT
86 ldr \irqstat, [\base, #INTRC_STAT]
87 ldr \tmp, [\base, #INTRC_TYPE]
88/* and with inverted mask : low priority interrupts */
89 bic \irqstat,\irqstat,\tmp
90
911004:
92
93 cmp \irqstat,#1<<16
94 addhs \irqnr,\irqnr,#16
95 movhs \irqstat,\irqstat,lsr#16
96 cmp \irqstat,#1<<8
97 addhs \irqnr,\irqnr,#8
98 movhs \irqstat,\irqstat,lsr#8
99 cmp \irqstat,#1<<4
100 addhs \irqnr,\irqnr,#4
101 movhs \irqstat,\irqstat,lsr#4
102 cmp \irqstat,#1<<2
103 addhs \irqnr,\irqnr,#2
104 movhs \irqstat,\irqstat,lsr#2
105 cmp \irqstat,#1<<1
106 addhs \irqnr,\irqnr,#1
107
108
109/* is irqstat not zero */
110
1111002:
112/* we assert that irqstat is not equal to zero and return ne status if true*/
113 teq \irqstat,#0
1141003:
115 .endm
116
117
118 .macro irq_prio_table
119 .endm
120
121
diff --git a/include/asm-arm/arch-pnx4008/gpio.h b/include/asm-arm/arch-pnx4008/gpio.h
new file mode 100644
index 000000000000..1fa5a77c3010
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/gpio.h
@@ -0,0 +1,139 @@
1/*
2 * include/asm-arm/arch-pnx4008/gpio.h
3 *
4 * PNX4008 GPIO driver - header file
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
9 * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
10 *
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17#ifndef _PNX4008_GPIO_H_
18#define _PNX4008_GPIO_H_
19
20
21/* Block numbers */
22#define GPIO_IN (0)
23#define GPIO_OUT (0x100)
24#define GPIO_BID (0x200)
25#define GPIO_RAM (0x300)
26#define GPIO_MUX (0x400)
27
28#define GPIO_TYPE_MASK(K) ((K) & 0x700)
29
30/* INPUT GPIOs */
31/* GPI */
32#define GPI_00 (GPIO_IN | 0)
33#define GPI_01 (GPIO_IN | 1)
34#define GPI_02 (GPIO_IN | 2)
35#define GPI_03 (GPIO_IN | 3)
36#define GPI_04 (GPIO_IN | 4)
37#define GPI_05 (GPIO_IN | 5)
38#define GPI_06 (GPIO_IN | 6)
39#define GPI_07 (GPIO_IN | 7)
40#define GPI_08 (GPIO_IN | 8)
41#define GPI_09 (GPIO_IN | 9)
42#define U1_RX (GPIO_IN | 15)
43#define U2_HTCS (GPIO_IN | 16)
44#define U2_RX (GPIO_IN | 17)
45#define U3_RX (GPIO_IN | 18)
46#define U4_RX (GPIO_IN | 19)
47#define U5_RX (GPIO_IN | 20)
48#define U6_IRRX (GPIO_IN | 21)
49#define U7_HCTS (GPIO_IN | 22)
50#define U7_RX (GPIO_IN | 23)
51/* MISC IN */
52#define SPI1_DATIN (GPIO_IN | 25)
53#define DISP_SYNC (GPIO_IN | 26)
54#define SPI2_DATIN (GPIO_IN | 27)
55#define GPI_11 (GPIO_IN | 28)
56
57#define GPIO_IN_MASK 0x1eff83ff
58
59/* OUTPUT GPIOs */
60/* GPO */
61#define GPO_00 (GPIO_OUT | 0)
62#define GPO_01 (GPIO_OUT | 1)
63#define GPO_02 (GPIO_OUT | 2)
64#define GPO_03 (GPIO_OUT | 3)
65#define GPO_04 (GPIO_OUT | 4)
66#define GPO_05 (GPIO_OUT | 5)
67#define GPO_06 (GPIO_OUT | 6)
68#define GPO_07 (GPIO_OUT | 7)
69#define GPO_08 (GPIO_OUT | 8)
70#define GPO_09 (GPIO_OUT | 9)
71#define GPO_10 (GPIO_OUT | 10)
72#define GPO_11 (GPIO_OUT | 11)
73#define GPO_12 (GPIO_OUT | 12)
74#define GPO_13 (GPIO_OUT | 13)
75#define GPO_14 (GPIO_OUT | 14)
76#define GPO_15 (GPIO_OUT | 15)
77#define GPO_16 (GPIO_OUT | 16)
78#define GPO_17 (GPIO_OUT | 17)
79#define GPO_18 (GPIO_OUT | 18)
80#define GPO_19 (GPIO_OUT | 19)
81#define GPO_20 (GPIO_OUT | 20)
82#define GPO_21 (GPIO_OUT | 21)
83#define GPO_22 (GPIO_OUT | 22)
84#define GPO_23 (GPIO_OUT | 23)
85
86#define GPIO_OUT_MASK 0xffffff
87
88/* BIDIRECTIONAL GPIOs */
89/* RAM pins */
90#define RAM_D19 (GPIO_RAM | 0)
91#define RAM_D20 (GPIO_RAM | 1)
92#define RAM_D21 (GPIO_RAM | 2)
93#define RAM_D22 (GPIO_RAM | 3)
94#define RAM_D23 (GPIO_RAM | 4)
95#define RAM_D24 (GPIO_RAM | 5)
96#define RAM_D25 (GPIO_RAM | 6)
97#define RAM_D26 (GPIO_RAM | 7)
98#define RAM_D27 (GPIO_RAM | 8)
99#define RAM_D28 (GPIO_RAM | 9)
100#define RAM_D29 (GPIO_RAM | 10)
101#define RAM_D30 (GPIO_RAM | 11)
102#define RAM_D31 (GPIO_RAM | 12)
103
104#define GPIO_RAM_MASK 0x1fff
105
106/* I/O pins */
107#define GPIO_00 (GPIO_BID | 25)
108#define GPIO_01 (GPIO_BID | 26)
109#define GPIO_02 (GPIO_BID | 27)
110#define GPIO_03 (GPIO_BID | 28)
111#define GPIO_04 (GPIO_BID | 29)
112#define GPIO_05 (GPIO_BID | 30)
113
114#define GPIO_BID_MASK 0x7e000000
115
116/* Non-GPIO multiplexed PIOs. For multiplexing with GPIO, please use GPIO macros */
117#define GPIO_SDRAM_SEL (GPIO_MUX | 3)
118
119#define GPIO_MUX_MASK 0x8
120
121/* Extraction/assembly macros */
122#define GPIO_BIT_MASK(K) ((K) & 0x1F)
123#define GPIO_BIT(K) (1 << GPIO_BIT_MASK(K))
124#define GPIO_ISMUX(K) ((GPIO_TYPE_MASK(K) == GPIO_MUX) && (GPIO_BIT(K) & GPIO_MUX_MASK))
125#define GPIO_ISRAM(K) ((GPIO_TYPE_MASK(K) == GPIO_RAM) && (GPIO_BIT(K) & GPIO_RAM_MASK))
126#define GPIO_ISBID(K) ((GPIO_TYPE_MASK(K) == GPIO_BID) && (GPIO_BIT(K) & GPIO_BID_MASK))
127#define GPIO_ISOUT(K) ((GPIO_TYPE_MASK(K) == GPIO_OUT) && (GPIO_BIT(K) & GPIO_OUT_MASK))
128#define GPIO_ISIN(K) ((GPIO_TYPE_MASK(K) == GPIO_IN) && (GPIO_BIT(K) & GPIO_IN_MASK))
129
130extern int pnx4008_gpio_register_pin(unsigned short pin);
131extern int pnx4008_gpio_unregister_pin(unsigned short pin);
132extern unsigned long pnx4008_gpio_read_pin(unsigned short pin);
133extern int pnx4008_gpio_write_pin(unsigned short pin, int output);
134extern int pnx4008_gpio_set_pin_direction(unsigned short pin, int output);
135extern int pnx4008_gpio_read_pin_direction(unsigned short pin);
136extern int pnx4008_gpio_set_pin_mux(unsigned short pin, int output);
137extern int pnx4008_gpio_read_pin_mux(unsigned short pin);
138
139#endif /* _PNX4008_GPIO_H_ */
diff --git a/include/asm-arm/arch-pnx4008/hardware.h b/include/asm-arm/arch-pnx4008/hardware.h
new file mode 100644
index 000000000000..a4410397a921
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/hardware.h
@@ -0,0 +1,32 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/hardware.h
3 *
4 * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_HARDWARE_H
21#define __ASM_ARCH_HARDWARE_H
22
23#include <asm/sizes.h>
24#include <asm/arch/platform.h>
25
26/* Start of virtual addresses for IO devices */
27#define IO_BASE 0xF0000000
28
29/* This macro relies on fact that for all HW i/o addresses bits 20-23 are 0 */
30#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
31
32#endif
diff --git a/include/asm-arm/arch-pnx4008/io.h b/include/asm-arm/arch-pnx4008/io.h
new file mode 100644
index 000000000000..29ee43955c52
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/io.h
@@ -0,0 +1,21 @@
1
2/*
3 * include/asm-arm/arch-pnx4008/io.h
4 *
5 * Author: Dmitry Chigirev <chigirev@ru.mvista.com>
6 *
7 * 2005 (c) MontaVista Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12
13#ifndef __ASM_ARM_ARCH_IO_H
14#define __ASM_ARM_ARCH_IO_H
15
16#define IO_SPACE_LIMIT 0xffffffff
17
18#define __io(a) ((void __iomem *)(a))
19#define __mem_pci(a) (a)
20
21#endif
diff --git a/include/asm-arm/arch-pnx4008/irq.h b/include/asm-arm/arch-pnx4008/irq.h
new file mode 100644
index 000000000000..fabff5dc337f
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/irq.h
@@ -0,0 +1,42 @@
1/*
2 * include/asm-arm/arch-pnx4008/irq.h
3 *
4 * PNX4008 IRQ controller driver - header file
5 * this one is used in entry-arnv.S as well so it cannot contain C code
6 *
7 * Copyright (c) 2005 Philips Semiconductors
8 * Copyright (c) 2005 MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15#ifndef __PNX4008_IRQ_H__
16#define __PNX4008_IRQ_H__
17
18#define MIC_VA_BASE IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
19#define SIC1_VA_BASE IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
20#define SIC2_VA_BASE IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
21
22/* Manual: Chapter 20, page 195 */
23
24#define INTC_BIT(irq) (1<< ((irq) & 0x1F))
25
26#define INTC_ER(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x0 + (((irq)&(0x3<<5))<<9)))
27#define INTC_RSR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x4 + (((irq)&(0x3<<5))<<9)))
28#define INTC_SR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x8 + (((irq)&(0x3<<5))<<9)))
29#define INTC_APR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0xC + (((irq)&(0x3<<5))<<9)))
30#define INTC_ATR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x10 + (((irq)&(0x3<<5))<<9)))
31#define INTC_ITR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x14 + (((irq)&(0x3<<5))<<9)))
32
33#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
34
35#define START_INT_ER_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
36#define START_INT_RSR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
37#define START_INT_SR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
38#define START_INT_APR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
39
40extern void __init pnx4008_init_irq(void);
41
42#endif /* __PNX4008_IRQ_H__ */
diff --git a/include/asm-arm/arch-pnx4008/irqs.h b/include/asm-arm/arch-pnx4008/irqs.h
new file mode 100644
index 000000000000..13ec7ed0f501
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/irqs.h
@@ -0,0 +1,215 @@
1/*
2 * include/asm-arm/arch-pnx4008/irqs.h
3 *
4 * PNX4008 IRQ controller driver - header file
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#ifndef __PNX4008_IRQS_h__
14#define __PNX4008_IRQS_h__
15
16#define NR_IRQS 96
17
18/*Manual: table 259, page 199*/
19
20/*SUB2 Interrupt Routing (SIC2)*/
21
22#define SIC2_BASE_INT 64
23
24#define CLK_SWITCH_ARM_INT 95 /*manual: Clkswitch ARM */
25#define CLK_SWITCH_DSP_INT 94 /*manual: ClkSwitch DSP */
26#define CLK_SWITCH_AUD_INT 93 /*manual: Clkswitch AUD */
27#define GPI_06_INT 92
28#define GPI_05_INT 91
29#define GPI_04_INT 90
30#define GPI_03_INT 89
31#define GPI_02_INT 88
32#define GPI_01_INT 87
33#define GPI_00_INT 86
34#define BT_CLKREQ_INT 85
35#define SPI1_DATIN_INT 84
36#define U5_RX_INT 83
37#define SDIO_INT_N 82
38#define CAM_HS_INT 81
39#define CAM_VS_INT 80
40#define GPI_07_INT 79
41#define DISP_SYNC_INT 78
42#define DSP_INT8 77
43#define U7_HCTS_INT 76
44#define GPI_10_INT 75
45#define GPI_09_INT 74
46#define GPI_08_INT 73
47#define DSP_INT7 72
48#define U2_HCTS_INT 71
49#define SPI2_DATIN_INT 70
50#define GPIO_05_INT 69
51#define GPIO_04_INT 68
52#define GPIO_03_INT 67
53#define GPIO_02_INT 66
54#define GPIO_01_INT 65
55#define GPIO_00_INT 64
56
57/*Manual: table 258, page 198*/
58
59/*SUB1 Interrupt Routing (SIC1)*/
60
61#define SIC1_BASE_INT 32
62
63#define USB_I2C_INT 63
64#define USB_DEV_HP_INT 62
65#define USB_DEV_LP_INT 61
66#define USB_DEV_DMA_INT 60
67#define USB_HOST_INT 59
68#define USB_OTG_ATX_INT_N 58
69#define USB_OTG_TIMER_INT 57
70#define SW_INT 56
71#define SPI1_INT 55
72#define KEY_IRQ 54
73#define DSP_M_INT 53
74#define RTC_INT 52
75#define I2C_1_INT 51
76#define I2C_2_INT 50
77#define PLL1_LOCK_INT 49
78#define PLL2_LOCK_INT 48
79#define PLL3_LOCK_INT 47
80#define PLL4_LOCK_INT 46
81#define PLL5_LOCK_INT 45
82#define SPI2_INT 44
83#define DSP_INT1 43
84#define DSP_INT2 42
85#define DSP_TDM_INT2 41
86#define TS_AUX_INT 40
87#define TS_IRQ 39
88#define TS_P_INT 38
89#define UOUT1_TO_PAD_INT 37
90#define GPI_11_INT 36
91#define DSP_INT4 35
92#define JTAG_COMM_RX_INT 34
93#define JTAG_COMM_TX_INT 33
94#define DSP_INT3 32
95
96/*Manual: table 257, page 197*/
97
98/*MAIN Interrupt Routing*/
99
100#define MAIN_BASE_INT 0
101
102#define SUB2_FIQ_N 31 /*active low */
103#define SUB1_FIQ_N 30 /*active low */
104#define JPEG_INT 29
105#define DMA_INT 28
106#define MSTIMER_INT 27
107#define IIR1_INT 26
108#define IIR2_INT 25
109#define IIR7_INT 24
110#define DSP_TDM_INT0 23
111#define DSP_TDM_INT1 22
112#define DSP_P_INT 21
113#define DSP_INT0 20
114#define DUM_INT 19
115#define UOUT0_TO_PAD_INT 18
116#define MP4_ENC_INT 17
117#define MP4_DEC_INT 16
118#define SD0_INT 15
119#define MBX_INT 14
120#define SD1_INT 13
121#define MS_INT_N 12
122#define FLASH_INT 11 /*NAND*/
123#define IIR6_INT 10
124#define IIR5_INT 9
125#define IIR4_INT 8
126#define IIR3_INT 7
127#define WATCH_INT 6
128#define HSTIMER_INT 5
129#define ARCH_TIMER_IRQ HSTIMER_INT
130#define CAM_INT 4
131#define PRNG_INT 3
132#define CRYPTO_INT 2
133#define SUB2_IRQ_N 1 /*active low */
134#define SUB1_IRQ_N 0 /*active low */
135
136#define PNX4008_IRQ_TYPES \
137{ /*IRQ #'s: */ \
138IRQT_LOW, IRQT_LOW, IRQT_LOW, IRQT_HIGH, /* 0, 1, 2, 3 */ \
139IRQT_LOW, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 4, 5, 6, 7 */ \
140IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 8, 9,10,11 */ \
141IRQT_LOW, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 12,13,14,15 */ \
142IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 16,17,18,19 */ \
143IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 20,21,22,23 */ \
144IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 24,25,26,27 */ \
145IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_LOW, /* 28,29,30,31 */ \
146IRQT_HIGH, IRQT_LOW, IRQT_HIGH, IRQT_HIGH, /* 32,33,34,35 */ \
147IRQT_HIGH, IRQT_HIGH, IRQT_FALLING, IRQT_HIGH, /* 36,37,38,39 */ \
148IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 40,41,42,43 */ \
149IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 44,45,46,47 */ \
150IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_LOW, /* 48,49,50,51 */ \
151IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 52,53,54,55 */ \
152IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_HIGH, /* 56,57,58,59 */ \
153IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 60,61,62,63 */ \
154IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 64,65,66,67 */ \
155IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 68,69,70,71 */ \
156IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 72,73,74,75 */ \
157IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 76,77,78,79 */ \
158IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 80,81,82,83 */ \
159IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 84,85,86,87 */ \
160IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 88,89,90,91 */ \
161IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 92,93,94,95 */ \
162}
163
164/* Start Enable Pin Interrupts - table 58 page 66 */
165
166#define SE_PIN_BASE_INT 32
167
168#define SE_U7_RX_INT 63
169#define SE_U7_HCTS_INT 62
170#define SE_BT_CLKREQ_INT 61
171#define SE_U6_IRRX_INT 60
172/*59 unused*/
173#define SE_U5_RX_INT 58
174#define SE_GPI_11_INT 57
175#define SE_U3_RX_INT 56
176#define SE_U2_HCTS_INT 55
177#define SE_U2_RX_INT 54
178#define SE_U1_RX_INT 53
179#define SE_DISP_SYNC_INT 52
180/*51 unused*/
181#define SE_SDIO_INT_N 50
182#define SE_MSDIO_START_INT 49
183#define SE_GPI_06_INT 48
184#define SE_GPI_05_INT 47
185#define SE_GPI_04_INT 46
186#define SE_GPI_03_INT 45
187#define SE_GPI_02_INT 44
188#define SE_GPI_01_INT 43
189#define SE_GPI_00_INT 42
190#define SE_SYSCLKEN_PIN_INT 41
191#define SE_SPI1_DATAIN_INT 40
192#define SE_GPI_07_INT 39
193#define SE_SPI2_DATAIN_INT 38
194#define SE_GPI_10_INT 37
195#define SE_GPI_09_INT 36
196#define SE_GPI_08_INT 35
197/*34-32 unused*/
198
199/* Start Enable Internal Interrupts - table 57 page 65 */
200
201#define SE_INT_BASE_INT 0
202
203#define SE_TS_IRQ 31
204#define SE_TS_P_INT 30
205#define SE_TS_AUX_INT 29
206/*27-28 unused*/
207#define SE_USB_AHB_NEED_CLK_INT 26
208#define SE_MSTIMER_INT 25
209#define SE_RTC_INT 24
210#define SE_USB_NEED_CLK_INT 23
211#define SE_USB_INT 22
212#define SE_USB_I2C_INT 21
213#define SE_USB_OTG_TIMER_INT 20
214
215#endif /* __PNX4008_IRQS_h__ */
diff --git a/include/asm-arm/arch-pnx4008/memory.h b/include/asm-arm/arch-pnx4008/memory.h
new file mode 100644
index 000000000000..0d8268a95261
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/memory.h
@@ -0,0 +1,24 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/memory.h
3 *
4 * Copyright (c) 2005 Philips Semiconductors
5 * Copyright (c) 2005 MontaVista Software, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef __ASM_ARCH_MEMORY_H
14#define __ASM_ARCH_MEMORY_H
15
16/*
17 * Physical DRAM offset.
18 */
19#define PHYS_OFFSET (0x80000000)
20
21#define __virt_to_bus(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
22#define __bus_to_virt(x) ((x) + PAGE_OFFSET - PHYS_OFFSET)
23
24#endif
diff --git a/include/asm-arm/arch-pnx4008/param.h b/include/asm-arm/arch-pnx4008/param.h
new file mode 100644
index 000000000000..95d5f547b416
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/param.h
@@ -0,0 +1,21 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/param.h
3 *
4 * Copyright (C) 1999 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define HZ 100
diff --git a/include/asm-arm/arch-pnx4008/platform.h b/include/asm-arm/arch-pnx4008/platform.h
new file mode 100644
index 000000000000..485a3651b4d7
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/platform.h
@@ -0,0 +1,69 @@
1/*
2 * include/asm-arm/arch-pnx4008/platfrom.h
3 *
4 * PNX4008 Base addresses - header file
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * Based on reference code received from Philips:
9 * Copyright (C) 2003 Philips Semiconductors
10 *
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17
18#ifndef __ASM_ARCH_PLATFORM_H__
19#define __ASM_ARCH_PLATFORM_H__
20
21#define PNX4008_IRAM_BASE 0x08000000
22#define PNX4008_IRAM_SIZE 0x00010000
23#define PNX4008_YUV_SLAVE_BASE 0x10000000
24#define PNX4008_DUM_SLAVE_BASE 0x18000000
25#define PNX4008_NDF_FLASH_BASE 0x20020000
26#define PNX4008_SPI1_BASE 0x20088000
27#define PNX4008_SPI2_BASE 0x20090000
28#define PNX4008_SD_CONFIG_BASE 0x20098000
29#define PNX4008_FLASH_DATA 0x200B0000
30#define PNX4008_MLC_FLASH_BASE 0x200B8000
31#define PNX4008_JPEG_CONFIG_BASE 0x300A0000
32#define PNX4008_DMA_CONFIG_BASE 0x31000000
33#define PNX4008_USB_CONFIG_BASE 0x31020000
34#define PNX4008_SDRAM_CFG_BASE 0x31080000
35#define PNX4008_AHB2FAB_BASE 0x40000000
36#define PNX4008_PWRMAN_BASE 0x40004000
37#define PNX4008_INTCTRLMIC_BASE 0x40008000
38#define PNX4008_INTCTRLSIC1_BASE 0x4000C000
39#define PNX4008_INTCTRLSIC2_BASE 0x40010000
40#define PNX4008_HSUART1_BASE 0x40014000
41#define PNX4008_HSUART2_BASE 0x40018000
42#define PNX4008_HSUART7_BASE 0x4001C000
43#define PNX4008_RTC_BASE 0x40024000
44#define PNX4008_PIO_BASE 0x40028000
45#define PNX4008_MSTIMER_BASE 0x40034000
46#define PNX4008_HSTIMER_BASE 0x40038000
47#define PNX4008_WDOG_BASE 0x4003C000
48#define PNX4008_DEBUG_BASE 0x40040000
49#define PNX4008_TOUCH1_BASE 0x40048000
50#define PNX4008_KEYSCAN_BASE 0x40050000
51#define PNX4008_UARTCTRL_BASE 0x40054000
52#define PNX4008_PWM_BASE 0x4005C000
53#define PNX4008_UART3_BASE 0x40080000
54#define PNX4008_UART4_BASE 0x40088000
55#define PNX4008_UART5_BASE 0x40090000
56#define PNX4008_UART6_BASE 0x40098000
57#define PNX4008_I2C1_BASE 0x400A0000
58#define PNX4008_I2C2_BASE 0x400A8000
59#define PNX4008_MAGICGATE_BASE 0x400B0000
60#define PNX4008_DUMCONF_BASE 0x400B8000
61#define PNX4008_DUM_MAINCFG_BASE 0x400BC000
62#define PNX4008_DSP_BASE 0x400C0000
63#define PNX4008_PROFCOUNTER_BASE 0x400C8000
64#define PNX4008_CRYPTO_BASE 0x400D0000
65#define PNX4008_CAMIFCONF_BASE 0x400D8000
66#define PNX4008_YUV2RGB_BASE 0x400E0000
67#define PNX4008_AUDIOCONFIG_BASE 0x400E8000
68
69#endif
diff --git a/include/asm-arm/arch-pnx4008/pm.h b/include/asm-arm/arch-pnx4008/pm.h
new file mode 100644
index 000000000000..c660486670fb
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/pm.h
@@ -0,0 +1,62 @@
1/*
2 * include/asm-arm/arch-pnx4008/pm.h
3 *
4 * PNX4008 Power Management Routiness - header file
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __ASM_ARCH_PNX4008_PM_H
15#define __ASM_ARCH_PNX4008_PM_H
16
17#ifndef __ASSEMBLER__
18#include "irq.h"
19#include "irqs.h"
20#include "clock.h"
21
22extern void pnx4008_pm_idle(void);
23extern void pnx4008_pm_suspend(void);
24extern unsigned int pnx4008_cpu_suspend_sz;
25extern void pnx4008_cpu_suspend(void);
26extern unsigned int pnx4008_cpu_standby_sz;
27extern void pnx4008_cpu_standby(void);
28
29extern int pnx4008_startup_pll(struct clk *);
30extern int pnx4008_shutdown_pll(struct clk *);
31
32static inline void start_int_umask(u8 irq)
33{
34 __raw_writel(__raw_readl(START_INT_ER_REG(irq)) |
35 START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
36}
37
38static inline void start_int_mask(u8 irq)
39{
40 __raw_writel(__raw_readl(START_INT_ER_REG(irq)) &
41 ~START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
42}
43
44static inline void start_int_ack(u8 irq)
45{
46 __raw_writel(START_INT_REG_BIT(irq), START_INT_RSR_REG(irq));
47}
48
49static inline void start_int_set_falling_edge(u8 irq)
50{
51 __raw_writel(__raw_readl(START_INT_APR_REG(irq)) &
52 ~START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
53}
54
55static inline void start_int_set_rising_edge(u8 irq)
56{
57 __raw_writel(__raw_readl(START_INT_APR_REG(irq)) |
58 START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
59}
60
61#endif /* ASSEMBLER */
62#endif /* __ASM_ARCH_PNX4008_PM_H */
diff --git a/include/asm-arm/arch-pnx4008/system.h b/include/asm-arm/arch-pnx4008/system.h
new file mode 100644
index 000000000000..6e3da70ab107
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/system.h
@@ -0,0 +1,38 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/system.h
3 *
4 * Copyright (C) 2003 Philips Semiconductors
5 * Copyright (C) 2005 MontaVista Software, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef __ASM_ARCH_SYSTEM_H
22#define __ASM_ARCH_SYSTEM_H
23
24#include <asm/hardware.h>
25#include <asm/io.h>
26#include <asm/arch/platform.h>
27
28static void arch_idle(void)
29{
30 cpu_do_idle();
31}
32
33static inline void arch_reset(char mode)
34{
35 cpu_reset(0);
36}
37
38#endif
diff --git a/include/asm-arm/arch-pnx4008/timex.h b/include/asm-arm/arch-pnx4008/timex.h
new file mode 100644
index 000000000000..ee470a39089a
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/timex.h
@@ -0,0 +1,73 @@
1/*
2 * include/asm-arm/arch-pnx4008/timex.h
3 *
4 * PNX4008 timers header file
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __PNX4008_TIMEX_H
15#define __PNX4008_TIMEX_H
16
17#include <asm/hardware.h>
18#include <asm/io.h>
19
20#define CLOCK_TICK_RATE 1000000
21
22#define TICKS2USECS(x) (x)
23
24/* MilliSecond Timer - Chapter 21 Page 202 */
25
26#define MSTIM_INT IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
27#define MSTIM_CTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
28#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
29#define MSTIM_MCTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
30#define MSTIM_MATCH0 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
31#define MSTIM_MATCH1 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
32
33/* High Speed Timer - Chpater 22, Page 205 */
34
35#define HSTIM_INT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
36#define HSTIM_CTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
37#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
38#define HSTIM_PMATCH IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
39#define HSTIM_PCOUNT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
40#define HSTIM_MCTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
41#define HSTIM_MATCH0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
42#define HSTIM_MATCH1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
43#define HSTIM_MATCH2 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
44#define HSTIM_CCR IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
45#define HSTIM_CR0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
46#define HSTIM_CR1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
47
48/* IMPORTANT: both timers are UPCOUNTING */
49
50/* xSTIM_MCTRL bit definitions */
51#define MR0_INT 1
52#define RESET_COUNT0 (1<<1)
53#define STOP_COUNT0 (1<<2)
54#define MR1_INT (1<<3)
55#define RESET_COUNT1 (1<<4)
56#define STOP_COUNT1 (1<<5)
57#define MR2_INT (1<<6)
58#define RESET_COUNT2 (1<<7)
59#define STOP_COUNT2 (1<<8)
60
61/* xSTIM_CTRL bit definitions */
62#define COUNT_ENAB 1
63#define RESET_COUNT (1<<1)
64#define DEBUG_EN (1<<2)
65
66/* xSTIM_INT bit definitions */
67#define MATCH0_INT 1
68#define MATCH1_INT (1<<1)
69#define MATCH2_INT (1<<2)
70#define RTC_TICK0 (1<<4)
71#define RTC_TICK1 (1<<5)
72
73#endif
diff --git a/include/asm-arm/arch-pnx4008/uncompress.h b/include/asm-arm/arch-pnx4008/uncompress.h
new file mode 100644
index 000000000000..8fa4d24b72b4
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/uncompress.h
@@ -0,0 +1,46 @@
1/*
2 * linux/include/asm-arm/arch-pnx4008/uncompress.h
3 *
4 * Copyright (C) 1999 ARM Limited
5 * Copyright (C) 2006 MontaVista Software, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#define UART5_BASE 0x40090000
23
24#define UART5_DR (*(volatile unsigned char *) (UART5_BASE))
25#define UART5_FR (*(volatile unsigned char *) (UART5_BASE + 18))
26
27static __inline__ void putc(char c)
28{
29 while (UART5_FR & (1 << 5))
30 barrier();
31
32 UART5_DR = c;
33}
34
35/*
36 * This does not append a newline
37 */
38static inline void flush(void)
39{
40}
41
42/*
43 * nothing to do
44 */
45#define arch_decomp_setup()
46#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-pnx4008/vmalloc.h b/include/asm-arm/arch-pnx4008/vmalloc.h
new file mode 100644
index 000000000000..140d925f6f37
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/vmalloc.h
@@ -0,0 +1,20 @@
1/*
2 * include/asm-arm/arch-pnx4008/vmalloc.h
3 *
4 * Author: Vitaly Wool <source@mvista.com>
5 *
6 * 2006 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12/*
13 * Just any arbitrary offset to the start of the vmalloc VM area: the
14 * current 8MB value just means that there will be a 8MB "hole" after the
15 * physical memory until the kernel virtual memory starts. That means that
16 * any out-of-bounds memory accesses will hopefully be caught.
17 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
18 * area for the same reason. ;)
19 */
20#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
diff --git a/include/asm-arm/arch-pxa/idp.h b/include/asm-arm/arch-pxa/idp.h
index e7ef497417bb..b6952534a4e1 100644
--- a/include/asm-arm/arch-pxa/idp.h
+++ b/include/asm-arm/arch-pxa/idp.h
@@ -15,7 +15,6 @@
15 * Changes for 2.6 kernel. 15 * Changes for 2.6 kernel.
16 */ 16 */
17 17
18#include <linux/config.h>
19 18
20/* 19/*
21 * Note: this file must be safe to include in assembly files 20 * Note: this file must be safe to include in assembly files
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index 67af238a8f8e..f3bc70eee35b 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -10,7 +10,6 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/config.h>
14 13
15#ifdef CONFIG_PXA27x 14#ifdef CONFIG_PXA27x
16#define PXA_IRQ_SKIP 0 15#define PXA_IRQ_SKIP 0
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index c8f53a71c076..6650d4decaeb 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -13,7 +13,6 @@
13#ifndef __PXA_REGS_H 13#ifndef __PXA_REGS_H
14#define __PXA_REGS_H 14#define __PXA_REGS_H
15 15
16#include <linux/config.h>
17 16
18/* 17/*
19 * PXA Chip selects 18 * PXA Chip selects
diff --git a/include/asm-arm/arch-pxa/timex.h b/include/asm-arm/arch-pxa/timex.h
index aa125ec56a32..2473bb51d0a6 100644
--- a/include/asm-arm/arch-pxa/timex.h
+++ b/include/asm-arm/arch-pxa/timex.h
@@ -10,7 +10,6 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/config.h>
14 13
15#if defined(CONFIG_PXA25x) 14#if defined(CONFIG_PXA25x)
16/* PXA250/210 timer base */ 15/* PXA250/210 timer base */
diff --git a/include/asm-arm/arch-realview/smp.h b/include/asm-arm/arch-realview/smp.h
index fc87783e8e8b..515819efd046 100644
--- a/include/asm-arm/arch-realview/smp.h
+++ b/include/asm-arm/arch-realview/smp.h
@@ -1,7 +1,6 @@
1#ifndef ASMARM_ARCH_SMP_H 1#ifndef ASMARM_ARCH_SMP_H
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <linux/config.h>
5 4
6#include <asm/hardware/gic.h> 5#include <asm/hardware/gic.h>
7 6
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index b011e14f3bc6..72964f9b8414 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_ARCH_DMA_H 18#ifndef __ASM_ARCH_DMA_H
19#define __ASM_ARCH_DMA_H __FILE__ 19#define __ASM_ARCH_DMA_H __FILE__
20 20
21#include <linux/config.h>
22#include <linux/sysdev.h> 21#include <linux/sysdev.h>
23#include "hardware.h" 22#include "hardware.h"
24 23
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h
index c380d264a847..5e4c8c37bc66 100644
--- a/include/asm-arm/arch-s3c2410/map.h
+++ b/include/asm-arm/arch-s3c2410/map.h
@@ -126,9 +126,18 @@
126#define S3C24XX_SZ_IIS SZ_1M 126#define S3C24XX_SZ_IIS SZ_1M
127 127
128/* GPIO ports */ 128/* GPIO ports */
129#define S3C24XX_VA_GPIO S3C2410_ADDR(0x00E00000) 129
130/* the calculation for the VA of this must ensure that
131 * it is the same distance apart from the UART in the
132 * phsyical address space, as the initial mapping for the IO
133 * is done as a 1:1 maping. This puts it (currently) at
134 * 0xF6800000, which is not in the way of any current mapping
135 * by the base system.
136*/
137
130#define S3C2400_PA_GPIO (0x15600000) 138#define S3C2400_PA_GPIO (0x15600000)
131#define S3C2410_PA_GPIO (0x56000000) 139#define S3C2410_PA_GPIO (0x56000000)
140#define S3C24XX_VA_GPIO ((S3C2410_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
132#define S3C24XX_SZ_GPIO SZ_1M 141#define S3C24XX_SZ_GPIO SZ_1M
133 142
134/* RTC */ 143/* RTC */
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index 34360706e016..6c92faffe985 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -114,7 +114,7 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
114 114
115#endif /* __ASSEMBLY__ */ 115#endif /* __ASSEMBLY__ */
116 116
117#ifdef CONFIG_CPU_S3C2440 117#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
118 118
119/* extra registers */ 119/* extra registers */
120#define S3C2440_CAMDIVN S3C2410_CLKREG(0x18) 120#define S3C2440_CAMDIVN S3C2410_CLKREG(0x18)
@@ -136,7 +136,9 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
136#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9) 136#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
137#define S3C2440_CAMDIVN_DVSEN (1<<12) 137#define S3C2440_CAMDIVN_DVSEN (1<<12)
138 138
139#endif /* CONFIG_CPU_S3C2440 */ 139#define S3C2442_CAMDIVN_CAMCLK_DIV3 (1<<5)
140
141#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
140 142
141 143
142#endif /* __ASM_ARM_REGS_CLOCK */ 144#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index d2574084697f..5f10334f06bf 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -450,12 +450,14 @@
450#define S3C2410_GPD0_OUTP (0x01 << 0) 450#define S3C2410_GPD0_OUTP (0x01 << 0)
451#define S3C2410_GPD0_VD8 (0x02 << 0) 451#define S3C2410_GPD0_VD8 (0x02 << 0)
452#define S3C2400_GPD0_VFRAME (0x02 << 0) 452#define S3C2400_GPD0_VFRAME (0x02 << 0)
453#define S3C2442_GPD0_nSPICS1 (0x03 << 0)
453 454
454#define S3C2410_GPD1 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 1) 455#define S3C2410_GPD1 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 1)
455#define S3C2410_GPD1_INP (0x00 << 2) 456#define S3C2410_GPD1_INP (0x00 << 2)
456#define S3C2410_GPD1_OUTP (0x01 << 2) 457#define S3C2410_GPD1_OUTP (0x01 << 2)
457#define S3C2410_GPD1_VD9 (0x02 << 2) 458#define S3C2410_GPD1_VD9 (0x02 << 2)
458#define S3C2400_GPD1_VM (0x02 << 2) 459#define S3C2400_GPD1_VM (0x02 << 2)
460#define S3C2442_GPD1_SPICLK1 (0x03 << 2)
459 461
460#define S3C2410_GPD2 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 2) 462#define S3C2410_GPD2 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 2)
461#define S3C2410_GPD2_INP (0x00 << 4) 463#define S3C2410_GPD2_INP (0x00 << 4)
@@ -858,6 +860,7 @@
858#define S3C2410_GPG12_OUTP (0x01 << 24) 860#define S3C2410_GPG12_OUTP (0x01 << 24)
859#define S3C2410_GPG12_EINT20 (0x02 << 24) 861#define S3C2410_GPG12_EINT20 (0x02 << 24)
860#define S3C2410_GPG12_XMON (0x03 << 24) 862#define S3C2410_GPG12_XMON (0x03 << 24)
863#define S3C2442_GPG12_nSPICS0 (0x03 << 24)
861 864
862#define S3C2410_GPG13 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13) 865#define S3C2410_GPG13 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13)
863#define S3C2410_GPG13_INP (0x00 << 26) 866#define S3C2410_GPG13_INP (0x00 << 26)
@@ -943,6 +946,7 @@
943#define S3C2410_GPH9_INP (0x00 << 18) 946#define S3C2410_GPH9_INP (0x00 << 18)
944#define S3C2410_GPH9_OUTP (0x01 << 18) 947#define S3C2410_GPH9_OUTP (0x01 << 18)
945#define S3C2410_GPH9_CLKOUT0 (0x02 << 18) 948#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
949#define S3C2442_GPH9_nSPICS0 (0x03 << 18)
946 950
947#define S3C2410_GPH10 S3C2410_GPIONO(S3C2410_GPIO_BANKH, 10) 951#define S3C2410_GPH10 S3C2410_GPIONO(S3C2410_GPIO_BANKH, 10)
948#define S3C2410_GPH10_INP (0x00 << 20) 952#define S3C2410_GPH10_INP (0x00 << 20)
@@ -1051,6 +1055,7 @@
1051#define S3C2410_GSTATUS1_IDMASK (0xffff0000) 1055#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
1052#define S3C2410_GSTATUS1_2410 (0x32410000) 1056#define S3C2410_GSTATUS1_2410 (0x32410000)
1053#define S3C2410_GSTATUS1_2440 (0x32440000) 1057#define S3C2410_GSTATUS1_2440 (0x32440000)
1058#define S3C2410_GSTATUS1_2442 (0x32440aaa)
1054 1059
1055#define S3C2410_GSTATUS2_WTRESET (1<<2) 1060#define S3C2410_GSTATUS2_WTRESET (1<<2)
1056#define S3C2410_GSTATUS2_OFFRESET (1<<1) 1061#define S3C2410_GSTATUS2_OFFRESET (1<<1)
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h
index a6f6a0e44afa..8e152a05e533 100644
--- a/include/asm-arm/arch-s3c2410/uncompress.h
+++ b/include/asm-arm/arch-s3c2410/uncompress.h
@@ -22,7 +22,6 @@
22#ifndef __ASM_ARCH_UNCOMPRESS_H 22#ifndef __ASM_ARCH_UNCOMPRESS_H
23#define __ASM_ARCH_UNCOMPRESS_H 23#define __ASM_ARCH_UNCOMPRESS_H
24 24
25#include <linux/config.h>
26 25
27/* defines for UART registers */ 26/* defines for UART registers */
28#include "asm/arch/regs-serial.h" 27#include "asm/arch/regs-serial.h"
@@ -82,7 +81,8 @@ static void putc(int ch)
82 while (1) { 81 while (1) {
83 level = uart_rd(S3C2410_UFSTAT); 82 level = uart_rd(S3C2410_UFSTAT);
84 83
85 if (cpuid == S3C2410_GSTATUS1_2440) { 84 if (cpuid == S3C2410_GSTATUS1_2440 ||
85 cpuid == S3C2410_GSTATUS1_2442) {
86 level &= S3C2440_UFSTAT_TXMASK; 86 level &= S3C2440_UFSTAT_TXMASK;
87 level >>= S3C2440_UFSTAT_TXSHIFT; 87 level >>= S3C2440_UFSTAT_TXSHIFT;
88 } else { 88 } else {
@@ -130,7 +130,7 @@ static void arch_decomp_wdog_start(void)
130{ 130{
131 __raw_writel(WDOG_COUNT, S3C2410_WTDAT); 131 __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
132 __raw_writel(WDOG_COUNT, S3C2410_WTCNT); 132 __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
133 __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); 133 __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
134} 134}
135 135
136#else 136#else
diff --git a/include/asm-arm/arch-sa1100/assabet.h b/include/asm-arm/arch-sa1100/assabet.h
index 1f59b368c3f6..d6a1bb5b4944 100644
--- a/include/asm-arm/arch-sa1100/assabet.h
+++ b/include/asm-arm/arch-sa1100/assabet.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_ARCH_ASSABET_H 12#ifndef __ASM_ARCH_ASSABET_H
13#define __ASM_ARCH_ASSABET_H 13#define __ASM_ARCH_ASSABET_H
14 14
15#include <linux/config.h>
16 15
17/* System Configuration Register flags */ 16/* System Configuration Register flags */
18 17
diff --git a/include/asm-arm/arch-sa1100/cerf.h b/include/asm-arm/arch-sa1100/cerf.h
index 356d5ba88991..9a19c3d07c1e 100644
--- a/include/asm-arm/arch-sa1100/cerf.h
+++ b/include/asm-arm/arch-sa1100/cerf.h
@@ -10,7 +10,6 @@
10#ifndef _INCLUDE_CERF_H_ 10#ifndef _INCLUDE_CERF_H_
11#define _INCLUDE_CERF_H_ 11#define _INCLUDE_CERF_H_
12 12
13#include <linux/config.h>
14 13
15#define CERF_ETH_IO 0xf0000000 14#define CERF_ETH_IO 0xf0000000
16#define CERF_ETH_IRQ IRQ_GPIO26 15#define CERF_ETH_IRQ IRQ_GPIO26
diff --git a/include/asm-arm/arch-sa1100/collie.h b/include/asm-arm/arch-sa1100/collie.h
index d49e5ff63ca4..14a344aa3cc7 100644
--- a/include/asm-arm/arch-sa1100/collie.h
+++ b/include/asm-arm/arch-sa1100/collie.h
@@ -13,7 +13,6 @@
13#ifndef __ASM_ARCH_COLLIE_H 13#ifndef __ASM_ARCH_COLLIE_H
14#define __ASM_ARCH_COLLIE_H 14#define __ASM_ARCH_COLLIE_H
15 15
16#include <linux/config.h>
17 16
18#define COLLIE_SCP_CHARGE_ON SCOOP_GPCR_PA11 17#define COLLIE_SCP_CHARGE_ON SCOOP_GPCR_PA11
19#define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12 18#define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12
diff --git a/include/asm-arm/arch-sa1100/dma.h b/include/asm-arm/arch-sa1100/dma.h
index 02575d72ac6b..6b7917a2e77a 100644
--- a/include/asm-arm/arch-sa1100/dma.h
+++ b/include/asm-arm/arch-sa1100/dma.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_ARCH_DMA_H 10#ifndef __ASM_ARCH_DMA_H
11#define __ASM_ARCH_DMA_H 11#define __ASM_ARCH_DMA_H
12 12
13#include <linux/config.h>
14#include "hardware.h" 13#include "hardware.h"
15 14
16 15
diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h
index ee008a5484f3..1abd7cfc8bce 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_ARCH_HARDWARE_H 12#ifndef __ASM_ARCH_HARDWARE_H
13#define __ASM_ARCH_HARDWARE_H 13#define __ASM_ARCH_HARDWARE_H
14 14
15#include <linux/config.h>
16 15
17#define UNCACHEABLE_ADDR 0xfa050000 16#define UNCACHEABLE_ADDR 0xfa050000
18 17
diff --git a/include/asm-arm/arch-sa1100/ide.h b/include/asm-arm/arch-sa1100/ide.h
index 2153538069c7..98b10bcf9f1b 100644
--- a/include/asm-arm/arch-sa1100/ide.h
+++ b/include/asm-arm/arch-sa1100/ide.h
@@ -9,7 +9,6 @@
9 * architectures. 9 * architectures.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <asm/irq.h> 12#include <asm/irq.h>
14#include <asm/hardware.h> 13#include <asm/hardware.h>
15#include <asm/mach-types.h> 14#include <asm/mach-types.h>
diff --git a/include/asm-arm/arch-sa1100/irqs.h b/include/asm-arm/arch-sa1100/irqs.h
index eabd3be3d705..d7940683efb1 100644
--- a/include/asm-arm/arch-sa1100/irqs.h
+++ b/include/asm-arm/arch-sa1100/irqs.h
@@ -7,7 +7,6 @@
7 * 7 *
8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs. 8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
9 */ 9 */
10#include <linux/config.h>
11 10
12#define IRQ_GPIO0 0 11#define IRQ_GPIO0 0
13#define IRQ_GPIO1 1 12#define IRQ_GPIO1 1
diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h
index a29fac1387ca..1ff172dc8e33 100644
--- a/include/asm-arm/arch-sa1100/memory.h
+++ b/include/asm-arm/arch-sa1100/memory.h
@@ -7,7 +7,6 @@
7#ifndef __ASM_ARCH_MEMORY_H 7#ifndef __ASM_ARCH_MEMORY_H
8#define __ASM_ARCH_MEMORY_H 8#define __ASM_ARCH_MEMORY_H
9 9
10#include <linux/config.h>
11#include <asm/sizes.h> 10#include <asm/sizes.h>
12 11
13/* 12/*
diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h
index 0f0612f79b2b..aef91e3b63fe 100644
--- a/include/asm-arm/arch-sa1100/system.h
+++ b/include/asm-arm/arch-sa1100/system.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Copyright (c) 1999 Nicolas Pitre <nico@cam.org> 4 * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
5 */ 5 */
6#include <linux/config.h>
7#include <asm/hardware.h> 6#include <asm/hardware.h>
8 7
9static inline void arch_idle(void) 8static inline void arch_idle(void)
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index 3d7283d84405..4b0ce3e7de9a 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_ARM_ATOMIC_H 11#ifndef __ASM_ARM_ATOMIC_H
12#define __ASM_ARM_ATOMIC_H 12#define __ASM_ARM_ATOMIC_H
13 13
14#include <linux/config.h>
15#include <linux/compiler.h> 14#include <linux/compiler.h>
16 15
17typedef struct { volatile int counter; } atomic_t; 16typedef struct { volatile int counter; } atomic_t;
diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h
index 5ab8216f5204..7fb02138f585 100644
--- a/include/asm-arm/bug.h
+++ b/include/asm-arm/bug.h
@@ -2,7 +2,6 @@
2#define _ASMARM_BUG_H 2#define _ASMARM_BUG_H
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5#include <linux/stddef.h>
6 5
7#ifdef CONFIG_BUG 6#ifdef CONFIG_BUG
8#ifdef CONFIG_DEBUG_BUGVERBOSE 7#ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 746be56b1b70..fe0c744e0266 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -10,7 +10,6 @@
10#ifndef _ASMARM_CACHEFLUSH_H 10#ifndef _ASMARM_CACHEFLUSH_H
11#define _ASMARM_CACHEFLUSH_H 11#define _ASMARM_CACHEFLUSH_H
12 12
13#include <linux/config.h>
14#include <linux/sched.h> 13#include <linux/sched.h>
15#include <linux/mm.h> 14#include <linux/mm.h>
16 15
diff --git a/include/asm-arm/cpu.h b/include/asm-arm/cpu.h
index 751bc7462074..715426b9b08e 100644
--- a/include/asm-arm/cpu.h
+++ b/include/asm-arm/cpu.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_ARM_CPU_H 10#ifndef __ASM_ARM_CPU_H
11#define __ASM_ARM_CPU_H 11#define __ASM_ARM_CPU_H
12 12
13#include <linux/config.h>
14#include <linux/percpu.h> 13#include <linux/percpu.h>
15 14
16struct cpuinfo_arm { 15struct cpuinfo_arm {
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 63ca7412a462..55eb4dc3253d 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7#include <linux/mm.h> /* need struct page */ 6#include <linux/mm.h> /* need struct page */
8 7
9#include <asm/scatterlist.h> 8#include <asm/scatterlist.h>
diff --git a/include/asm-arm/dma.h b/include/asm-arm/dma.h
index 49c01e2bf7c8..9f2c5305c260 100644
--- a/include/asm-arm/dma.h
+++ b/include/asm-arm/dma.h
@@ -3,7 +3,6 @@
3 3
4typedef unsigned int dmach_t; 4typedef unsigned int dmach_t;
5 5
6#include <linux/config.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
8#include <asm/system.h> 7#include <asm/system.h>
9#include <asm/scatterlist.h> 8#include <asm/scatterlist.h>
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index 2d44b42d1847..71061ca5c5d0 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -1,7 +1,6 @@
1#ifndef __ASMARM_ELF_H 1#ifndef __ASMARM_ELF_H
2#define __ASMARM_ELF_H 2#define __ASMARM_ELF_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * ELF register definitions.. 6 * ELF register definitions..
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h
index 52bae088a185..132c3c5628b2 100644
--- a/include/asm-arm/fpstate.h
+++ b/include/asm-arm/fpstate.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_ARM_FPSTATE_H 11#ifndef __ASM_ARM_FPSTATE_H
12#define __ASM_ARM_FPSTATE_H 12#define __ASM_ARM_FPSTATE_H
13 13
14#include <linux/config.h>
15 14
16#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
17 16
diff --git a/include/asm-arm/glue.h b/include/asm-arm/glue.h
index 223e0d6c41be..0cc5d3b10ce2 100644
--- a/include/asm-arm/glue.h
+++ b/include/asm-arm/glue.h
@@ -15,7 +15,6 @@
15 */ 15 */
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/config.h>
19 18
20#ifdef __STDC__ 19#ifdef __STDC__
21#define ____glue(name,fn) name##fn 20#define ____glue(name,fn) name##fn
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index 1cbb173bf5b1..182310b99195 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_HARDIRQ_H 1#ifndef __ASM_HARDIRQ_H
2#define __ASM_HARDIRQ_H 2#define __ASM_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/cache.h> 4#include <linux/cache.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <asm/irq.h> 6#include <asm/irq.h>
diff --git a/include/asm-arm/hardware/dec21285.h b/include/asm-arm/hardware/dec21285.h
index 6685e3fb97b1..546f7077be9c 100644
--- a/include/asm-arm/hardware/dec21285.h
+++ b/include/asm-arm/hardware/dec21285.h
@@ -18,7 +18,6 @@
18#define DC21285_PCI_IO 0x7c000000 18#define DC21285_PCI_IO 0x7c000000
19#define DC21285_PCI_MEM 0x80000000 19#define DC21285_PCI_MEM 0x80000000
20 20
21#include <linux/config.h>
22#ifndef __ASSEMBLY__ 21#ifndef __ASSEMBLY__
23#include <asm/hardware.h> 22#include <asm/hardware.h>
24#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x))) 23#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
diff --git a/include/asm-arm/hardware/iomd.h b/include/asm-arm/hardware/iomd.h
index 82fa2c279a18..396e55ad06c6 100644
--- a/include/asm-arm/hardware/iomd.h
+++ b/include/asm-arm/hardware/iomd.h
@@ -13,7 +13,6 @@
13#ifndef __ASMARM_HARDWARE_IOMD_H 13#ifndef __ASMARM_HARDWARE_IOMD_H
14#define __ASMARM_HARDWARE_IOMD_H 14#define __ASMARM_HARDWARE_IOMD_H
15 15
16#include <linux/config.h>
17 16
18#ifndef __ASSEMBLY__ 17#ifndef __ASSEMBLY__
19 18
diff --git a/include/asm-arm/leds.h b/include/asm-arm/leds.h
index 88ce4124f854..12290ea55801 100644
--- a/include/asm-arm/leds.h
+++ b/include/asm-arm/leds.h
@@ -13,7 +13,6 @@
13#ifndef ASM_ARM_LEDS_H 13#ifndef ASM_ARM_LEDS_H
14#define ASM_ARM_LEDS_H 14#define ASM_ARM_LEDS_H
15 15
16#include <linux/config.h>
17 16
18typedef enum { 17typedef enum {
19 led_idle_start, 18 led_idle_start,
diff --git a/include/asm-arm/mach/serial_at91rm9200.h b/include/asm-arm/mach/serial_at91rm9200.h
index 98f4b0cb883c..a0269de12079 100644
--- a/include/asm-arm/mach/serial_at91rm9200.h
+++ b/include/asm-arm/mach/serial_at91rm9200.h
@@ -7,7 +7,6 @@
7 * 7 *
8 * Low level machine dependent UART functions. 8 * Low level machine dependent UART functions.
9 */ 9 */
10#include <linux/config.h>
11 10
12struct uart_port; 11struct uart_port;
13 12
diff --git a/include/asm-arm/mach/serial_sa1100.h b/include/asm-arm/mach/serial_sa1100.h
index 9162018585df..20c22bb218d9 100644
--- a/include/asm-arm/mach/serial_sa1100.h
+++ b/include/asm-arm/mach/serial_sa1100.h
@@ -7,7 +7,6 @@
7 * 7 *
8 * Low level machine dependent UART functions. 8 * Low level machine dependent UART functions.
9 */ 9 */
10#include <linux/config.h>
11 10
12struct uart_port; 11struct uart_port;
13struct uart_info; 12struct uart_info;
diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h
index 96c6db7dd0e1..9f28073559e8 100644
--- a/include/asm-arm/mach/time.h
+++ b/include/asm-arm/mach/time.h
@@ -50,6 +50,7 @@ struct sys_timer {
50#define DYN_TICK_ENABLED (1 << 1) 50#define DYN_TICK_ENABLED (1 << 1)
51 51
52struct dyn_tick_timer { 52struct dyn_tick_timer {
53 spinlock_t lock;
53 unsigned int state; /* Current state */ 54 unsigned int state; /* Current state */
54 int (*enable)(void); /* Enables dynamic tick */ 55 int (*enable)(void); /* Enables dynamic tick */
55 int (*disable)(void); /* Disables dynamic tick */ 56 int (*disable)(void); /* Disables dynamic tick */
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index 209289407595..731e321a57d1 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -22,7 +22,6 @@
22#define UL(x) (x) 22#define UL(x) (x)
23#endif 23#endif
24 24
25#include <linux/config.h>
26#include <linux/compiler.h> 25#include <linux/compiler.h>
27#include <asm/arch/memory.h> 26#include <asm/arch/memory.h>
28#include <asm/sizes.h> 27#include <asm/sizes.h>
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index a404d2bf0c68..66cfeb5290ea 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -10,7 +10,6 @@
10#ifndef _ASMARM_PAGE_H 10#ifndef _ASMARM_PAGE_H
11#define _ASMARM_PAGE_H 11#define _ASMARM_PAGE_H
12 12
13#include <linux/config.h>
14 13
15/* PAGE_SHIFT determines the page size */ 14/* PAGE_SHIFT determines the page size */
16#define PAGE_SHIFT 12 15#define PAGE_SHIFT 12
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index ead3ced38cb8..f21abd4ddac6 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -2,7 +2,6 @@
2#define ASMARM_PCI_H 2#define ASMARM_PCI_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#include <linux/config.h>
6#include <asm-generic/pci-dma-compat.h> 5#include <asm-generic/pci-dma-compat.h>
7 6
8#include <asm/hardware.h> /* for PCIBIOS_MIN_* */ 7#include <asm/hardware.h> /* for PCIBIOS_MIN_* */
diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h
index 106045edb862..e9310895e79d 100644
--- a/include/asm-arm/proc-fns.h
+++ b/include/asm-arm/proc-fns.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17 16
18/* 17/*
19 * Work out if we need multiple CPU support 18 * Work out if we need multiple CPU support
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
index 77adb7fa169b..2bebe3dc0a30 100644
--- a/include/asm-arm/ptrace.h
+++ b/include/asm-arm/ptrace.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_ARM_PTRACE_H 10#ifndef __ASM_ARM_PTRACE_H
11#define __ASM_ARM_PTRACE_H 11#define __ASM_ARM_PTRACE_H
12 12
13#include <linux/config.h>
14 13
15#define PTRACE_GETREGS 12 14#define PTRACE_GETREGS 12
16#define PTRACE_SETREGS 13 15#define PTRACE_SETREGS 13
diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h
index fe45f7f61223..f67acce387e7 100644
--- a/include/asm-arm/smp.h
+++ b/include/asm-arm/smp.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_ARM_SMP_H 10#ifndef __ASM_ARM_SMP_H
11#define __ASM_ARM_SMP_H 11#define __ASM_ARM_SMP_H
12 12
13#include <linux/config.h>
14#include <linux/threads.h> 13#include <linux/threads.h>
15#include <linux/cpumask.h> 14#include <linux/cpumask.h>
16#include <linux/thread_info.h> 15#include <linux/thread_info.h>
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 7c9568d30307..9c744ae6c6e3 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8#define CPU_ARCH_UNKNOWN 0 7#define CPU_ARCH_UNKNOWN 0
9#define CPU_ARCH_ARMv3 1 8#define CPU_ARCH_ARMv3 1
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 728992451dd1..d97fc76189a5 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -10,7 +10,6 @@
10#ifndef _ASMARM_TLBFLUSH_H 10#ifndef _ASMARM_TLBFLUSH_H
11#define _ASMARM_TLBFLUSH_H 11#define _ASMARM_TLBFLUSH_H
12 12
13#include <linux/config.h>
14 13
15#ifndef CONFIG_MMU 14#ifndef CONFIG_MMU
16 15
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index cbf39a56dbe7..1e891f860ef3 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -13,8 +13,6 @@
13#ifndef __ASM_ARM_UNISTD_H 13#ifndef __ASM_ARM_UNISTD_H
14#define __ASM_ARM_UNISTD_H 14#define __ASM_ARM_UNISTD_H
15 15
16#include <linux/linkage.h>
17
18#define __NR_OABI_SYSCALL_BASE 0x900000 16#define __NR_OABI_SYSCALL_BASE 0x900000
19 17
20#if defined(__thumb__) || defined(__ARM_EABI__) 18#if defined(__thumb__) || defined(__ARM_EABI__)
@@ -378,6 +376,9 @@
378#undef __NR_ipc 376#undef __NR_ipc
379#endif 377#endif
380 378
379#ifdef __KERNEL__
380#include <linux/linkage.h>
381
381#define __sys2(x) #x 382#define __sys2(x) #x
382#define __sys1(x) __sys2(x) 383#define __sys1(x) __sys2(x)
383 384
@@ -526,7 +527,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
526 __syscall_return(type,__res); \ 527 __syscall_return(type,__res); \
527} 528}
528 529
529#ifdef __KERNEL__
530#define __ARCH_WANT_IPC_PARSE_VERSION 530#define __ARCH_WANT_IPC_PARSE_VERSION
531#define __ARCH_WANT_STAT64 531#define __ARCH_WANT_STAT64
532#define __ARCH_WANT_SYS_GETHOSTNAME 532#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -547,7 +547,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
547#define __ARCH_WANT_OLD_READDIR 547#define __ARCH_WANT_OLD_READDIR
548#define __ARCH_WANT_SYS_SOCKETCALL 548#define __ARCH_WANT_SYS_SOCKETCALL
549#endif 549#endif
550#endif
551 550
552#ifdef __KERNEL_SYSCALLS__ 551#ifdef __KERNEL_SYSCALLS__
553 552
@@ -571,7 +570,7 @@ asmlinkage long sys_rt_sigaction(int sig,
571 struct sigaction __user *oact, 570 struct sigaction __user *oact,
572 size_t sigsetsize); 571 size_t sigsetsize);
573 572
574#endif 573#endif /* __KERNEL_SYSCALLS__ */
575 574
576/* 575/*
577 * "Conditional" syscalls 576 * "Conditional" syscalls
@@ -581,4 +580,5 @@ asmlinkage long sys_rt_sigaction(int sig,
581 */ 580 */
582#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 581#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
583 582
583#endif /* __KERNEL__ */
584#endif /* __ASM_ARM_UNISTD_H */ 584#endif /* __ASM_ARM_UNISTD_H */
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index 1552c8653990..97e944fe1cff 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -20,7 +20,6 @@
20#ifndef __ASM_ARM_ATOMIC_H 20#ifndef __ASM_ARM_ATOMIC_H
21#define __ASM_ARM_ATOMIC_H 21#define __ASM_ARM_ATOMIC_H
22 22
23#include <linux/config.h>
24 23
25#ifdef CONFIG_SMP 24#ifdef CONFIG_SMP
26#error SMP is NOT supported 25#error SMP is NOT supported
diff --git a/include/asm-arm26/bug.h b/include/asm-arm26/bug.h
index 7177c7399967..8545d58b0475 100644
--- a/include/asm-arm26/bug.h
+++ b/include/asm-arm26/bug.h
@@ -1,7 +1,6 @@
1#ifndef _ASMARM_BUG_H 1#ifndef _ASMARM_BUG_H
2#define _ASMARM_BUG_H 2#define _ASMARM_BUG_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_BUG 5#ifdef CONFIG_BUG
7#ifdef CONFIG_DEBUG_BUGVERBOSE 6#ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/include/asm-arm26/dma.h b/include/asm-arm26/dma.h
index 995e223e43a1..4326ba85eb72 100644
--- a/include/asm-arm26/dma.h
+++ b/include/asm-arm26/dma.h
@@ -3,7 +3,6 @@
3 3
4typedef unsigned int dmach_t; 4typedef unsigned int dmach_t;
5 5
6#include <linux/config.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
8#include <asm/system.h> 7#include <asm/system.h>
9#include <asm/memory.h> 8#include <asm/memory.h>
diff --git a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h
index 87c19d2bb6a8..e717742ffce0 100644
--- a/include/asm-arm26/hardirq.h
+++ b/include/asm-arm26/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_HARDIRQ_H 1#ifndef __ASM_HARDIRQ_H
2#define __ASM_HARDIRQ_H 2#define __ASM_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/cache.h> 4#include <linux/cache.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <asm/irq.h> 6#include <asm/irq.h>
diff --git a/include/asm-arm26/hardware.h b/include/asm-arm26/hardware.h
index 82fc55e2a009..801df0bde8b7 100644
--- a/include/asm-arm26/hardware.h
+++ b/include/asm-arm26/hardware.h
@@ -16,7 +16,6 @@
16#ifndef __ASM_HARDWARE_H 16#ifndef __ASM_HARDWARE_H
17#define __ASM_HARDWARE_H 17#define __ASM_HARDWARE_H
18 18
19#include <linux/config.h>
20 19
21 20
22/* 21/*
diff --git a/include/asm-arm26/io.h b/include/asm-arm26/io.h
index 02f94d88a124..2aa033bd0678 100644
--- a/include/asm-arm26/io.h
+++ b/include/asm-arm26/io.h
@@ -22,7 +22,6 @@
22 22
23#ifdef __KERNEL__ 23#ifdef __KERNEL__
24 24
25#include <linux/config.h>
26#include <linux/types.h> 25#include <linux/types.h>
27#include <asm/byteorder.h> 26#include <asm/byteorder.h>
28#include <asm/memory.h> 27#include <asm/memory.h>
diff --git a/include/asm-arm26/leds.h b/include/asm-arm26/leds.h
index 88ce4124f854..12290ea55801 100644
--- a/include/asm-arm26/leds.h
+++ b/include/asm-arm26/leds.h
@@ -13,7 +13,6 @@
13#ifndef ASM_ARM_LEDS_H 13#ifndef ASM_ARM_LEDS_H
14#define ASM_ARM_LEDS_H 14#define ASM_ARM_LEDS_H
15 15
16#include <linux/config.h>
17 16
18typedef enum { 17typedef enum {
19 led_idle_start, 18 led_idle_start,
diff --git a/include/asm-arm26/mach-types.h b/include/asm-arm26/mach-types.h
index b34045b78128..0aeaedcbac96 100644
--- a/include/asm-arm26/mach-types.h
+++ b/include/asm-arm26/mach-types.h
@@ -6,7 +6,6 @@
6#ifndef __ASM_ARM_MACH_TYPE_H 6#ifndef __ASM_ARM_MACH_TYPE_H
7#define __ASM_ARM_MACH_TYPE_H 7#define __ASM_ARM_MACH_TYPE_H
8 8
9#include <linux/config.h>
10 9
11#ifndef __ASSEMBLY__ 10#ifndef __ASSEMBLY__
12extern unsigned int __machine_arch_type; 11extern unsigned int __machine_arch_type;
diff --git a/include/asm-arm26/page.h b/include/asm-arm26/page.h
index d3f23ac4d468..fa19de28fda0 100644
--- a/include/asm-arm26/page.h
+++ b/include/asm-arm26/page.h
@@ -1,7 +1,6 @@
1#ifndef _ASMARM_PAGE_H 1#ifndef _ASMARM_PAGE_H
2#define _ASMARM_PAGE_H 2#define _ASMARM_PAGE_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7#ifndef __ASSEMBLY__ 6#ifndef __ASSEMBLY__
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index a590250277f8..19ac9101a6bb 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -13,7 +13,6 @@
13 13
14#include <asm-generic/4level-fixup.h> 14#include <asm-generic/4level-fixup.h>
15 15
16#include <linux/config.h>
17#include <asm/memory.h> 16#include <asm/memory.h>
18 17
19/* 18/*
diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h
index 5fc747d1b501..dd86a716cb0b 100644
--- a/include/asm-arm26/serial.h
+++ b/include/asm-arm26/serial.h
@@ -14,7 +14,6 @@
14#ifndef __ASM_SERIAL_H 14#ifndef __ASM_SERIAL_H
15#define __ASM_SERIAL_H 15#define __ASM_SERIAL_H
16 16
17#include <linux/config.h>
18 17
19/* 18/*
20 * This assumes you have a 1.8432 MHz clock for your UART. 19 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-arm26/smp.h b/include/asm-arm26/smp.h
index 5ca771631fd8..38349ec8b61b 100644
--- a/include/asm-arm26/smp.h
+++ b/include/asm-arm26/smp.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SMP_H 1#ifndef __ASM_SMP_H
2#define __ASM_SMP_H 2#define __ASM_SMP_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_SMP 5#ifdef CONFIG_SMP
7#error SMP not supported 6#error SMP not supported
diff --git a/include/asm-arm26/sysirq.h b/include/asm-arm26/sysirq.h
index cad250c7b9ec..81dca90d9a3f 100644
--- a/include/asm-arm26/sysirq.h
+++ b/include/asm-arm26/sysirq.h
@@ -11,7 +11,6 @@
11 * 04-04-1998 PJB Merged arc and a5k versions 11 * 04-04-1998 PJB Merged arc and a5k versions
12 */ 12 */
13 13
14#include <linux/config.h>
15 14
16#if defined(CONFIG_ARCH_A5K) 15#if defined(CONFIG_ARCH_A5K)
17#define IRQ_PRINTER 0 16#define IRQ_PRINTER 0
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index 702884926a55..d1f69d706198 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8/* 7/*
9 * This is used to ensure the compiler did actually allocate the register we 8 * This is used to ensure the compiler did actually allocate the register we
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
index be4c2fb9c049..70eb6d91cfd0 100644
--- a/include/asm-arm26/unistd.h
+++ b/include/asm-arm26/unistd.h
@@ -14,8 +14,6 @@
14#ifndef __ASM_ARM_UNISTD_H 14#ifndef __ASM_ARM_UNISTD_H
15#define __ASM_ARM_UNISTD_H 15#define __ASM_ARM_UNISTD_H
16 16
17#include <linux/linkage.h>
18
19#define __NR_SYSCALL_BASE 0x900000 17#define __NR_SYSCALL_BASE 0x900000
20 18
21/* 19/*
@@ -312,6 +310,9 @@
312#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) 310#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
313#define __ARM_NR_usr26 (__ARM_NR_BASE+3) 311#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
314 312
313#ifdef __KERNEL__
314#include <linux/linkage.h>
315
315#define __sys2(x) #x 316#define __sys2(x) #x
316#define __sys1(x) __sys2(x) 317#define __sys1(x) __sys2(x)
317 318
@@ -443,7 +444,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
443 __syscall_return(type,__res); \ 444 __syscall_return(type,__res); \
444} 445}
445 446
446#ifdef __KERNEL__
447#define __ARCH_WANT_IPC_PARSE_VERSION 447#define __ARCH_WANT_IPC_PARSE_VERSION
448#define __ARCH_WANT_OLD_READDIR 448#define __ARCH_WANT_OLD_READDIR
449#define __ARCH_WANT_STAT64 449#define __ARCH_WANT_STAT64
@@ -462,7 +462,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
462#define __ARCH_WANT_SYS_SIGPENDING 462#define __ARCH_WANT_SYS_SIGPENDING
463#define __ARCH_WANT_SYS_SIGPROCMASK 463#define __ARCH_WANT_SYS_SIGPROCMASK
464#define __ARCH_WANT_SYS_RT_SIGACTION 464#define __ARCH_WANT_SYS_RT_SIGACTION
465#endif
466 465
467#ifdef __KERNEL_SYSCALLS__ 466#ifdef __KERNEL_SYSCALLS__
468 467
@@ -486,7 +485,7 @@ asmlinkage long sys_rt_sigaction(int sig,
486 struct sigaction __user *oact, 485 struct sigaction __user *oact,
487 size_t sigsetsize); 486 size_t sigsetsize);
488 487
489#endif 488#endif /* __KERNEL_SYSCALLS__ */
490 489
491/* 490/*
492 * "Conditional" syscalls 491 * "Conditional" syscalls
@@ -496,4 +495,5 @@ asmlinkage long sys_rt_sigaction(int sig,
496 */ 495 */
497#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 496#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
498 497
498#endif /* __KERNEL__ */
499#endif /* __ASM_ARM_UNISTD_H */ 499#endif /* __ASM_ARM_UNISTD_H */
diff --git a/include/asm-cris/arch-v10/io.h b/include/asm-cris/arch-v10/io.h
index dd39198ec67d..11ef5b53d84e 100644
--- a/include/asm-cris/arch-v10/io.h
+++ b/include/asm-cris/arch-v10/io.h
@@ -2,7 +2,6 @@
2#define _ASM_ARCH_CRIS_IO_H 2#define _ASM_ARCH_CRIS_IO_H
3 3
4#include <asm/arch/svinto.h> 4#include <asm/arch/svinto.h>
5#include <linux/config.h>
6 5
7/* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */ 6/* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */
8 7
diff --git a/include/asm-cris/arch-v10/page.h b/include/asm-cris/arch-v10/page.h
index 407e6e68f49e..7d8307aed7f3 100644
--- a/include/asm-cris/arch-v10/page.h
+++ b/include/asm-cris/arch-v10/page.h
@@ -1,7 +1,6 @@
1#ifndef _CRIS_ARCH_PAGE_H 1#ifndef _CRIS_ARCH_PAGE_H
2#define _CRIS_ARCH_PAGE_H 2#define _CRIS_ARCH_PAGE_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7 6
diff --git a/include/asm-cris/arch-v10/system.h b/include/asm-cris/arch-v10/system.h
index 1ac7b639b1b0..4a9cd36c9e16 100644
--- a/include/asm-cris/arch-v10/system.h
+++ b/include/asm-cris/arch-v10/system.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_CRIS_ARCH_SYSTEM_H 1#ifndef __ASM_CRIS_ARCH_SYSTEM_H
2#define __ASM_CRIS_ARCH_SYSTEM_H 2#define __ASM_CRIS_ARCH_SYSTEM_H
3 3
4#include <linux/config.h>
5 4
6/* read the CPU version register */ 5/* read the CPU version register */
7 6
diff --git a/include/asm-cris/arch-v32/io.h b/include/asm-cris/arch-v32/io.h
index 043c9ce5294e..5efe4d949001 100644
--- a/include/asm-cris/arch-v32/io.h
+++ b/include/asm-cris/arch-v32/io.h
@@ -4,7 +4,6 @@
4#include <asm/arch/hwregs/reg_map.h> 4#include <asm/arch/hwregs/reg_map.h>
5#include <asm/arch/hwregs/reg_rdwr.h> 5#include <asm/arch/hwregs/reg_rdwr.h>
6#include <asm/arch/hwregs/gio_defs.h> 6#include <asm/arch/hwregs/gio_defs.h>
7#include <linux/config.h>
8 7
9enum crisv32_io_dir 8enum crisv32_io_dir
10{ 9{
diff --git a/include/asm-cris/arch-v32/irq.h b/include/asm-cris/arch-v32/irq.h
index d35aa8174c2f..eeb0a80262c8 100644
--- a/include/asm-cris/arch-v32/irq.h
+++ b/include/asm-cris/arch-v32/irq.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_ARCH_IRQ_H 1#ifndef _ASM_ARCH_IRQ_H
2#define _ASM_ARCH_IRQ_H 2#define _ASM_ARCH_IRQ_H
3 3
4#include <linux/config.h>
5#include "hwregs/intr_vect.h" 4#include "hwregs/intr_vect.h"
6 5
7/* Number of non-cpu interrupts. */ 6/* Number of non-cpu interrupts. */
diff --git a/include/asm-cris/arch-v32/page.h b/include/asm-cris/arch-v32/page.h
index 77827bc17cca..fa454fe12425 100644
--- a/include/asm-cris/arch-v32/page.h
+++ b/include/asm-cris/arch-v32/page.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_CRIS_ARCH_PAGE_H 1#ifndef _ASM_CRIS_ARCH_PAGE_H
2#define _ASM_CRIS_ARCH_PAGE_H 2#define _ASM_CRIS_ARCH_PAGE_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7 6
diff --git a/include/asm-cris/arch-v32/processor.h b/include/asm-cris/arch-v32/processor.h
index 32bf2e538ced..5553b0cd02bf 100644
--- a/include/asm-cris/arch-v32/processor.h
+++ b/include/asm-cris/arch-v32/processor.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_CRIS_ARCH_PROCESSOR_H 1#ifndef _ASM_CRIS_ARCH_PROCESSOR_H
2#define _ASM_CRIS_ARCH_PROCESSOR_H 2#define _ASM_CRIS_ARCH_PROCESSOR_H
3 3
4#include <linux/config.h>
5 4
6/* Return current instruction pointer. */ 5/* Return current instruction pointer. */
7#define current_text_addr() \ 6#define current_text_addr() \
diff --git a/include/asm-cris/arch-v32/system.h b/include/asm-cris/arch-v32/system.h
index a3d75d581e2f..d20e2d6d64a3 100644
--- a/include/asm-cris/arch-v32/system.h
+++ b/include/asm-cris/arch-v32/system.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_CRIS_ARCH_SYSTEM_H 1#ifndef _ASM_CRIS_ARCH_SYSTEM_H
2#define _ASM_CRIS_ARCH_SYSTEM_H 2#define _ASM_CRIS_ARCH_SYSTEM_H
3 3
4#include <linux/config.h>
5 4
6/* Read the CPU version register. */ 5/* Read the CPU version register. */
7static inline unsigned long rdvr(void) 6static inline unsigned long rdvr(void)
diff --git a/include/asm-cris/eshlibld.h b/include/asm-cris/eshlibld.h
index 2b577cde17eb..10ce36cf79a9 100644
--- a/include/asm-cris/eshlibld.h
+++ b/include/asm-cris/eshlibld.h
@@ -32,7 +32,6 @@
32/* We have dependencies all over the place for the host system 32/* We have dependencies all over the place for the host system
33 for xsim being a linux system, so let's not pretend anything 33 for xsim being a linux system, so let's not pretend anything
34 else with #ifdef:s here until fixed. */ 34 else with #ifdef:s here until fixed. */
35#include <linux/config.h>
36#include <linux/limits.h> 35#include <linux/limits.h>
37 36
38/* Maybe do sanity checking if file input. */ 37/* Maybe do sanity checking if file input. */
diff --git a/include/asm-cris/etraxgpio.h b/include/asm-cris/etraxgpio.h
index 80ee10f70d43..5d0028dba7c6 100644
--- a/include/asm-cris/etraxgpio.h
+++ b/include/asm-cris/etraxgpio.h
@@ -25,7 +25,6 @@
25#ifndef _ASM_ETRAXGPIO_H 25#ifndef _ASM_ETRAXGPIO_H
26#define _ASM_ETRAXGPIO_H 26#define _ASM_ETRAXGPIO_H
27 27
28#include <linux/config.h>
29/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */ 28/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
30#ifdef CONFIG_ETRAX_ARCH_V10 29#ifdef CONFIG_ETRAX_ARCH_V10
31#define ETRAXGPIO_IOCTYPE 43 30#define ETRAXGPIO_IOCTYPE 43
diff --git a/include/asm-cris/fasttimer.h b/include/asm-cris/fasttimer.h
index 69522028baa5..a3a77132ce32 100644
--- a/include/asm-cris/fasttimer.h
+++ b/include/asm-cris/fasttimer.h
@@ -5,7 +5,6 @@
5 * This may be useful in other OS than Linux so use 2 space indentation... 5 * This may be useful in other OS than Linux so use 2 space indentation...
6 * Copyright (C) 2000, 2002 Axis Communications AB 6 * Copyright (C) 2000, 2002 Axis Communications AB
7 */ 7 */
8#include <linux/config.h>
9#include <linux/time.h> /* struct timeval */ 8#include <linux/time.h> /* struct timeval */
10#include <linux/timex.h> 9#include <linux/timex.h>
11 10
diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h
index 3787633e6209..81832e9e157f 100644
--- a/include/asm-cris/page.h
+++ b/include/asm-cris/page.h
@@ -1,7 +1,6 @@
1#ifndef _CRIS_PAGE_H 1#ifndef _CRIS_PAGE_H
2#define _CRIS_PAGE_H 2#define _CRIS_PAGE_H
3 3
4#include <linux/config.h>
5#include <asm/arch/page.h> 4#include <asm/arch/page.h>
6 5
7/* PAGE_SHIFT determines the page size */ 6/* PAGE_SHIFT determines the page size */
diff --git a/include/asm-cris/pci.h b/include/asm-cris/pci.h
index 2064bc1de074..b2ac8a331da1 100644
--- a/include/asm-cris/pci.h
+++ b/include/asm-cris/pci.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_CRIS_PCI_H 1#ifndef __ASM_CRIS_PCI_H
2#define __ASM_CRIS_PCI_H 2#define __ASM_CRIS_PCI_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7#include <linux/mm.h> /* for struct page */ 6#include <linux/mm.h> /* for struct page */
diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h
index 70a832514f62..5d76c1c0d6c9 100644
--- a/include/asm-cris/pgtable.h
+++ b/include/asm-cris/pgtable.h
@@ -9,7 +9,6 @@
9#include <asm-generic/pgtable-nopmd.h> 9#include <asm-generic/pgtable-nopmd.h>
10 10
11#ifndef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
12#include <linux/config.h>
13#include <linux/sched.h> 12#include <linux/sched.h>
14#include <asm/mmu.h> 13#include <asm/mmu.h>
15#endif 14#endif
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
index 961e2bceadbc..568da1deceb9 100644
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_CRIS_PROCESSOR_H 10#ifndef __ASM_CRIS_PROCESSOR_H
11#define __ASM_CRIS_PROCESSOR_H 11#define __ASM_CRIS_PROCESSOR_H
12 12
13#include <linux/config.h>
14#include <asm/system.h> 13#include <asm/system.h>
15#include <asm/page.h> 14#include <asm/page.h>
16#include <asm/ptrace.h> 15#include <asm/ptrace.h>
diff --git a/include/asm-cris/rtc.h b/include/asm-cris/rtc.h
index 97c13039834a..cb4bf9217fee 100644
--- a/include/asm-cris/rtc.h
+++ b/include/asm-cris/rtc.h
@@ -4,7 +4,6 @@
4#define __RTC_H__ 4#define __RTC_H__
5 5
6 6
7#include <linux/config.h>
8 7
9#ifdef CONFIG_ETRAX_DS1302 8#ifdef CONFIG_ETRAX_DS1302
10 /* Dallas DS1302 clock/calendar register numbers. */ 9 /* Dallas DS1302 clock/calendar register numbers. */
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
index c52238005b55..0569612477e3 100644
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _CRIS_TLBFLUSH_H 1#ifndef _CRIS_TLBFLUSH_H
2#define _CRIS_TLBFLUSH_H 2#define _CRIS_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/processor.h> 5#include <asm/processor.h>
7#include <asm/pgtable.h> 6#include <asm/pgtable.h>
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index bb2dfe480213..c2954e90aa24 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -295,11 +295,11 @@
295#define __NR_request_key 287 295#define __NR_request_key 287
296#define __NR_keyctl 288 296#define __NR_keyctl 288
297 297
298#define NR_syscalls 289 298#ifdef __KERNEL__
299 299
300#define NR_syscalls 289
300 301
301 302
302#ifdef __KERNEL__
303#define __ARCH_WANT_IPC_PARSE_VERSION 303#define __ARCH_WANT_IPC_PARSE_VERSION
304#define __ARCH_WANT_OLD_READDIR 304#define __ARCH_WANT_OLD_READDIR
305#define __ARCH_WANT_OLD_STAT 305#define __ARCH_WANT_OLD_STAT
@@ -379,12 +379,10 @@ asmlinkage long sys_rt_sigaction(int sig,
379 * complaints. We don't want to use -fno-builtin, so just use a 379 * complaints. We don't want to use -fno-builtin, so just use a
380 * different name when in the kernel. 380 * different name when in the kernel.
381 */ 381 */
382#ifdef __KERNEL__
383#define _exit kernel_syscall_exit 382#define _exit kernel_syscall_exit
384#endif
385static inline _syscall1(int,_exit,int,exitcode) 383static inline _syscall1(int,_exit,int,exitcode)
386static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 384static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
387#endif 385#endif /* __KERNEL_SYSCALLS__ */
388 386
389 387
390/* 388/*
@@ -395,4 +393,5 @@ static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
395 */ 393 */
396#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 394#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
397 395
396#endif /* __KERNEL__ */
398#endif /* _ASM_CRIS_UNISTD_H_ */ 397#endif /* _ASM_CRIS_UNISTD_H_ */
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index 5d9f84bfdcad..9a4ff03c3969 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -14,7 +14,6 @@
14#ifndef _ASM_ATOMIC_H 14#ifndef _ASM_ATOMIC_H
15#define _ASM_ATOMIC_H 15#define _ASM_ATOMIC_H
16 16
17#include <linux/config.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <asm/spr-regs.h> 18#include <asm/spr-regs.h>
20 19
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index 6344d06390b9..980ae1b0cd28 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -14,7 +14,6 @@
14#ifndef _ASM_BITOPS_H 14#ifndef _ASM_BITOPS_H
15#define _ASM_BITOPS_H 15#define _ASM_BITOPS_H
16 16
17#include <linux/config.h>
18#include <linux/compiler.h> 17#include <linux/compiler.h>
19#include <asm/byteorder.h> 18#include <asm/byteorder.h>
20#include <asm/system.h> 19#include <asm/system.h>
diff --git a/include/asm-frv/bug.h b/include/asm-frv/bug.h
index 451712cc3060..6b1b44d71028 100644
--- a/include/asm-frv/bug.h
+++ b/include/asm-frv/bug.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_BUG_H 11#ifndef _ASM_BUG_H
12#define _ASM_BUG_H 12#define _ASM_BUG_H
13 13
14#include <linux/config.h>
15#include <linux/linkage.h> 14#include <linux/linkage.h>
16 15
17#ifdef CONFIG_BUG 16#ifdef CONFIG_BUG
diff --git a/include/asm-frv/cache.h b/include/asm-frv/cache.h
index cf69b6373b34..2797163b8f4f 100644
--- a/include/asm-frv/cache.h
+++ b/include/asm-frv/cache.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_CACHE_H 12#ifndef __ASM_CACHE_H
13#define __ASM_CACHE_H 13#define __ASM_CACHE_H
14 14
15#include <linux/config.h>
16 15
17/* bytes per L1 cache line */ 16/* bytes per L1 cache line */
18#define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT) 17#define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT)
diff --git a/include/asm-frv/dma.h b/include/asm-frv/dma.h
index d8f9a2f21521..18d6bb8f84fc 100644
--- a/include/asm-frv/dma.h
+++ b/include/asm-frv/dma.h
@@ -14,7 +14,6 @@
14 14
15//#define DMA_DEBUG 1 15//#define DMA_DEBUG 1
16 16
17#include <linux/config.h>
18#include <linux/interrupt.h> 17#include <linux/interrupt.h>
19 18
20#undef MAX_DMA_CHANNELS /* don't use kernel/dma.c */ 19#undef MAX_DMA_CHANNELS /* don't use kernel/dma.c */
diff --git a/include/asm-frv/elf.h b/include/asm-frv/elf.h
index 7d2098f0476b..38656da00e40 100644
--- a/include/asm-frv/elf.h
+++ b/include/asm-frv/elf.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_ELF_H 12#ifndef __ASM_ELF_H
13#define __ASM_ELF_H 13#define __ASM_ELF_H
14 14
15#include <linux/config.h>
16#include <asm/ptrace.h> 15#include <asm/ptrace.h>
17#include <asm/user.h> 16#include <asm/user.h>
18 17
diff --git a/include/asm-frv/fpu.h b/include/asm-frv/fpu.h
index b1178f8ca5ce..d73c60b56641 100644
--- a/include/asm-frv/fpu.h
+++ b/include/asm-frv/fpu.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_FPU_H 1#ifndef __ASM_FPU_H
2#define __ASM_FPU_H 2#define __ASM_FPU_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * MAX floating point unit state size (FSAVE/FRESTORE) 6 * MAX floating point unit state size (FSAVE/FRESTORE)
diff --git a/include/asm-frv/hardirq.h b/include/asm-frv/hardirq.h
index 685123981e8b..7581b5a7559a 100644
--- a/include/asm-frv/hardirq.h
+++ b/include/asm-frv/hardirq.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_HARDIRQ_H 12#ifndef __ASM_HARDIRQ_H
13#define __ASM_HARDIRQ_H 13#define __ASM_HARDIRQ_H
14 14
15#include <linux/config.h>
16#include <linux/threads.h> 15#include <linux/threads.h>
17#include <linux/irq.h> 16#include <linux/irq.h>
18 17
diff --git a/include/asm-frv/highmem.h b/include/asm-frv/highmem.h
index 295f74a57f22..cfbf7d3a1feb 100644
--- a/include/asm-frv/highmem.h
+++ b/include/asm-frv/highmem.h
@@ -17,7 +17,6 @@
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <asm/mem-layout.h> 21#include <asm/mem-layout.h>
23#include <asm/spr-regs.h> 22#include <asm/spr-regs.h>
diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h
index ae031eaa3dd2..f0bd2cb250c1 100644
--- a/include/asm-frv/ide.h
+++ b/include/asm-frv/ide.h
@@ -14,7 +14,6 @@
14 14
15#ifdef __KERNEL__ 15#ifdef __KERNEL__
16 16
17#include <linux/config.h>
18#include <asm/setup.h> 17#include <asm/setup.h>
19#include <asm/io.h> 18#include <asm/io.h>
20#include <asm/irq.h> 19#include <asm/irq.h>
diff --git a/include/asm-frv/io.h b/include/asm-frv/io.h
index 01247cb2bc39..b56eba59e3cd 100644
--- a/include/asm-frv/io.h
+++ b/include/asm-frv/io.h
@@ -17,7 +17,6 @@
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/virtconvert.h> 21#include <asm/virtconvert.h>
23#include <asm/string.h> 22#include <asm/string.h>
diff --git a/include/asm-frv/irq.h b/include/asm-frv/irq.h
index 2c16d8dc02fd..58b619215a50 100644
--- a/include/asm-frv/irq.h
+++ b/include/asm-frv/irq.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_IRQ_H_ 12#ifndef _ASM_IRQ_H_
13#define _ASM_IRQ_H_ 13#define _ASM_IRQ_H_
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * the system has an on-CPU PIC and another PIC on the FPGA and other PICs on other peripherals, 17 * the system has an on-CPU PIC and another PIC on the FPGA and other PICs on other peripherals,
diff --git a/include/asm-frv/mmu_context.h b/include/asm-frv/mmu_context.h
index 4fb9ea3c5bc9..72edcaaccd5d 100644
--- a/include/asm-frv/mmu_context.h
+++ b/include/asm-frv/mmu_context.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_MMU_CONTEXT_H 12#ifndef _ASM_MMU_CONTEXT_H
13#define _ASM_MMU_CONTEXT_H 13#define _ASM_MMU_CONTEXT_H
14 14
15#include <linux/config.h>
16#include <asm/setup.h> 15#include <asm/setup.h>
17#include <asm/page.h> 16#include <asm/page.h>
18#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h
index dc0f7e08a4c2..134cc0cdf6c2 100644
--- a/include/asm-frv/page.h
+++ b/include/asm-frv/page.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7#include <asm/virtconvert.h> 6#include <asm/virtconvert.h>
8#include <asm/mem-layout.h> 7#include <asm/mem-layout.h>
9#include <asm/sections.h> 8#include <asm/sections.h>
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index 598b0c6b695d..f35a4511e7b9 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -13,7 +13,6 @@
13#ifndef ASM_PCI_H 13#ifndef ASM_PCI_H
14#define ASM_PCI_H 14#define ASM_PCI_H
15 15
16#include <linux/config.h>
17#include <linux/mm.h> 16#include <linux/mm.h>
18#include <asm/scatterlist.h> 17#include <asm/scatterlist.h>
19#include <asm-generic/pci-dma-compat.h> 18#include <asm-generic/pci-dma-compat.h>
diff --git a/include/asm-frv/pgalloc.h b/include/asm-frv/pgalloc.h
index 1bd28f41bfa8..ce982a6c610f 100644
--- a/include/asm-frv/pgalloc.h
+++ b/include/asm-frv/pgalloc.h
@@ -15,7 +15,6 @@
15#ifndef _ASM_PGALLOC_H 15#ifndef _ASM_PGALLOC_H
16#define _ASM_PGALLOC_H 16#define _ASM_PGALLOC_H
17 17
18#include <linux/config.h>
19#include <asm/setup.h> 18#include <asm/setup.h>
20#include <asm/virtconvert.h> 19#include <asm/virtconvert.h>
21 20
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index d1c3b182c691..7af7485e889e 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -16,7 +16,6 @@
16#ifndef _ASM_PGTABLE_H 16#ifndef _ASM_PGTABLE_H
17#define _ASM_PGTABLE_H 17#define _ASM_PGTABLE_H
18 18
19#include <linux/config.h>
20#include <asm/mem-layout.h> 19#include <asm/mem-layout.h>
21#include <asm/setup.h> 20#include <asm/setup.h>
22#include <asm/processor.h> 21#include <asm/processor.h>
diff --git a/include/asm-frv/processor.h b/include/asm-frv/processor.h
index 5228c18b7f78..1c4dba1c5f57 100644
--- a/include/asm-frv/processor.h
+++ b/include/asm-frv/processor.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_PROCESSOR_H 12#ifndef _ASM_PROCESSOR_H
13#define _ASM_PROCESSOR_H 13#define _ASM_PROCESSOR_H
14 14
15#include <linux/config.h>
16#include <asm/mem-layout.h> 15#include <asm/mem-layout.h>
17 16
18#ifndef __ASSEMBLY__ 17#ifndef __ASSEMBLY__
diff --git a/include/asm-frv/segment.h b/include/asm-frv/segment.h
index 61222f00dfc1..e3616a6f941d 100644
--- a/include/asm-frv/segment.h
+++ b/include/asm-frv/segment.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_SEGMENT_H 12#ifndef _ASM_SEGMENT_H
13#define _ASM_SEGMENT_H 13#define _ASM_SEGMENT_H
14 14
15#include <linux/config.h>
16 15
17#ifndef __ASSEMBLY__ 16#ifndef __ASSEMBLY__
18 17
diff --git a/include/asm-frv/serial.h b/include/asm-frv/serial.h
index 6917d556a1e1..dbb825998689 100644
--- a/include/asm-frv/serial.h
+++ b/include/asm-frv/serial.h
@@ -6,7 +6,6 @@
6 * 6 *
7 * Based on linux/include/asm-i386/serial.h 7 * Based on linux/include/asm-i386/serial.h
8 */ 8 */
9#include <linux/config.h>
10#include <asm/serial-regs.h> 9#include <asm/serial-regs.h>
11 10
12/* 11/*
diff --git a/include/asm-frv/smp.h b/include/asm-frv/smp.h
index 5ca771631fd8..38349ec8b61b 100644
--- a/include/asm-frv/smp.h
+++ b/include/asm-frv/smp.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SMP_H 1#ifndef __ASM_SMP_H
2#define __ASM_SMP_H 2#define __ASM_SMP_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_SMP 5#ifdef CONFIG_SMP
7#error SMP not supported 6#error SMP not supported
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index 1734ed91bcdc..351863dfd06e 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_SYSTEM_H 12#ifndef _ASM_SYSTEM_H
13#define _ASM_SYSTEM_H 13#define _ASM_SYSTEM_H
14 14
15#include <linux/config.h> /* get configuration macros */
16#include <linux/linkage.h> 15#include <linux/linkage.h>
17#include <asm/atomic.h> 16#include <asm/atomic.h>
18 17
diff --git a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
index bc3462625084..da3a3179a85d 100644
--- a/include/asm-frv/tlbflush.h
+++ b/include/asm-frv/tlbflush.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_TLBFLUSH_H 12#ifndef _ASM_TLBFLUSH_H
13#define _ASM_TLBFLUSH_H 13#define _ASM_TLBFLUSH_H
14 14
15#include <linux/config.h>
16#include <linux/mm.h> 15#include <linux/mm.h>
17#include <asm/processor.h> 16#include <asm/processor.h>
18 17
diff --git a/include/asm-frv/types.h b/include/asm-frv/types.h
index 2560f596a75d..1b6d1923b25b 100644
--- a/include/asm-frv/types.h
+++ b/include/asm-frv/types.h
@@ -46,7 +46,6 @@ typedef unsigned long long __u64;
46 46
47#ifndef __ASSEMBLY__ 47#ifndef __ASSEMBLY__
48 48
49#include <linux/config.h>
50 49
51typedef signed char s8; 50typedef signed char s8;
52typedef unsigned char u8; 51typedef unsigned char u8;
diff --git a/include/asm-frv/unaligned.h b/include/asm-frv/unaligned.h
index a0d199bf01d9..dc8e9c9bf6bd 100644
--- a/include/asm-frv/unaligned.h
+++ b/include/asm-frv/unaligned.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_UNALIGNED_H 12#ifndef _ASM_UNALIGNED_H
13#define _ASM_UNALIGNED_H 13#define _ASM_UNALIGNED_H
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Unaligned accesses on uClinux can't be performed in a fault handler - the 17 * Unaligned accesses on uClinux can't be performed in a fault handler - the
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index 2662a3e12dc4..7c2e712c3b73 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -317,6 +317,8 @@
317#define __NR_pselect6 308 317#define __NR_pselect6 308
318#define __NR_ppoll 309 318#define __NR_ppoll 309
319 319
320#ifdef __KERNEL__
321
320#define NR_syscalls 310 322#define NR_syscalls 310
321 323
322/* 324/*
@@ -477,9 +479,8 @@ static inline pid_t wait(int * wait_stat)
477 return waitpid(-1,wait_stat,0); 479 return waitpid(-1,wait_stat,0);
478} 480}
479 481
480#endif 482#endif /* __KERNEL_SYSCALLS__ */
481 483
482#ifdef __KERNEL__
483#define __ARCH_WANT_IPC_PARSE_VERSION 484#define __ARCH_WANT_IPC_PARSE_VERSION
484/* #define __ARCH_WANT_OLD_READDIR */ 485/* #define __ARCH_WANT_OLD_READDIR */
485#define __ARCH_WANT_OLD_STAT 486#define __ARCH_WANT_OLD_STAT
@@ -503,7 +504,6 @@ static inline pid_t wait(int * wait_stat)
503#define __ARCH_WANT_SYS_SIGPROCMASK 504#define __ARCH_WANT_SYS_SIGPROCMASK
504#define __ARCH_WANT_SYS_RT_SIGACTION 505#define __ARCH_WANT_SYS_RT_SIGACTION
505#define __ARCH_WANT_SYS_RT_SIGSUSPEND 506#define __ARCH_WANT_SYS_RT_SIGSUSPEND
506#endif
507 507
508/* 508/*
509 * "Conditional" syscalls 509 * "Conditional" syscalls
@@ -515,4 +515,5 @@ static inline pid_t wait(int * wait_stat)
515#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 515#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
516#endif 516#endif
517 517
518#endif /* __KERNEL__ */
518#endif /* _ASM_UNISTD_H_ */ 519#endif /* _ASM_UNISTD_H_ */
diff --git a/include/asm-frv/virtconvert.h b/include/asm-frv/virtconvert.h
index a29a0aec291f..59788fa2a813 100644
--- a/include/asm-frv/virtconvert.h
+++ b/include/asm-frv/virtconvert.h
@@ -17,7 +17,6 @@
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h>
21#include <asm/setup.h> 20#include <asm/setup.h>
22 21
23#ifdef CONFIG_MMU 22#ifdef CONFIG_MMU
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 1a565a9d2fa7..0cd9711895fa 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -2,7 +2,6 @@
2#define _ASM_GENERIC_BUG_H 2#define _ASM_GENERIC_BUG_H
3 3
4#include <linux/compiler.h> 4#include <linux/compiler.h>
5#include <linux/config.h>
6 5
7#ifdef CONFIG_BUG 6#ifdef CONFIG_BUG
8#ifndef HAVE_ARCH_BUG 7#ifndef HAVE_ARCH_BUG
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 1b356207712c..b541e48cc545 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_GENERIC_DMA_MAPPING_H 7#ifndef _ASM_GENERIC_DMA_MAPPING_H
8#define _ASM_GENERIC_DMA_MAPPING_H 8#define _ASM_GENERIC_DMA_MAPPING_H
9 9
10#include <linux/config.h>
11 10
12#ifdef CONFIG_PCI 11#ifdef CONFIG_PCI
13 12
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index b663520dcdc4..c154b9d6e7e5 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_GENERIC_FCNTL_H 1#ifndef _ASM_GENERIC_FCNTL_H
2#define _ASM_GENERIC_FCNTL_H 2#define _ASM_GENERIC_FCNTL_H
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7/* open/fcntl - O_SYNC is only implemented on blocks devices and on files 6/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
index 9291c24f5819..ab469297272c 100644
--- a/include/asm-generic/local.h
+++ b/include/asm-generic/local.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_GENERIC_LOCAL_H 1#ifndef _ASM_GENERIC_LOCAL_H
2#define _ASM_GENERIC_LOCAL_H 2#define _ASM_GENERIC_LOCAL_H
3 3
4#include <linux/config.h>
5#include <linux/percpu.h> 4#include <linux/percpu.h>
6#include <linux/hardirq.h> 5#include <linux/hardirq.h>
7#include <asm/atomic.h> 6#include <asm/atomic.h>
diff --git a/include/asm-generic/signal.h b/include/asm-generic/signal.h
index 9418d6e9b8cd..dae1d8720076 100644
--- a/include/asm-generic/signal.h
+++ b/include/asm-generic/signal.h
@@ -1,3 +1,8 @@
1#ifndef __ASM_GENERIC_SIGNAL_H
2#define __ASM_GENERIC_SIGNAL_H
3
4#include <linux/compiler.h>
5
1#ifndef SIG_BLOCK 6#ifndef SIG_BLOCK
2#define SIG_BLOCK 0 /* for blocking signals */ 7#define SIG_BLOCK 0 /* for blocking signals */
3#endif 8#endif
@@ -19,3 +24,5 @@ typedef __restorefn_t __user *__sigrestore_t;
19#define SIG_IGN ((__force __sighandler_t)1) /* ignore signal */ 24#define SIG_IGN ((__force __sighandler_t)1) /* ignore signal */
20#define SIG_ERR ((__force __sighandler_t)-1) /* error return from signal */ 25#define SIG_ERR ((__force __sighandler_t)-1) /* error return from signal */
21#endif 26#endif
27
28#endif /* __ASM_GENERIC_SIGNAL_H */
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index cdd4145243cd..867d9008fafa 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_GENERIC__TLB_H 13#ifndef _ASM_GENERIC__TLB_H
14#define _ASM_GENERIC__TLB_H 14#define _ASM_GENERIC__TLB_H
15 15
16#include <linux/config.h>
17#include <linux/swap.h> 16#include <linux/swap.h>
18#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
19#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index 574f57b6c4d1..d76299c98b81 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -6,7 +6,6 @@
6 * Copyright 2002, Yoshinori Sato 6 * Copyright 2002, Yoshinori Sato
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/compiler.h> 9#include <linux/compiler.h>
11#include <asm/system.h> 10#include <asm/system.h>
12 11
diff --git a/include/asm-h8300/dma.h b/include/asm-h8300/dma.h
index 3708681b7ddc..3edbaaaedf5b 100644
--- a/include/asm-h8300/dma.h
+++ b/include/asm-h8300/dma.h
@@ -1,7 +1,6 @@
1#ifndef _H8300_DMA_H 1#ifndef _H8300_DMA_H
2#define _H8300_DMA_H 2#define _H8300_DMA_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * Set number of channels of DMA on ColdFire for different implementations. 6 * Set number of channels of DMA on ColdFire for different implementations.
diff --git a/include/asm-h8300/elf.h b/include/asm-h8300/elf.h
index f4af1553a55f..7ba6a0af447c 100644
--- a/include/asm-h8300/elf.h
+++ b/include/asm-h8300/elf.h
@@ -5,7 +5,6 @@
5 * ELF register definitions.. 5 * ELF register definitions..
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <asm/ptrace.h> 8#include <asm/ptrace.h>
10#include <asm/user.h> 9#include <asm/user.h>
11 10
diff --git a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h
index e961bfe201b8..18fa7931e09f 100644
--- a/include/asm-h8300/hardirq.h
+++ b/include/asm-h8300/hardirq.h
@@ -2,7 +2,6 @@
2#define __H8300_HARDIRQ_H 2#define __H8300_HARDIRQ_H
3 3
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/config.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8#include <linux/irq.h> 7#include <linux/irq.h>
diff --git a/include/asm-h8300/io.h b/include/asm-h8300/io.h
index 1773e373e9c6..91b7487cb7ae 100644
--- a/include/asm-h8300/io.h
+++ b/include/asm-h8300/io.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7#include <asm/virtconvert.h> 6#include <asm/virtconvert.h>
8 7
9#if defined(CONFIG_H83007) || defined(CONFIG_H83068) 8#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
diff --git a/include/asm-h8300/keyboard.h b/include/asm-h8300/keyboard.h
index b05d11387ae5..fbad65e8a5c0 100644
--- a/include/asm-h8300/keyboard.h
+++ b/include/asm-h8300/keyboard.h
@@ -7,7 +7,6 @@
7#ifndef _H8300_KEYBOARD_H 7#ifndef _H8300_KEYBOARD_H
8#define _H8300_KEYBOARD_H 8#define _H8300_KEYBOARD_H
9 9
10#include <linux/config.h>
11 10
12/* dummy i.e. no real keyboard */ 11/* dummy i.e. no real keyboard */
13#define kbd_setkeycode(x...) (-ENOSYS) 12#define kbd_setkeycode(x...) (-ENOSYS)
diff --git a/include/asm-h8300/mmu_context.h b/include/asm-h8300/mmu_context.h
index 23b555b7b4b9..855721a5dcc9 100644
--- a/include/asm-h8300/mmu_context.h
+++ b/include/asm-h8300/mmu_context.h
@@ -1,7 +1,6 @@
1#ifndef __H8300_MMU_CONTEXT_H 1#ifndef __H8300_MMU_CONTEXT_H
2#define __H8300_MMU_CONTEXT_H 2#define __H8300_MMU_CONTEXT_H
3 3
4#include <linux/config.h>
5#include <asm/setup.h> 4#include <asm/setup.h>
6#include <asm/page.h> 5#include <asm/page.h>
7#include <asm/pgalloc.h> 6#include <asm/pgalloc.h>
diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h
index 6472c9f88227..f9f9d3eea8ed 100644
--- a/include/asm-h8300/page.h
+++ b/include/asm-h8300/page.h
@@ -1,7 +1,6 @@
1#ifndef _H8300_PAGE_H 1#ifndef _H8300_PAGE_H
2#define _H8300_PAGE_H 2#define _H8300_PAGE_H
3 3
4#include <linux/config.h>
5 4
6/* PAGE_SHIFT determines the page size */ 5/* PAGE_SHIFT determines the page size */
7 6
diff --git a/include/asm-h8300/page_offset.h b/include/asm-h8300/page_offset.h
index 8cc6e17218a8..f8706463008c 100644
--- a/include/asm-h8300/page_offset.h
+++ b/include/asm-h8300/page_offset.h
@@ -1,4 +1,3 @@
1 1
2#include <linux/config.h>
3#define PAGE_OFFSET_RAW 0x00000000 2#define PAGE_OFFSET_RAW 0x00000000
4 3
diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h
index 126dddf72359..c25806ed1fb3 100644
--- a/include/asm-h8300/param.h
+++ b/include/asm-h8300/param.h
@@ -1,7 +1,6 @@
1#ifndef _H8300_PARAM_H 1#ifndef _H8300_PARAM_H
2#define _H8300_PARAM_H 2#define _H8300_PARAM_H
3 3
4#include <linux/config.h>
5 4
6#ifndef HZ 5#ifndef HZ
7#define HZ 100 6#define HZ 100
diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
index f6e296fc1297..8b7c6857998b 100644
--- a/include/asm-h8300/pgtable.h
+++ b/include/asm-h8300/pgtable.h
@@ -3,7 +3,6 @@
3 3
4#include <asm-generic/4level-fixup.h> 4#include <asm-generic/4level-fixup.h>
5 5
6#include <linux/config.h>
7#include <linux/slab.h> 6#include <linux/slab.h>
8#include <asm/processor.h> 7#include <asm/processor.h>
9#include <asm/page.h> 8#include <asm/page.h>
diff --git a/include/asm-h8300/processor.h b/include/asm-h8300/processor.h
index c6f0a7108ef3..c7e2f454b83a 100644
--- a/include/asm-h8300/processor.h
+++ b/include/asm-h8300/processor.h
@@ -17,7 +17,6 @@
17 */ 17 */
18#define current_text_addr() ({ __label__ _l; _l: &&_l;}) 18#define current_text_addr() ({ __label__ _l; _l: &&_l;})
19 19
20#include <linux/config.h>
21#include <asm/segment.h> 20#include <asm/segment.h>
22#include <asm/fpu.h> 21#include <asm/fpu.h>
23#include <asm/ptrace.h> 22#include <asm/ptrace.h>
diff --git a/include/asm-h8300/semaphore-helper.h b/include/asm-h8300/semaphore-helper.h
index 29e0fbf1acb7..4fea36be5fd8 100644
--- a/include/asm-h8300/semaphore-helper.h
+++ b/include/asm-h8300/semaphore-helper.h
@@ -10,7 +10,6 @@
10 * m68k version by Andreas Schwab 10 * m68k version by Andreas Schwab
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
15 14
16/* 15/*
diff --git a/include/asm-h8300/shm.h b/include/asm-h8300/shm.h
index bec758524839..ed6623c0545d 100644
--- a/include/asm-h8300/shm.h
+++ b/include/asm-h8300/shm.h
@@ -1,7 +1,6 @@
1#ifndef _H8300_SHM_H 1#ifndef _H8300_SHM_H
2#define _H8300_SHM_H 2#define _H8300_SHM_H
3 3
4#include <linux/config.h>
5 4
6/* format of page table entries that correspond to shared memory pages 5/* format of page table entries that correspond to shared memory pages
7 currently out in swap space (see also mm/swap.c): 6 currently out in swap space (see also mm/swap.c):
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 8e81cf665e75..134e0929fce5 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -1,7 +1,6 @@
1#ifndef _H8300_SYSTEM_H 1#ifndef _H8300_SYSTEM_H
2#define _H8300_SYSTEM_H 2#define _H8300_SYSTEM_H
3 3
4#include <linux/config.h> /* get configuration macros */
5#include <linux/linkage.h> 4#include <linux/linkage.h>
6 5
7/* 6/*
diff --git a/include/asm-h8300/unaligned.h b/include/asm-h8300/unaligned.h
index 8a93961173c3..ffb67f472070 100644
--- a/include/asm-h8300/unaligned.h
+++ b/include/asm-h8300/unaligned.h
@@ -1,7 +1,6 @@
1#ifndef __H8300_UNALIGNED_H 1#ifndef __H8300_UNALIGNED_H
2#define __H8300_UNALIGNED_H 2#define __H8300_UNALIGNED_H
3 3
4#include <linux/config.h>
5 4
6/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ 5/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
7 6
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index adb05159379b..226dd596c2da 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -292,6 +292,8 @@
292#define __NR_request_key 287 292#define __NR_request_key 287
293#define __NR_keyctl 288 293#define __NR_keyctl 288
294 294
295#ifdef __KERNEL__
296
295#define NR_syscalls 289 297#define NR_syscalls 289
296 298
297 299
@@ -460,7 +462,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
460 __syscall_return(type, __res); \ 462 __syscall_return(type, __res); \
461} 463}
462 464
463#ifdef __KERNEL__
464#define __ARCH_WANT_IPC_PARSE_VERSION 465#define __ARCH_WANT_IPC_PARSE_VERSION
465#define __ARCH_WANT_OLD_READDIR 466#define __ARCH_WANT_OLD_READDIR
466#define __ARCH_WANT_OLD_STAT 467#define __ARCH_WANT_OLD_STAT
@@ -483,7 +484,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
483#define __ARCH_WANT_SYS_SIGPENDING 484#define __ARCH_WANT_SYS_SIGPENDING
484#define __ARCH_WANT_SYS_SIGPROCMASK 485#define __ARCH_WANT_SYS_SIGPROCMASK
485#define __ARCH_WANT_SYS_RT_SIGACTION 486#define __ARCH_WANT_SYS_RT_SIGACTION
486#endif
487 487
488#ifdef __KERNEL_SYSCALLS__ 488#ifdef __KERNEL_SYSCALLS__
489 489
@@ -534,7 +534,7 @@ asmlinkage long sys_rt_sigaction(int sig,
534 struct sigaction __user *oact, 534 struct sigaction __user *oact,
535 size_t sigsetsize); 535 size_t sigsetsize);
536 536
537#endif 537#endif /* __KERNEL_SYSCALLS__ */
538 538
539/* 539/*
540 * "Conditional" syscalls 540 * "Conditional" syscalls
@@ -543,4 +543,5 @@ asmlinkage long sys_rt_sigaction(int sig,
543 asm (".weak\t_" #name "\n" \ 543 asm (".weak\t_" #name "\n" \
544 ".set\t_" #name ",_sys_ni_syscall"); 544 ".set\t_" #name ",_sys_ni_syscall");
545 545
546#endif /* __KERNEL__ */
546#endif /* _ASM_H8300_UNISTD_H_ */ 547#endif /* _ASM_H8300_UNISTD_H_ */
diff --git a/include/asm-h8300/virtconvert.h b/include/asm-h8300/virtconvert.h
index 3b344c1dfe0f..ee7d5ea10065 100644
--- a/include/asm-h8300/virtconvert.h
+++ b/include/asm-h8300/virtconvert.h
@@ -7,7 +7,6 @@
7 7
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9 9
10#include <linux/config.h>
11#include <asm/setup.h> 10#include <asm/setup.h>
12#include <asm/page.h> 11#include <asm/page.h>
13 12
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index 288233fd77d7..cc9b940fb7e8 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_APIC_H 1#ifndef __ASM_APIC_H
2#define __ASM_APIC_H 2#define __ASM_APIC_H
3 3
4#include <linux/config.h>
5#include <linux/pm.h> 4#include <linux/pm.h>
6#include <asm/fixmap.h> 5#include <asm/fixmap.h>
7#include <asm/apicdef.h> 6#include <asm/apicdef.h>
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 4ddce5296a78..4f061fa73794 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -1,7 +1,6 @@
1#ifndef __ARCH_I386_ATOMIC__ 1#ifndef __ARCH_I386_ATOMIC__
2#define __ARCH_I386_ATOMIC__ 2#define __ARCH_I386_ATOMIC__
3 3
4#include <linux/config.h>
5#include <linux/compiler.h> 4#include <linux/compiler.h>
6#include <asm/processor.h> 5#include <asm/processor.h>
7 6
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index 08deaeee6be9..1c780fa1e762 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -5,7 +5,6 @@
5 * Copyright 1992, Linus Torvalds. 5 * Copyright 1992, Linus Torvalds.
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/compiler.h> 8#include <linux/compiler.h>
10#include <asm/alternative.h> 9#include <asm/alternative.h>
11 10
diff --git a/include/asm-i386/bug.h b/include/asm-i386/bug.h
index 8f79de19eb94..8062cdbf2587 100644
--- a/include/asm-i386/bug.h
+++ b/include/asm-i386/bug.h
@@ -1,7 +1,6 @@
1#ifndef _I386_BUG_H 1#ifndef _I386_BUG_H
2#define _I386_BUG_H 2#define _I386_BUG_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * Tell the user there is some problem. 6 * Tell the user there is some problem.
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index 50233e0345fb..2a9e4ee5904d 100644
--- a/include/asm-i386/bugs.h
+++ b/include/asm-i386/bugs.h
@@ -17,7 +17,6 @@
17 * void check_bugs(void); 17 * void check_bugs(void);
18 */ 18 */
19 19
20#include <linux/config.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <asm/processor.h> 21#include <asm/processor.h>
23#include <asm/i387.h> 22#include <asm/i387.h>
diff --git a/include/asm-i386/byteorder.h b/include/asm-i386/byteorder.h
index a0d73f48d5be..a45470a8b74a 100644
--- a/include/asm-i386/byteorder.h
+++ b/include/asm-i386/byteorder.h
@@ -8,7 +8,6 @@
8 8
9/* For avoiding bswap on i386 */ 9/* For avoiding bswap on i386 */
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11#include <linux/config.h>
12#endif 11#endif
13 12
14static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) 13static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
diff --git a/include/asm-i386/cache.h b/include/asm-i386/cache.h
index ca15c9c665cf..57c62f414158 100644
--- a/include/asm-i386/cache.h
+++ b/include/asm-i386/cache.h
@@ -4,7 +4,6 @@
4#ifndef __ARCH_I386_CACHE_H 4#ifndef __ARCH_I386_CACHE_H
5#define __ARCH_I386_CACHE_H 5#define __ARCH_I386_CACHE_H
6 6
7#include <linux/config.h>
8 7
9/* L1 cache line size */ 8/* L1 cache line size */
10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 9#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
diff --git a/include/asm-i386/dma.h b/include/asm-i386/dma.h
index f24b2bba2831..d23aac8e1a50 100644
--- a/include/asm-i386/dma.h
+++ b/include/asm-i386/dma.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_DMA_H 8#ifndef _ASM_DMA_H
9#define _ASM_DMA_H 9#define _ASM_DMA_H
10 10
11#include <linux/config.h>
12#include <linux/spinlock.h> /* And spinlocks */ 11#include <linux/spinlock.h> /* And spinlocks */
13#include <asm/io.h> /* need byte IO */ 12#include <asm/io.h> /* need byte IO */
14#include <linux/delay.h> 13#include <linux/delay.h>
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
index cfb1c61d3b9c..f7e068f4d2f9 100644
--- a/include/asm-i386/fixmap.h
+++ b/include/asm-i386/fixmap.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_FIXMAP_H 13#ifndef _ASM_FIXMAP_H
14#define _ASM_FIXMAP_H 14#define _ASM_FIXMAP_H
15 15
16#include <linux/config.h>
17 16
18/* used by vmalloc.c, vsyscall.lds.S. 17/* used by vmalloc.c, vsyscall.lds.S.
19 * 18 *
diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
index ee754d359734..0e358dc405f8 100644
--- a/include/asm-i386/hardirq.h
+++ b/include/asm-i386/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_HARDIRQ_H 1#ifndef __ASM_HARDIRQ_H
2#define __ASM_HARDIRQ_H 2#define __ASM_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/irq.h> 5#include <linux/irq.h>
7 6
diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h
index 0fd331306b60..e9a34ebc25d5 100644
--- a/include/asm-i386/highmem.h
+++ b/include/asm-i386/highmem.h
@@ -20,7 +20,6 @@
20 20
21#ifdef __KERNEL__ 21#ifdef __KERNEL__
22 22
23#include <linux/config.h>
24#include <linux/interrupt.h> 23#include <linux/interrupt.h>
25#include <linux/threads.h> 24#include <linux/threads.h>
26#include <asm/kmap_types.h> 25#include <asm/kmap_types.h>
diff --git a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h
index 7f1a8a6ee32f..af5d435519d1 100644
--- a/include/asm-i386/hpet.h
+++ b/include/asm-i386/hpet.h
@@ -27,7 +27,6 @@
27#include <asm/processor.h> 27#include <asm/processor.h>
28 28
29#include <linux/timex.h> 29#include <linux/timex.h>
30#include <linux/config.h>
31 30
32#include <asm/fixmap.h> 31#include <asm/fixmap.h>
33 32
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 622815bf3243..95d3fd090298 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -12,7 +12,6 @@
12 * <tomsoft@informatik.tu-chemnitz.de> 12 * <tomsoft@informatik.tu-chemnitz.de>
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/profile.h> 15#include <linux/profile.h>
17#include <asm/atomic.h> 16#include <asm/atomic.h>
18#include <asm/irq.h> 17#include <asm/irq.h>
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h
index 454440193eac..73465d2892b9 100644
--- a/include/asm-i386/ide.h
+++ b/include/asm-i386/ide.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17 16
18#ifndef MAX_HWIFS 17#ifndef MAX_HWIFS
19# ifdef CONFIG_BLK_DEV_IDEPCI 18# ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 79670bb4b0c7..b3724fe93ff1 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IO_H 1#ifndef _ASM_IO_H
2#define _ASM_IO_H 2#define _ASM_IO_H
3 3
4#include <linux/config.h>
5#include <linux/string.h> 4#include <linux/string.h>
6#include <linux/compiler.h> 5#include <linux/compiler.h>
7 6
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index d92e253f7f6f..5092e819b8a2 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_IO_APIC_H 1#ifndef __ASM_IO_APIC_H
2#define __ASM_IO_APIC_H 2#define __ASM_IO_APIC_H
3 3
4#include <linux/config.h>
5#include <asm/types.h> 4#include <asm/types.h>
6#include <asm/mpspec.h> 5#include <asm/mpspec.h>
7 6
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
index 5169d7af456f..331726b41128 100644
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -10,7 +10,6 @@
10 * <tomsoft@informatik.tu-chemnitz.de> 10 * <tomsoft@informatik.tu-chemnitz.de>
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/sched.h> 13#include <linux/sched.h>
15/* include comes from machine specific directory */ 14/* include comes from machine specific directory */
16#include "irq_vectors.h" 15#include "irq_vectors.h"
diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h
index 6886a0c3fedf..806aae3c5338 100644
--- a/include/asm-i386/kmap_types.h
+++ b/include/asm-i386/kmap_types.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_KMAP_TYPES_H 1#ifndef _ASM_KMAP_TYPES_H
2#define _ASM_KMAP_TYPES_H 2#define _ASM_KMAP_TYPES_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_DEBUG_HIGHMEM 5#ifdef CONFIG_DEBUG_HIGHMEM
7# define D(n) __KM_FENCE_##n , 6# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index 3d6d12937e1f..9fd073286289 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_APIC_H 1#ifndef __ASM_MACH_APIC_H
2#define __ASM_MACH_APIC_H 2#define __ASM_MACH_APIC_H
3 3
4#include <linux/config.h>
5#include <asm/smp.h> 4#include <asm/smp.h>
6 5
7#define esr_disable (1) 6#define esr_disable (1)
diff --git a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h
index bf08218357ea..62b7bf184094 100644
--- a/include/asm-i386/mmu_context.h
+++ b/include/asm-i386/mmu_context.h
@@ -1,7 +1,6 @@
1#ifndef __I386_SCHED_H 1#ifndef __I386_SCHED_H
2#define __I386_SCHED_H 2#define __I386_SCHED_H
3 3
4#include <linux/config.h>
5#include <asm/desc.h> 4#include <asm/desc.h>
6#include <asm/atomic.h> 5#include <asm/atomic.h>
7#include <asm/pgalloc.h> 6#include <asm/pgalloc.h>
diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h
index 64cf937c7e33..5a46de08efea 100644
--- a/include/asm-i386/mtrr.h
+++ b/include/asm-i386/mtrr.h
@@ -23,7 +23,6 @@
23#ifndef _LINUX_MTRR_H 23#ifndef _LINUX_MTRR_H
24#define _LINUX_MTRR_H 24#define _LINUX_MTRR_H
25 25
26#include <linux/config.h>
27#include <linux/ioctl.h> 26#include <linux/ioctl.h>
28#include <linux/errno.h> 27#include <linux/errno.h>
29 28
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 30f52a2263ba..e3a552fa5538 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -12,7 +12,6 @@
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
14 14
15#include <linux/config.h>
16 15
17#ifdef CONFIG_X86_USE_3DNOW 16#ifdef CONFIG_X86_USE_3DNOW
18 17
@@ -137,9 +136,9 @@ extern int page_is_ram(unsigned long pagenr);
137 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ 136 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
138 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 137 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
139 138
140#endif /* __KERNEL__ */
141
142#include <asm-generic/memory_model.h> 139#include <asm-generic/memory_model.h>
143#include <asm-generic/page.h> 140#include <asm-generic/page.h>
144 141
142#endif /* __KERNEL__ */
143
145#endif /* _I386_PAGE_H */ 144#endif /* _I386_PAGE_H */
diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h
index 095580f3a45c..745dc5bd0fbc 100644
--- a/include/asm-i386/param.h
+++ b/include/asm-i386/param.h
@@ -2,7 +2,6 @@
2#define _ASMi386_PARAM_H 2#define _ASMi386_PARAM_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5# include <linux/config.h>
6# define HZ CONFIG_HZ /* Internal kernel timer frequency */ 5# define HZ CONFIG_HZ /* Internal kernel timer frequency */
7# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ 6# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
8# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ 7# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index 78c85985aee3..64b6d0baedbc 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -1,7 +1,6 @@
1#ifndef __i386_PCI_H 1#ifndef __i386_PCI_H
2#define __i386_PCI_H 2#define __i386_PCI_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7#include <linux/mm.h> /* for struct page */ 6#include <linux/mm.h> /* for struct page */
diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h
index 0380c3dc1f7e..4b1e61359f89 100644
--- a/include/asm-i386/pgalloc.h
+++ b/include/asm-i386/pgalloc.h
@@ -1,7 +1,6 @@
1#ifndef _I386_PGALLOC_H 1#ifndef _I386_PGALLOC_H
2#define _I386_PGALLOC_H 2#define _I386_PGALLOC_H
3 3
4#include <linux/config.h>
5#include <asm/fixmap.h> 4#include <asm/fixmap.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <linux/mm.h> /* for struct page */ 6#include <linux/mm.h> /* for struct page */
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 672c3f76b9df..09697fec3d2b 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -1,7 +1,6 @@
1#ifndef _I386_PGTABLE_H 1#ifndef _I386_PGTABLE_H
2#define _I386_PGTABLE_H 2#define _I386_PGTABLE_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * The Linux memory management assumes a three-level page table setup. On 6 * The Linux memory management assumes a three-level page table setup. On
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 805f0dcda468..4df3818e4122 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -17,7 +17,6 @@
17#include <asm/msr.h> 17#include <asm/msr.h>
18#include <asm/system.h> 18#include <asm/system.h>
19#include <linux/cache.h> 19#include <linux/cache.h>
20#include <linux/config.h>
21#include <linux/threads.h> 20#include <linux/threads.h>
22#include <asm/percpu.h> 21#include <asm/percpu.h>
23#include <linux/cpumask.h> 22#include <linux/cpumask.h>
diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h
index e1ecfccb743b..bd67480ca109 100644
--- a/include/asm-i386/serial.h
+++ b/include/asm-i386/serial.h
@@ -2,7 +2,6 @@
2 * include/asm-i386/serial.h 2 * include/asm-i386/serial.h
3 */ 3 */
4 4
5#include <linux/config.h>
6 5
7/* 6/*
8 * This assumes you have a 1.8432 MHz clock for your UART. 7 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 61d3ab9db70c..142d10e34ade 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -5,7 +5,6 @@
5 * We need the APIC definitions automatically as part of 'smp.h' 5 * We need the APIC definitions automatically as part of 'smp.h'
6 */ 6 */
7#ifndef __ASSEMBLY__ 7#ifndef __ASSEMBLY__
8#include <linux/config.h>
9#include <linux/kernel.h> 8#include <linux/kernel.h>
10#include <linux/threads.h> 9#include <linux/threads.h>
11#include <linux/cpumask.h> 10#include <linux/cpumask.h>
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index d76b7693cf1d..04ba30234c48 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -4,7 +4,6 @@
4#include <asm/atomic.h> 4#include <asm/atomic.h>
5#include <asm/rwlock.h> 5#include <asm/rwlock.h>
6#include <asm/page.h> 6#include <asm/page.h>
7#include <linux/config.h>
8#include <linux/compiler.h> 7#include <linux/compiler.h>
9 8
10/* 9/*
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h
index bb5f88a27f7a..b9277361954b 100644
--- a/include/asm-i386/string.h
+++ b/include/asm-i386/string.h
@@ -2,7 +2,6 @@
2#define _I386_STRING_H_ 2#define _I386_STRING_H_
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#include <linux/config.h>
6/* 5/*
7 * On a 486 or Pentium, we are better off not using the 6 * On a 486 or Pentium, we are better off not using the
8 * byte string operations. But on a 386 or a PPro the 7 * byte string operations. But on a 386 or a PPro the
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 19cc79c9a35d..0249f912a29c 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SYSTEM_H 1#ifndef __ASM_SYSTEM_H
2#define __ASM_SYSTEM_H 2#define __ASM_SYSTEM_H
3 3
4#include <linux/config.h>
5#include <linux/kernel.h> 4#include <linux/kernel.h>
6#include <asm/segment.h> 5#include <asm/segment.h>
7#include <asm/cpufeature.h> 6#include <asm/cpufeature.h>
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 1f7d48c9ba3f..8420ed12491e 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -9,7 +9,6 @@
9 9
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11 11
12#include <linux/config.h>
13#include <linux/compiler.h> 12#include <linux/compiler.h>
14#include <asm/page.h> 13#include <asm/page.h>
15 14
diff --git a/include/asm-i386/timex.h b/include/asm-i386/timex.h
index 292b5a68f627..d434984303ca 100644
--- a/include/asm-i386/timex.h
+++ b/include/asm-i386/timex.h
@@ -6,7 +6,6 @@
6#ifndef _ASMi386_TIMEX_H 6#ifndef _ASMi386_TIMEX_H
7#define _ASMi386_TIMEX_H 7#define _ASMi386_TIMEX_H
8 8
9#include <linux/config.h>
10#include <asm/processor.h> 9#include <asm/processor.h>
11 10
12#ifdef CONFIG_X86_ELAN 11#ifdef CONFIG_X86_ELAN
diff --git a/include/asm-i386/tlbflush.h b/include/asm-i386/tlbflush.h
index ab216e1370ef..d57ca5c540b6 100644
--- a/include/asm-i386/tlbflush.h
+++ b/include/asm-i386/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _I386_TLBFLUSH_H 1#ifndef _I386_TLBFLUSH_H
2#define _I386_TLBFLUSH_H 2#define _I386_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/processor.h> 5#include <asm/processor.h>
7 6
diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h
index e50a08bd7ced..4b4b295ccdb9 100644
--- a/include/asm-i386/types.h
+++ b/include/asm-i386/types.h
@@ -35,7 +35,6 @@ typedef unsigned long long __u64;
35 35
36#ifndef __ASSEMBLY__ 36#ifndef __ASSEMBLY__
37 37
38#include <linux/config.h>
39 38
40typedef signed char s8; 39typedef signed char s8;
41typedef unsigned char u8; 40typedef unsigned char u8;
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index 371457b1ceb6..1ec65523ea5e 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -4,7 +4,6 @@
4/* 4/*
5 * User space memory access functions 5 * User space memory access functions
6 */ 6 */
7#include <linux/config.h>
8#include <linux/errno.h> 7#include <linux/errno.h>
9#include <linux/thread_info.h> 8#include <linux/thread_info.h>
10#include <linux/prefetch.h> 9#include <linux/prefetch.h>
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index eb4b152c82fc..de2ccc149e34 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -323,6 +323,8 @@
323#define __NR_tee 315 323#define __NR_tee 315
324#define __NR_vmsplice 316 324#define __NR_vmsplice 316
325 325
326#ifdef __KERNEL__
327
326#define NR_syscalls 317 328#define NR_syscalls 317
327 329
328/* 330/*
@@ -422,7 +424,6 @@ __asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \
422__syscall_return(type,__res); \ 424__syscall_return(type,__res); \
423} 425}
424 426
425#ifdef __KERNEL__
426#define __ARCH_WANT_IPC_PARSE_VERSION 427#define __ARCH_WANT_IPC_PARSE_VERSION
427#define __ARCH_WANT_OLD_READDIR 428#define __ARCH_WANT_OLD_READDIR
428#define __ARCH_WANT_OLD_STAT 429#define __ARCH_WANT_OLD_STAT
@@ -446,7 +447,6 @@ __syscall_return(type,__res); \
446#define __ARCH_WANT_SYS_SIGPROCMASK 447#define __ARCH_WANT_SYS_SIGPROCMASK
447#define __ARCH_WANT_SYS_RT_SIGACTION 448#define __ARCH_WANT_SYS_RT_SIGACTION
448#define __ARCH_WANT_SYS_RT_SIGSUSPEND 449#define __ARCH_WANT_SYS_RT_SIGSUSPEND
449#endif
450 450
451#ifdef __KERNEL_SYSCALLS__ 451#ifdef __KERNEL_SYSCALLS__
452 452
@@ -485,7 +485,7 @@ asmlinkage long sys_rt_sigaction(int sig,
485 struct sigaction __user *oact, 485 struct sigaction __user *oact,
486 size_t sigsetsize); 486 size_t sigsetsize);
487 487
488#endif 488#endif /* __KERNEL_SYSCALLS__ */
489 489
490/* 490/*
491 * "Conditional" syscalls 491 * "Conditional" syscalls
@@ -497,4 +497,5 @@ asmlinkage long sys_rt_sigaction(int sig,
497#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 497#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
498#endif 498#endif
499 499
500#endif /* __KERNEL__ */
500#endif /* _ASM_I386_UNISTD_H_ */ 501#endif /* _ASM_I386_UNISTD_H_ */
diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h
index edf2cebb2969..c22b4658fc61 100644
--- a/include/asm-ia64/asmmacro.h
+++ b/include/asm-ia64/asmmacro.h
@@ -6,7 +6,6 @@
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#define ENTRY(name) \ 10#define ENTRY(name) \
12 .align 32; \ 11 .align 32; \
diff --git a/include/asm-ia64/cache.h b/include/asm-ia64/cache.h
index f0a104db8f20..e7482bd628ff 100644
--- a/include/asm-ia64/cache.h
+++ b/include/asm-ia64/cache.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IA64_CACHE_H 1#ifndef _ASM_IA64_CACHE_H
2#define _ASM_IA64_CACHE_H 2#define _ASM_IA64_CACHE_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * Copyright (C) 1998-2000 Hewlett-Packard Co 6 * Copyright (C) 1998-2000 Hewlett-Packard Co
diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h
index bba702076391..a30a62f235e1 100644
--- a/include/asm-ia64/delay.h
+++ b/include/asm-ia64/delay.h
@@ -12,7 +12,6 @@
12 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> 12 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18#include <linux/compiler.h> 17#include <linux/compiler.h>
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index df67d40801de..99a8f8e1218c 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -5,7 +5,6 @@
5 * Copyright (C) 2003-2004 Hewlett-Packard Co 5 * Copyright (C) 2003-2004 Hewlett-Packard Co
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8#include <linux/config.h>
9#include <asm/machvec.h> 8#include <asm/machvec.h>
10 9
11#define dma_alloc_coherent platform_dma_alloc_coherent 10#define dma_alloc_coherent platform_dma_alloc_coherent
diff --git a/include/asm-ia64/dma.h b/include/asm-ia64/dma.h
index 3be1b4925e18..dad3a735df8b 100644
--- a/include/asm-ia64/dma.h
+++ b/include/asm-ia64/dma.h
@@ -6,7 +6,6 @@
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#include <asm/io.h> /* need byte IO */ 10#include <asm/io.h> /* need byte IO */
12 11
diff --git a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
index 446fce036fd9..25f9835d5459 100644
--- a/include/asm-ia64/elf.h
+++ b/include/asm-ia64/elf.h
@@ -8,7 +8,6 @@
8 * David Mosberger-Tang <davidm@hpl.hp.com> 8 * David Mosberger-Tang <davidm@hpl.hp.com>
9 */ 9 */
10 10
11#include <linux/config.h>
12 11
13#include <asm/fpu.h> 12#include <asm/fpu.h>
14#include <asm/page.h> 13#include <asm/page.h>
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 33ef8f096d95..140e495b8e0e 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -6,7 +6,6 @@
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#include <linux/threads.h> 10#include <linux/threads.h>
12#include <linux/irq.h> 11#include <linux/irq.h>
diff --git a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h
index f8044a1169cd..5ff8d74c3e00 100644
--- a/include/asm-ia64/ia32.h
+++ b/include/asm-ia64/ia32.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IA64_IA32_H 1#ifndef _ASM_IA64_IA32_H
2#define _ASM_IA64_IA32_H 2#define _ASM_IA64_IA32_H
3 3
4#include <linux/config.h>
5 4
6#include <asm/ptrace.h> 5#include <asm/ptrace.h>
7#include <asm/signal.h> 6#include <asm/signal.h>
diff --git a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h
index 93f45c5f189f..e928675de352 100644
--- a/include/asm-ia64/ide.h
+++ b/include/asm-ia64/ide.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17 16
18#include <linux/irq.h> 17#include <linux/irq.h>
19 18
diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
index 8089f955e5d2..3a95aa432e99 100644
--- a/include/asm-ia64/intrinsics.h
+++ b/include/asm-ia64/intrinsics.h
@@ -9,7 +9,6 @@
9 */ 9 */
10 10
11#ifndef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
12#include <linux/config.h>
13 12
14/* include compiler specific intrinsics */ 13/* include compiler specific intrinsics */
15#include <asm/ia64regs.h> 14#include <asm/ia64regs.h>
diff --git a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h
index bc777525fa12..5d1658aa2b3b 100644
--- a/include/asm-ia64/kmap_types.h
+++ b/include/asm-ia64/kmap_types.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IA64_KMAP_TYPES_H 1#ifndef _ASM_IA64_KMAP_TYPES_H
2#define _ASM_IA64_KMAP_TYPES_H 2#define _ASM_IA64_KMAP_TYPES_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_DEBUG_HIGHMEM 5#ifdef CONFIG_DEBUG_HIGHMEM
7# define D(n) __KM_FENCE_##n , 6# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index a9c995a86c21..0df72a134c8b 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_IA64_MACHVEC_H 10#ifndef _ASM_IA64_MACHVEC_H
11#define _ASM_IA64_MACHVEC_H 11#define _ASM_IA64_MACHVEC_H
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15 14
16/* forward declarations: */ 15/* forward declarations: */
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 46501b01a5c5..894bc4d89dc0 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -7,7 +7,6 @@
7 * for more details. 7 * for more details.
8 */ 8 */
9 9
10#include <linux/config.h>
11 10
12/* 11/*
13 * Entries defined so far: 12 * Entries defined so far:
diff --git a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
index 9978c7ce7549..a140310bf84d 100644
--- a/include/asm-ia64/nodedata.h
+++ b/include/asm-ia64/nodedata.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_IA64_NODEDATA_H 11#ifndef _ASM_IA64_NODEDATA_H
12#define _ASM_IA64_NODEDATA_H 12#define _ASM_IA64_NODEDATA_H
13 13
14#include <linux/config.h>
15#include <linux/numa.h> 14#include <linux/numa.h>
16 15
17#include <asm/percpu.h> 16#include <asm/percpu.h>
diff --git a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
index dae6aeb7b119..e5a8260593a5 100644
--- a/include/asm-ia64/numa.h
+++ b/include/asm-ia64/numa.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_IA64_NUMA_H 11#ifndef _ASM_IA64_NUMA_H
12#define _ASM_IA64_NUMA_H 12#define _ASM_IA64_NUMA_H
13 13
14#include <linux/config.h>
15 14
16#ifdef CONFIG_NUMA 15#ifdef CONFIG_NUMA
17 16
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
index 2087825eefa4..f5a949ec6e1e 100644
--- a/include/asm-ia64/page.h
+++ b/include/asm-ia64/page.h
@@ -7,7 +7,6 @@
7 * David Mosberger-Tang <davidm@hpl.hp.com> 7 * David Mosberger-Tang <davidm@hpl.hp.com>
8 */ 8 */
9 9
10#include <linux/config.h>
11 10
12#include <asm/intrinsics.h> 11#include <asm/intrinsics.h>
13#include <asm/types.h> 12#include <asm/types.h>
diff --git a/include/asm-ia64/param.h b/include/asm-ia64/param.h
index 5e1e0d2d7baf..49c62dd5eccf 100644
--- a/include/asm-ia64/param.h
+++ b/include/asm-ia64/param.h
@@ -19,7 +19,6 @@
19#define MAXHOSTNAMELEN 64 /* max length of hostname */ 19#define MAXHOSTNAMELEN 64 /* max length of hostname */
20 20
21#ifdef __KERNEL__ 21#ifdef __KERNEL__
22# include <linux/config.h> /* mustn't include <linux/config.h> outside of #ifdef __KERNEL__ */
23# ifdef CONFIG_IA64_HP_SIM 22# ifdef CONFIG_IA64_HP_SIM
24 /* 23 /*
25 * Yeah, simulating stuff is slow, so let us catch some breath between 24 * Yeah, simulating stuff is slow, so let us catch some breath between
diff --git a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h
index 2b14dee29ce7..ae357d504fba 100644
--- a/include/asm-ia64/percpu.h
+++ b/include/asm-ia64/percpu.h
@@ -12,7 +12,6 @@
12# define THIS_CPU(var) (per_cpu__##var) /* use this to mark accesses to per-CPU variables... */ 12# define THIS_CPU(var) (per_cpu__##var) /* use this to mark accesses to per-CPU variables... */
13#else /* !__ASSEMBLY__ */ 13#else /* !__ASSEMBLY__ */
14 14
15#include <linux/config.h>
16 15
17#include <linux/threads.h> 16#include <linux/threads.h>
18 17
diff --git a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h
index f2f233846476..9cb68e9b377e 100644
--- a/include/asm-ia64/pgalloc.h
+++ b/include/asm-ia64/pgalloc.h
@@ -13,7 +13,6 @@
13 * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com> 13 * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com>
14 */ 14 */
15 15
16#include <linux/config.h>
17 16
18#include <linux/compiler.h> 17#include <linux/compiler.h>
19#include <linux/mm.h> 18#include <linux/mm.h>
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index c0f8144f2349..eaac08d5e0bd 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -12,7 +12,6 @@
12 * David Mosberger-Tang <davidm@hpl.hp.com> 12 * David Mosberger-Tang <davidm@hpl.hp.com>
13 */ 13 */
14 14
15#include <linux/config.h>
16 15
17#include <asm/mman.h> 16#include <asm/mman.h>
18#include <asm/page.h> 17#include <asm/page.h>
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index b3bd58e80690..265f4824db0e 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -13,7 +13,6 @@
13 * 06/16/00 A. Mallick added csd/ssd/tssd for ia32 support 13 * 06/16/00 A. Mallick added csd/ssd/tssd for ia32 support
14 */ 14 */
15 15
16#include <linux/config.h>
17 16
18#include <asm/intrinsics.h> 17#include <asm/intrinsics.h>
19#include <asm/kregs.h> 18#include <asm/kregs.h>
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 9471cdc3f4c0..415abb23b210 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -54,7 +54,6 @@
54 * This is because ar.ec is saved as part of ar.pfs. 54 * This is because ar.ec is saved as part of ar.pfs.
55 */ 55 */
56 56
57#include <linux/config.h>
58 57
59#include <asm/fpu.h> 58#include <asm/fpu.h>
60#ifndef ASM_OFFSETS_C 59#ifndef ASM_OFFSETS_C
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index a3914352c995..719ff309ce09 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_IA64_SMP_H 10#ifndef _ASM_IA64_SMP_H
11#define _ASM_IA64_SMP_H 11#define _ASM_IA64_SMP_H
12 12
13#include <linux/config.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/threads.h> 14#include <linux/threads.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h
index 16a48b5a039c..c3fd3eb25768 100644
--- a/include/asm-ia64/sn/simulator.h
+++ b/include/asm-ia64/sn/simulator.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_IA64_SN_SIMULATOR_H 8#ifndef _ASM_IA64_SN_SIMULATOR_H
9#define _ASM_IA64_SN_SIMULATOR_H 9#define _ASM_IA64_SN_SIMULATOR_H
10 10
11#include <linux/config.h>
12 11
13#define SNMAGIC 0xaeeeeeee8badbeefL 12#define SNMAGIC 0xaeeeeeee8badbeefL
14#define IS_MEDUSA() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) 13#define IS_MEDUSA() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
index 749deb2ca6c1..a676dd9ace3e 100644
--- a/include/asm-ia64/sn/sn_cpuid.h
+++ b/include/asm-ia64/sn/sn_cpuid.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_IA64_SN_SN_CPUID_H 11#ifndef _ASM_IA64_SN_SN_CPUID_H
12#define _ASM_IA64_SN_SN_CPUID_H 12#define _ASM_IA64_SN_SN_CPUID_H
13 13
14#include <linux/config.h>
15#include <linux/smp.h> 14#include <linux/smp.h>
16#include <asm/sn/addrs.h> 15#include <asm/sn/addrs.h>
17#include <asm/sn/pda.h> 16#include <asm/sn/pda.h>
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index 51aca022cf39..8c865e43f609 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14 14
15#include <linux/config.h>
16#include <asm/sal.h> 15#include <asm/sal.h>
17#include <asm/sn/sn_cpuid.h> 16#include <asm/sn/sn_cpuid.h>
18#include <asm/sn/arch.h> 17#include <asm/sn/arch.h>
diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h
index aa3b8ace9030..8406f1ef4caf 100644
--- a/include/asm-ia64/sn/xpc.h
+++ b/include/asm-ia64/sn/xpc.h
@@ -15,7 +15,6 @@
15#define _ASM_IA64_SN_XPC_H 15#define _ASM_IA64_SN_XPC_H
16 16
17 17
18#include <linux/config.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/sysctl.h> 19#include <linux/sysctl.h>
21#include <linux/device.h> 20#include <linux/device.h>
diff --git a/include/asm-ia64/string.h b/include/asm-ia64/string.h
index 43502d3b57e5..85fd65c52a8c 100644
--- a/include/asm-ia64/string.h
+++ b/include/asm-ia64/string.h
@@ -9,7 +9,6 @@
9 * David Mosberger-Tang <davidm@hpl.hp.com> 9 * David Mosberger-Tang <davidm@hpl.hp.com>
10 */ 10 */
11 11
12#include <linux/config.h> /* remove this once we remove the A-step workaround... */
13 12
14#define __HAVE_ARCH_STRLEN 1 /* see arch/ia64/lib/strlen.S */ 13#define __HAVE_ARCH_STRLEN 1 /* see arch/ia64/lib/strlen.S */
15#define __HAVE_ARCH_MEMSET 1 /* see arch/ia64/lib/memset.S */ 14#define __HAVE_ARCH_MEMSET 1 /* see arch/ia64/lib/memset.S */
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 2f3620593687..65db43ce4de6 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -12,7 +12,6 @@
12 * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com> 12 * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
13 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> 13 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
14 */ 14 */
15#include <linux/config.h>
16 15
17#include <asm/kregs.h> 16#include <asm/kregs.h>
18#include <asm/page.h> 17#include <asm/page.h>
diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
index 834370b9dea1..26edcb750f9f 100644
--- a/include/asm-ia64/tlb.h
+++ b/include/asm-ia64/tlb.h
@@ -37,7 +37,6 @@
37 * } 37 * }
38 * tlb_finish_mmu(tlb, start, end); // finish unmap for address space MM 38 * tlb_finish_mmu(tlb, start, end); // finish unmap for address space MM
39 */ 39 */
40#include <linux/config.h>
41#include <linux/mm.h> 40#include <linux/mm.h>
42#include <linux/pagemap.h> 41#include <linux/pagemap.h>
43#include <linux/swap.h> 42#include <linux/swap.h>
diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
index a35b323bae4c..cf9acb9bb1fb 100644
--- a/include/asm-ia64/tlbflush.h
+++ b/include/asm-ia64/tlbflush.h
@@ -6,7 +6,6 @@
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#include <linux/mm.h> 10#include <linux/mm.h>
12 11
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 7107763168bf..632f2eedf72c 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -294,7 +294,6 @@
294 294
295#ifdef __KERNEL__ 295#ifdef __KERNEL__
296 296
297#include <linux/config.h>
298 297
299#define NR_syscalls 279 /* length of syscall table */ 298#define NR_syscalls 279 /* length of syscall table */
300 299
diff --git a/include/asm-m32r/assembler.h b/include/asm-m32r/assembler.h
index 1a1aa17edd33..47041d19d4a8 100644
--- a/include/asm-m32r/assembler.h
+++ b/include/asm-m32r/assembler.h
@@ -9,7 +9,6 @@
9 * This file contains M32R architecture specific macro definitions. 9 * This file contains M32R architecture specific macro definitions.
10 */ 10 */
11 11
12#include <linux/config.h>
13 12
14#ifndef __STR 13#ifndef __STR
15#ifdef __ASSEMBLY__ 14#ifdef __ASSEMBLY__
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
index 3122fe106f05..f5a7d7301c72 100644
--- a/include/asm-m32r/atomic.h
+++ b/include/asm-m32r/atomic.h
@@ -9,7 +9,6 @@
9 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> 9 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <asm/assembler.h> 12#include <asm/assembler.h>
14#include <asm/system.h> 13#include <asm/system.h>
15 14
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index 902a366101a5..66ab672162cd 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -11,7 +11,6 @@
11 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> 11 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/compiler.h> 14#include <linux/compiler.h>
16#include <asm/assembler.h> 15#include <asm/assembler.h>
17#include <asm/system.h> 16#include <asm/system.h>
diff --git a/include/asm-m32r/cacheflush.h b/include/asm-m32r/cacheflush.h
index e57427b6e249..8b261b49149e 100644
--- a/include/asm-m32r/cacheflush.h
+++ b/include/asm-m32r/cacheflush.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_M32R_CACHEFLUSH_H 1#ifndef _ASM_M32R_CACHEFLUSH_H
2#define _ASM_M32R_CACHEFLUSH_H 2#define _ASM_M32R_CACHEFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6 5
7extern void _flush_cache_all(void); 6extern void _flush_cache_all(void);
diff --git a/include/asm-m32r/hardirq.h b/include/asm-m32r/hardirq.h
index 5da830ec1587..cb8aa762f235 100644
--- a/include/asm-m32r/hardirq.h
+++ b/include/asm-m32r/hardirq.h
@@ -2,7 +2,6 @@
2#ifndef __ASM_HARDIRQ_H 2#ifndef __ASM_HARDIRQ_H
3#define __ASM_HARDIRQ_H 3#define __ASM_HARDIRQ_H
4 4
5#include <linux/config.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <linux/irq.h> 6#include <linux/irq.h>
8 7
diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h
index f7aa96970d18..219a0f74eff3 100644
--- a/include/asm-m32r/ide.h
+++ b/include/asm-m32r/ide.h
@@ -15,7 +15,6 @@
15 15
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/config.h>
19 18
20#ifndef MAX_HWIFS 19#ifndef MAX_HWIFS
21# ifdef CONFIG_BLK_DEV_IDEPCI 20# ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-m32r/irq.h b/include/asm-m32r/irq.h
index ca943954572a..2f93f4743add 100644
--- a/include/asm-m32r/irq.h
+++ b/include/asm-m32r/irq.h
@@ -2,7 +2,6 @@
2#ifndef _ASM_M32R_IRQ_H 2#ifndef _ASM_M32R_IRQ_H
3#define _ASM_M32R_IRQ_H 3#define _ASM_M32R_IRQ_H
4 4
5#include <linux/config.h>
6 5
7#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_USRV) 6#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_USRV)
8/* 7/*
diff --git a/include/asm-m32r/kmap_types.h b/include/asm-m32r/kmap_types.h
index 7429591010b6..0524d89edb0f 100644
--- a/include/asm-m32r/kmap_types.h
+++ b/include/asm-m32r/kmap_types.h
@@ -3,7 +3,6 @@
3 3
4/* Dummy header just to define km_type. */ 4/* Dummy header just to define km_type. */
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_DEBUG_HIGHMEM 7#ifdef CONFIG_DEBUG_HIGHMEM
9# define D(n) __KM_FENCE_##n , 8# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-m32r/m32104ut/m32104ut_pld.h b/include/asm-m32r/m32104ut/m32104ut_pld.h
index a4eac20553df..6ba4ddf7dcf7 100644
--- a/include/asm-m32r/m32104ut/m32104ut_pld.h
+++ b/include/asm-m32r/m32104ut/m32104ut_pld.h
@@ -15,7 +15,6 @@
15#ifndef _M32104UT_M32104UT_PLD_H 15#ifndef _M32104UT_M32104UT_PLD_H
16#define _M32104UT_M32104UT_PLD_H 16#define _M32104UT_M32104UT_PLD_H
17 17
18#include <linux/config.h>
19 18
20#if defined(CONFIG_PLAT_M32104UT) 19#if defined(CONFIG_PLAT_M32104UT)
21#define PLD_PLAT_BASE 0x02c00000 20#define PLD_PLAT_BASE 0x02c00000
diff --git a/include/asm-m32r/m32700ut/m32700ut_lan.h b/include/asm-m32r/m32700ut/m32700ut_lan.h
index 50545ec9c42c..c050b19e8101 100644
--- a/include/asm-m32r/m32700ut/m32700ut_lan.h
+++ b/include/asm-m32r/m32700ut/m32700ut_lan.h
@@ -15,7 +15,6 @@
15#ifndef _M32700UT_M32700UT_LAN_H 15#ifndef _M32700UT_M32700UT_LAN_H
16#define _M32700UT_M32700UT_LAN_H 16#define _M32700UT_M32700UT_LAN_H
17 17
18#include <linux/config.h>
19 18
20#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
21/* 20/*
diff --git a/include/asm-m32r/m32700ut/m32700ut_lcd.h b/include/asm-m32r/m32700ut/m32700ut_lcd.h
index ede6c77bd5e6..4da4e822e2f3 100644
--- a/include/asm-m32r/m32700ut/m32700ut_lcd.h
+++ b/include/asm-m32r/m32700ut/m32700ut_lcd.h
@@ -15,7 +15,6 @@
15#ifndef _M32700UT_M32700UT_LCD_H 15#ifndef _M32700UT_M32700UT_LCD_H
16#define _M32700UT_M32700UT_LCD_H 16#define _M32700UT_M32700UT_LCD_H
17 17
18#include <linux/config.h>
19 18
20#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
21/* 20/*
diff --git a/include/asm-m32r/m32700ut/m32700ut_pld.h b/include/asm-m32r/m32700ut/m32700ut_pld.h
index f5e479486696..f35f9159acff 100644
--- a/include/asm-m32r/m32700ut/m32700ut_pld.h
+++ b/include/asm-m32r/m32700ut/m32700ut_pld.h
@@ -15,7 +15,6 @@
15#ifndef _M32700UT_M32700UT_PLD_H 15#ifndef _M32700UT_M32700UT_PLD_H
16#define _M32700UT_M32700UT_PLD_H 16#define _M32700UT_M32700UT_PLD_H
17 17
18#include <linux/config.h>
19 18
20#if defined(CONFIG_PLAT_M32700UT_Alpha) 19#if defined(CONFIG_PLAT_M32700UT_Alpha)
21#define PLD_PLAT_BASE 0x08c00000 20#define PLD_PLAT_BASE 0x08c00000
diff --git a/include/asm-m32r/m32r.h b/include/asm-m32r/m32r.h
index b133ca61acf1..decfc59907c7 100644
--- a/include/asm-m32r/m32r.h
+++ b/include/asm-m32r/m32r.h
@@ -7,7 +7,6 @@
7 * Copyright (C) 2003, 2004 Renesas Technology Corp. 7 * Copyright (C) 2003, 2004 Renesas Technology Corp.
8 */ 8 */
9 9
10#include <linux/config.h>
11 10
12/* Chip type */ 11/* Chip type */
13#if defined(CONFIG_CHIP_XNUX_MP) || defined(CONFIG_CHIP_XNUX2_MP) 12#if defined(CONFIG_CHIP_XNUX_MP) || defined(CONFIG_CHIP_XNUX2_MP)
diff --git a/include/asm-m32r/mmu.h b/include/asm-m32r/mmu.h
index 9c00eb78ee50..cf3f6d78ac66 100644
--- a/include/asm-m32r/mmu.h
+++ b/include/asm-m32r/mmu.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_M32R_MMU_H 1#ifndef _ASM_M32R_MMU_H
2#define _ASM_M32R_MMU_H 2#define _ASM_M32R_MMU_H
3 3
4#include <linux/config.h>
5 4
6#if !defined(CONFIG_MMU) 5#if !defined(CONFIG_MMU)
7typedef struct { 6typedef struct {
diff --git a/include/asm-m32r/mmu_context.h b/include/asm-m32r/mmu_context.h
index 3634c5361a9b..542302eb6bcb 100644
--- a/include/asm-m32r/mmu_context.h
+++ b/include/asm-m32r/mmu_context.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8#include <asm/m32r.h> 7#include <asm/m32r.h>
9 8
@@ -15,7 +14,6 @@
15 14
16#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
17 16
18#include <linux/config.h>
19#include <asm/atomic.h> 17#include <asm/atomic.h>
20#include <asm/pgalloc.h> 18#include <asm/pgalloc.h>
21#include <asm/mmu.h> 19#include <asm/mmu.h>
diff --git a/include/asm-m32r/opsput/opsput_lan.h b/include/asm-m32r/opsput/opsput_lan.h
index 7a2a839eedab..61948296f445 100644
--- a/include/asm-m32r/opsput/opsput_lan.h
+++ b/include/asm-m32r/opsput/opsput_lan.h
@@ -15,7 +15,6 @@
15#ifndef _OPSPUT_OPSPUT_LAN_H 15#ifndef _OPSPUT_OPSPUT_LAN_H
16#define _OPSPUT_OPSPUT_LAN_H 16#define _OPSPUT_OPSPUT_LAN_H
17 17
18#include <linux/config.h>
19 18
20#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
21/* 20/*
diff --git a/include/asm-m32r/opsput/opsput_lcd.h b/include/asm-m32r/opsput/opsput_lcd.h
index 3a883e3d7187..44cfd7fe2d88 100644
--- a/include/asm-m32r/opsput/opsput_lcd.h
+++ b/include/asm-m32r/opsput/opsput_lcd.h
@@ -15,7 +15,6 @@
15#ifndef _OPSPUT_OPSPUT_LCD_H 15#ifndef _OPSPUT_OPSPUT_LCD_H
16#define _OPSPUT_OPSPUT_LCD_H 16#define _OPSPUT_OPSPUT_LCD_H
17 17
18#include <linux/config.h>
19 18
20#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
21/* 20/*
diff --git a/include/asm-m32r/opsput/opsput_pld.h b/include/asm-m32r/opsput/opsput_pld.h
index 2018e6925035..46296fe1ec1a 100644
--- a/include/asm-m32r/opsput/opsput_pld.h
+++ b/include/asm-m32r/opsput/opsput_pld.h
@@ -15,7 +15,6 @@
15#ifndef _OPSPUT_OPSPUT_PLD_H 15#ifndef _OPSPUT_OPSPUT_PLD_H
16#define _OPSPUT_OPSPUT_PLD_H 16#define _OPSPUT_OPSPUT_PLD_H
17 17
18#include <linux/config.h>
19 18
20#define PLD_PLAT_BASE 0x1cc00000 19#define PLD_PLAT_BASE 0x1cc00000
21 20
diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h
index 9ddbc087dbc5..9688be003620 100644
--- a/include/asm-m32r/page.h
+++ b/include/asm-m32r/page.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_M32R_PAGE_H 1#ifndef _ASM_M32R_PAGE_H
2#define _ASM_M32R_PAGE_H 2#define _ASM_M32R_PAGE_H
3 3
4#include <linux/config.h>
5 4
6/* PAGE_SHIFT determines the page size */ 5/* PAGE_SHIFT determines the page size */
7#define PAGE_SHIFT 12 6#define PAGE_SHIFT 12
diff --git a/include/asm-m32r/pgalloc.h b/include/asm-m32r/pgalloc.h
index 6da309b6fda7..e09a86c3cadf 100644
--- a/include/asm-m32r/pgalloc.h
+++ b/include/asm-m32r/pgalloc.h
@@ -3,7 +3,6 @@
3 3
4/* $Id$ */ 4/* $Id$ */
5 5
6#include <linux/config.h>
7#include <linux/mm.h> 6#include <linux/mm.h>
8 7
9#include <asm/io.h> 8#include <asm/io.h>
diff --git a/include/asm-m32r/pgtable-2level.h b/include/asm-m32r/pgtable-2level.h
index 861727c20e8f..be0f167e344a 100644
--- a/include/asm-m32r/pgtable-2level.h
+++ b/include/asm-m32r/pgtable-2level.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8/* 7/*
9 * traditional M32R two-level paging structure: 8 * traditional M32R two-level paging structure:
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 75740debcd01..1983b7f4527a 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -20,7 +20,6 @@
20 20
21#ifndef __ASSEMBLY__ 21#ifndef __ASSEMBLY__
22 22
23#include <linux/config.h>
24#include <linux/threads.h> 23#include <linux/threads.h>
25#include <asm/processor.h> 24#include <asm/processor.h>
26#include <asm/addrspace.h> 25#include <asm/addrspace.h>
diff --git a/include/asm-m32r/processor.h b/include/asm-m32r/processor.h
index 09fd1813e780..32755bf136de 100644
--- a/include/asm-m32r/processor.h
+++ b/include/asm-m32r/processor.h
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/config.h>
18#include <asm/cache.h> 17#include <asm/cache.h>
19#include <asm/ptrace.h> /* pt_regs */ 18#include <asm/ptrace.h> /* pt_regs */
20 19
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 53c792452dfc..a07fa90314d2 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -12,7 +12,6 @@
12 * Copyright (C) 2001-2002, 2004 Hirokazu Takata <takata at linux-m32r.org> 12 * Copyright (C) 2001-2002, 2004 Hirokazu Takata <takata at linux-m32r.org>
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */ 15#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */
17 16
18/* 0 - 13 are integer registers (general purpose registers). */ 17/* 0 - 13 are integer registers (general purpose registers). */
diff --git a/include/asm-m32r/rtc.h b/include/asm-m32r/rtc.h
index ec3cdf666c68..6b2b837c5978 100644
--- a/include/asm-m32r/rtc.h
+++ b/include/asm-m32r/rtc.h
@@ -4,7 +4,6 @@
4#define __RTC_H__ 4#define __RTC_H__
5 5
6 6
7#include <linux/config.h>
8 7
9 /* Dallas DS1302 clock/calendar register numbers. */ 8 /* Dallas DS1302 clock/calendar register numbers. */
10# define RTC_SECONDS 0 9# define RTC_SECONDS 0
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
index 81750edc8916..41e45d7b87ef 100644
--- a/include/asm-m32r/semaphore.h
+++ b/include/asm-m32r/semaphore.h
@@ -12,7 +12,6 @@
12 * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> 12 * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/wait.h> 15#include <linux/wait.h>
17#include <linux/rwsem.h> 16#include <linux/rwsem.h>
18#include <asm/assembler.h> 17#include <asm/assembler.h>
diff --git a/include/asm-m32r/serial.h b/include/asm-m32r/serial.h
index 1bf480f58493..5ac244c72f15 100644
--- a/include/asm-m32r/serial.h
+++ b/include/asm-m32r/serial.h
@@ -3,7 +3,6 @@
3 3
4/* include/asm-m32r/serial.h */ 4/* include/asm-m32r/serial.h */
5 5
6#include <linux/config.h>
7 6
8#define BASE_BAUD 115200 7#define BASE_BAUD 115200
9 8
diff --git a/include/asm-m32r/sigcontext.h b/include/asm-m32r/sigcontext.h
index 942b8a30937d..73025c0c41a1 100644
--- a/include/asm-m32r/sigcontext.h
+++ b/include/asm-m32r/sigcontext.h
@@ -3,7 +3,6 @@
3 3
4/* $Id$ */ 4/* $Id$ */
5 5
6#include <linux/config.h>
7 6
8struct sigcontext { 7struct sigcontext {
9 /* CPU registers */ 8 /* CPU registers */
diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h
index 1184293e5712..650d2558c304 100644
--- a/include/asm-m32r/smp.h
+++ b/include/asm-m32r/smp.h
@@ -3,7 +3,6 @@
3 3
4/* $Id$ */ 4/* $Id$ */
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_SMP 7#ifdef CONFIG_SMP
9#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
diff --git a/include/asm-m32r/spinlock.h b/include/asm-m32r/spinlock.h
index 7de7def28da9..f94c1a673569 100644
--- a/include/asm-m32r/spinlock.h
+++ b/include/asm-m32r/spinlock.h
@@ -9,7 +9,6 @@
9 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> 9 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
10 */ 10 */
11 11
12#include <linux/config.h> /* CONFIG_DEBUG_SPINLOCK, CONFIG_SMP */
13#include <linux/compiler.h> 12#include <linux/compiler.h>
14#include <asm/atomic.h> 13#include <asm/atomic.h>
15#include <asm/page.h> 14#include <asm/page.h>
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index e55013f378e5..33567e8bfe6b 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -10,7 +10,6 @@
10 * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> 10 * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <asm/assembler.h> 13#include <asm/assembler.h>
15 14
16#ifdef __KERNEL__ 15#ifdef __KERNEL__
diff --git a/include/asm-m32r/timex.h b/include/asm-m32r/timex.h
index abf12e7ffbf3..e89bfd17db51 100644
--- a/include/asm-m32r/timex.h
+++ b/include/asm-m32r/timex.h
@@ -9,7 +9,6 @@
9 * m32r architecture timex specifications 9 * m32r architecture timex specifications
10 */ 10 */
11 11
12#include <linux/config.h>
13 12
14#define CLOCK_TICK_RATE (CONFIG_BUS_CLOCK / CONFIG_TIMER_DIVIDE) 13#define CLOCK_TICK_RATE (CONFIG_BUS_CLOCK / CONFIG_TIMER_DIVIDE)
15#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ 14#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
diff --git a/include/asm-m32r/tlbflush.h b/include/asm-m32r/tlbflush.h
index bc7c407dbd92..ae4494960593 100644
--- a/include/asm-m32r/tlbflush.h
+++ b/include/asm-m32r/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_M32R_TLBFLUSH_H 1#ifndef _ASM_M32R_TLBFLUSH_H
2#define _ASM_M32R_TLBFLUSH_H 2#define _ASM_M32R_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <asm/m32r.h> 4#include <asm/m32r.h>
6 5
7/* 6/*
diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h
index 819cc28a94f7..26e978c7e3b4 100644
--- a/include/asm-m32r/uaccess.h
+++ b/include/asm-m32r/uaccess.h
@@ -11,7 +11,6 @@
11/* 11/*
12 * User space memory access functions 12 * User space memory access functions
13 */ 13 */
14#include <linux/config.h>
15#include <linux/errno.h> 14#include <linux/errno.h>
16#include <linux/thread_info.h> 15#include <linux/thread_info.h>
17#include <asm/page.h> 16#include <asm/page.h>
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index be0eb014c3b0..cc31790d8077 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -295,6 +295,8 @@
295#define __NR_kexec_load 283 295#define __NR_kexec_load 283
296#define __NR_waitid 284 296#define __NR_waitid 284
297 297
298#ifdef __KERNEL__
299
298#define NR_syscalls 285 300#define NR_syscalls 285
299 301
300/* user-visible error numbers are in the range -1 - -124: see 302/* user-visible error numbers are in the range -1 - -124: see
@@ -405,7 +407,6 @@ __asm__ __volatile__ (\
405__syscall_return(type,__res); \ 407__syscall_return(type,__res); \
406} 408}
407 409
408#ifdef __KERNEL__
409#define __ARCH_WANT_IPC_PARSE_VERSION 410#define __ARCH_WANT_IPC_PARSE_VERSION
410#define __ARCH_WANT_STAT64 411#define __ARCH_WANT_STAT64
411#define __ARCH_WANT_SYS_ALARM 412#define __ARCH_WANT_SYS_ALARM
@@ -421,7 +422,6 @@ __syscall_return(type,__res); \
421#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ 422#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
422#define __ARCH_WANT_SYS_OLDUMOUNT 423#define __ARCH_WANT_SYS_OLDUMOUNT
423#define __ARCH_WANT_SYS_RT_SIGACTION 424#define __ARCH_WANT_SYS_RT_SIGACTION
424#endif
425 425
426#ifdef __KERNEL_SYSCALLS__ 426#ifdef __KERNEL_SYSCALLS__
427 427
@@ -470,4 +470,5 @@ asmlinkage long sys_rt_sigaction(int sig,
470#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 470#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
471#endif 471#endif
472 472
473#endif /* __KERNEL__ */
473#endif /* _ASM_M32R_UNISTD_H */ 474#endif /* _ASM_M32R_UNISTD_H */
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index 732d696d31a6..d5eed64cb833 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -1,7 +1,6 @@
1#ifndef __ARCH_M68K_ATOMIC__ 1#ifndef __ARCH_M68K_ATOMIC__
2#define __ARCH_M68K_ATOMIC__ 2#define __ARCH_M68K_ATOMIC__
3 3
4#include <linux/config.h>
5 4
6#include <asm/system.h> /* local_irq_XXX() */ 5#include <asm/system.h> /* local_irq_XXX() */
7 6
diff --git a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h
index 072ce274d537..7b60776cc966 100644
--- a/include/asm-m68k/bug.h
+++ b/include/asm-m68k/bug.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_BUG_H 1#ifndef _M68K_BUG_H
2#define _M68K_BUG_H 2#define _M68K_BUG_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_BUG 5#ifdef CONFIG_BUG
7#ifdef CONFIG_DEBUG_BUGVERBOSE 6#ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h
index b1920c703d82..dffd59cf1364 100644
--- a/include/asm-m68k/dma-mapping.h
+++ b/include/asm-m68k/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_DMA_MAPPING_H 1#ifndef _M68K_DMA_MAPPING_H
2#define _M68K_DMA_MAPPING_H 2#define _M68K_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7#include <asm-generic/dma-mapping.h> 6#include <asm-generic/dma-mapping.h>
diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h
index d5266a886226..d0c9e61e57b4 100644
--- a/include/asm-m68k/dma.h
+++ b/include/asm-m68k/dma.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_DMA_H 1#ifndef _M68K_DMA_H
2#define _M68K_DMA_H 1 2#define _M68K_DMA_H 1
3 3
4#include <linux/config.h>
5 4
6/* it's useless on the m68k, but unfortunately needed by the new 5/* it's useless on the m68k, but unfortunately needed by the new
7 bootmem allocator (but this should do it for this) */ 6 bootmem allocator (but this should do it for this) */
diff --git a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h
index 5978f87b0a8a..e1112de5a5e3 100644
--- a/include/asm-m68k/dvma.h
+++ b/include/asm-m68k/dvma.h
@@ -9,7 +9,6 @@
9#ifndef __M68K_DVMA_H 9#ifndef __M68K_DVMA_H
10#define __M68K_DVMA_H 10#define __M68K_DVMA_H
11 11
12#include <linux/config.h>
13 12
14#define DVMA_PAGE_SHIFT 13 13#define DVMA_PAGE_SHIFT 13
15#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) 14#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT)
diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h
index 38bf8347f14d..eb63b85f9336 100644
--- a/include/asm-m68k/elf.h
+++ b/include/asm-m68k/elf.h
@@ -5,7 +5,6 @@
5 * ELF register definitions.. 5 * ELF register definitions..
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <asm/ptrace.h> 8#include <asm/ptrace.h>
10#include <asm/user.h> 9#include <asm/user.h>
11 10
diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h
index 0396495cd97d..f8f6b185d793 100644
--- a/include/asm-m68k/entry.h
+++ b/include/asm-m68k/entry.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_ENTRY_H 1#ifndef __M68K_ENTRY_H
2#define __M68K_ENTRY_H 2#define __M68K_ENTRY_H
3 3
4#include <linux/config.h>
5#include <asm/setup.h> 4#include <asm/setup.h>
6#include <asm/page.h> 5#include <asm/page.h>
7 6
diff --git a/include/asm-m68k/fpu.h b/include/asm-m68k/fpu.h
index 3bcf85065c19..59701d7b4e78 100644
--- a/include/asm-m68k/fpu.h
+++ b/include/asm-m68k/fpu.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_FPU_H 1#ifndef __M68K_FPU_H
2#define __M68K_FPU_H 2#define __M68K_FPU_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * MAX floating point unit state size (FSAVE/FRESTORE) 6 * MAX floating point unit state size (FSAVE/FRESTORE)
diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
index 5e1c5826c83d..394ee946015c 100644
--- a/include/asm-m68k/hardirq.h
+++ b/include/asm-m68k/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_HARDIRQ_H 1#ifndef __M68K_HARDIRQ_H
2#define __M68K_HARDIRQ_H 2#define __M68K_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/cache.h> 5#include <linux/cache.h>
7 6
diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h
index 36118fd01867..365f76fb8013 100644
--- a/include/asm-m68k/ide.h
+++ b/include/asm-m68k/ide.h
@@ -31,7 +31,6 @@
31 31
32#ifdef __KERNEL__ 32#ifdef __KERNEL__
33 33
34#include <linux/config.h>
35 34
36#include <asm/setup.h> 35#include <asm/setup.h>
37#include <asm/io.h> 36#include <asm/io.h>
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index dcfaa352d34c..5e0fcf41804d 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -23,7 +23,6 @@
23 23
24#ifdef __KERNEL__ 24#ifdef __KERNEL__
25 25
26#include <linux/config.h>
27#include <linux/compiler.h> 26#include <linux/compiler.h>
28#include <asm/raw_io.h> 27#include <asm/raw_io.h>
29#include <asm/virtconvert.h> 28#include <asm/virtconvert.h>
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h
index 9ac047c400c4..b4f48b2a6a57 100644
--- a/include/asm-m68k/irq.h
+++ b/include/asm-m68k/irq.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_IRQ_H_ 1#ifndef _M68K_IRQ_H_
2#define _M68K_IRQ_H_ 2#define _M68K_IRQ_H_
3 3
4#include <linux/config.h>
5#include <linux/interrupt.h> 4#include <linux/interrupt.h>
6 5
7/* 6/*
diff --git a/include/asm-m68k/mc146818rtc.h b/include/asm-m68k/mc146818rtc.h
index 11442095a8cf..11fe12ddb913 100644
--- a/include/asm-m68k/mc146818rtc.h
+++ b/include/asm-m68k/mc146818rtc.h
@@ -4,7 +4,6 @@
4#ifndef _ASM_MC146818RTC_H 4#ifndef _ASM_MC146818RTC_H
5#define _ASM_MC146818RTC_H 5#define _ASM_MC146818RTC_H
6 6
7#include <linux/config.h>
8 7
9#ifdef CONFIG_ATARI 8#ifdef CONFIG_ATARI
10/* RTC in Atari machines */ 9/* RTC in Atari machines */
diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h
index 661191d15c81..231d11bd8e32 100644
--- a/include/asm-m68k/mmu_context.h
+++ b/include/asm-m68k/mmu_context.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_MMU_CONTEXT_H 1#ifndef __M68K_MMU_CONTEXT_H
2#define __M68K_MMU_CONTEXT_H 2#define __M68K_MMU_CONTEXT_H
3 3
4#include <linux/config.h>
5 4
6static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) 5static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
7{ 6{
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
index 1628723458f5..1ccc7338a54b 100644
--- a/include/asm-m68k/motorola_pgtable.h
+++ b/include/asm-m68k/motorola_pgtable.h
@@ -1,7 +1,6 @@
1#ifndef _MOTOROLA_PGTABLE_H 1#ifndef _MOTOROLA_PGTABLE_H
2#define _MOTOROLA_PGTABLE_H 2#define _MOTOROLA_PGTABLE_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * Definitions for MMU descriptors 6 * Definitions for MMU descriptors
diff --git a/include/asm-m68k/openprom.h b/include/asm-m68k/openprom.h
index efbfb0bec6e2..869ab9176e9f 100644
--- a/include/asm-m68k/openprom.h
+++ b/include/asm-m68k/openprom.h
@@ -8,7 +8,6 @@
8 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 8 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
9 */ 9 */
10 10
11#include <linux/config.h>
12 11
13/* Empirical constants... */ 12/* Empirical constants... */
14#ifdef CONFIG_SUN3 13#ifdef CONFIG_SUN3
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index f206dfbc1d48..db017f838c29 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_PAGE_H 1#ifndef _M68K_PAGE_H
2#define _M68K_PAGE_H 2#define _M68K_PAGE_H
3 3
4#include <linux/config.h>
5 4
6/* PAGE_SHIFT determines the page size */ 5/* PAGE_SHIFT determines the page size */
7#ifndef CONFIG_SUN3 6#ifndef CONFIG_SUN3
diff --git a/include/asm-m68k/page_offset.h b/include/asm-m68k/page_offset.h
index 86d3c2845ad4..1cbdb7f30ac2 100644
--- a/include/asm-m68k/page_offset.h
+++ b/include/asm-m68k/page_offset.h
@@ -1,4 +1,3 @@
1#include <linux/config.h>
2 1
3/* This handles the memory map.. */ 2/* This handles the memory map.. */
4#ifndef CONFIG_SUN3 3#ifndef CONFIG_SUN3
diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h
index b468b7958aaa..a9cfb4b99d88 100644
--- a/include/asm-m68k/pgalloc.h
+++ b/include/asm-m68k/pgalloc.h
@@ -2,7 +2,6 @@
2#ifndef M68K_PGALLOC_H 2#ifndef M68K_PGALLOC_H
3#define M68K_PGALLOC_H 3#define M68K_PGALLOC_H
4 4
5#include <linux/config.h>
6#include <linux/mm.h> 5#include <linux/mm.h>
7#include <linux/highmem.h> 6#include <linux/highmem.h>
8#include <asm/setup.h> 7#include <asm/setup.h>
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index add129e93fd7..f3aa05377987 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -3,7 +3,6 @@
3 3
4#include <asm-generic/4level-fixup.h> 4#include <asm-generic/4level-fixup.h>
5 5
6#include <linux/config.h>
7#include <asm/setup.h> 6#include <asm/setup.h>
8 7
9#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
index 7982285e84ed..352799e71f08 100644
--- a/include/asm-m68k/processor.h
+++ b/include/asm-m68k/processor.h
@@ -13,7 +13,6 @@
13 */ 13 */
14#define current_text_addr() ({ __label__ _l; _l: &&_l;}) 14#define current_text_addr() ({ __label__ _l; _l: &&_l;})
15 15
16#include <linux/config.h>
17#include <linux/thread_info.h> 16#include <linux/thread_info.h>
18#include <asm/segment.h> 17#include <asm/segment.h>
19#include <asm/fpu.h> 18#include <asm/fpu.h>
diff --git a/include/asm-m68k/semaphore-helper.h b/include/asm-m68k/semaphore-helper.h
index 1516a642f9a5..eef30ba0b499 100644
--- a/include/asm-m68k/semaphore-helper.h
+++ b/include/asm-m68k/semaphore-helper.h
@@ -9,7 +9,6 @@
9 * m68k version by Andreas Schwab 9 * m68k version by Andreas Schwab
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/errno.h> 12#include <linux/errno.h>
14 13
15/* 14/*
diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h
index 3fe29f8b0194..2b90d6e69070 100644
--- a/include/asm-m68k/serial.h
+++ b/include/asm-m68k/serial.h
@@ -6,7 +6,6 @@
6 * 6 *
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11/* 10/*
12 * This assumes you have a 1.8432 MHz clock for your UART. 11 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h
index a89aa84073e5..7facc9a46e74 100644
--- a/include/asm-m68k/setup.h
+++ b/include/asm-m68k/setup.h
@@ -23,7 +23,6 @@
23#ifndef _M68K_SETUP_H 23#ifndef _M68K_SETUP_H
24#define _M68K_SETUP_H 24#define _M68K_SETUP_H
25 25
26#include <linux/config.h>
27 26
28 27
29 /* 28 /*
diff --git a/include/asm-m68k/shm.h b/include/asm-m68k/shm.h
index 3fa2f368fc1a..fa56ec84a126 100644
--- a/include/asm-m68k/shm.h
+++ b/include/asm-m68k/shm.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_SHM_H 1#ifndef _M68K_SHM_H
2#define _M68K_SHM_H 2#define _M68K_SHM_H
3 3
4#include <linux/config.h>
5 4
6/* format of page table entries that correspond to shared memory pages 5/* format of page table entries that correspond to shared memory pages
7 currently out in swap space (see also mm/swap.c): 6 currently out in swap space (see also mm/swap.c):
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 64d3481df74c..d6dd8052cd6f 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_SYSTEM_H 1#ifndef _M68K_SYSTEM_H
2#define _M68K_SYSTEM_H 2#define _M68K_SYSTEM_H
3 3
4#include <linux/config.h> /* get configuration macros */
5#include <linux/linkage.h> 4#include <linux/linkage.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <asm/segment.h> 6#include <asm/segment.h>
diff --git a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h
index 8e61ccffe13a..31678831ee47 100644
--- a/include/asm-m68k/tlbflush.h
+++ b/include/asm-m68k/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_TLBFLUSH_H 1#ifndef _M68K_TLBFLUSH_H
2#define _M68K_TLBFLUSH_H 2#define _M68K_TLBFLUSH_H
3 3
4#include <linux/config.h>
5 4
6#ifndef CONFIG_SUN3 5#ifndef CONFIG_SUN3
7 6
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index c2554bcd1747..f236fe92156f 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -285,6 +285,8 @@
285#define __NR_request_key 280 285#define __NR_request_key 280
286#define __NR_keyctl 281 286#define __NR_keyctl 281
287 287
288#ifdef __KERNEL__
289
288#define NR_syscalls 282 290#define NR_syscalls 282
289 291
290/* user-visible error numbers are in the range -1 - -124: see 292/* user-visible error numbers are in the range -1 - -124: see
@@ -383,7 +385,6 @@ __asm__ __volatile__ ("trap #0" \
383__syscall_return(type,__res); \ 385__syscall_return(type,__res); \
384} 386}
385 387
386#ifdef __KERNEL__
387#define __ARCH_WANT_IPC_PARSE_VERSION 388#define __ARCH_WANT_IPC_PARSE_VERSION
388#define __ARCH_WANT_OLD_READDIR 389#define __ARCH_WANT_OLD_READDIR
389#define __ARCH_WANT_OLD_STAT 390#define __ARCH_WANT_OLD_STAT
@@ -406,7 +407,6 @@ __syscall_return(type,__res); \
406#define __ARCH_WANT_SYS_SIGPENDING 407#define __ARCH_WANT_SYS_SIGPENDING
407#define __ARCH_WANT_SYS_SIGPROCMASK 408#define __ARCH_WANT_SYS_SIGPROCMASK
408#define __ARCH_WANT_SYS_RT_SIGACTION 409#define __ARCH_WANT_SYS_RT_SIGACTION
409#endif
410 410
411#ifdef __KERNEL_SYSCALLS__ 411#ifdef __KERNEL_SYSCALLS__
412 412
@@ -451,7 +451,7 @@ asmlinkage long sys_rt_sigaction(int sig,
451 struct sigaction __user *oact, 451 struct sigaction __user *oact,
452 size_t sigsetsize); 452 size_t sigsetsize);
453 453
454#endif 454#endif /* __KERNEL_SYSCALLS__ */
455 455
456/* 456/*
457 * "Conditional" syscalls 457 * "Conditional" syscalls
@@ -461,4 +461,5 @@ asmlinkage long sys_rt_sigaction(int sig,
461 */ 461 */
462#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 462#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
463 463
464#endif /* __KERNEL__ */
464#endif /* _ASM_M68K_UNISTD_H_ */ 465#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
index 8c4e8037b898..83a87c9b1a16 100644
--- a/include/asm-m68k/virtconvert.h
+++ b/include/asm-m68k/virtconvert.h
@@ -7,7 +7,6 @@
7 7
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9 9
10#include <linux/config.h>
11#include <linux/compiler.h> 10#include <linux/compiler.h>
12#include <asm/setup.h> 11#include <asm/setup.h>
13#include <asm/page.h> 12#include <asm/page.h>
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index 0b68ccd327f7..d7fa7d9c0e0f 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -5,7 +5,6 @@
5 * Copyright 1992, Linus Torvalds. 5 * Copyright 1992, Linus Torvalds.
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/compiler.h> 8#include <linux/compiler.h>
10#include <asm/byteorder.h> /* swab32 */ 9#include <asm/byteorder.h> /* swab32 */
11#include <asm/system.h> /* save_flags */ 10#include <asm/system.h> /* save_flags */
diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
index 6190f77b1e6c..2fabca91df83 100644
--- a/include/asm-m68knommu/coldfire.h
+++ b/include/asm-m68knommu/coldfire.h
@@ -12,7 +12,6 @@
12#define coldfire_h 12#define coldfire_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Define the processor support peripherals base address. 17 * Define the processor support peripherals base address.
diff --git a/include/asm-m68knommu/commproc.h b/include/asm-m68knommu/commproc.h
index e522ca8193a2..0161ebb5d883 100644
--- a/include/asm-m68knommu/commproc.h
+++ b/include/asm-m68knommu/commproc.h
@@ -17,7 +17,6 @@
17#ifndef __CPM_360__ 17#ifndef __CPM_360__
18#define __CPM_360__ 18#define __CPM_360__
19 19
20#include <linux/config.h>
21 20
22/* CPM Command register masks: */ 21/* CPM Command register masks: */
23#define CPM_CR_RST ((ushort)0x8000) 22#define CPM_CR_RST ((ushort)0x8000)
diff --git a/include/asm-m68knommu/dma-mapping.h b/include/asm-m68knommu/dma-mapping.h
index a6c42ba48da6..5622b855a577 100644
--- a/include/asm-m68knommu/dma-mapping.h
+++ b/include/asm-m68knommu/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _M68KNOMMU_DMA_MAPPING_H 1#ifndef _M68KNOMMU_DMA_MAPPING_H
2#define _M68KNOMMU_DMA_MAPPING_H 2#define _M68KNOMMU_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7#include <asm-generic/dma-mapping.h> 6#include <asm-generic/dma-mapping.h>
diff --git a/include/asm-m68knommu/dma.h b/include/asm-m68knommu/dma.h
index 43e98c96a5c2..3338001abb40 100644
--- a/include/asm-m68knommu/dma.h
+++ b/include/asm-m68knommu/dma.h
@@ -3,7 +3,6 @@
3 3
4//#define DMA_DEBUG 1 4//#define DMA_DEBUG 1
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_COLDFIRE 7#ifdef CONFIG_COLDFIRE
9/* 8/*
diff --git a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h
index 9919487703bc..40b1ed6827db 100644
--- a/include/asm-m68knommu/elf.h
+++ b/include/asm-m68knommu/elf.h
@@ -5,7 +5,6 @@
5 * ELF register definitions.. 5 * ELF register definitions..
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <asm/ptrace.h> 8#include <asm/ptrace.h>
10#include <asm/user.h> 9#include <asm/user.h>
11 10
diff --git a/include/asm-m68knommu/elia.h b/include/asm-m68knommu/elia.h
index f18b8e9d8c36..e037d4e2de33 100644
--- a/include/asm-m68knommu/elia.h
+++ b/include/asm-m68knommu/elia.h
@@ -12,7 +12,6 @@
12#define elia_h 12#define elia_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16#include <asm/coldfire.h> 15#include <asm/coldfire.h>
17 16
18#ifdef CONFIG_eLIA 17#ifdef CONFIG_eLIA
diff --git a/include/asm-m68knommu/entry.h b/include/asm-m68knommu/entry.h
index 06f5aa70b0b5..c2553d26273d 100644
--- a/include/asm-m68knommu/entry.h
+++ b/include/asm-m68knommu/entry.h
@@ -1,7 +1,6 @@
1#ifndef __M68KNOMMU_ENTRY_H 1#ifndef __M68KNOMMU_ENTRY_H
2#define __M68KNOMMU_ENTRY_H 2#define __M68KNOMMU_ENTRY_H
3 3
4#include <linux/config.h>
5#include <asm/setup.h> 4#include <asm/setup.h>
6#include <asm/page.h> 5#include <asm/page.h>
7 6
diff --git a/include/asm-m68knommu/fpu.h b/include/asm-m68knommu/fpu.h
index 225082991a03..b16b2e4fca2a 100644
--- a/include/asm-m68knommu/fpu.h
+++ b/include/asm-m68knommu/fpu.h
@@ -1,7 +1,6 @@
1#ifndef __M68KNOMMU_FPU_H 1#ifndef __M68KNOMMU_FPU_H
2#define __M68KNOMMU_FPU_H 2#define __M68KNOMMU_FPU_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * MAX floating point unit state size (FSAVE/FRESTORE) 6 * MAX floating point unit state size (FSAVE/FRESTORE)
diff --git a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h
index 476180f4cba2..980075bab792 100644
--- a/include/asm-m68knommu/hardirq.h
+++ b/include/asm-m68knommu/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_HARDIRQ_H 1#ifndef __M68K_HARDIRQ_H
2#define __M68K_HARDIRQ_H 2#define __M68K_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/cache.h> 4#include <linux/cache.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7#include <asm/irq.h> 6#include <asm/irq.h>
diff --git a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h
index e08f2ee4b4a2..8df4cee2a0cd 100644
--- a/include/asm-m68knommu/io.h
+++ b/include/asm-m68knommu/io.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8/* 7/*
9 * These are for ISA/PCI shared memory _only_ and should never be used 8 * These are for ISA/PCI shared memory _only_ and should never be used
diff --git a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h
index 20c48ec858a4..2b408842a30e 100644
--- a/include/asm-m68knommu/irq.h
+++ b/include/asm-m68knommu/irq.h
@@ -1,7 +1,6 @@
1#ifndef _M68K_IRQ_H_ 1#ifndef _M68K_IRQ_H_
2#define _M68K_IRQ_H_ 2#define _M68K_IRQ_H_
3 3
4#include <linux/config.h>
5#include <asm/ptrace.h> 4#include <asm/ptrace.h>
6 5
7#ifdef CONFIG_COLDFIRE 6#ifdef CONFIG_COLDFIRE
diff --git a/include/asm-m68knommu/m5206sim.h b/include/asm-m68knommu/m5206sim.h
index d1e7509021c5..7e3594dea88b 100644
--- a/include/asm-m68knommu/m5206sim.h
+++ b/include/asm-m68knommu/m5206sim.h
@@ -12,7 +12,6 @@
12#define m5206sim_h 12#define m5206sim_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Define the 5206 SIM register set addresses. 17 * Define the 5206 SIM register set addresses.
diff --git a/include/asm-m68knommu/m520xsim.h b/include/asm-m68knommu/m520xsim.h
index 6dc62869e62b..1dac22ea95ba 100644
--- a/include/asm-m68knommu/m520xsim.h
+++ b/include/asm-m68knommu/m520xsim.h
@@ -11,7 +11,6 @@
11#define m520xsim_h 11#define m520xsim_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Define the 5282 SIM register set addresses. 16 * Define the 5282 SIM register set addresses.
diff --git a/include/asm-m68knommu/m523xsim.h b/include/asm-m68knommu/m523xsim.h
index 926cfb805df7..bf397313e93f 100644
--- a/include/asm-m68knommu/m523xsim.h
+++ b/include/asm-m68knommu/m523xsim.h
@@ -11,7 +11,6 @@
11#define m523xsim_h 11#define m523xsim_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Define the 523x SIM register set addresses. 16 * Define the 523x SIM register set addresses.
diff --git a/include/asm-m68knommu/m5272sim.h b/include/asm-m68knommu/m5272sim.h
index b40875362f46..6217edc21139 100644
--- a/include/asm-m68knommu/m5272sim.h
+++ b/include/asm-m68knommu/m5272sim.h
@@ -12,7 +12,6 @@
12#define m5272sim_h 12#define m5272sim_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Define the 5272 SIM register set addresses. 17 * Define the 5272 SIM register set addresses.
diff --git a/include/asm-m68knommu/m527xsim.h b/include/asm-m68knommu/m527xsim.h
index e7878d0f7d7a..1f63ab3fb3e6 100644
--- a/include/asm-m68knommu/m527xsim.h
+++ b/include/asm-m68knommu/m527xsim.h
@@ -11,7 +11,6 @@
11#define m527xsim_h 11#define m527xsim_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Define the 5270/5271 SIM register set addresses. 16 * Define the 5270/5271 SIM register set addresses.
diff --git a/include/asm-m68knommu/m528xsim.h b/include/asm-m68knommu/m528xsim.h
index 610774a17f70..1a3b1ae06b1e 100644
--- a/include/asm-m68knommu/m528xsim.h
+++ b/include/asm-m68knommu/m528xsim.h
@@ -11,7 +11,6 @@
11#define m528xsim_h 11#define m528xsim_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Define the 5280/5282 SIM register set addresses. 16 * Define the 5280/5282 SIM register set addresses.
diff --git a/include/asm-m68knommu/mcfcache.h b/include/asm-m68knommu/mcfcache.h
index 9cb401421835..45d1ac57ea82 100644
--- a/include/asm-m68knommu/mcfcache.h
+++ b/include/asm-m68knommu/mcfcache.h
@@ -11,7 +11,6 @@
11#define __M68KNOMMU_MCFCACHE_H 11#define __M68KNOMMU_MCFCACHE_H
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * The different ColdFire families have different cache arrangments. 16 * The different ColdFire families have different cache arrangments.
diff --git a/include/asm-m68knommu/mcfdma.h b/include/asm-m68knommu/mcfdma.h
index b93f8ba8a248..ea729e81a6be 100644
--- a/include/asm-m68knommu/mcfdma.h
+++ b/include/asm-m68knommu/mcfdma.h
@@ -11,7 +11,6 @@
11#define mcfdma_h 11#define mcfdma_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Get address specific defines for this Coldfire member. 16 * Get address specific defines for this Coldfire member.
diff --git a/include/asm-m68knommu/mcfmbus.h b/include/asm-m68knommu/mcfmbus.h
index 4762589e858a..13df9d41bd1a 100644
--- a/include/asm-m68knommu/mcfmbus.h
+++ b/include/asm-m68knommu/mcfmbus.h
@@ -11,7 +11,6 @@
11 11
12#ifndef mcfmbus_h 12#ifndef mcfmbus_h
13#define mcfmbus_h 13#define mcfmbus_h
14#include <linux/config.h>
15 14
16 15
17#define MCFMBUS_BASE 0x280 16#define MCFMBUS_BASE 0x280
diff --git a/include/asm-m68knommu/mcfne.h b/include/asm-m68knommu/mcfne.h
index a71b1c8cb4f8..c920ccdb61fe 100644
--- a/include/asm-m68knommu/mcfne.h
+++ b/include/asm-m68knommu/mcfne.h
@@ -18,7 +18,6 @@
18#define mcfne_h 18#define mcfne_h
19/****************************************************************************/ 19/****************************************************************************/
20 20
21#include <linux/config.h>
22 21
23/* 22/*
24 * Support for NE2000 clones devices in ColdFire based boards. 23 * Support for NE2000 clones devices in ColdFire based boards.
diff --git a/include/asm-m68knommu/mcfpci.h b/include/asm-m68knommu/mcfpci.h
index d6229047d06e..f1507dd06ec6 100644
--- a/include/asm-m68knommu/mcfpci.h
+++ b/include/asm-m68knommu/mcfpci.h
@@ -12,7 +12,6 @@
12#define mcfpci_h 12#define mcfpci_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17#ifdef CONFIG_PCI 16#ifdef CONFIG_PCI
18 17
diff --git a/include/asm-m68knommu/mcfpit.h b/include/asm-m68knommu/mcfpit.h
index a685f1b45401..0d2672dd518a 100644
--- a/include/asm-m68knommu/mcfpit.h
+++ b/include/asm-m68knommu/mcfpit.h
@@ -11,7 +11,6 @@
11#define mcfpit_h 11#define mcfpit_h
12/****************************************************************************/ 12/****************************************************************************/
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Get address specific defines for the 5270/5271, 5280/5282, and 5208. 16 * Get address specific defines for the 5270/5271, 5280/5282, and 5208.
diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
index 81d74a31dc43..97a0c2734a72 100644
--- a/include/asm-m68knommu/mcfsim.h
+++ b/include/asm-m68knommu/mcfsim.h
@@ -12,7 +12,6 @@
12#define mcfsim_h 12#define mcfsim_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282, 17 * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
diff --git a/include/asm-m68knommu/mcfsmc.h b/include/asm-m68knommu/mcfsmc.h
index 2583900b9591..2d7a4dbd9683 100644
--- a/include/asm-m68knommu/mcfsmc.h
+++ b/include/asm-m68knommu/mcfsmc.h
@@ -17,7 +17,6 @@
17 * allow 8 bit accesses. So this code is 16bit access only. 17 * allow 8 bit accesses. So this code is 16bit access only.
18 */ 18 */
19 19
20#include <linux/config.h>
21 20
22#undef outb 21#undef outb
23#undef inb 22#undef inb
diff --git a/include/asm-m68knommu/mcftimer.h b/include/asm-m68knommu/mcftimer.h
index 0f47164c33a9..68bf33ac10d1 100644
--- a/include/asm-m68knommu/mcftimer.h
+++ b/include/asm-m68knommu/mcftimer.h
@@ -12,7 +12,6 @@
12#define mcftimer_h 12#define mcftimer_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Get address specific defines for this ColdFire member. 17 * Get address specific defines for this ColdFire member.
diff --git a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
index b016fad83119..8040e43786be 100644
--- a/include/asm-m68knommu/mcfuart.h
+++ b/include/asm-m68knommu/mcfuart.h
@@ -12,7 +12,6 @@
12#define mcfuart_h 12#define mcfuart_h
13/****************************************************************************/ 13/****************************************************************************/
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Define the base address of the UARTS within the MBAR address 17 * Define the base address of the UARTS within the MBAR address
diff --git a/include/asm-m68knommu/mcfwdebug.h b/include/asm-m68knommu/mcfwdebug.h
index 6ceae103596b..27f70e45d700 100644
--- a/include/asm-m68knommu/mcfwdebug.h
+++ b/include/asm-m68knommu/mcfwdebug.h
@@ -10,7 +10,6 @@
10#ifndef mcfdebug_h 10#ifndef mcfdebug_h
11#define mcfdebug_h 11#define mcfdebug_h
12/****************************************************************************/ 12/****************************************************************************/
13#include <linux/config.h>
14 13
15/* Define the debug module registers */ 14/* Define the debug module registers */
16#define MCFDEBUG_CSR 0x0 /* Configuration status */ 15#define MCFDEBUG_CSR 0x0 /* Configuration status */
diff --git a/include/asm-m68knommu/mmu_context.h b/include/asm-m68knommu/mmu_context.h
index 1e080eca9ca8..6c077d3a2572 100644
--- a/include/asm-m68knommu/mmu_context.h
+++ b/include/asm-m68knommu/mmu_context.h
@@ -1,7 +1,6 @@
1#ifndef __M68KNOMMU_MMU_CONTEXT_H 1#ifndef __M68KNOMMU_MMU_CONTEXT_H
2#define __M68KNOMMU_MMU_CONTEXT_H 2#define __M68KNOMMU_MMU_CONTEXT_H
3 3
4#include <linux/config.h>
5#include <asm/setup.h> 4#include <asm/setup.h>
6#include <asm/page.h> 5#include <asm/page.h>
7#include <asm/pgalloc.h> 6#include <asm/pgalloc.h>
diff --git a/include/asm-m68knommu/nettel.h b/include/asm-m68knommu/nettel.h
index 9bda307e6544..0299f6a2deeb 100644
--- a/include/asm-m68knommu/nettel.h
+++ b/include/asm-m68knommu/nettel.h
@@ -13,7 +13,6 @@
13#define nettel_h 13#define nettel_h
14/****************************************************************************/ 14/****************************************************************************/
15 15
16#include <linux/config.h>
17 16
18/****************************************************************************/ 17/****************************************************************************/
19#ifdef CONFIG_NETtel 18#ifdef CONFIG_NETtel
diff --git a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h
index 942dfbead27f..a22bf5a88160 100644
--- a/include/asm-m68knommu/page.h
+++ b/include/asm-m68knommu/page.h
@@ -1,7 +1,6 @@
1#ifndef _M68KNOMMU_PAGE_H 1#ifndef _M68KNOMMU_PAGE_H
2#define _M68KNOMMU_PAGE_H 2#define _M68KNOMMU_PAGE_H
3 3
4#include <linux/config.h>
5 4
6/* PAGE_SHIFT determines the page size */ 5/* PAGE_SHIFT determines the page size */
7 6
diff --git a/include/asm-m68knommu/page_offset.h b/include/asm-m68knommu/page_offset.h
index 2b45645e9b29..8ed6d7b7d9d1 100644
--- a/include/asm-m68knommu/page_offset.h
+++ b/include/asm-m68knommu/page_offset.h
@@ -1,5 +1,4 @@
1 1
2#include <linux/config.h>
3 2
4/* This handles the memory map.. */ 3/* This handles the memory map.. */
5 4
diff --git a/include/asm-m68knommu/param.h b/include/asm-m68knommu/param.h
index 3f57d5db81f5..4c9904d6512e 100644
--- a/include/asm-m68knommu/param.h
+++ b/include/asm-m68knommu/param.h
@@ -1,7 +1,6 @@
1#ifndef _M68KNOMMU_PARAM_H 1#ifndef _M68KNOMMU_PARAM_H
2#define _M68KNOMMU_PARAM_H 2#define _M68KNOMMU_PARAM_H
3 3
4#include <linux/config.h>
5 4
6#if defined(CONFIG_CLEOPATRA) 5#if defined(CONFIG_CLEOPATRA)
7#define HZ 1000 6#define HZ 1000
diff --git a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index 00893055e6c2..549ad231efad 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -7,7 +7,6 @@
7 * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com> 7 * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <linux/slab.h> 10#include <linux/slab.h>
12#include <asm/processor.h> 11#include <asm/processor.h>
13#include <asm/page.h> 12#include <asm/page.h>
diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
index ba393b1a023b..278b00bc60c5 100644
--- a/include/asm-m68knommu/processor.h
+++ b/include/asm-m68knommu/processor.h
@@ -13,7 +13,6 @@
13 */ 13 */
14#define current_text_addr() ({ __label__ _l; _l: &&_l;}) 14#define current_text_addr() ({ __label__ _l; _l: &&_l;})
15 15
16#include <linux/config.h>
17#include <linux/threads.h> 16#include <linux/threads.h>
18#include <asm/types.h> 17#include <asm/types.h>
19#include <asm/segment.h> 18#include <asm/segment.h>
diff --git a/include/asm-m68knommu/semaphore-helper.h b/include/asm-m68knommu/semaphore-helper.h
index a6586417c1c2..43da7bc483c7 100644
--- a/include/asm-m68knommu/semaphore-helper.h
+++ b/include/asm-m68knommu/semaphore-helper.h
@@ -9,7 +9,6 @@
9 * m68k version by Andreas Schwab 9 * m68k version by Andreas Schwab
10 */ 10 */
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * These two _must_ execute atomically wrt each other. 14 * These two _must_ execute atomically wrt each other.
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 6338afc850ba..2bbe2db00a22 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -1,7 +1,6 @@
1#ifndef _M68KNOMMU_SYSTEM_H 1#ifndef _M68KNOMMU_SYSTEM_H
2#define _M68KNOMMU_SYSTEM_H 2#define _M68KNOMMU_SYSTEM_H
3 3
4#include <linux/config.h> /* get configuration macros */
5#include <linux/linkage.h> 4#include <linux/linkage.h>
6#include <asm/segment.h> 5#include <asm/segment.h>
7#include <asm/entry.h> 6#include <asm/entry.h>
diff --git a/include/asm-m68knommu/unaligned.h b/include/asm-m68knommu/unaligned.h
index 8876f034ea64..869e9dd24f54 100644
--- a/include/asm-m68knommu/unaligned.h
+++ b/include/asm-m68knommu/unaligned.h
@@ -1,7 +1,6 @@
1#ifndef __M68K_UNALIGNED_H 1#ifndef __M68K_UNALIGNED_H
2#define __M68K_UNALIGNED_H 2#define __M68K_UNALIGNED_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_COLDFIRE 5#ifdef CONFIG_COLDFIRE
7 6
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 5373988a7e51..1b2abdf281e1 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -286,6 +286,8 @@
286#define __NR_request_key 280 286#define __NR_request_key 280
287#define __NR_keyctl 281 287#define __NR_keyctl 281
288 288
289#ifdef __KERNEL__
290
289#define NR_syscalls 282 291#define NR_syscalls 282
290 292
291/* user-visible error numbers are in the range -1 - -122: see 293/* user-visible error numbers are in the range -1 - -122: see
@@ -437,7 +439,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e) \
437 return (type)__res; \ 439 return (type)__res; \
438} 440}
439 441
440#ifdef __KERNEL__
441#define __ARCH_WANT_IPC_PARSE_VERSION 442#define __ARCH_WANT_IPC_PARSE_VERSION
442#define __ARCH_WANT_OLD_READDIR 443#define __ARCH_WANT_OLD_READDIR
443#define __ARCH_WANT_OLD_STAT 444#define __ARCH_WANT_OLD_STAT
@@ -460,7 +461,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e) \
460#define __ARCH_WANT_SYS_SIGPENDING 461#define __ARCH_WANT_SYS_SIGPENDING
461#define __ARCH_WANT_SYS_SIGPROCMASK 462#define __ARCH_WANT_SYS_SIGPROCMASK
462#define __ARCH_WANT_SYS_RT_SIGACTION 463#define __ARCH_WANT_SYS_RT_SIGACTION
463#endif
464 464
465#ifdef __KERNEL_SYSCALLS__ 465#ifdef __KERNEL_SYSCALLS__
466 466
@@ -515,7 +515,7 @@ asmlinkage long sys_rt_sigaction(int sig,
515 struct sigaction __user *oact, 515 struct sigaction __user *oact,
516 size_t sigsetsize); 516 size_t sigsetsize);
517 517
518#endif 518#endif /* __KERNEL_SYSCALLS__ */
519 519
520/* 520/*
521 * "Conditional" syscalls 521 * "Conditional" syscalls
@@ -525,4 +525,5 @@ asmlinkage long sys_rt_sigaction(int sig,
525 */ 525 */
526#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 526#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
527 527
528#endif /* __KERNEL__ */
528#endif /* _ASM_M68K_UNISTD_H_ */ 529#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/include/asm-mips/a.out.h b/include/asm-mips/a.out.h
index 2b3dc3bed4da..ef33c3f13484 100644
--- a/include/asm-mips/a.out.h
+++ b/include/asm-mips/a.out.h
@@ -10,7 +10,6 @@
10 10
11#ifdef __KERNEL__ 11#ifdef __KERNEL__
12 12
13#include <linux/config.h>
14 13
15#endif 14#endif
16 15
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 0cc6c7060f3c..45c706e34df1 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_ADDRSPACE_H 10#ifndef _ASM_ADDRSPACE_H
11#define _ASM_ADDRSPACE_H 11#define _ASM_ADDRSPACE_H
12 12
13#include <linux/config.h>
14#include <spaces.h> 13#include <spaces.h>
15 14
16/* 15/*
diff --git a/include/asm-mips/arc/types.h b/include/asm-mips/arc/types.h
index bbb725c366fb..b9adcd6f0860 100644
--- a/include/asm-mips/arc/types.h
+++ b/include/asm-mips/arc/types.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_ARC_TYPES_H 9#ifndef _ASM_ARC_TYPES_H
10#define _ASM_ARC_TYPES_H 10#define _ASM_ARC_TYPES_H
11 11
12#include <linux/config.h>
13 12
14#ifdef CONFIG_ARC32 13#ifdef CONFIG_ARC32
15 14
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
index 4b090f3142e0..e3038a4599ee 100644
--- a/include/asm-mips/asm.h
+++ b/include/asm-mips/asm.h
@@ -17,7 +17,6 @@
17#ifndef __ASM_ASM_H 17#ifndef __ASM_ASM_H
18#define __ASM_ASM_H 18#define __ASM_ASM_H
19 19
20#include <linux/config.h>
21#include <asm/sgidefs.h> 20#include <asm/sgidefs.h>
22 21
23#ifndef CAT 22#ifndef CAT
diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h
index f54aa147ec19..2c42f6b00a49 100644
--- a/include/asm-mips/asmmacro.h
+++ b/include/asm-mips/asmmacro.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_ASMMACRO_H 8#ifndef _ASM_ASMMACRO_H
9#define _ASM_ASMMACRO_H 9#define _ASM_ASMMACRO_H
10 10
11#include <linux/config.h>
12#include <asm/hazards.h> 11#include <asm/hazards.h>
13 12
14#ifdef CONFIG_32BIT 13#ifdef CONFIG_32BIT
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 2c8b853376c9..13d44e14025a 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -17,7 +17,6 @@
17 * <linux/spinlock.h> we have to include <linux/spinlock.h> outside the 17 * <linux/spinlock.h> we have to include <linux/spinlock.h> outside the
18 * main big wrapper ... 18 * main big wrapper ...
19 */ 19 */
20#include <linux/config.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
22 21
23#ifndef _ASM_ATOMIC_H 22#ifndef _ASM_ATOMIC_H
diff --git a/include/asm-mips/bcache.h b/include/asm-mips/bcache.h
index 446102b34f4e..3646a3f2ed38 100644
--- a/include/asm-mips/bcache.h
+++ b/include/asm-mips/bcache.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_BCACHE_H 9#ifndef _ASM_BCACHE_H
10#define _ASM_BCACHE_H 10#define _ASM_BCACHE_H
11 11
12#include <linux/config.h>
13 12
14/* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent, 13/* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
15 chipset implemented caches. On machines with other CPUs the CPU does the 14 chipset implemented caches. On machines with other CPUs the CPU does the
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index d2f444537e4b..098cec263681 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_BITOPS_H 9#ifndef _ASM_BITOPS_H
10#define _ASM_BITOPS_H 10#define _ASM_BITOPS_H
11 11
12#include <linux/config.h>
13#include <linux/compiler.h> 12#include <linux/compiler.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <asm/bug.h> 14#include <asm/bug.h>
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
index 87d49a5bdc63..7b4739dc8f3f 100644
--- a/include/asm-mips/bug.h
+++ b/include/asm-mips/bug.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_BUG_H 1#ifndef __ASM_BUG_H
2#define __ASM_BUG_H 2#define __ASM_BUG_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_BUG 5#ifdef CONFIG_BUG
7 6
diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h
index cb2ea7c15c7a..0d7f9c1f5546 100644
--- a/include/asm-mips/bugs.h
+++ b/include/asm-mips/bugs.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_BUGS_H 7#ifndef _ASM_BUGS_H
8#define _ASM_BUGS_H 8#define _ASM_BUGS_H
9 9
10#include <linux/config.h>
11#include <linux/delay.h> 10#include <linux/delay.h>
12#include <asm/cpu.h> 11#include <asm/cpu.h>
13#include <asm/cpu-info.h> 12#include <asm/cpu-info.h>
diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h
index aefc02f16fd8..eee83cbdf2b0 100644
--- a/include/asm-mips/byteorder.h
+++ b/include/asm-mips/byteorder.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_BYTEORDER_H 8#ifndef _ASM_BYTEORDER_H
9#define _ASM_BYTEORDER_H 9#define _ASM_BYTEORDER_H
10 10
11#include <linux/config.h>
12#include <linux/compiler.h> 11#include <linux/compiler.h>
13#include <asm/types.h> 12#include <asm/types.h>
14 13
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 55e19f2ff0e0..37f175c42bb5 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_CACHE_H 9#ifndef _ASM_CACHE_H
10#define _ASM_CACHE_H 10#define _ASM_CACHE_H
11 11
12#include <linux/config.h>
13#include <kmalloc.h> 12#include <kmalloc.h>
14 13
15#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT 14#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index b09f8971e95d..a5e6050ec0f3 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_CHECKSUM_H 11#ifndef _ASM_CHECKSUM_H
12#define _ASM_CHECKSUM_H 12#define _ASM_CHECKSUM_H
13 13
14#include <linux/config.h>
15#include <linux/in6.h> 14#include <linux/in6.h>
16 15
17#include <asm/uaccess.h> 16#include <asm/uaccess.h>
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 254e11ed247b..881ce1f9803d 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -9,7 +9,6 @@
9#ifndef __ASM_CPU_FEATURES_H 9#ifndef __ASM_CPU_FEATURES_H
10#define __ASM_CPU_FEATURES_H 10#define __ASM_CPU_FEATURES_H
11 11
12#include <linux/config.h>
13 12
14#include <asm/cpu.h> 13#include <asm/cpu.h>
15#include <asm/cpu-info.h> 14#include <asm/cpu-info.h>
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index 6572ac703662..a2f0c8ea9160 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_CPU_INFO_H 12#ifndef __ASM_CPU_INFO_H
13#define __ASM_CPU_INFO_H 13#define __ASM_CPU_INFO_H
14 14
15#include <linux/config.h>
16#include <asm/cache.h> 15#include <asm/cache.h>
17 16
18#ifdef CONFIG_SGI_IP27 17#ifdef CONFIG_SGI_IP27
diff --git a/include/asm-mips/ddb5xxx/ddb5477.h b/include/asm-mips/ddb5xxx/ddb5477.h
index a438548e6ef3..c5af4b73fdd7 100644
--- a/include/asm-mips/ddb5xxx/ddb5477.h
+++ b/include/asm-mips/ddb5xxx/ddb5477.h
@@ -17,7 +17,6 @@
17#ifndef __ASM_DDB5XXX_DDB5477_H 17#ifndef __ASM_DDB5XXX_DDB5477_H
18#define __ASM_DDB5XXX_DDB5477_H 18#define __ASM_DDB5XXX_DDB5477_H
19 19
20#include <linux/config.h>
21 20
22/* 21/*
23 * This contains macros that are specific to DDB5477 or renamed from 22 * This contains macros that are specific to DDB5477 or renamed from
diff --git a/include/asm-mips/ddb5xxx/ddb5xxx.h b/include/asm-mips/ddb5xxx/ddb5xxx.h
index 2f1b191c6fff..e97fcc8d548b 100644
--- a/include/asm-mips/ddb5xxx/ddb5xxx.h
+++ b/include/asm-mips/ddb5xxx/ddb5xxx.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_DDB5XXX_DDB5XXX_H 18#ifndef __ASM_DDB5XXX_DDB5XXX_H
19#define __ASM_DDB5XXX_DDB5XXX_H 19#define __ASM_DDB5XXX_DDB5XXX_H
20 20
21#include <linux/config.h>
22#include <linux/types.h> 21#include <linux/types.h>
23 22
24/* 23/*
diff --git a/include/asm-mips/debug.h b/include/asm-mips/debug.h
index 930f2b75e766..1fd5a2b39445 100644
--- a/include/asm-mips/debug.h
+++ b/include/asm-mips/debug.h
@@ -15,7 +15,6 @@
15#ifndef _ASM_DEBUG_H 15#ifndef _ASM_DEBUG_H
16#define _ASM_DEBUG_H 16#define _ASM_DEBUG_H
17 17
18#include <linux/config.h>
19 18
20/* 19/*
21 * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in 20 * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in
diff --git a/include/asm-mips/dec/prom.h b/include/asm-mips/dec/prom.h
index 1384dd0964b9..b9c8203688d5 100644
--- a/include/asm-mips/dec/prom.h
+++ b/include/asm-mips/dec/prom.h
@@ -15,7 +15,6 @@
15#ifndef _ASM_DEC_PROM_H 15#ifndef _ASM_DEC_PROM_H
16#define _ASM_DEC_PROM_H 16#define _ASM_DEC_PROM_H
17 17
18#include <linux/config.h>
19#include <linux/types.h> 18#include <linux/types.h>
20 19
21#include <asm/addrspace.h> 20#include <asm/addrspace.h>
diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
index 928f30f8c45c..ea77050f8e3a 100644
--- a/include/asm-mips/delay.h
+++ b/include/asm-mips/delay.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_DELAY_H 10#ifndef _ASM_DELAY_H
11#define _ASM_DELAY_H 11#define _ASM_DELAY_H
12 12
13#include <linux/config.h>
14#include <linux/param.h> 13#include <linux/param.h>
15#include <linux/smp.h> 14#include <linux/smp.h>
16#include <asm/compiler.h> 15#include <asm/compiler.h>
diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h
index 6aaf9939a716..e85849ac165f 100644
--- a/include/asm-mips/dma.h
+++ b/include/asm-mips/dma.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_DMA_H 12#ifndef _ASM_DMA_H
13#define _ASM_DMA_H 13#define _ASM_DMA_H
14 14
15#include <linux/config.h>
16#include <asm/io.h> /* need byte IO */ 15#include <asm/io.h> /* need byte IO */
17#include <linux/spinlock.h> /* And spinlocks */ 16#include <linux/spinlock.h> /* And spinlocks */
18#include <linux/delay.h> 17#include <linux/delay.h>
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index bdc9de2df1ef..ebd6bfb19d66 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_ELF_H 8#ifndef _ASM_ELF_H
9#define _ASM_ELF_H 9#define _ASM_ELF_H
10 10
11#include <linux/config.h>
12 11
13/* ELF header e_flags defines. */ 12/* ELF header e_flags defines. */
14/* MIPS architecture level. */ 13/* MIPS architecture level. */
diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h
index 43d047a9a6af..787220e6c1fc 100644
--- a/include/asm-mips/fcntl.h
+++ b/include/asm-mips/fcntl.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_FCNTL_H 8#ifndef _ASM_FCNTL_H
9#define _ASM_FCNTL_H 9#define _ASM_FCNTL_H
10 10
11#include <linux/config.h>
12 11
13#define O_APPEND 0x0008 12#define O_APPEND 0x0008
14#define O_SYNC 0x0010 13#define O_SYNC 0x0010
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
index 73a3028dd9f9..1cadefbbc037 100644
--- a/include/asm-mips/fixmap.h
+++ b/include/asm-mips/fixmap.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_FIXMAP_H 13#ifndef _ASM_FIXMAP_H
14#define _ASM_FIXMAP_H 14#define _ASM_FIXMAP_H
15 15
16#include <linux/config.h>
17#include <asm/page.h> 16#include <asm/page.h>
18#ifdef CONFIG_HIGHMEM 17#ifdef CONFIG_HIGHMEM
19#include <linux/threads.h> 18#include <linux/threads.h>
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index 8bf510a27c64..58c561a9ec6b 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_FPU_H 10#ifndef _ASM_FPU_H
11#define _ASM_FPU_H 11#define _ASM_FPU_H
12 12
13#include <linux/config.h>
14#include <linux/sched.h> 13#include <linux/sched.h>
15#include <linux/thread_info.h> 14#include <linux/thread_info.h>
16 15
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 1f94640becc4..ed023eae0674 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7#include <linux/futex.h> 6#include <linux/futex.h>
8#include <asm/errno.h> 7#include <asm/errno.h>
9#include <asm/uaccess.h> 8#include <asm/uaccess.h>
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index dadc05188db7..66943c451c1d 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_HAZARDS_H 10#ifndef _ASM_HAZARDS_H
11#define _ASM_HAZARDS_H 11#define _ASM_HAZARDS_H
12 12
13#include <linux/config.h>
14 13
15#ifdef __ASSEMBLY__ 14#ifdef __ASSEMBLY__
16 15
diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h
index 8cf598402492..c976bfaaba83 100644
--- a/include/asm-mips/highmem.h
+++ b/include/asm-mips/highmem.h
@@ -19,7 +19,6 @@
19 19
20#ifdef __KERNEL__ 20#ifdef __KERNEL__
21 21
22#include <linux/config.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/interrupt.h> 23#include <linux/interrupt.h>
25#include <asm/kmap_types.h> 24#include <asm/kmap_types.h>
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
index 4bb9c06f4410..a99d6867510f 100644
--- a/include/asm-mips/interrupt.h
+++ b/include/asm-mips/interrupt.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_INTERRUPT_H 11#ifndef _ASM_INTERRUPT_H
12#define _ASM_INTERRUPT_H 12#define _ASM_INTERRUPT_H
13 13
14#include <linux/config.h>
15#include <asm/hazards.h> 14#include <asm/hazards.h>
16 15
17__asm__ ( 16__asm__ (
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 6b17eb9d79a5..df624e1ee6e2 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_IO_H 12#ifndef _ASM_IO_H
13#define _ASM_IO_H 13#define _ASM_IO_H
14 14
15#include <linux/config.h>
16#include <linux/compiler.h> 15#include <linux/compiler.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/types.h> 17#include <linux/types.h>
diff --git a/include/asm-mips/ip32/machine.h b/include/asm-mips/ip32/machine.h
index e440fdf4b232..1b631b8da6f8 100644
--- a/include/asm-mips/ip32/machine.h
+++ b/include/asm-mips/ip32/machine.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_IP32_MACHINE_H 10#ifndef _ASM_IP32_MACHINE_H
11#define _ASM_IP32_MACHINE_H 11#define _ASM_IP32_MACHINE_H
12 12
13#include <linux/config.h>
14 13
15#ifdef CONFIG_SGI_IP32 14#ifdef CONFIG_SGI_IP32
16 15
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index dde677f02bc0..d35c61776a02 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_IRQ_H 9#ifndef _ASM_IRQ_H
10#define _ASM_IRQ_H 10#define _ASM_IRQ_H
11 11
12#include <linux/config.h>
13#include <linux/linkage.h> 12#include <linux/linkage.h>
14 13
15#include <asm/mipsmtregs.h> 14#include <asm/mipsmtregs.h>
diff --git a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h
index 7bb003511d9e..24c6cda79377 100644
--- a/include/asm-mips/isadep.h
+++ b/include/asm-mips/isadep.h
@@ -5,7 +5,6 @@
5 * 5 *
6 * Copyright (c) 1998 Harald Koerfgen 6 * Copyright (c) 1998 Harald Koerfgen
7 */ 7 */
8#include <linux/config.h>
9 8
10#ifndef __ASM_ISADEP_H 9#ifndef __ASM_ISADEP_H
11#define __ASM_ISADEP_H 10#define __ASM_ISADEP_H
diff --git a/include/asm-mips/jmr3927/irq.h b/include/asm-mips/jmr3927/irq.h
index b0c325a22343..fe551f33a74f 100644
--- a/include/asm-mips/jmr3927/irq.h
+++ b/include/asm-mips/jmr3927/irq.h
@@ -12,7 +12,6 @@
12 12
13#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
14 14
15#include <linux/config.h>
16#include <asm/irq.h> 15#include <asm/irq.h>
17 16
18struct tb_irq_space { 17struct tb_irq_space {
diff --git a/include/asm-mips/kmap_types.h b/include/asm-mips/kmap_types.h
index 6886a0c3fedf..806aae3c5338 100644
--- a/include/asm-mips/kmap_types.h
+++ b/include/asm-mips/kmap_types.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_KMAP_TYPES_H 1#ifndef _ASM_KMAP_TYPES_H
2#define _ASM_KMAP_TYPES_H 2#define _ASM_KMAP_TYPES_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_DEBUG_HIGHMEM 5#ifdef CONFIG_DEBUG_HIGHMEM
7# define D(n) __KM_FENCE_##n , 6# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-mips/local.h b/include/asm-mips/local.h
index c38844f615fc..9e2d43bae388 100644
--- a/include/asm-mips/local.h
+++ b/include/asm-mips/local.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_LOCAL_H 1#ifndef _ASM_LOCAL_H
2#define _ASM_LOCAL_H 2#define _ASM_LOCAL_H
3 3
4#include <linux/config.h>
5#include <linux/percpu.h> 4#include <linux/percpu.h>
6#include <asm/atomic.h> 5#include <asm/atomic.h>
7 6
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 4686e17c206c..582acd8adb81 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -35,7 +35,6 @@
35#ifndef _AU1000_H_ 35#ifndef _AU1000_H_
36#define _AU1000_H_ 36#define _AU1000_H_
37 37
38#include <linux/config.h>
39 38
40#ifndef _LANGUAGE_ASSEMBLY 39#ifndef _LANGUAGE_ASSEMBLY
41 40
diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
index b7b46dd9b929..947135941033 100644
--- a/include/asm-mips/mach-au1x00/au1xxx.h
+++ b/include/asm-mips/mach-au1x00/au1xxx.h
@@ -23,7 +23,6 @@
23#ifndef _AU1XXX_H_ 23#ifndef _AU1XXX_H_
24#define _AU1XXX_H_ 24#define _AU1XXX_H_
25 25
26#include <linux/config.h>
27 26
28#include <asm/mach-au1x00/au1000.h> 27#include <asm/mach-au1x00/au1000.h>
29 28
diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
index b327bcd3fee1..d5b38a247e5a 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
@@ -34,7 +34,6 @@
34#ifndef _AU1000_DBDMA_H_ 34#ifndef _AU1000_DBDMA_H_
35#define _AU1000_DBDMA_H_ 35#define _AU1000_DBDMA_H_
36 36
37#include <linux/config.h>
38 37
39#ifndef _LANGUAGE_ASSEMBLY 38#ifndef _LANGUAGE_ASSEMBLY
40 39
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index e867b4ef96d1..301e71300779 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -29,7 +29,6 @@
29 * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE 29 * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
30 * Interface and Linux Device Driver" Application Note. 30 * Interface and Linux Device Driver" Application Note.
31 */ 31 */
32#include <linux/config.h>
33 32
34#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 33#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
35 #define DMA_WAIT_TIMEOUT 100 34 #define DMA_WAIT_TIMEOUT 100
diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
index 8e5fb3c7da4d..5c3e2a38ce12 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
@@ -33,7 +33,6 @@
33#ifndef _AU1000_PSC_H_ 33#ifndef _AU1000_PSC_H_
34#define _AU1000_PSC_H_ 34#define _AU1000_PSC_H_
35 35
36#include <linux/config.h>
37 36
38/* The PSC base addresses. */ 37/* The PSC base addresses. */
39#ifdef CONFIG_SOC_AU1550 38#ifdef CONFIG_SOC_AU1550
diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h
index d3ec6274575a..098fca4289bb 100644
--- a/include/asm-mips/mach-au1x00/ioremap.h
+++ b/include/asm-mips/mach-au1x00/ioremap.h
@@ -9,7 +9,6 @@
9#ifndef __ASM_MACH_AU1X00_IOREMAP_H 9#ifndef __ASM_MACH_AU1X00_IOREMAP_H
10#define __ASM_MACH_AU1X00_IOREMAP_H 10#define __ASM_MACH_AU1X00_IOREMAP_H
11 11
12#include <linux/config.h>
13#include <linux/types.h> 12#include <linux/types.h>
14 13
15#ifdef CONFIG_64BIT_PHYS_ADDR 14#ifdef CONFIG_64BIT_PHYS_ADDR
diff --git a/include/asm-mips/mach-cobalt/cpu-feature-overrides.h b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
index ace8c5ef9701..e0e08fc5d7f7 100644
--- a/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
@@ -8,7 +8,6 @@
8#ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H 8#ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
9#define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H 9#define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
10 10
11#include <linux/config.h>
12 11
13#define cpu_has_tlb 1 12#define cpu_has_tlb 1
14#define cpu_has_4kex 1 13#define cpu_has_4kex 1
diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h
index 7b28b23f91ce..8fbb4b42a8b5 100644
--- a/include/asm-mips/mach-db1x00/db1x00.h
+++ b/include/asm-mips/mach-db1x00/db1x00.h
@@ -28,7 +28,6 @@
28#ifndef __ASM_DB1X00_H 28#ifndef __ASM_DB1X00_H
29#define __ASM_DB1X00_H 29#define __ASM_DB1X00_H
30 30
31#include <linux/config.h>
32 31
33#ifdef CONFIG_MIPS_DB1550 32#ifdef CONFIG_MIPS_DB1550
34#define BCSR_KSEG1_ADDR 0xAF000000 33#define BCSR_KSEG1_ADDR 0xAF000000
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
index e3315359500a..6eba2e576aaa 100644
--- a/include/asm-mips/mach-generic/ide.h
+++ b/include/asm-mips/mach-generic/ide.h
@@ -15,7 +15,6 @@
15 15
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/config.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
20#include <linux/stddef.h> 19#include <linux/stddef.h>
21#include <asm/processor.h> 20#include <asm/processor.h>
diff --git a/include/asm-mips/mach-generic/kmalloc.h b/include/asm-mips/mach-generic/kmalloc.h
index 373d66dee9d7..410ab5f6c563 100644
--- a/include/asm-mips/mach-generic/kmalloc.h
+++ b/include/asm-mips/mach-generic/kmalloc.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_GENERIC_KMALLOC_H 1#ifndef __ASM_MACH_GENERIC_KMALLOC_H
2#define __ASM_MACH_GENERIC_KMALLOC_H 2#define __ASM_MACH_GENERIC_KMALLOC_H
3 3
4#include <linux/config.h>
5 4
6#ifndef CONFIG_DMA_COHERENT 5#ifndef CONFIG_DMA_COHERENT
7/* 6/*
diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h
index b849d8dd7e78..0ae9997bc9a8 100644
--- a/include/asm-mips/mach-generic/spaces.h
+++ b/include/asm-mips/mach-generic/spaces.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_MACH_GENERIC_SPACES_H 10#ifndef _ASM_MACH_GENERIC_SPACES_H
11#define _ASM_MACH_GENERIC_SPACES_H 11#define _ASM_MACH_GENERIC_SPACES_H
12 12
13#include <linux/config.h>
14 13
15#ifdef CONFIG_32BIT 14#ifdef CONFIG_32BIT
16 15
diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h
index 8385f716798d..ab20c026fd19 100644
--- a/include/asm-mips/mach-ip22/spaces.h
+++ b/include/asm-mips/mach-ip22/spaces.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_MACH_IP22_SPACES_H 10#ifndef _ASM_MACH_IP22_SPACES_H
11#define _ASM_MACH_IP22_SPACES_H 11#define _ASM_MACH_IP22_SPACES_H
12 12
13#include <linux/config.h>
14 13
15#ifdef CONFIG_32BIT 14#ifdef CONFIG_32BIT
16 15
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
index f0ef1ac9ecd7..2a3de092bf13 100644
--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
@@ -9,7 +9,6 @@
9#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H 9#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
10#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H 10#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * R5000 has an interesting "restriction": ll(d)/sc(d) 14 * R5000 has an interesting "restriction": ll(d)/sc(d)
diff --git a/include/asm-mips/mach-ip32/kmalloc.h b/include/asm-mips/mach-ip32/kmalloc.h
index 9d2d4d9ac036..f6198a21fba1 100644
--- a/include/asm-mips/mach-ip32/kmalloc.h
+++ b/include/asm-mips/mach-ip32/kmalloc.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_IP32_KMALLOC_H 1#ifndef __ASM_MACH_IP32_KMALLOC_H
2#define __ASM_MACH_IP32_KMALLOC_H 2#define __ASM_MACH_IP32_KMALLOC_H
3 3
4#include <linux/config.h>
5 4
6#if defined(CONFIG_CPU_R5000) || defined (CONFIG_CPU_RM7000) 5#if defined(CONFIG_CPU_R5000) || defined (CONFIG_CPU_RM7000)
7#define ARCH_KMALLOC_MINALIGN 32 6#define ARCH_KMALLOC_MINALIGN 32
diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h
index 12c937283bb4..e960679f54ba 100644
--- a/include/asm-mips/mach-mips/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h
@@ -9,7 +9,6 @@
9#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H 9#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
10#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H 10#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * CPU feature overrides for MIPS boards 14 * CPU feature overrides for MIPS boards
diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-mips/irq.h
index f8579696ca54..083d9c512a04 100644
--- a/include/asm-mips/mach-mips/irq.h
+++ b/include/asm-mips/mach-mips/irq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_MIPS_IRQ_H 1#ifndef __ASM_MACH_MIPS_IRQ_H
2#define __ASM_MACH_MIPS_IRQ_H 2#define __ASM_MACH_MIPS_IRQ_H
3 3
4#include <linux/config.h>
5 4
6#define NR_IRQS 256 5#define NR_IRQS 256
7 6
diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h
index 9578ead11e8a..9a4955ce3b4a 100644
--- a/include/asm-mips/mach-pb1x00/pb1550.h
+++ b/include/asm-mips/mach-pb1x00/pb1550.h
@@ -27,7 +27,6 @@
27#ifndef __ASM_PB1550_H 27#ifndef __ASM_PB1550_H
28#define __ASM_PB1550_H 28#define __ASM_PB1550_H
29 29
30#include <linux/config.h>
31#include <linux/types.h> 30#include <linux/types.h>
32 31
33#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX 32#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-sim/cpu-feature-overrides.h
index d9653e47d5fc..d736bdadb6df 100644
--- a/include/asm-mips/mach-sim/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-sim/cpu-feature-overrides.h
@@ -8,7 +8,6 @@
8#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H 8#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
9#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H 9#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
10 10
11#include <linux/config.h>
12 11
13/* 12/*
14 * CPU feature overrides for MIPS boards 13 * CPU feature overrides for MIPS boards
diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h
index fa8b913cc3e0..b98f1658cfd0 100644
--- a/include/asm-mips/mips-boards/generic.h
+++ b/include/asm-mips/mips-boards/generic.h
@@ -20,7 +20,6 @@
20#ifndef __ASM_MIPS_BOARDS_GENERIC_H 20#ifndef __ASM_MIPS_BOARDS_GENERIC_H
21#define __ASM_MIPS_BOARDS_GENERIC_H 21#define __ASM_MIPS_BOARDS_GENERIC_H
22 22
23#include <linux/config.h>
24#include <asm/addrspace.h> 23#include <asm/addrspace.h>
25#include <asm/byteorder.h> 24#include <asm/byteorder.h>
26#include <asm/mips-boards/bonito64.h> 25#include <asm/mips-boards/bonito64.h>
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 98b68089aa53..673977901ed3 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_MIPSREGS_H 13#ifndef _ASM_MIPSREGS_H
14#define _ASM_MIPSREGS_H 14#define _ASM_MIPSREGS_H
15 15
16#include <linux/config.h>
17#include <linux/linkage.h> 16#include <linux/linkage.h>
18#include <asm/hazards.h> 17#include <asm/hazards.h>
19 18
diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h
index 6e09f4c87211..18b69de87daa 100644
--- a/include/asm-mips/mmu_context.h
+++ b/include/asm-mips/mmu_context.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_MMU_CONTEXT_H 11#ifndef _ASM_MMU_CONTEXT_H
12#define _ASM_MMU_CONTEXT_H 12#define _ASM_MMU_CONTEXT_H
13 13
14#include <linux/config.h>
15#include <linux/errno.h> 14#include <linux/errno.h>
16#include <linux/sched.h> 15#include <linux/sched.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
index f6bd2e0c45a1..dc231c89bef9 100644
--- a/include/asm-mips/mmzone.h
+++ b/include/asm-mips/mmzone.h
@@ -5,7 +5,6 @@
5#ifndef _ASM_MMZONE_H_ 5#ifndef _ASM_MMZONE_H_
6#define _ASM_MMZONE_H_ 6#define _ASM_MMZONE_H_
7 7
8#include <linux/config.h>
9#include <asm/page.h> 8#include <asm/page.h>
10#include <mmzone.h> 9#include <mmzone.h>
11 10
diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
index 2af496c78c12..399d03f1c4fc 100644
--- a/include/asm-mips/module.h
+++ b/include/asm-mips/module.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_MODULE_H 1#ifndef _ASM_MODULE_H
2#define _ASM_MODULE_H 2#define _ASM_MODULE_H
3 3
4#include <linux/config.h>
5#include <linux/list.h> 4#include <linux/list.h>
6#include <asm/uaccess.h> 5#include <asm/uaccess.h>
7 6
diff --git a/include/asm-mips/msgbuf.h b/include/asm-mips/msgbuf.h
index a1533959742e..0d6c7f14de31 100644
--- a/include/asm-mips/msgbuf.h
+++ b/include/asm-mips/msgbuf.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_MSGBUF_H 1#ifndef _ASM_MSGBUF_H
2#define _ASM_MSGBUF_H 2#define _ASM_MSGBUF_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * The msqid64_ds structure for the MIPS architecture. 6 * The msqid64_ds structure for the MIPS architecture.
diff --git a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h
index 46f2d23d2697..147844ef103b 100644
--- a/include/asm-mips/paccess.h
+++ b/include/asm-mips/paccess.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_PACCESS_H 13#ifndef _ASM_PACCESS_H
14#define _ASM_PACCESS_H 14#define _ASM_PACCESS_H
15 15
16#include <linux/config.h>
17#include <linux/errno.h> 16#include <linux/errno.h>
18 17
19#ifdef CONFIG_32BIT 18#ifdef CONFIG_32BIT
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 3d262c01521c..6b97744f00cd 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_PAGE_H 9#ifndef _ASM_PAGE_H
10#define _ASM_PAGE_H 10#define _ASM_PAGE_H
11 11
12#include <linux/config.h>
13 12
14#ifdef __KERNEL__ 13#ifdef __KERNEL__
15 14
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index 6c9ad8171a77..c4d68bebdca6 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -6,7 +6,6 @@
6#ifndef _ASM_PCI_H 6#ifndef _ASM_PCI_H
7#define _ASM_PCI_H 7#define _ASM_PCI_H
8 8
9#include <linux/config.h>
10#include <linux/mm.h> 9#include <linux/mm.h>
11 10
12#ifdef __KERNEL__ 11#ifdef __KERNEL__
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index fe1df572318b..582c1fe6cc4a 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_PGALLOC_H 9#ifndef _ASM_PGALLOC_H
10#define _ASM_PGALLOC_H 10#define _ASM_PGALLOC_H
11 11
12#include <linux/config.h>
13#include <linux/highmem.h> 12#include <linux/highmem.h>
14#include <linux/mm.h> 13#include <linux/mm.h>
15 14
diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h
index 087c20769256..4b26d8528133 100644
--- a/include/asm-mips/pgtable-32.h
+++ b/include/asm-mips/pgtable-32.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_PGTABLE_32_H 9#ifndef _ASM_PGTABLE_32_H
10#define _ASM_PGTABLE_32_H 10#define _ASM_PGTABLE_32_H
11 11
12#include <linux/config.h>
13#include <asm/addrspace.h> 12#include <asm/addrspace.h>
14#include <asm/page.h> 13#include <asm/page.h>
15 14
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index 2faf5c9ff127..e3db93212eab 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_PGTABLE_64_H 9#ifndef _ASM_PGTABLE_64_H
10#define _ASM_PGTABLE_64_H 10#define _ASM_PGTABLE_64_H
11 11
12#include <linux/config.h>
13#include <linux/linkage.h> 12#include <linux/linkage.h>
14 13
15#include <asm/addrspace.h> 14#include <asm/addrspace.h>
diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h
index 01e76e932e3f..7494ba91112a 100644
--- a/include/asm-mips/pgtable-bits.h
+++ b/include/asm-mips/pgtable-bits.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_PGTABLE_BITS_H 10#ifndef _ASM_PGTABLE_BITS_H
11#define _ASM_PGTABLE_BITS_H 11#define _ASM_PGTABLE_BITS_H
12 12
13#include <linux/config.h>
14 13
15/* 14/*
16 * Note that we shift the lower 32bits of each EntryLo[01] entry 15 * Note that we shift the lower 32bits of each EntryLo[01] entry
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index be75cca20e8d..a36ca1be17f2 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_PGTABLE_H 8#ifndef _ASM_PGTABLE_H
9#define _ASM_PGTABLE_H 9#define _ASM_PGTABLE_H
10 10
11#include <linux/config.h>
12#ifdef CONFIG_32BIT 11#ifdef CONFIG_32BIT
13#include <asm/pgtable-32.h> 12#include <asm/pgtable-32.h>
14#endif 13#endif
diff --git a/include/asm-mips/prefetch.h b/include/asm-mips/prefetch.h
index 71293ec1657c..17850834ccb0 100644
--- a/include/asm-mips/prefetch.h
+++ b/include/asm-mips/prefetch.h
@@ -8,7 +8,6 @@
8#ifndef __ASM_PREFETCH_H 8#ifndef __ASM_PREFETCH_H
9#define __ASM_PREFETCH_H 9#define __ASM_PREFETCH_H
10 10
11#include <linux/config.h>
12 11
13/* 12/*
14 * R5000 and RM5200 implements pref and prefx instructions but they're nops, so 13 * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index 83936469fe87..5f80ba71ab92 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_PROCESSOR_H 11#ifndef _ASM_PROCESSOR_H
12#define _ASM_PROCESSOR_H 12#define _ASM_PROCESSOR_H
13 13
14#include <linux/config.h>
15#include <linux/cpumask.h> 14#include <linux/cpumask.h>
16#include <linux/threads.h> 15#include <linux/threads.h>
17 16
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index fa9d8713c12a..4113316ee0da 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_PTRACE_H 9#ifndef _ASM_PTRACE_H
10#define _ASM_PTRACE_H 10#define _ASM_PTRACE_H
11 11
12#include <linux/config.h>
13 12
14#include <asm/isadep.h> 13#include <asm/isadep.h>
15 14
diff --git a/include/asm-mips/reg.h b/include/asm-mips/reg.h
index 6173004cc88e..634b55d7e7f6 100644
--- a/include/asm-mips/reg.h
+++ b/include/asm-mips/reg.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_MIPS_REG_H 12#ifndef __ASM_MIPS_REG_H
13#define __ASM_MIPS_REG_H 13#define __ASM_MIPS_REG_H
14 14
15#include <linux/config.h>
16 15
17#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H) 16#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H)
18 17
diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h
index 1fba00c22077..87cb3085269c 100644
--- a/include/asm-mips/resource.h
+++ b/include/asm-mips/resource.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_RESOURCE_H 9#ifndef _ASM_RESOURCE_H
10#define _ASM_RESOURCE_H 10#define _ASM_RESOURCE_H
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * These five resource limit IDs have a MIPS/Linux-specific ordering, 14 * These five resource limit IDs have a MIPS/Linux-specific ordering,
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 7196ceb0e948..584bd9c0ab2e 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SERIAL_H 9#ifndef _ASM_SERIAL_H
10#define _ASM_SERIAL_H 10#define _ASM_SERIAL_H
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * This assumes you have a 1.8432 MHz clock for your UART. 14 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-mips/sgiarcs.h b/include/asm-mips/sgiarcs.h
index 722b77a8c5e5..ddb859d05257 100644
--- a/include/asm-mips/sgiarcs.h
+++ b/include/asm-mips/sgiarcs.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_SGIARCS_H 12#ifndef _ASM_SGIARCS_H
13#define _ASM_SGIARCS_H 13#define _ASM_SGIARCS_H
14 14
15#include <linux/config.h>
16#include <asm/types.h> 15#include <asm/types.h>
17#include <asm/arc/types.h> 16#include <asm/arc/types.h>
18 17
diff --git a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h
index 900edcbeec37..3dfe29ed42a8 100644
--- a/include/asm-mips/sibyte/board.h
+++ b/include/asm-mips/sibyte/board.h
@@ -19,7 +19,6 @@
19#ifndef _SIBYTE_BOARD_H 19#ifndef _SIBYTE_BOARD_H
20#define _SIBYTE_BOARD_H 20#define _SIBYTE_BOARD_H
21 21
22#include <linux/config.h>
23 22
24#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \ 23#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \
25 defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \ 24 defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \
diff --git a/include/asm-mips/sibyte/carmel.h b/include/asm-mips/sibyte/carmel.h
index b5e7dae19f0f..57c53e62a37a 100644
--- a/include/asm-mips/sibyte/carmel.h
+++ b/include/asm-mips/sibyte/carmel.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_SIBYTE_CARMEL_H 18#ifndef __ASM_SIBYTE_CARMEL_H
19#define __ASM_SIBYTE_CARMEL_H 19#define __ASM_SIBYTE_CARMEL_H
20 20
21#include <linux/config.h>
22 21
23#include <asm/sibyte/sb1250.h> 22#include <asm/sibyte/sb1250.h>
24#include <asm/sibyte/sb1250_int.h> 23#include <asm/sibyte/sb1250_int.h>
diff --git a/include/asm-mips/sibyte/sentosa.h b/include/asm-mips/sibyte/sentosa.h
index 824605847af4..64c47874f32d 100644
--- a/include/asm-mips/sibyte/sentosa.h
+++ b/include/asm-mips/sibyte/sentosa.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_SIBYTE_SENTOSA_H 18#ifndef __ASM_SIBYTE_SENTOSA_H
19#define __ASM_SIBYTE_SENTOSA_H 19#define __ASM_SIBYTE_SENTOSA_H
20 20
21#include <linux/config.h>
22#include <asm/sibyte/sb1250.h> 21#include <asm/sibyte/sb1250.h>
23#include <asm/sibyte/sb1250_int.h> 22#include <asm/sibyte/sb1250_int.h>
24 23
diff --git a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h
index 06e1d528e03a..86db37e5ad85 100644
--- a/include/asm-mips/sibyte/swarm.h
+++ b/include/asm-mips/sibyte/swarm.h
@@ -18,7 +18,6 @@
18#ifndef __ASM_SIBYTE_SWARM_H 18#ifndef __ASM_SIBYTE_SWARM_H
19#define __ASM_SIBYTE_SWARM_H 19#define __ASM_SIBYTE_SWARM_H
20 20
21#include <linux/config.h>
22#include <asm/sibyte/sb1250.h> 21#include <asm/sibyte/sb1250.h>
23#include <asm/sibyte/sb1250_int.h> 22#include <asm/sibyte/sb1250_int.h>
24 23
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
index 2ba313d94a78..2e32949bd674 100644
--- a/include/asm-mips/siginfo.h
+++ b/include/asm-mips/siginfo.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SIGINFO_H 9#ifndef _ASM_SIGINFO_H
10#define _ASM_SIGINFO_H 10#define _ASM_SIGINFO_H
11 11
12#include <linux/config.h>
13 12
14#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int)) 13#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
15#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */ 14#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
index d8349e4b55ee..a1f3a3fa9bd6 100644
--- a/include/asm-mips/signal.h
+++ b/include/asm-mips/signal.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SIGNAL_H 9#ifndef _ASM_SIGNAL_H
10#define _ASM_SIGNAL_H 10#define _ASM_SIGNAL_H
11 11
12#include <linux/config.h>
13#include <linux/types.h> 12#include <linux/types.h>
14 13
15#define _NSIG 128 14#define _NSIG 128
diff --git a/include/asm-mips/sim.h b/include/asm-mips/sim.h
index 9c2af1b00e19..67c4fe52bb42 100644
--- a/include/asm-mips/sim.h
+++ b/include/asm-mips/sim.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SIM_H 9#ifndef _ASM_SIM_H
10#define _ASM_SIM_H 10#define _ASM_SIM_H
11 11
12#include <linux/config.h>
13 12
14#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
15 14
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
index e14e4b69de21..1608fd71d6f7 100644
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_SMP_H 11#ifndef __ASM_SMP_H
12#define __ASM_SMP_H 12#define __ASM_SMP_H
13 13
14#include <linux/config.h>
15 14
16#ifdef CONFIG_SMP 15#ifdef CONFIG_SMP
17 16
diff --git a/include/asm-mips/sn/addrs.h b/include/asm-mips/sn/addrs.h
index 6c8a5577ddf1..8fa0af6b68d2 100644
--- a/include/asm-mips/sn/addrs.h
+++ b/include/asm-mips/sn/addrs.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SN_ADDRS_H 9#ifndef _ASM_SN_ADDRS_H
10#define _ASM_SN_ADDRS_H 10#define _ASM_SN_ADDRS_H
11 11
12#include <linux/config.h>
13 12
14#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
15#include <linux/types.h> 14#include <linux/types.h>
diff --git a/include/asm-mips/sn/agent.h b/include/asm-mips/sn/agent.h
index d6df13aaed49..ac4ea85c3a5c 100644
--- a/include/asm-mips/sn/agent.h
+++ b/include/asm-mips/sn/agent.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SGI_SN_AGENT_H 11#ifndef _ASM_SGI_SN_AGENT_H
12#define _ASM_SGI_SN_AGENT_H 12#define _ASM_SGI_SN_AGENT_H
13 13
14#include <linux/config.h>
15#include <linux/topology.h> 14#include <linux/topology.h>
16#include <asm/sn/addrs.h> 15#include <asm/sn/addrs.h>
17#include <asm/sn/arch.h> 16#include <asm/sn/arch.h>
diff --git a/include/asm-mips/sn/arch.h b/include/asm-mips/sn/arch.h
index d247a819de7f..51174af6ac52 100644
--- a/include/asm-mips/sn/arch.h
+++ b/include/asm-mips/sn/arch.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SN_ARCH_H 11#ifndef _ASM_SN_ARCH_H
12#define _ASM_SN_ARCH_H 12#define _ASM_SN_ARCH_H
13 13
14#include <linux/config.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <asm/sn/types.h> 15#include <asm/sn/types.h>
17#ifdef CONFIG_SGI_IP27 16#ifdef CONFIG_SGI_IP27
diff --git a/include/asm-mips/sn/io.h b/include/asm-mips/sn/io.h
index 13326453efc9..ab2fa8cd2627 100644
--- a/include/asm-mips/sn/io.h
+++ b/include/asm-mips/sn/io.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SN_IO_H 9#ifndef _ASM_SN_IO_H
10#define _ASM_SN_IO_H 10#define _ASM_SN_IO_H
11 11
12#include <linux/config.h>
13#if defined (CONFIG_SGI_IP27) 12#if defined (CONFIG_SGI_IP27)
14#include <asm/sn/sn0/hubio.h> 13#include <asm/sn/sn0/hubio.h>
15#endif 14#endif
diff --git a/include/asm-mips/sn/klconfig.h b/include/asm-mips/sn/klconfig.h
index dc706268d2cf..52238e65af8e 100644
--- a/include/asm-mips/sn/klconfig.h
+++ b/include/asm-mips/sn/klconfig.h
@@ -27,7 +27,6 @@
27 * that offsets of existing fields do not change. 27 * that offsets of existing fields do not change.
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/types.h> 30#include <linux/types.h>
32#include <asm/sn/types.h> 31#include <asm/sn/types.h>
33 32
diff --git a/include/asm-mips/sn/kldir.h b/include/asm-mips/sn/kldir.h
index 97ad52e3cbc7..0573cbffc104 100644
--- a/include/asm-mips/sn/kldir.h
+++ b/include/asm-mips/sn/kldir.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SN_KLDIR_H 11#ifndef _ASM_SN_KLDIR_H
12#define _ASM_SN_KLDIR_H 12#define _ASM_SN_KLDIR_H
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * The kldir memory area resides at a fixed place in each node's memory and 16 * The kldir memory area resides at a fixed place in each node's memory and
diff --git a/include/asm-mips/sn/launch.h b/include/asm-mips/sn/launch.h
index b67699c0c475..b7c2226312c6 100644
--- a/include/asm-mips/sn/launch.h
+++ b/include/asm-mips/sn/launch.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_SN_LAUNCH_H 9#ifndef _ASM_SN_LAUNCH_H
10#define _ASM_SN_LAUNCH_H 10#define _ASM_SN_LAUNCH_H
11 11
12#include <linux/config.h>
13#include <asm/sn/types.h> 12#include <asm/sn/types.h>
14#include <asm/sn/addrs.h> 13#include <asm/sn/addrs.h>
15 14
diff --git a/include/asm-mips/sn/mapped_kernel.h b/include/asm-mips/sn/mapped_kernel.h
index 59edb20f8ec5..c3dd5d0d525f 100644
--- a/include/asm-mips/sn/mapped_kernel.h
+++ b/include/asm-mips/sn/mapped_kernel.h
@@ -20,7 +20,6 @@
20 * code. So no jumps can be done before we have switched to using 20 * code. So no jumps can be done before we have switched to using
21 * cksseg addresses. 21 * cksseg addresses.
22 */ 22 */
23#include <linux/config.h>
24#include <asm/addrspace.h> 23#include <asm/addrspace.h>
25 24
26#define REP_BASE CAC_BASE 25#define REP_BASE CAC_BASE
diff --git a/include/asm-mips/sn/sn0/addrs.h b/include/asm-mips/sn/sn0/addrs.h
index 2c4b758f6736..9e8cc52910f6 100644
--- a/include/asm-mips/sn/sn0/addrs.h
+++ b/include/asm-mips/sn/sn0/addrs.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SN_SN0_ADDRS_H 11#ifndef _ASM_SN_SN0_ADDRS_H
12#define _ASM_SN_SN0_ADDRS_H 12#define _ASM_SN_SN0_ADDRS_H
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * SN0 (on a T5) Address map 16 * SN0 (on a T5) Address map
diff --git a/include/asm-mips/sn/sn0/arch.h b/include/asm-mips/sn/sn0/arch.h
index f7c43fa24aa8..f734f2007f24 100644
--- a/include/asm-mips/sn/sn0/arch.h
+++ b/include/asm-mips/sn/sn0/arch.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SN_SN0_ARCH_H 11#ifndef _ASM_SN_SN0_ARCH_H
12#define _ASM_SN_SN0_ARCH_H 12#define _ASM_SN_SN0_ARCH_H
13 13
14#include <linux/config.h>
15 14
16#ifndef SN0XXL /* 128 cpu SMP max */ 15#ifndef SN0XXL /* 128 cpu SMP max */
17/* 16/*
diff --git a/include/asm-mips/sn/sn0/hubmd.h b/include/asm-mips/sn/sn0/hubmd.h
index 1006aa26d771..14c225d80664 100644
--- a/include/asm-mips/sn/sn0/hubmd.h
+++ b/include/asm-mips/sn/sn0/hubmd.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_SN_SN0_HUBMD_H 11#ifndef _ASM_SN_SN0_HUBMD_H
12#define _ASM_SN_SN0_HUBMD_H 12#define _ASM_SN_SN0_HUBMD_H
13 13
14#include <linux/config.h>
15 14
16/* 15/*
17 * Hub Memory/Directory interface registers 16 * Hub Memory/Directory interface registers
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index c4856a874965..513aa5133830 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_STACKFRAME_H 10#ifndef _ASM_STACKFRAME_H
11#define _ASM_STACKFRAME_H 11#define _ASM_STACKFRAME_H
12 12
13#include <linux/config.h>
14#include <linux/threads.h> 13#include <linux/threads.h>
15 14
16#include <asm/asm.h> 15#include <asm/asm.h>
diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h
index 907da600fddd..436e3ad352d9 100644
--- a/include/asm-mips/string.h
+++ b/include/asm-mips/string.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_STRING_H 10#ifndef _ASM_STRING_H
11#define _ASM_STRING_H 11#define _ASM_STRING_H
12 12
13#include <linux/config.h>
14 13
15/* 14/*
16 * Most of the inline functions are rather naive implementations so I just 15 * Most of the inline functions are rather naive implementations so I just
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 261f71d16a07..130333d7c4ee 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -12,7 +12,6 @@
12#ifndef _ASM_SYSTEM_H 12#ifndef _ASM_SYSTEM_H
13#define _ASM_SYSTEM_H 13#define _ASM_SYSTEM_H
14 14
15#include <linux/config.h>
16#include <linux/types.h> 15#include <linux/types.h>
17 16
18#include <asm/addrspace.h> 17#include <asm/addrspace.h>
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index f8d97dafd2f4..ae8ada5b42a9 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -9,7 +9,6 @@
9 9
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11 11
12#include <linux/config.h>
13 12
14#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
15 14
diff --git a/include/asm-mips/tlbflush.h b/include/asm-mips/tlbflush.h
index bb4ae3cdcbf1..276be77c3e85 100644
--- a/include/asm-mips/tlbflush.h
+++ b/include/asm-mips/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_TLBFLUSH_H 1#ifndef __ASM_TLBFLUSH_H
2#define __ASM_TLBFLUSH_H 2#define __ASM_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6 5
7/* 6/*
diff --git a/include/asm-mips/tx4927/toshiba_rbtx4927.h b/include/asm-mips/tx4927/toshiba_rbtx4927.h
index 6ce1e9475f99..94bef03d9635 100644
--- a/include/asm-mips/tx4927/toshiba_rbtx4927.h
+++ b/include/asm-mips/tx4927/toshiba_rbtx4927.h
@@ -27,7 +27,6 @@
27#ifndef __ASM_TX4927_TOSHIBA_RBTX4927_H 27#ifndef __ASM_TX4927_TOSHIBA_RBTX4927_H
28#define __ASM_TX4927_TOSHIBA_RBTX4927_H 28#define __ASM_TX4927_TOSHIBA_RBTX4927_H
29 29
30#include <linux/config.h>
31#include <asm/tx4927/tx4927.h> 30#include <asm/tx4927/tx4927.h>
32#include <asm/tx4927/tx4927_mips.h> 31#include <asm/tx4927/tx4927_mips.h>
33#ifdef CONFIG_PCI 32#ifdef CONFIG_PCI
diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h
index cd2813d8e136..2b52e180c6f2 100644
--- a/include/asm-mips/types.h
+++ b/include/asm-mips/types.h
@@ -52,7 +52,6 @@ typedef unsigned long long __u64;
52 52
53#ifndef __ASSEMBLY__ 53#ifndef __ASSEMBLY__
54 54
55#include <linux/config.h>
56 55
57typedef __signed char s8; 56typedef __signed char s8;
58typedef unsigned char u8; 57typedef unsigned char u8;
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index b96f3e0f3933..1cdd4eeb2f73 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_UACCESS_H 9#ifndef _ASM_UACCESS_H
10#define _ASM_UACCESS_H 10#define _ASM_UACCESS_H
11 11
12#include <linux/config.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
15#include <linux/thread_info.h> 14#include <linux/thread_info.h>
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index 1068fe9a0a58..8bb0bb9b2e68 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -905,6 +905,8 @@
905#define __NR_N32_Linux 6000 905#define __NR_N32_Linux 6000
906#define __NR_N32_Linux_syscalls 268 906#define __NR_N32_Linux_syscalls 268
907 907
908#ifdef __KERNEL__
909
908#ifndef __ASSEMBLY__ 910#ifndef __ASSEMBLY__
909 911
910/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ 912/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
@@ -1168,9 +1170,6 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
1168 1170
1169#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */ 1171#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
1170 1172
1171#ifdef __KERNEL__
1172
1173#include <linux/config.h>
1174 1173
1175#define __ARCH_WANT_IPC_PARSE_VERSION 1174#define __ARCH_WANT_IPC_PARSE_VERSION
1176#define __ARCH_WANT_OLD_READDIR 1175#define __ARCH_WANT_OLD_READDIR
@@ -1197,7 +1196,6 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
1197# ifdef CONFIG_MIPS32_O32 1196# ifdef CONFIG_MIPS32_O32
1198# define __ARCH_WANT_COMPAT_SYS_TIME 1197# define __ARCH_WANT_COMPAT_SYS_TIME
1199# endif 1198# endif
1200#endif
1201 1199
1202#ifdef __KERNEL_SYSCALLS__ 1200#ifdef __KERNEL_SYSCALLS__
1203 1201
@@ -1248,4 +1246,5 @@ asmlinkage long sys_rt_sigaction(int sig,
1248 */ 1246 */
1249#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall") 1247#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
1250 1248
1249#endif /* __KERNEL__ */
1251#endif /* _ASM_UNISTD_H */ 1250#endif /* _ASM_UNISTD_H */
diff --git a/include/asm-mips/vr41xx/vrc4173.h b/include/asm-mips/vr41xx/vrc4173.h
index 4d41a9c091d4..96fdcd54cec7 100644
--- a/include/asm-mips/vr41xx/vrc4173.h
+++ b/include/asm-mips/vr41xx/vrc4173.h
@@ -24,7 +24,6 @@
24#ifndef __NEC_VRC4173_H 24#ifndef __NEC_VRC4173_H
25#define __NEC_VRC4173_H 25#define __NEC_VRC4173_H
26 26
27#include <linux/config.h>
28#include <asm/io.h> 27#include <asm/io.h>
29 28
30/* 29/*
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 70636b41832c..3ac146c019c9 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_WAR_H 8#ifndef _ASM_WAR_H
9#define _ASM_WAR_H 9#define _ASM_WAR_H
10 10
11#include <linux/config.h>
12 11
13/* 12/*
14 * Another R4600 erratum. Due to the lack of errata information the exact 13 * Another R4600 erratum. Due to the lack of errata information the exact
diff --git a/include/asm-mips/wbflush.h b/include/asm-mips/wbflush.h
index c3bef50f37a8..eadc0ac47e24 100644
--- a/include/asm-mips/wbflush.h
+++ b/include/asm-mips/wbflush.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_WBFLUSH_H 11#ifndef _ASM_WBFLUSH_H
12#define _ASM_WBFLUSH_H 12#define _ASM_WBFLUSH_H
13 13
14#include <linux/config.h>
15 14
16#ifdef CONFIG_CPU_HAS_WB 15#ifdef CONFIG_CPU_HAS_WB
17 16
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 403ea97316cf..48bf9b8ab8ff 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -5,7 +5,6 @@
5#ifndef _ASM_PARISC_ATOMIC_H_ 5#ifndef _ASM_PARISC_ATOMIC_H_
6#define _ASM_PARISC_ATOMIC_H_ 6#define _ASM_PARISC_ATOMIC_H_
7 7
8#include <linux/config.h>
9#include <linux/types.h> 8#include <linux/types.h>
10#include <asm/system.h> 9#include <asm/system.h>
11 10
diff --git a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
index c831665473cb..7d22fa206fc4 100644
--- a/include/asm-parisc/cache.h
+++ b/include/asm-parisc/cache.h
@@ -5,7 +5,6 @@
5#ifndef __ARCH_PARISC_CACHE_H 5#ifndef __ARCH_PARISC_CACHE_H
6#define __ARCH_PARISC_CACHE_H 6#define __ARCH_PARISC_CACHE_H
7 7
8#include <linux/config.h>
9 8
10/* 9/*
11 * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have 10 * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 76b6b7d6046a..0b459cdfbd6f 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -1,7 +1,6 @@
1#ifndef _PARISC_CACHEFLUSH_H 1#ifndef _PARISC_CACHEFLUSH_H
2#define _PARISC_CACHEFLUSH_H 2#define _PARISC_CACHEFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/cache.h> /* for flush_user_dcache_range_asm() proto */ 5#include <asm/cache.h> /* for flush_user_dcache_range_asm() proto */
7 6
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 74d4ac6f2151..1e387e1dad30 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _PARISC_DMA_MAPPING_H 1#ifndef _PARISC_DMA_MAPPING_H
2#define _PARISC_DMA_MAPPING_H 2#define _PARISC_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/cacheflush.h> 5#include <asm/cacheflush.h>
7#include <asm/scatterlist.h> 6#include <asm/scatterlist.h>
diff --git a/include/asm-parisc/dma.h b/include/asm-parisc/dma.h
index 31fd10df43a7..9979c3cb3745 100644
--- a/include/asm-parisc/dma.h
+++ b/include/asm-parisc/dma.h
@@ -9,7 +9,6 @@
9#ifndef _ASM_DMA_H 9#ifndef _ASM_DMA_H
10#define _ASM_DMA_H 10#define _ASM_DMA_H
11 11
12#include <linux/config.h>
13#include <asm/io.h> /* need byte IO */ 12#include <asm/io.h> /* need byte IO */
14#include <asm/system.h> 13#include <asm/system.h>
15 14
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index 244f6b8883f4..b9eb245b8874 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IO_H 1#ifndef _ASM_IO_H
2#define _ASM_IO_H 2#define _ASM_IO_H
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6#include <asm/pgtable.h> 5#include <asm/pgtable.h>
7 6
diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
index b0a30e2c9813..377ba90c7d02 100644
--- a/include/asm-parisc/irq.h
+++ b/include/asm-parisc/irq.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_PARISC_IRQ_H 7#ifndef _ASM_PARISC_IRQ_H
8#define _ASM_PARISC_IRQ_H 8#define _ASM_PARISC_IRQ_H
9 9
10#include <linux/config.h>
11#include <linux/cpumask.h> 10#include <linux/cpumask.h>
12#include <asm/types.h> 11#include <asm/types.h>
13 12
diff --git a/include/asm-parisc/kmap_types.h b/include/asm-parisc/kmap_types.h
index 6886a0c3fedf..806aae3c5338 100644
--- a/include/asm-parisc/kmap_types.h
+++ b/include/asm-parisc/kmap_types.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_KMAP_TYPES_H 1#ifndef _ASM_KMAP_TYPES_H
2#define _ASM_KMAP_TYPES_H 2#define _ASM_KMAP_TYPES_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_DEBUG_HIGHMEM 5#ifdef CONFIG_DEBUG_HIGHMEM
7# define D(n) __KM_FENCE_##n , 6# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index c0dd461fb8f1..0695bc958d56 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -10,7 +10,6 @@
10 10
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13#include <linux/config.h>
14 13
15#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) 14#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
16# define PAGE_SHIFT 12 /* 4k */ 15# define PAGE_SHIFT 12 /* 4k */
diff --git a/include/asm-parisc/param.h b/include/asm-parisc/param.h
index f4694d452dd6..07cb9b93cfe2 100644
--- a/include/asm-parisc/param.h
+++ b/include/asm-parisc/param.h
@@ -2,7 +2,6 @@
2#define _ASMPARISC_PARAM_H 2#define _ASMPARISC_PARAM_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#include <linux/config.h>
6# ifdef CONFIG_PA20 5# ifdef CONFIG_PA20
7# define HZ 1000 /* Faster machines */ 6# define HZ 1000 /* Faster machines */
8# else 7# else
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 77bbafb7f73e..8b631f47eb25 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_PARISC_PCI_H 1#ifndef __ASM_PARISC_PCI_H
2#define __ASM_PARISC_PCI_H 2#define __ASM_PARISC_PCI_H
3 3
4#include <linux/config.h>
5#include <asm/scatterlist.h> 4#include <asm/scatterlist.h>
6 5
7 6
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
index 0a3face6c480..08364f957e7a 100644
--- a/include/asm-parisc/pdc.h
+++ b/include/asm-parisc/pdc.h
@@ -1,7 +1,6 @@
1#ifndef _PARISC_PDC_H 1#ifndef _PARISC_PDC_H
2#define _PARISC_PDC_H 2#define _PARISC_PDC_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * PDC return values ... 6 * PDC return values ...
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index aec089eb8b85..b6bcc672ba80 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -3,7 +3,6 @@
3 3
4#include <asm-generic/4level-fixup.h> 4#include <asm-generic/4level-fixup.h>
5 5
6#include <linux/config.h>
7#include <asm/fixmap.h> 6#include <asm/fixmap.h>
8 7
9#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index 89f2f1c16c12..ca49dc91f4fc 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -9,7 +9,6 @@
9#define __ASM_PARISC_PROCESSOR_H 9#define __ASM_PARISC_PROCESSOR_H
10 10
11#ifndef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
12#include <linux/config.h>
13#include <linux/threads.h> 12#include <linux/threads.h>
14#include <linux/spinlock_types.h> 13#include <linux/spinlock_types.h>
15 14
diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h
index 4334d6ca2add..5a3e23c9ce63 100644
--- a/include/asm-parisc/psw.h
+++ b/include/asm-parisc/psw.h
@@ -1,6 +1,5 @@
1#ifndef _PARISC_PSW_H 1#ifndef _PARISC_PSW_H
2 2
3#include <linux/config.h>
4 3
5#define PSW_I 0x00000001 4#define PSW_I 0x00000001
6#define PSW_D 0x00000002 5#define PSW_D 0x00000002
diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h
index dbdbd2e9fdf9..d4c0e26afcd1 100644
--- a/include/asm-parisc/smp.h
+++ b/include/asm-parisc/smp.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SMP_H 1#ifndef __ASM_SMP_H
2#define __ASM_SMP_H 2#define __ASM_SMP_H
3 3
4#include <linux/config.h>
5 4
6#if defined(CONFIG_SMP) 5#if defined(CONFIG_SMP)
7 6
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index a5a973c0c07f..863876134b2c 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -1,7 +1,6 @@
1#ifndef __PARISC_SYSTEM_H 1#ifndef __PARISC_SYSTEM_H
2#define __PARISC_SYSTEM_H 2#define __PARISC_SYSTEM_H
3 3
4#include <linux/config.h>
5#include <asm/psw.h> 4#include <asm/psw.h>
6 5
7/* The program status word as bitfields. */ 6/* The program status word as bitfields. */
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index 825994a90e2d..f662e837dea1 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -3,7 +3,6 @@
3 3
4/* TLB flushing routines.... */ 4/* TLB flushing routines.... */
5 5
6#include <linux/config.h>
7#include <linux/mm.h> 6#include <linux/mm.h>
8#include <asm/mmu_context.h> 7#include <asm/mmu_context.h>
9 8
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index 0e1a30be2e30..12b867238a47 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -792,6 +792,7 @@
792#define HPUX_GATEWAY_ADDR 0xC0000004 792#define HPUX_GATEWAY_ADDR 0xC0000004
793#define LINUX_GATEWAY_ADDR 0x100 793#define LINUX_GATEWAY_ADDR 0x100
794 794
795#ifdef __KERNEL__
795#ifndef __ASSEMBLY__ 796#ifndef __ASSEMBLY__
796 797
797#define SYS_ify(syscall_name) __NR_##syscall_name 798#define SYS_ify(syscall_name) __NR_##syscall_name
@@ -934,7 +935,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
934 return K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \ 935 return K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
935} 936}
936 937
937#ifdef __KERNEL__
938#define __ARCH_WANT_OLD_READDIR 938#define __ARCH_WANT_OLD_READDIR
939#define __ARCH_WANT_STAT64 939#define __ARCH_WANT_STAT64
940#define __ARCH_WANT_SYS_ALARM 940#define __ARCH_WANT_SYS_ALARM
@@ -956,7 +956,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
956#define __ARCH_WANT_SYS_SIGPENDING 956#define __ARCH_WANT_SYS_SIGPENDING
957#define __ARCH_WANT_SYS_SIGPROCMASK 957#define __ARCH_WANT_SYS_SIGPROCMASK
958#define __ARCH_WANT_SYS_RT_SIGACTION 958#define __ARCH_WANT_SYS_RT_SIGACTION
959#endif
960 959
961/* mmap & mmap2 take 6 arguments */ 960/* mmap & mmap2 take 6 arguments */
962#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ 961#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
@@ -1056,4 +1055,5 @@ asmlinkage long sys_rt_sigaction(int sig,
1056 */ 1055 */
1057#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 1056#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
1058 1057
1058#endif /* __KERNEL__ */
1059#endif /* _ASM_PARISC_UNISTD_H_ */ 1059#endif /* _ASM_PARISC_UNISTD_H_ */
diff --git a/include/asm-powerpc/abs_addr.h b/include/asm-powerpc/abs_addr.h
index c5c3259e0f86..4aa220718b19 100644
--- a/include/asm-powerpc/abs_addr.h
+++ b/include/asm-powerpc/abs_addr.h
@@ -2,7 +2,6 @@
2#define _ASM_POWERPC_ABS_ADDR_H 2#define _ASM_POWERPC_ABS_ADDR_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/config.h>
6 5
7/* 6/*
8 * c 2001 PPC 64 Team, IBM Corp 7 * c 2001 PPC 64 Team, IBM Corp
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
index 6379c2df5c40..642be62cf393 100644
--- a/include/asm-powerpc/cache.h
+++ b/include/asm-powerpc/cache.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8/* bytes per L1 cache line */ 7/* bytes per L1 cache line */
9#if defined(CONFIG_8xx) || defined(CONFIG_403GCX) 8#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ac63f569592..2ab9baf78bb4 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -8,7 +8,6 @@
8#define _ASM_DMA_MAPPING_H 8#define _ASM_DMA_MAPPING_H
9#ifdef __KERNEL__ 9#ifdef __KERNEL__
10 10
11#include <linux/config.h>
12#include <linux/types.h> 11#include <linux/types.h>
13#include <linux/cache.h> 12#include <linux/cache.h>
14/* need struct page definitions */ 13/* need struct page definitions */
diff --git a/include/asm-powerpc/dma.h b/include/asm-powerpc/dma.h
index 4bb57fe37097..7a4374bdbef4 100644
--- a/include/asm-powerpc/dma.h
+++ b/include/asm-powerpc/dma.h
@@ -22,7 +22,6 @@
22 * with a grain of salt. 22 * with a grain of salt.
23 */ 23 */
24 24
25#include <linux/config.h>
26#include <asm/io.h> 25#include <asm/io.h>
27#include <linux/spinlock.h> 26#include <linux/spinlock.h>
28#include <asm/system.h> 27#include <asm/system.h>
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h
index 868c7139dbff..e9c86b1eedab 100644
--- a/include/asm-powerpc/eeh.h
+++ b/include/asm-powerpc/eeh.h
@@ -21,7 +21,6 @@
21#define _PPC64_EEH_H 21#define _PPC64_EEH_H
22#ifdef __KERNEL__ 22#ifdef __KERNEL__
23 23
24#include <linux/config.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/list.h> 25#include <linux/list.h>
27#include <linux/string.h> 26#include <linux/string.h>
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 94d228f9c6ac..99c18b71aa82 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -3,14 +3,14 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#include <linux/sched.h> /* for task_struct */ 5#include <linux/sched.h> /* for task_struct */
6#include <asm/page.h>
7#include <asm/string.h>
6#endif 8#endif
7 9
8#include <asm/types.h> 10#include <asm/types.h>
9#include <asm/ptrace.h> 11#include <asm/ptrace.h>
10#include <asm/cputable.h> 12#include <asm/cputable.h>
11#include <asm/auxvec.h> 13#include <asm/auxvec.h>
12#include <asm/page.h>
13#include <asm/string.h>
14 14
15/* PowerPC relocations defined by the ABIs */ 15/* PowerPC relocations defined by the ABIs */
16#define R_PPC_NONE 0 16#define R_PPC_NONE 0
@@ -129,7 +129,7 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
129 /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */ 129 /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
130 typedef elf_greg_t32 elf_greg_t; 130 typedef elf_greg_t32 elf_greg_t;
131 typedef elf_gregset_t32 elf_gregset_t; 131 typedef elf_gregset_t32 elf_gregset_t;
132# define elf_addr_t u32 132# define elf_addr_t __u32
133#endif /* ELF_ARCH */ 133#endif /* ELF_ARCH */
134 134
135/* Floating point registers */ 135/* Floating point registers */
@@ -161,6 +161,7 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
161typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; 161typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
162#endif 162#endif
163 163
164#ifdef __KERNEL__
164/* 165/*
165 * This is used to ensure we don't load something for the wrong architecture. 166 * This is used to ensure we don't load something for the wrong architecture.
166 */ 167 */
@@ -176,8 +177,6 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
176 177
177#define ELF_ET_DYN_BASE (0x08000000) 178#define ELF_ET_DYN_BASE (0x08000000)
178 179
179#ifdef __KERNEL__
180
181/* Common routine for both 32-bit and 64-bit processes */ 180/* Common routine for both 32-bit and 64-bit processes */
182static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs, 181static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
183 struct pt_regs *regs) 182 struct pt_regs *regs)
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index 608164c39efb..7e2d169ee856 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -11,7 +11,6 @@
11#define __ASM_POWERPC_FLOPPY_H 11#define __ASM_POWERPC_FLOPPY_H
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <asm/machdep.h> 14#include <asm/machdep.h>
16 15
17#define fd_inb(port) inb_p(port) 16#define fd_inb(port) inb_p(port)
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index 26b89d859c56..ce0f7db63c16 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -6,7 +6,6 @@
6 6
7#ifdef __KERNEL__ 7#ifdef __KERNEL__
8 8
9#include <linux/config.h>
10#include <linux/errno.h> 9#include <linux/errno.h>
11#include <asm/ptrace.h> 10#include <asm/ptrace.h>
12#include <asm/processor.h> 11#include <asm/processor.h>
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h
index da5f640480cf..b09b42af6a1e 100644
--- a/include/asm-powerpc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -22,7 +22,6 @@
22#endif 22#endif
23 23
24#ifndef __powerpc64__ 24#ifndef __powerpc64__
25#include <linux/config.h>
26#include <linux/hdreg.h> 25#include <linux/hdreg.h>
27#include <linux/ioport.h> 26#include <linux/ioport.h>
28#include <asm/io.h> 27#include <asm/io.h>
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 18ca29e9105a..2acf7b29ef06 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -22,7 +22,6 @@
22#define _ASM_IOMMU_H 22#define _ASM_IOMMU_H
23#ifdef __KERNEL__ 23#ifdef __KERNEL__
24 24
25#include <linux/config.h>
26#include <asm/types.h> 25#include <asm/types.h>
27#include <linux/spinlock.h> 26#include <linux/spinlock.h>
28#include <linux/device.h> 27#include <linux/device.h>
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index 7bc6d73b2823..1e9f25330307 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -9,7 +9,6 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/threads.h> 12#include <linux/threads.h>
14 13
15#include <asm/types.h> 14#include <asm/types.h>
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index 496aa852b617..f29009bd63c9 100644
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H 1#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
2#define _ASM_POWERPC_ISERIES_ISERIES_IO_H 2#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PPC_ISERIES 5#ifdef CONFIG_PPC_ISERIES
7#include <linux/types.h> 6#include <linux/types.h>
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 0f9254c18914..3e7d37aa4a6d 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -9,7 +9,6 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/seq_file.h> 12#include <linux/seq_file.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
diff --git a/include/asm-powerpc/mmzone.h b/include/asm-powerpc/mmzone.h
index 88d70bae7769..d484ca94cb7c 100644
--- a/include/asm-powerpc/mmzone.h
+++ b/include/asm-powerpc/mmzone.h
@@ -8,7 +8,6 @@
8#define _ASM_MMZONE_H_ 8#define _ASM_MMZONE_H_
9#ifdef __KERNEL__ 9#ifdef __KERNEL__
10 10
11#include <linux/config.h>
12 11
13/* 12/*
14 * generic non-linear memory support: 13 * generic non-linear memory support:
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 706325f99a84..3c6f644d49b4 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -16,7 +16,6 @@
16#define _ASM_POWERPC_PACA_H 16#define _ASM_POWERPC_PACA_H
17#ifdef __KERNEL__ 17#ifdef __KERNEL__
18 18
19#include <linux/config.h>
20#include <asm/types.h> 19#include <asm/types.h>
21#include <asm/lppaca.h> 20#include <asm/lppaca.h>
22#include <asm/mmu.h> 21#include <asm/mmu.h>
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index 2fbecebe1c92..f0469b961359 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#ifdef __KERNEL__ 13#ifdef __KERNEL__
14#include <linux/config.h>
15#include <asm/asm-compat.h> 14#include <asm/asm-compat.h>
16 15
17/* 16/*
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index e9f1f4627e6b..964e312a1ffc 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#ifndef __ASSEMBLY__ 14#ifndef __ASSEMBLY__
15#include <linux/config.h>
16#include <linux/stddef.h> 15#include <linux/stddef.h>
17#include <asm/processor.h> /* For TASK_SIZE */ 16#include <asm/processor.h> /* For TASK_SIZE */
18#include <asm/mmu.h> 17#include <asm/mmu.h>
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index dd1c0a913d5f..a940cfe040da 100644
--- a/include/asm-powerpc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -5,7 +5,6 @@
5#define _ASM_POWERPC_PPC_ASM_H 5#define _ASM_POWERPC_PPC_ASM_H
6 6
7#include <linux/stringify.h> 7#include <linux/stringify.h>
8#include <linux/config.h>
9#include <asm/asm-compat.h> 8#include <asm/asm-compat.h>
10 9
11#ifndef __ASSEMBLY__ 10#ifndef __ASSEMBLY__
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 97ef1cd71a4d..f4e2ca6fd53f 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -15,7 +15,6 @@
15 * as published by the Free Software Foundation; either version 15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version. 16 * 2 of the License, or (at your option) any later version.
17 */ 17 */
18#include <linux/config.h>
19#include <linux/types.h> 18#include <linux/types.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
21#include <asm/atomic.h> 20#include <asm/atomic.h>
diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h
index 4a716f707cf6..068f119aa298 100644
--- a/include/asm-powerpc/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -17,7 +17,6 @@
17#define _ASM_POWERPC_SMP_H 17#define _ASM_POWERPC_SMP_H
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h>
21#include <linux/threads.h> 20#include <linux/threads.h>
22#include <linux/cpumask.h> 21#include <linux/cpumask.h>
23#include <linux/kernel.h> 22#include <linux/kernel.h>
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 2dc93632f210..51e65fc46a03 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -5,7 +5,6 @@
5 * Definitions for talking to the SMU chip in newer G5 PowerMacs 5 * Definitions for talking to the SMU chip in newer G5 PowerMacs
6 */ 6 */
7#ifdef __KERNEL__ 7#ifdef __KERNEL__
8#include <linux/config.h>
9#include <linux/list.h> 8#include <linux/list.h>
10#endif 9#endif
11#include <linux/types.h> 10#include <linux/types.h>
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 7cfcff3ef027..95713f397357 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -24,7 +24,6 @@
24#define _SPU_H 24#define _SPU_H
25#ifdef __KERNEL__ 25#ifdef __KERNEL__
26 26
27#include <linux/config.h>
28#include <linux/kref.h> 27#include <linux/kref.h>
29#include <linux/workqueue.h> 28#include <linux/workqueue.h>
30 29
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 88b553c6b26c..d339e2e88b11 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -21,7 +21,6 @@
21#define THREAD_SIZE (1 << THREAD_SHIFT) 21#define THREAD_SIZE (1 << THREAD_SHIFT)
22 22
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24#include <linux/config.h>
25#include <linux/cache.h> 24#include <linux/cache.h>
26#include <asm/processor.h> 25#include <asm/processor.h>
27#include <asm/page.h> 26#include <asm/page.h>
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index 912118db13ae..4463148c659f 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -14,7 +14,6 @@
14#define __POWERPC_TIME_H 14#define __POWERPC_TIME_H
15 15
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17#include <linux/config.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/percpu.h> 18#include <linux/percpu.h>
20 19
diff --git a/include/asm-powerpc/timex.h b/include/asm-powerpc/timex.h
index c02d15aced91..3b9a8e786806 100644
--- a/include/asm-powerpc/timex.h
+++ b/include/asm-powerpc/timex.h
@@ -7,7 +7,6 @@
7 * PowerPC architecture timex specifications 7 * PowerPC architecture timex specifications
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <asm/cputable.h> 10#include <asm/cputable.h>
12 11
13#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */ 12#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
diff --git a/include/asm-powerpc/tlb.h b/include/asm-powerpc/tlb.h
index 601a53cf96d5..4e2a834683fb 100644
--- a/include/asm-powerpc/tlb.h
+++ b/include/asm-powerpc/tlb.h
@@ -13,7 +13,6 @@
13#define _ASM_POWERPC_TLB_H 13#define _ASM_POWERPC_TLB_H
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17#ifndef __powerpc64__ 16#ifndef __powerpc64__
18#include <asm/pgtable.h> 17#include <asm/pgtable.h>
19#endif 18#endif
diff --git a/include/asm-powerpc/tlbflush.h b/include/asm-powerpc/tlbflush.h
index a2998eee37bb..93c7d0c7230f 100644
--- a/include/asm-powerpc/tlbflush.h
+++ b/include/asm-powerpc/tlbflush.h
@@ -17,7 +17,6 @@
17 */ 17 */
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h>
21 20
22struct mm_struct; 21struct mm_struct;
23 22
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 87362a05542b..19c575f39164 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -2,7 +2,6 @@
2#define _ASM_POWERPC_TOPOLOGY_H 2#define _ASM_POWERPC_TOPOLOGY_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/config.h>
6 5
7struct sys_device; 6struct sys_device;
8struct device_node; 7struct device_node;
diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h
index baabba96e313..d6fb56b80453 100644
--- a/include/asm-powerpc/types.h
+++ b/include/asm-powerpc/types.h
@@ -64,7 +64,6 @@ typedef struct {
64 64
65#ifndef __ASSEMBLY__ 65#ifndef __ASSEMBLY__
66 66
67#include <linux/config.h>
68 67
69typedef signed char s8; 68typedef signed char s8;
70typedef unsigned char u8; 69typedef unsigned char u8;
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index edde2462bf52..eb66eae6616f 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -324,12 +324,12 @@
324#define __NR_get_robust_list 299 324#define __NR_get_robust_list 299
325#define __NR_set_robust_list 300 325#define __NR_set_robust_list 300
326 326
327#ifdef __KERNEL__
328
327#define __NR_syscalls 301 329#define __NR_syscalls 301
328 330
329#ifdef __KERNEL__
330#define __NR__exit __NR_exit 331#define __NR__exit __NR_exit
331#define NR_syscalls __NR_syscalls 332#define NR_syscalls __NR_syscalls
332#endif
333 333
334#ifndef __ASSEMBLY__ 334#ifndef __ASSEMBLY__
335 335
@@ -441,9 +441,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
441 __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ 441 __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
442} 442}
443 443
444#ifdef __KERNEL__
445 444
446#include <linux/config.h>
447#include <linux/types.h> 445#include <linux/types.h>
448#include <linux/compiler.h> 446#include <linux/compiler.h>
449#include <linux/linkage.h> 447#include <linux/linkage.h>
@@ -499,8 +497,8 @@ extern int execve(const char *file, char **argv, char **envp);
499#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall") 497#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
500#endif 498#endif
501 499
502#endif /* __KERNEL__ */
503 500
504#endif /* __ASSEMBLY__ */ 501#endif /* __ASSEMBLY__ */
502#endif /* __KERNEL__ */
505 503
506#endif /* _ASM_PPC_UNISTD_H_ */ 504#endif /* _ASM_PPC_UNISTD_H_ */
diff --git a/include/asm-powerpc/vga.h b/include/asm-powerpc/vga.h
index f8d350aabf1a..eadaf2f3d032 100644
--- a/include/asm-powerpc/vga.h
+++ b/include/asm-powerpc/vga.h
@@ -12,7 +12,6 @@
12 12
13#include <asm/io.h> 13#include <asm/io.h>
14 14
15#include <linux/config.h>
16 15
17#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) 16#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
18 17
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 0544ece51761..be14c59846f9 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -15,7 +15,6 @@
15#define _ASM_POWERPC_VIO_H 15#define _ASM_POWERPC_VIO_H
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/config.h>
19#include <linux/init.h> 18#include <linux/init.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
21#include <linux/device.h> 20#include <linux/device.h>
diff --git a/include/asm-ppc/amigahw.h b/include/asm-ppc/amigahw.h
index 8c98945e7dc1..90fd1274d727 100644
--- a/include/asm-ppc/amigahw.h
+++ b/include/asm-ppc/amigahw.h
@@ -2,7 +2,6 @@
2#ifndef __ASMPPC_AMIGAHW_H 2#ifndef __ASMPPC_AMIGAHW_H
3#define __ASMPPC_AMIGAHW_H 3#define __ASMPPC_AMIGAHW_H
4 4
5#include <linux/config.h>
6#include <asm-m68k/amigahw.h> 5#include <asm-m68k/amigahw.h>
7 6
8#undef CHIP_PHYSADDR 7#undef CHIP_PHYSADDR
diff --git a/include/asm-ppc/bootinfo.h b/include/asm-ppc/bootinfo.h
index 93d955c70d65..2ace4a74f263 100644
--- a/include/asm-ppc/bootinfo.h
+++ b/include/asm-ppc/bootinfo.h
@@ -9,7 +9,6 @@
9#ifndef _PPC_BOOTINFO_H 9#ifndef _PPC_BOOTINFO_H
10#define _PPC_BOOTINFO_H 10#define _PPC_BOOTINFO_H
11 11
12#include <linux/config.h>
13#include <asm/page.h> 12#include <asm/page.h>
14 13
15#if defined(CONFIG_APUS) && !defined(__BOOTER__) 14#if defined(CONFIG_APUS) && !defined(__BOOTER__)
diff --git a/include/asm-ppc/commproc.h b/include/asm-ppc/commproc.h
index 31f362966a58..3247bea5fc2b 100644
--- a/include/asm-ppc/commproc.h
+++ b/include/asm-ppc/commproc.h
@@ -17,7 +17,6 @@
17#ifndef __CPM_8XX__ 17#ifndef __CPM_8XX__
18#define __CPM_8XX__ 18#define __CPM_8XX__
19 19
20#include <linux/config.h>
21#include <asm/8xx_immap.h> 20#include <asm/8xx_immap.h>
22#include <asm/ptrace.h> 21#include <asm/ptrace.h>
23 22
diff --git a/include/asm-ppc/ibm403.h b/include/asm-ppc/ibm403.h
index bf6efa0417ab..c9c5d539cfdb 100644
--- a/include/asm-ppc/ibm403.h
+++ b/include/asm-ppc/ibm403.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_IBM403_H__ 12#ifndef __ASM_IBM403_H__
13#define __ASM_IBM403_H__ 13#define __ASM_IBM403_H__
14 14
15#include <linux/config.h>
16 15
17#if defined(CONFIG_403GCX) 16#if defined(CONFIG_403GCX)
18 17
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
index 3acc382cc83f..7818b54b6e37 100644
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -17,7 +17,6 @@
17#ifndef __ASM_IBM44x_H__ 17#ifndef __ASM_IBM44x_H__
18#define __ASM_IBM44x_H__ 18#define __ASM_IBM44x_H__
19 19
20#include <linux/config.h>
21 20
22#ifndef NR_BOARD_IRQS 21#ifndef NR_BOARD_IRQS
23#define NR_BOARD_IRQS 0 22#define NR_BOARD_IRQS 0
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
index 38f99710752b..cf62b69cb69a 100644
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -14,7 +14,6 @@
14#ifndef __ASM_IBM4XX_H__ 14#ifndef __ASM_IBM4XX_H__
15#define __ASM_IBM4XX_H__ 15#define __ASM_IBM4XX_H__
16 16
17#include <linux/config.h>
18#include <asm/types.h> 17#include <asm/types.h>
19 18
20#ifdef CONFIG_40x 19#ifdef CONFIG_40x
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index b919d8fb7d98..89c6f1bc3aab 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -2,7 +2,6 @@
2#ifndef _PPC_IO_H 2#ifndef _PPC_IO_H
3#define _PPC_IO_H 3#define _PPC_IO_H
4 4
5#include <linux/config.h>
6#include <linux/string.h> 5#include <linux/string.h>
7#include <linux/types.h> 6#include <linux/types.h>
8 7
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index e1a0a7b213d7..da7746738aee 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -2,7 +2,6 @@
2#ifndef _PPC_MACHDEP_H 2#ifndef _PPC_MACHDEP_H
3#define _PPC_MACHDEP_H 3#define _PPC_MACHDEP_H
4 4
5#include <linux/config.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/kexec.h> 6#include <linux/kexec.h>
8 7
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
index 9205db404c7a..0a70b05b3afb 100644
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -6,7 +6,6 @@
6#ifndef _PPC_MMU_H_ 6#ifndef _PPC_MMU_H_
7#define _PPC_MMU_H_ 7#define _PPC_MMU_H_
8 8
9#include <linux/config.h>
10 9
11#ifndef __ASSEMBLY__ 10#ifndef __ASSEMBLY__
12 11
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index 4f152cca13c1..94f2bf71310d 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -2,7 +2,6 @@
2#ifndef __PPC_MMU_CONTEXT_H 2#ifndef __PPC_MMU_CONTEXT_H
3#define __PPC_MMU_CONTEXT_H 3#define __PPC_MMU_CONTEXT_H
4 4
5#include <linux/config.h>
6#include <asm/atomic.h> 5#include <asm/atomic.h>
7#include <asm/bitops.h> 6#include <asm/bitops.h>
8#include <asm/mmu.h> 7#include <asm/mmu.h>
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 6ba69a86b9dd..4b93481e7679 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -8,7 +8,6 @@
8#ifndef __ASM_PPC_MPC8260_H__ 8#ifndef __ASM_PPC_MPC8260_H__
9#define __ASM_PPC_MPC8260_H__ 9#define __ASM_PPC_MPC8260_H__
10 10
11#include <linux/config.h>
12 11
13#ifdef CONFIG_8260 12#ifdef CONFIG_8260
14 13
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 3c23fc43bfbc..02ed2c325714 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -17,7 +17,6 @@
17#ifndef __ASM_MPC83xx_H__ 17#ifndef __ASM_MPC83xx_H__
18#define __ASM_MPC83xx_H__ 18#define __ASM_MPC83xx_H__
19 19
20#include <linux/config.h>
21#include <asm/mmu.h> 20#include <asm/mmu.h>
22 21
23#ifdef CONFIG_83xx 22#ifdef CONFIG_83xx
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index f47002a60edf..c25bdd9debf8 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -17,7 +17,6 @@
17#ifndef __ASM_MPC85xx_H__ 17#ifndef __ASM_MPC85xx_H__
18#define __ASM_MPC85xx_H__ 18#define __ASM_MPC85xx_H__
19 19
20#include <linux/config.h>
21#include <asm/mmu.h> 20#include <asm/mmu.h>
22 21
23#ifdef CONFIG_85xx 22#ifdef CONFIG_85xx
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 3515a7fa6c89..adcce33f20ae 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -8,7 +8,6 @@
8#ifndef __CONFIG_8xx_DEFS 8#ifndef __CONFIG_8xx_DEFS
9#define __CONFIG_8xx_DEFS 9#define __CONFIG_8xx_DEFS
10 10
11#include <linux/config.h>
12 11
13#ifdef CONFIG_8xx 12#ifdef CONFIG_8xx
14 13
diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
index 4f2405b83612..663edbee3e91 100644
--- a/include/asm-ppc/mv64x60.h
+++ b/include/asm-ppc/mv64x60.h
@@ -17,7 +17,6 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/config.h>
21 20
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
23#include <asm/io.h> 22#include <asm/io.h>
diff --git a/include/asm-ppc/ocp.h b/include/asm-ppc/ocp.h
index 983116f59d90..3be5d760ffcd 100644
--- a/include/asm-ppc/ocp.h
+++ b/include/asm-ppc/ocp.h
@@ -26,7 +26,6 @@
26 26
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/config.h>
30#include <linux/devfs_fs_kernel.h> 29#include <linux/devfs_fs_kernel.h>
31#include <linux/device.h> 30#include <linux/device.h>
32 31
diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
index ec2f46629ca2..a4fe962d9f73 100644
--- a/include/asm-ppc/open_pic.h
+++ b/include/asm-ppc/open_pic.h
@@ -12,7 +12,6 @@
12#ifndef _PPC_KERNEL_OPEN_PIC_H 12#ifndef _PPC_KERNEL_OPEN_PIC_H
13#define _PPC_KERNEL_OPEN_PIC_H 13#define _PPC_KERNEL_OPEN_PIC_H
14 14
15#include <linux/config.h>
16#include <linux/irq.h> 15#include <linux/irq.h>
17 16
18#define OPENPIC_SIZE 0x40000 17#define OPENPIC_SIZE 0x40000
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index 0fb68a0b0181..0b19af82507f 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -1,7 +1,6 @@
1#ifndef _PPC_PAGE_H 1#ifndef _PPC_PAGE_H
2#define _PPC_PAGE_H 2#define _PPC_PAGE_H
3 3
4#include <linux/config.h>
5#include <asm/asm-compat.h> 4#include <asm/asm-compat.h>
6 5
7/* PAGE_SHIFT determines the page size */ 6/* PAGE_SHIFT determines the page size */
@@ -15,7 +14,6 @@
15#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) 14#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
16 15
17#ifdef __KERNEL__ 16#ifdef __KERNEL__
18#include <linux/config.h>
19 17
20/* This must match what is in arch/ppc/Makefile */ 18/* This must match what is in arch/ppc/Makefile */
21#define PAGE_OFFSET CONFIG_KERNEL_START 19#define PAGE_OFFSET CONFIG_KERNEL_START
diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h
index 8f994f9f8857..81a2d0fdaf00 100644
--- a/include/asm-ppc/pc_serial.h
+++ b/include/asm-ppc/pc_serial.h
@@ -9,7 +9,6 @@
9 * anyone using any of those on a PPC platform. -- paulus 9 * anyone using any of those on a PPC platform. -- paulus
10 */ 10 */
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * This assumes you have a 1.8432 MHz clock for your UART. 14 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-ppc/pgalloc.h b/include/asm-ppc/pgalloc.h
index bdefd1c4a558..44d88a98e87c 100644
--- a/include/asm-ppc/pgalloc.h
+++ b/include/asm-ppc/pgalloc.h
@@ -2,7 +2,6 @@
2#ifndef _PPC_PGALLOC_H 2#ifndef _PPC_PGALLOC_H
3#define _PPC_PGALLOC_H 3#define _PPC_PGALLOC_H
4 4
5#include <linux/config.h>
6#include <linux/threads.h> 5#include <linux/threads.h>
7 6
8extern void __bad_pte(pmd_t *pmd); 7extern void __bad_pte(pmd_t *pmd);
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 570b355162fa..9cb83679836c 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -4,7 +4,6 @@
4 4
5#include <asm-generic/4level-fixup.h> 5#include <asm-generic/4level-fixup.h>
6 6
7#include <linux/config.h>
8 7
9#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
10#include <linux/sched.h> 9#include <linux/sched.h>
diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h
index 46a086fff816..935d1e05366b 100644
--- a/include/asm-ppc/ppc4xx_dma.h
+++ b/include/asm-ppc/ppc4xx_dma.h
@@ -24,7 +24,6 @@
24#ifndef __ASMPPC_PPC4xx_DMA_H 24#ifndef __ASMPPC_PPC4xx_DMA_H
25#define __ASMPPC_PPC4xx_DMA_H 25#define __ASMPPC_PPC4xx_DMA_H
26 26
27#include <linux/config.h>
28#include <linux/types.h> 27#include <linux/types.h>
29#include <asm/mmu.h> 28#include <asm/mmu.h>
30#include <asm/ibm4xx.h> 29#include <asm/ibm4xx.h>
diff --git a/include/asm-ppc/ppc4xx_pic.h b/include/asm-ppc/ppc4xx_pic.h
index c16c7f81cfd8..e44261206f8b 100644
--- a/include/asm-ppc/ppc4xx_pic.h
+++ b/include/asm-ppc/ppc4xx_pic.h
@@ -17,7 +17,6 @@
17#ifndef __PPC4XX_PIC_H__ 17#ifndef __PPC4XX_PIC_H__
18#define __PPC4XX_PIC_H__ 18#define __PPC4XX_PIC_H__
19 19
20#include <linux/config.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <linux/irq.h> 21#include <linux/irq.h>
23 22
diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h
index b74af5461564..8a59f8871f32 100644
--- a/include/asm-ppc/serial.h
+++ b/include/asm-ppc/serial.h
@@ -6,7 +6,6 @@
6#ifndef __ASM_SERIAL_H__ 6#ifndef __ASM_SERIAL_H__
7#define __ASM_SERIAL_H__ 7#define __ASM_SERIAL_H__
8 8
9#include <linux/config.h>
10 9
11#if defined(CONFIG_EV64260) 10#if defined(CONFIG_EV64260)
12#include <platforms/ev64260.h> 11#include <platforms/ev64260.h>
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index 30e9268a888c..0b7fa89589df 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -10,7 +10,6 @@
10#ifndef _PPC_SMP_H 10#ifndef _PPC_SMP_H
11#define _PPC_SMP_H 11#define _PPC_SMP_H
12 12
13#include <linux/config.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/bitops.h> 14#include <linux/bitops.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h
index c86112323c9f..f7eadf6ac806 100644
--- a/include/asm-ppc/time.h
+++ b/include/asm-ppc/time.h
@@ -9,7 +9,6 @@
9#ifndef __ASM_TIME_H__ 9#ifndef __ASM_TIME_H__
10#define __ASM_TIME_H__ 10#define __ASM_TIME_H__
11 11
12#include <linux/config.h>
13#include <linux/types.h> 12#include <linux/types.h>
14#include <linux/rtc.h> 13#include <linux/rtc.h>
15#include <linux/threads.h> 14#include <linux/threads.h>
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index ca092ffb7a95..4d2b126ba159 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -12,7 +12,6 @@
12 * Copyright (C) 1992, Linus Torvalds 12 * Copyright (C) 1992, Linus Torvalds
13 * 13 *
14 */ 14 */
15#include <linux/config.h>
16#include <linux/compiler.h> 15#include <linux/compiler.h>
17 16
18/* 17/*
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h
index dae1dd4fb937..2d09950a9c11 100644
--- a/include/asm-s390/cmb.h
+++ b/include/asm-s390/cmb.h
@@ -47,7 +47,7 @@ struct cmbdata {
47/* reset channel measurement block */ 47/* reset channel measurement block */
48#define BIODASDRESETCMB _IO(DASD_IOCTL_LETTER,34) 48#define BIODASDRESETCMB _IO(DASD_IOCTL_LETTER,34)
49/* read channel measurement data */ 49/* read channel measurement data */
50#define BIODASDREADCMB _IOWR(DASD_IOCTL_LETTER,32,u64) 50#define BIODASDREADCMB _IOWR(DASD_IOCTL_LETTER,32,__u64)
51/* read channel measurement data */ 51/* read channel measurement data */
52#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) 52#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata)
53 53
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h
index 23450ed4b571..7f1ef99fd1e1 100644
--- a/include/asm-s390/debug.h
+++ b/include/asm-s390/debug.h
@@ -9,7 +9,6 @@
9#ifndef DEBUG_H 9#ifndef DEBUG_H
10#define DEBUG_H 10#define DEBUG_H
11 11
12#include <linux/config.h>
13#include <linux/fs.h> 12#include <linux/fs.h>
14#include <linux/string.h> 13#include <linux/string.h>
15 14
diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h
index 6792c559a124..e84b7ef54aac 100644
--- a/include/asm-s390/hardirq.h
+++ b/include/asm-s390/hardirq.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_HARDIRQ_H 12#ifndef __ASM_HARDIRQ_H
13#define __ASM_HARDIRQ_H 13#define __ASM_HARDIRQ_H
14 14
15#include <linux/config.h>
16#include <linux/threads.h> 15#include <linux/threads.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18#include <linux/cache.h> 17#include <linux/cache.h>
diff --git a/include/asm-s390/idals.h b/include/asm-s390/idals.h
index 8038858b86bb..e82c10efe65a 100644
--- a/include/asm-s390/idals.h
+++ b/include/asm-s390/idals.h
@@ -13,7 +13,6 @@
13#ifndef _S390_IDALS_H 13#ifndef _S390_IDALS_H
14#define _S390_IDALS_H 14#define _S390_IDALS_H
15 15
16#include <linux/config.h>
17#include <linux/errno.h> 16#include <linux/errno.h>
18#include <linux/err.h> 17#include <linux/err.h>
19#include <linux/types.h> 18#include <linux/types.h>
diff --git a/include/asm-s390/local.h b/include/asm-s390/local.h
index cf8189009c30..86745a1b29bb 100644
--- a/include/asm-s390/local.h
+++ b/include/asm-s390/local.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_LOCAL_H 1#ifndef _ASM_LOCAL_H
2#define _ASM_LOCAL_H 2#define _ASM_LOCAL_H
3 3
4#include <linux/config.h>
5#include <linux/percpu.h> 4#include <linux/percpu.h>
6#include <asm/atomic.h> 5#include <asm/atomic.h>
7 6
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index bea727904287..596c8b172104 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -124,7 +124,6 @@
124 124
125#ifndef __ASSEMBLY__ 125#ifndef __ASSEMBLY__
126 126
127#include <linux/config.h>
128#include <asm/processor.h> 127#include <asm/processor.h>
129#include <linux/types.h> 128#include <linux/types.h>
130#include <asm/sigp.h> 129#include <asm/sigp.h>
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index 3b1138ac7e79..b2628dc5c490 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -9,7 +9,6 @@
9#ifndef _S390_PAGE_H 9#ifndef _S390_PAGE_H
10#define _S390_PAGE_H 10#define _S390_PAGE_H
11 11
12#include <asm/setup.h>
13#include <asm/types.h> 12#include <asm/types.h>
14 13
15/* PAGE_SHIFT determines the page size */ 14/* PAGE_SHIFT determines the page size */
@@ -20,6 +19,7 @@
20#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) 19#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4)
21 20
22#ifdef __KERNEL__ 21#ifdef __KERNEL__
22#include <asm/setup.h>
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24 24
25#ifndef __s390x__ 25#ifndef __s390x__
@@ -189,9 +189,9 @@ page_get_storage_key(unsigned long addr)
189#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 189#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
190 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 190 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
191 191
192#endif /* __KERNEL__ */
193
194#include <asm-generic/memory_model.h> 192#include <asm-generic/memory_model.h>
195#include <asm-generic/page.h> 193#include <asm-generic/page.h>
196 194
195#endif /* __KERNEL__ */
196
197#endif /* _S390_PAGE_H */ 197#endif /* _S390_PAGE_H */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index e28aaf28e4a8..3002fda89d33 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -13,7 +13,6 @@
13#ifndef _S390_PGALLOC_H 13#ifndef _S390_PGALLOC_H
14#define _S390_PGALLOC_H 14#define _S390_PGALLOC_H
15 15
16#include <linux/config.h>
17#include <linux/threads.h> 16#include <linux/threads.h>
18#include <linux/gfp.h> 17#include <linux/gfp.h>
19#include <linux/mm.h> 18#include <linux/mm.h>
diff --git a/include/asm-s390/posix_types.h b/include/asm-s390/posix_types.h
index 61788de3c0c3..b94c98856e12 100644
--- a/include/asm-s390/posix_types.h
+++ b/include/asm-s390/posix_types.h
@@ -76,24 +76,36 @@ typedef struct {
76} __kernel_fsid_t; 76} __kernel_fsid_t;
77 77
78 78
79#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) 79#ifdef __KERNEL__
80 80
81#ifndef _S390_BITOPS_H 81#undef __FD_SET
82#include <asm/bitops.h> 82static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
83#endif 83{
84 84 unsigned long _tmp = fd / __NFDBITS;
85#undef __FD_SET 85 unsigned long _rem = fd % __NFDBITS;
86#define __FD_SET(fd,fdsetp) set_bit((fd),(fdsetp)->fds_bits) 86 fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
87 87}
88#undef __FD_CLR 88
89#define __FD_CLR(fd,fdsetp) clear_bit((fd),(fdsetp)->fds_bits) 89#undef __FD_CLR
90 90static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
91#undef __FD_ISSET 91{
92#define __FD_ISSET(fd,fdsetp) test_bit((fd),(fdsetp)->fds_bits) 92 unsigned long _tmp = fd / __NFDBITS;
93 unsigned long _rem = fd % __NFDBITS;
94 fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
95}
96
97#undef __FD_ISSET
98static inline int __FD_ISSET(unsigned long fd, const __kernel_fd_set *fdsetp)
99{
100 unsigned long _tmp = fd / __NFDBITS;
101 unsigned long _rem = fd % __NFDBITS;
102 return (fdsetp->fds_bits[_tmp] & (1UL<<_rem)) != 0;
103}
93 104
94#undef __FD_ZERO 105#undef __FD_ZERO
95#define __FD_ZERO(fdsetp) (memset ((fdsetp), 0, sizeof(*(fd_set *)(fdsetp)))) 106#define __FD_ZERO(fdsetp) \
107 ((void) memset ((__ptr_t) (fdsetp), 0, sizeof (__kernel_fd_set)))
96 108
97#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)*/ 109#endif /* __KERNEL__ */
98 110
99#endif 111#endif
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index a949cc077cc7..4d75d77b0f99 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -181,11 +181,8 @@
181#define PTRACE_OLDSETOPTIONS 21 181#define PTRACE_OLDSETOPTIONS 21
182 182
183#ifndef __ASSEMBLY__ 183#ifndef __ASSEMBLY__
184#include <linux/config.h>
185#include <linux/stddef.h> 184#include <linux/stddef.h>
186#include <linux/types.h> 185#include <linux/types.h>
187#include <asm/setup.h>
188#include <asm/page.h>
189 186
190typedef union 187typedef union
191{ 188{
@@ -301,6 +298,9 @@ typedef struct
301} s390_regs; 298} s390_regs;
302 299
303#ifdef __KERNEL__ 300#ifdef __KERNEL__
301#include <asm/setup.h>
302#include <asm/page.h>
303
304/* 304/*
305 * The pt_regs struct defines the way the registers are stored on 305 * The pt_regs struct defines the way the registers are stored on
306 * the stack during a system call. 306 * the stack during a system call.
diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h
index 3c79b5384f44..de69dfa46fbb 100644
--- a/include/asm-s390/sfp-machine.h
+++ b/include/asm-s390/sfp-machine.h
@@ -25,7 +25,6 @@
25#ifndef _SFP_MACHINE_H 25#ifndef _SFP_MACHINE_H
26#define _SFP_MACHINE_H 26#define _SFP_MACHINE_H
27 27
28#include <linux/config.h>
29 28
30#define _FP_W_TYPE_SIZE 32 29#define _FP_W_TYPE_SIZE 32
31#define _FP_W_TYPE unsigned long 30#define _FP_W_TYPE unsigned long
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index 444dae5912e6..657646054c5e 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_SMP_H 10#ifndef __ASM_SMP_H
11#define __ASM_SMP_H 11#define __ASM_SMP_H
12 12
13#include <linux/config.h>
14#include <linux/threads.h> 13#include <linux/threads.h>
15#include <linux/cpumask.h> 14#include <linux/cpumask.h>
16#include <linux/bitops.h> 15#include <linux/bitops.h>
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 6a89dbb03c1e..71a0732cd518 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -11,7 +11,6 @@
11#ifndef __ASM_SYSTEM_H 11#ifndef __ASM_SYSTEM_H
12#define __ASM_SYSTEM_H 12#define __ASM_SYSTEM_H
13 13
14#include <linux/config.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <asm/types.h> 15#include <asm/types.h>
17#include <asm/ptrace.h> 16#include <asm/ptrace.h>
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h
index 1bb73b0e61fa..73cd85bebfb2 100644
--- a/include/asm-s390/tlbflush.h
+++ b/include/asm-s390/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _S390_TLBFLUSH_H 1#ifndef _S390_TLBFLUSH_H
2#define _S390_TLBFLUSH_H 2#define _S390_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/processor.h> 5#include <asm/processor.h>
7 6
diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h
index 5738ad63537c..ae2951cc83ac 100644
--- a/include/asm-s390/types.h
+++ b/include/asm-s390/types.h
@@ -58,7 +58,6 @@ typedef __signed__ long saddr_t;
58 58
59#ifndef __ASSEMBLY__ 59#ifndef __ASSEMBLY__
60 60
61#include <linux/config.h>
62 61
63typedef signed char s8; 62typedef signed char s8;
64typedef unsigned char u8; 63typedef unsigned char u8;
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 41c2792ff6b0..e21443d3ea1d 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -392,6 +392,8 @@
392 392
393#endif 393#endif
394 394
395#ifdef __KERNEL__
396
395/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */ 397/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
396 398
397#define __syscall_return(type, res) \ 399#define __syscall_return(type, res) \
@@ -546,7 +548,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
546 __syscall_return(type,__res); \ 548 __syscall_return(type,__res); \
547} 549}
548 550
549#ifdef __KERNEL__
550#define __ARCH_WANT_IPC_PARSE_VERSION 551#define __ARCH_WANT_IPC_PARSE_VERSION
551#define __ARCH_WANT_OLD_READDIR 552#define __ARCH_WANT_OLD_READDIR
552#define __ARCH_WANT_SYS_ALARM 553#define __ARCH_WANT_SYS_ALARM
@@ -573,11 +574,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
573# define __ARCH_WANT_COMPAT_SYS_TIME 574# define __ARCH_WANT_COMPAT_SYS_TIME
574# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 575# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
575# endif 576# endif
576#endif
577 577
578#ifdef __KERNEL_SYSCALLS__ 578#ifdef __KERNEL_SYSCALLS__
579 579
580#include <linux/config.h>
581#include <linux/compiler.h> 580#include <linux/compiler.h>
582#include <linux/types.h> 581#include <linux/types.h>
583#include <asm/ptrace.h> 582#include <asm/ptrace.h>
@@ -625,7 +624,7 @@ asmlinkage long sys_rt_sigaction(int sig,
625 struct sigaction __user *oact, 624 struct sigaction __user *oact,
626 size_t sigsetsize); 625 size_t sigsetsize);
627 626
628#endif 627#endif /* __KERNEL_SYSCALLS__ */
629 628
630/* 629/*
631 * "Conditional" syscalls 630 * "Conditional" syscalls
@@ -635,4 +634,5 @@ asmlinkage long sys_rt_sigaction(int sig,
635 */ 634 */
636#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 635#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
637 636
637#endif /* __KERNEL__ */
638#endif /* _ASM_S390_UNISTD_H_ */ 638#endif /* _ASM_S390_UNISTD_H_ */
diff --git a/include/asm-s390/vtoc.h b/include/asm-s390/vtoc.h
index d1de5b7ebb0b..3a5267d90d29 100644
--- a/include/asm-s390/vtoc.h
+++ b/include/asm-s390/vtoc.h
@@ -177,27 +177,27 @@ struct vtoc_format7_label
177} __attribute__ ((packed)); 177} __attribute__ ((packed));
178 178
179struct vtoc_cms_label { 179struct vtoc_cms_label {
180 u8 label_id[4]; /* Label identifier */ 180 __u8 label_id[4]; /* Label identifier */
181 u8 vol_id[6]; /* Volid */ 181 __u8 vol_id[6]; /* Volid */
182 u16 version_id; /* Version identifier */ 182 __u16 version_id; /* Version identifier */
183 u32 block_size; /* Disk block size */ 183 __u32 block_size; /* Disk block size */
184 u32 origin_ptr; /* Disk origin pointer */ 184 __u32 origin_ptr; /* Disk origin pointer */
185 u32 usable_count; /* Number of usable cylinders/blocks */ 185 __u32 usable_count; /* Number of usable cylinders/blocks */
186 u32 formatted_count; /* Maximum number of formatted cylinders/ 186 __u32 formatted_count; /* Maximum number of formatted cylinders/
187 * blocks */ 187 * blocks */
188 u32 block_count; /* Disk size in CMS blocks */ 188 __u32 block_count; /* Disk size in CMS blocks */
189 u32 used_count; /* Number of CMS blocks in use */ 189 __u32 used_count; /* Number of CMS blocks in use */
190 u32 fst_size; /* File Status Table (FST) size */ 190 __u32 fst_size; /* File Status Table (FST) size */
191 u32 fst_count; /* Number of FSTs per CMS block */ 191 __u32 fst_count; /* Number of FSTs per CMS block */
192 u8 format_date[6]; /* Disk FORMAT date */ 192 __u8 format_date[6]; /* Disk FORMAT date */
193 u8 reserved1[2]; 193 __u8 reserved1[2];
194 u32 disk_offset; /* Disk offset when reserved*/ 194 __u32 disk_offset; /* Disk offset when reserved*/
195 u32 map_block; /* Allocation Map Block with next hole */ 195 __u32 map_block; /* Allocation Map Block with next hole */
196 u32 hblk_disp; /* Displacement into HBLK data of next hole */ 196 __u32 hblk_disp; /* Displacement into HBLK data of next hole */
197 u32 user_disp; /* Displacement into user part of Allocation 197 __u32 user_disp; /* Displacement into user part of Allocation
198 * map */ 198 * map */
199 u8 reserved2[4]; 199 __u8 reserved2[4];
200 u8 segment_name[8]; /* Name of shared segment */ 200 __u8 segment_name[8]; /* Name of shared segment */
201} __attribute__ ((packed)); 201} __attribute__ ((packed));
202 202
203#endif /* _ASM_S390_VTOC_H */ 203#endif /* _ASM_S390_VTOC_H */
diff --git a/include/asm-s390/z90crypt.h b/include/asm-s390/z90crypt.h
new file mode 100644
index 000000000000..31a2439b07bd
--- /dev/null
+++ b/include/asm-s390/z90crypt.h
@@ -0,0 +1,212 @@
1/*
2 * include/asm-s390/z90crypt.h
3 *
4 * z90crypt 1.3.3 (user-visible header)
5 *
6 * Copyright (C) 2001, 2005 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef __ASM_S390_Z90CRYPT_H
28#define __ASM_S390_Z90CRYPT_H
29#include <linux/ioctl.h>
30
31#define z90crypt_VERSION 1
32#define z90crypt_RELEASE 3 // 2 = PCIXCC, 3 = rewrite for coding standards
33#define z90crypt_VARIANT 3 // 3 = CEX2A support
34
35/**
36 * struct ica_rsa_modexpo
37 *
38 * Requirements:
39 * - outputdatalength is at least as large as inputdatalength.
40 * - All key parts are right justified in their fields, padded on
41 * the left with zeroes.
42 * - length(b_key) = inputdatalength
43 * - length(n_modulus) = inputdatalength
44 */
45struct ica_rsa_modexpo {
46 char __user * inputdata;
47 unsigned int inputdatalength;
48 char __user * outputdata;
49 unsigned int outputdatalength;
50 char __user * b_key;
51 char __user * n_modulus;
52};
53
54/**
55 * struct ica_rsa_modexpo_crt
56 *
57 * Requirements:
58 * - inputdatalength is even.
59 * - outputdatalength is at least as large as inputdatalength.
60 * - All key parts are right justified in their fields, padded on
61 * the left with zeroes.
62 * - length(bp_key) = inputdatalength/2 + 8
63 * - length(bq_key) = inputdatalength/2
64 * - length(np_key) = inputdatalength/2 + 8
65 * - length(nq_key) = inputdatalength/2
66 * - length(u_mult_inv) = inputdatalength/2 + 8
67 */
68struct ica_rsa_modexpo_crt {
69 char __user * inputdata;
70 unsigned int inputdatalength;
71 char __user * outputdata;
72 unsigned int outputdatalength;
73 char __user * bp_key;
74 char __user * bq_key;
75 char __user * np_prime;
76 char __user * nq_prime;
77 char __user * u_mult_inv;
78};
79
80#define Z90_IOCTL_MAGIC 'z' // NOTE: Need to allocate from linux folks
81
82/**
83 * Interface notes:
84 *
85 * The ioctl()s which are implemented (along with relevant details)
86 * are:
87 *
88 * ICARSAMODEXPO
89 * Perform an RSA operation using a Modulus-Exponent pair
90 * This takes an ica_rsa_modexpo struct as its arg.
91 *
92 * NOTE: please refer to the comments preceding this structure
93 * for the implementation details for the contents of the
94 * block
95 *
96 * ICARSACRT
97 * Perform an RSA operation using a Chinese-Remainder Theorem key
98 * This takes an ica_rsa_modexpo_crt struct as its arg.
99 *
100 * NOTE: please refer to the comments preceding this structure
101 * for the implementation details for the contents of the
102 * block
103 *
104 * Z90STAT_TOTALCOUNT
105 * Return an integer count of all device types together.
106 *
107 * Z90STAT_PCICACOUNT
108 * Return an integer count of all PCICAs.
109 *
110 * Z90STAT_PCICCCOUNT
111 * Return an integer count of all PCICCs.
112 *
113 * Z90STAT_PCIXCCMCL2COUNT
114 * Return an integer count of all MCL2 PCIXCCs.
115 *
116 * Z90STAT_PCIXCCMCL3COUNT
117 * Return an integer count of all MCL3 PCIXCCs.
118 *
119 * Z90STAT_CEX2CCOUNT
120 * Return an integer count of all CEX2Cs.
121 *
122 * Z90STAT_CEX2ACOUNT
123 * Return an integer count of all CEX2As.
124 *
125 * Z90STAT_REQUESTQ_COUNT
126 * Return an integer count of the number of entries waiting to be
127 * sent to a device.
128 *
129 * Z90STAT_PENDINGQ_COUNT
130 * Return an integer count of the number of entries sent to a
131 * device awaiting the reply.
132 *
133 * Z90STAT_TOTALOPEN_COUNT
134 * Return an integer count of the number of open file handles.
135 *
136 * Z90STAT_DOMAIN_INDEX
137 * Return the integer value of the Cryptographic Domain.
138 *
139 * Z90STAT_STATUS_MASK
140 * Return an 64 element array of unsigned chars for the status of
141 * all devices.
142 * 0x01: PCICA
143 * 0x02: PCICC
144 * 0x03: PCIXCC_MCL2
145 * 0x04: PCIXCC_MCL3
146 * 0x05: CEX2C
147 * 0x06: CEX2A
148 * 0x0d: device is disabled via the proc filesystem
149 *
150 * Z90STAT_QDEPTH_MASK
151 * Return an 64 element array of unsigned chars for the queue
152 * depth of all devices.
153 *
154 * Z90STAT_PERDEV_REQCNT
155 * Return an 64 element array of unsigned integers for the number
156 * of successfully completed requests per device since the device
157 * was detected and made available.
158 *
159 * ICAZ90STATUS (deprecated)
160 * Return some device driver status in a ica_z90_status struct
161 * This takes an ica_z90_status struct as its arg.
162 *
163 * NOTE: this ioctl() is deprecated, and has been replaced with
164 * single ioctl()s for each type of status being requested
165 *
166 * Z90STAT_PCIXCCCOUNT (deprecated)
167 * Return an integer count of all PCIXCCs (MCL2 + MCL3).
168 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
169 * MCL2 PCIXCCs.
170 *
171 * Z90QUIESCE (not recommended)
172 * Quiesce the driver. This is intended to stop all new
173 * requests from being processed. Its use is NOT recommended,
174 * except in circumstances where there is no other way to stop
175 * callers from accessing the driver. Its original use was to
176 * allow the driver to be "drained" of work in preparation for
177 * a system shutdown.
178 *
179 * NOTE: once issued, this ban on new work cannot be undone
180 * except by unloading and reloading the driver.
181 */
182
183/**
184 * Supported ioctl calls
185 */
186#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x05, 0)
187#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x06, 0)
188
189/* DEPRECATED status calls (bound for removal at some point) */
190#define ICAZ90STATUS _IOR(Z90_IOCTL_MAGIC, 0x10, struct ica_z90_status)
191#define Z90STAT_PCIXCCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x43, int)
192
193/* unrelated to ICA callers */
194#define Z90QUIESCE _IO(Z90_IOCTL_MAGIC, 0x11)
195
196/* New status calls */
197#define Z90STAT_TOTALCOUNT _IOR(Z90_IOCTL_MAGIC, 0x40, int)
198#define Z90STAT_PCICACOUNT _IOR(Z90_IOCTL_MAGIC, 0x41, int)
199#define Z90STAT_PCICCCOUNT _IOR(Z90_IOCTL_MAGIC, 0x42, int)
200#define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int)
201#define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int)
202#define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int)
203#define Z90STAT_CEX2ACOUNT _IOR(Z90_IOCTL_MAGIC, 0x4e, int)
204#define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int)
205#define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int)
206#define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
207#define Z90STAT_DOMAIN_INDEX _IOR(Z90_IOCTL_MAGIC, 0x47, int)
208#define Z90STAT_STATUS_MASK _IOR(Z90_IOCTL_MAGIC, 0x48, char[64])
209#define Z90STAT_QDEPTH_MASK _IOR(Z90_IOCTL_MAGIC, 0x49, char[64])
210#define Z90STAT_PERDEV_REQCNT _IOR(Z90_IOCTL_MAGIC, 0x4a, int[64])
211
212#endif /* __ASM_S390_Z90CRYPT_H */
diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h
index 70508a360cd6..1b4fc52a59e8 100644
--- a/include/asm-sh/bug.h
+++ b/include/asm-sh/bug.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH_BUG_H 1#ifndef __ASM_SH_BUG_H
2#define __ASM_SH_BUG_H 2#define __ASM_SH_BUG_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_BUG 5#ifdef CONFIG_BUG
7/* 6/*
diff --git a/include/asm-sh/checksum.h b/include/asm-sh/checksum.h
index 5ebd0f24299e..fa03b30c4269 100644
--- a/include/asm-sh/checksum.h
+++ b/include/asm-sh/checksum.h
@@ -9,7 +9,6 @@
9 * Copyright (C) 1999 by Kaz Kojima & Niibe Yutaka 9 * Copyright (C) 1999 by Kaz Kojima & Niibe Yutaka
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/in6.h> 12#include <linux/in6.h>
14 13
15/* 14/*
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 48f1f42c5d14..124968f9866e 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH_DMA_MAPPING_H 1#ifndef __ASM_SH_DMA_MAPPING_H
2#define __ASM_SH_DMA_MAPPING_H 2#define __ASM_SH_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/scatterlist.h> 5#include <asm/scatterlist.h>
7#include <asm/cacheflush.h> 6#include <asm/cacheflush.h>
diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h
index a118a0d43053..e62a6d0ed932 100644
--- a/include/asm-sh/dma.h
+++ b/include/asm-sh/dma.h
@@ -11,7 +11,6 @@
11#define __ASM_SH_DMA_H 11#define __ASM_SH_DMA_H
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
16#include <linux/wait.h> 15#include <linux/wait.h>
17#include <linux/sysdev.h> 16#include <linux/sysdev.h>
diff --git a/include/asm-sh/fixmap.h b/include/asm-sh/fixmap.h
index 509224bdba28..412bccaa07e6 100644
--- a/include/asm-sh/fixmap.h
+++ b/include/asm-sh/fixmap.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_FIXMAP_H 13#ifndef _ASM_FIXMAP_H
14#define _ASM_FIXMAP_H 14#define _ASM_FIXMAP_H
15 15
16#include <linux/config.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <asm/page.h> 17#include <asm/page.h>
19#ifdef CONFIG_HIGHMEM 18#ifdef CONFIG_HIGHMEM
diff --git a/include/asm-sh/hardirq.h b/include/asm-sh/hardirq.h
index f2fdf0f760e5..715ee237fc77 100644
--- a/include/asm-sh/hardirq.h
+++ b/include/asm-sh/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH_HARDIRQ_H 1#ifndef __ASM_SH_HARDIRQ_H
2#define __ASM_SH_HARDIRQ_H 2#define __ASM_SH_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/irq.h> 5#include <linux/irq.h>
7 6
diff --git a/include/asm-sh/hd64461/hd64461.h b/include/asm-sh/hd64461/hd64461.h
index c457ca277a42..87f13d24c630 100644
--- a/include/asm-sh/hd64461/hd64461.h
+++ b/include/asm-sh/hd64461/hd64461.h
@@ -5,7 +5,6 @@
5 * Copyright (C) 2000 YAEGASHI Takeshi 5 * Copyright (C) 2000 YAEGASHI Takeshi
6 * Hitachi HD64461 companion chip support 6 * Hitachi HD64461 companion chip support
7 */ 7 */
8#include <linux/config.h>
9 8
10/* Constants for PCMCIA mappings */ 9/* Constants for PCMCIA mappings */
11#define HD64461_PCC_WINDOW 0x01000000 10#define HD64461_PCC_WINDOW 0x01000000
diff --git a/include/asm-sh/hd64465/hd64465.h b/include/asm-sh/hd64465/hd64465.h
index c672032b72c9..cfd0e803d2a2 100644
--- a/include/asm-sh/hd64465/hd64465.h
+++ b/include/asm-sh/hd64465/hd64465.h
@@ -11,7 +11,6 @@
11 * Derived from <asm/hd64461.h> which bore the message: 11 * Derived from <asm/hd64461.h> which bore the message:
12 * Copyright (C) 2000 YAEGASHI Takeshi 12 * Copyright (C) 2000 YAEGASHI Takeshi
13 */ 13 */
14#include <linux/config.h>
15#include <asm/io.h> 14#include <asm/io.h>
16#include <asm/irq.h> 15#include <asm/irq.h>
17 16
diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h
index 711dad4cb48b..9f8e9142dc33 100644
--- a/include/asm-sh/ide.h
+++ b/include/asm-sh/ide.h
@@ -14,7 +14,6 @@
14 14
15#ifdef __KERNEL__ 15#ifdef __KERNEL__
16 16
17#include <linux/config.h>
18 17
19#define ide_default_io_ctl(base) (0) 18#define ide_default_io_ctl(base) (0)
20 19
diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h
index 2c3afe71323d..894e64b2d5f0 100644
--- a/include/asm-sh/io.h
+++ b/include/asm-sh/io.h
@@ -23,7 +23,6 @@
23 * inb by default expands to _inb, but the machine specific code may 23 * inb by default expands to _inb, but the machine specific code may
24 * define it to __inb if it chooses. 24 * define it to __inb if it chooses.
25 */ 25 */
26#include <linux/config.h>
27#include <asm/cache.h> 26#include <asm/cache.h>
28#include <asm/system.h> 27#include <asm/system.h>
29#include <asm/addrspace.h> 28#include <asm/addrspace.h>
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 42b8394c04ed..611e67cd0627 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -11,7 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <asm/machvec.h> 14#include <asm/machvec.h>
16#include <asm/ptrace.h> /* for pt_regs */ 15#include <asm/ptrace.h> /* for pt_regs */
17 16
diff --git a/include/asm-sh/keyboard.h b/include/asm-sh/keyboard.h
index 1103df003243..31dcc4fa5f28 100644
--- a/include/asm-sh/keyboard.h
+++ b/include/asm-sh/keyboard.h
@@ -5,7 +5,6 @@
5 */ 5 */
6 6
7#include <linux/kd.h> 7#include <linux/kd.h>
8#include <linux/config.h>
9#include <asm/machvec.h> 8#include <asm/machvec.h>
10 9
11#ifdef CONFIG_SH_MPC1211 10#ifdef CONFIG_SH_MPC1211
diff --git a/include/asm-sh/kmap_types.h b/include/asm-sh/kmap_types.h
index 2492ba07148f..84d565c696be 100644
--- a/include/asm-sh/kmap_types.h
+++ b/include/asm-sh/kmap_types.h
@@ -3,7 +3,6 @@
3 3
4/* Dummy header just to define km_type. */ 4/* Dummy header just to define km_type. */
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_DEBUG_HIGHMEM 7#ifdef CONFIG_DEBUG_HIGHMEM
9# define D(n) __KM_FENCE_##n , 8# define D(n) __KM_FENCE_##n ,
diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h
index 550c50a7359e..550501fa4fed 100644
--- a/include/asm-sh/machvec.h
+++ b/include/asm-sh/machvec.h
@@ -10,7 +10,6 @@
10#ifndef _ASM_SH_MACHVEC_H 10#ifndef _ASM_SH_MACHVEC_H
11#define _ASM_SH_MACHVEC_H 1 11#define _ASM_SH_MACHVEC_H 1
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/time.h> 14#include <linux/time.h>
16 15
diff --git a/include/asm-sh/machvec_init.h b/include/asm-sh/machvec_init.h
index 9e7de808f7f8..e397798ebd94 100644
--- a/include/asm-sh/machvec_init.h
+++ b/include/asm-sh/machvec_init.h
@@ -12,7 +12,6 @@
12#ifndef __SH_MACHVEC_INIT_H 12#ifndef __SH_MACHVEC_INIT_H
13#define __SH_MACHVEC_INIT_H 13#define __SH_MACHVEC_INIT_H
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * In a GENERIC kernel, we have lots of these vectors floating about, 17 * In a GENERIC kernel, we have lots of these vectors floating about,
diff --git a/include/asm-sh/mpc1211/dma.h b/include/asm-sh/mpc1211/dma.h
index 0a2fdab3e454..e506d1aaa0d0 100644
--- a/include/asm-sh/mpc1211/dma.h
+++ b/include/asm-sh/mpc1211/dma.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_MPC1211_DMA_H 8#ifndef _ASM_MPC1211_DMA_H
9#define _ASM_MPC1211_DMA_H 9#define _ASM_MPC1211_DMA_H
10 10
11#include <linux/config.h>
12#include <linux/spinlock.h> /* And spinlocks */ 11#include <linux/spinlock.h> /* And spinlocks */
13#include <asm/io.h> /* need byte IO */ 12#include <asm/io.h> /* need byte IO */
14#include <linux/delay.h> 13#include <linux/delay.h>
diff --git a/include/asm-sh/overdrive/overdrive.h b/include/asm-sh/overdrive/overdrive.h
index aa62ae68c55c..fc746c244f83 100644
--- a/include/asm-sh/overdrive/overdrive.h
+++ b/include/asm-sh/overdrive/overdrive.h
@@ -6,7 +6,6 @@
6 * 6 *
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#ifndef __OVERDRIVE_H__ 10#ifndef __OVERDRIVE_H__
12#define __OVERDRIVE_H__ 11#define __OVERDRIVE_H__
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 9c89287c3e56..a5559e38744e 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -13,7 +13,6 @@
13 [ P4 control ] 0xE0000000 13 [ P4 control ] 0xE0000000
14 */ 14 */
15 15
16#include <linux/config.h>
17 16
18/* PAGE_SHIFT determines the page size */ 17/* PAGE_SHIFT determines the page size */
19#define PAGE_SHIFT 12 18#define PAGE_SHIFT 12
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index bb0efb31a8cb..dcd23a03683d 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -8,7 +8,6 @@
8 * Copyright (C) 2002, 2003, 2004 Paul Mundt 8 * Copyright (C) 2002, 2003, 2004 Paul Mundt
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <asm/pgtable-2level.h> 11#include <asm/pgtable-2level.h>
13 12
14/* 13/*
diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h
index f51e232d5cd9..8734590d27e8 100644
--- a/include/asm-sh/serial.h
+++ b/include/asm-sh/serial.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_SERIAL_H 7#ifndef _ASM_SERIAL_H
8#define _ASM_SERIAL_H 8#define _ASM_SERIAL_H
9 9
10#include <linux/config.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12 11
13#ifdef CONFIG_SH_EC3104 12#ifdef CONFIG_SH_EC3104
diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h
index f19a8b3b69a6..f57c4fe9692a 100644
--- a/include/asm-sh/smp.h
+++ b/include/asm-sh/smp.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_SH_SMP_H 10#ifndef __ASM_SH_SMP_H
11#define __ASM_SH_SMP_H 11#define __ASM_SH_SMP_H
12 12
13#include <linux/config.h>
14#include <linux/bitops.h> 13#include <linux/bitops.h>
15#include <linux/cpumask.h> 14#include <linux/cpumask.h>
16 15
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index bb0330499bdf..b752e5cbb830 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -6,7 +6,6 @@
6 * Copyright (C) 2002 Paul Mundt 6 * Copyright (C) 2002 Paul Mundt
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11/* 10/*
12 * switch_to() should switch tasks to task nr n, first 11 * switch_to() should switch tasks to task nr n, first
diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h
index 488552f43b2a..3c09dd4ca31c 100644
--- a/include/asm-sh/types.h
+++ b/include/asm-sh/types.h
@@ -35,7 +35,6 @@ typedef unsigned long long __u64;
35 35
36#ifndef __ASSEMBLY__ 36#ifndef __ASSEMBLY__
37 37
38#include <linux/config.h>
39 38
40typedef __signed__ char s8; 39typedef __signed__ char s8;
41typedef unsigned char u8; 40typedef unsigned char u8;
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index 05520cebda12..76b5430cb458 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -304,6 +304,8 @@
304 304
305#define NR_syscalls 293 305#define NR_syscalls 293
306 306
307#ifdef __KERNEL__
308
307/* user-visible error numbers are in the range -1 - -124: see <asm-sh/errno.h> */ 309/* user-visible error numbers are in the range -1 - -124: see <asm-sh/errno.h> */
308 310
309#define __syscall_return(type, res) \ 311#define __syscall_return(type, res) \
@@ -420,7 +422,6 @@ __asm__ __volatile__ ("trapa #0x16" \
420__syscall_return(type,__sc0); \ 422__syscall_return(type,__sc0); \
421} 423}
422 424
423#ifdef __KERNEL__
424#define __ARCH_WANT_IPC_PARSE_VERSION 425#define __ARCH_WANT_IPC_PARSE_VERSION
425#define __ARCH_WANT_OLD_READDIR 426#define __ARCH_WANT_OLD_READDIR
426#define __ARCH_WANT_OLD_STAT 427#define __ARCH_WANT_OLD_STAT
@@ -443,7 +444,6 @@ __syscall_return(type,__sc0); \
443#define __ARCH_WANT_SYS_SIGPENDING 444#define __ARCH_WANT_SYS_SIGPENDING
444#define __ARCH_WANT_SYS_SIGPROCMASK 445#define __ARCH_WANT_SYS_SIGPROCMASK
445#define __ARCH_WANT_SYS_RT_SIGACTION 446#define __ARCH_WANT_SYS_RT_SIGACTION
446#endif
447 447
448#ifdef __KERNEL_SYSCALLS__ 448#ifdef __KERNEL_SYSCALLS__
449 449
@@ -513,7 +513,7 @@ asmlinkage long sys_rt_sigaction(int sig,
513 struct sigaction __user *oact, 513 struct sigaction __user *oact,
514 size_t sigsetsize); 514 size_t sigsetsize);
515 515
516#endif 516#endif /* __KERNEL_SYSCALLS__ */
517 517
518/* 518/*
519 * "Conditional" syscalls 519 * "Conditional" syscalls
@@ -525,4 +525,5 @@ asmlinkage long sys_rt_sigaction(int sig,
525#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 525#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
526#endif 526#endif
527 527
528#endif /* __KERNEL__ */
528#endif /* __ASM_SH_UNISTD_H */ 529#endif /* __ASM_SH_UNISTD_H */
diff --git a/include/asm-sh/watchdog.h b/include/asm-sh/watchdog.h
index f0cf4be21655..09ca41972a11 100644
--- a/include/asm-sh/watchdog.h
+++ b/include/asm-sh/watchdog.h
@@ -13,7 +13,6 @@
13#ifdef __KERNEL__ 13#ifdef __KERNEL__
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/config.h>
17#include <asm/cpu/watchdog.h> 16#include <asm/cpu/watchdog.h>
18#include <asm/io.h> 17#include <asm/io.h>
19 18
diff --git a/include/asm-sh64/bug.h b/include/asm-sh64/bug.h
index 5d659ec28e10..81f722efeb63 100644
--- a/include/asm-sh64/bug.h
+++ b/include/asm-sh64/bug.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH64_BUG_H 1#ifndef __ASM_SH64_BUG_H
2#define __ASM_SH64_BUG_H 2#define __ASM_SH64_BUG_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * Tell the user there is some problem, then force a segfault (in process 6 * Tell the user there is some problem, then force a segfault (in process
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index cc9a2e86f5b4..a74a49e47922 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH_DMA_MAPPING_H 1#ifndef __ASM_SH_DMA_MAPPING_H
2#define __ASM_SH_DMA_MAPPING_H 2#define __ASM_SH_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/scatterlist.h> 5#include <asm/scatterlist.h>
7#include <asm/io.h> 6#include <asm/io.h>
diff --git a/include/asm-sh64/hardirq.h b/include/asm-sh64/hardirq.h
index ad2330e41fd5..555fd7a35108 100644
--- a/include/asm-sh64/hardirq.h
+++ b/include/asm-sh64/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SH64_HARDIRQ_H 1#ifndef __ASM_SH64_HARDIRQ_H
2#define __ASM_SH64_HARDIRQ_H 2#define __ASM_SH64_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/irq.h> 5#include <linux/irq.h>
7 6
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index 852f50afe39c..c9d84d5f772e 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -15,7 +15,6 @@
15 15
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/config.h>
19 18
20/* Without this, the initialisation of PCI IDE cards end up calling 19/* Without this, the initialisation of PCI IDE cards end up calling
21 * ide_init_hwif_ports, which won't work. */ 20 * ide_init_hwif_ports, which won't work. */
diff --git a/include/asm-sh64/irq.h b/include/asm-sh64/irq.h
index f815b43df845..1ca49e29288a 100644
--- a/include/asm-sh64/irq.h
+++ b/include/asm-sh64/irq.h
@@ -12,7 +12,6 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/config.h>
16 15
17/* 16/*
18 * Encoded IRQs are not considered worth to be supported. 17 * Encoded IRQs are not considered worth to be supported.
diff --git a/include/asm-sh64/mmu_context.h b/include/asm-sh64/mmu_context.h
index 991cfda4cdf6..8c860dab2d0e 100644
--- a/include/asm-sh64/mmu_context.h
+++ b/include/asm-sh64/mmu_context.h
@@ -26,7 +26,6 @@
26 */ 26 */
27extern unsigned long mmu_context_cache; 27extern unsigned long mmu_context_cache;
28 28
29#include <linux/config.h>
30#include <asm/page.h> 29#include <asm/page.h>
31 30
32 31
diff --git a/include/asm-sh64/page.h b/include/asm-sh64/page.h
index e4937cdabebd..34fb34754ae6 100644
--- a/include/asm-sh64/page.h
+++ b/include/asm-sh64/page.h
@@ -17,7 +17,6 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/config.h>
21 20
22/* PAGE_SHIFT determines the page size */ 21/* PAGE_SHIFT determines the page size */
23#define PAGE_SHIFT 12 22#define PAGE_SHIFT 12
diff --git a/include/asm-sh64/param.h b/include/asm-sh64/param.h
index d18cc87c1a80..f409adb41540 100644
--- a/include/asm-sh64/param.h
+++ b/include/asm-sh64/param.h
@@ -12,7 +12,6 @@
12#ifndef __ASM_SH64_PARAM_H 12#ifndef __ASM_SH64_PARAM_H
13#define __ASM_SH64_PARAM_H 13#define __ASM_SH64_PARAM_H
14 14
15#include <linux/config.h>
16 15
17#ifdef __KERNEL__ 16#ifdef __KERNEL__
18# ifdef CONFIG_SH_WDT 17# ifdef CONFIG_SH_WDT
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 57af6b3eb271..54c7821893f5 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -22,7 +22,6 @@
22#include <asm/processor.h> 22#include <asm/processor.h>
23#include <asm/page.h> 23#include <asm/page.h>
24#include <linux/threads.h> 24#include <linux/threads.h>
25#include <linux/config.h>
26 25
27struct vm_area_struct; 26struct vm_area_struct;
28 27
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index 3002e988180c..7606f6e1f01e 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <asm/registers.h> 17#include <asm/registers.h>
19#include <asm/processor.h> 18#include <asm/processor.h>
20 19
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h
index 1f8f394ae371..9a1590fffc15 100644
--- a/include/asm-sh64/unistd.h
+++ b/include/asm-sh64/unistd.h
@@ -344,6 +344,8 @@
344#define __NR_inotify_add_watch 319 344#define __NR_inotify_add_watch 319
345#define __NR_inotify_rm_watch 320 345#define __NR_inotify_rm_watch 320
346 346
347#ifdef __KERNEL__
348
347#define NR_syscalls 321 349#define NR_syscalls 321
348 350
349/* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */ 351/* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */
@@ -486,7 +488,6 @@ __asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4 %5 %6" \
486__syscall_return(type,__sc0); \ 488__syscall_return(type,__sc0); \
487} 489}
488 490
489#ifdef __KERNEL__
490#define __ARCH_WANT_IPC_PARSE_VERSION 491#define __ARCH_WANT_IPC_PARSE_VERSION
491#define __ARCH_WANT_OLD_READDIR 492#define __ARCH_WANT_OLD_READDIR
492#define __ARCH_WANT_OLD_STAT 493#define __ARCH_WANT_OLD_STAT
@@ -509,7 +510,6 @@ __syscall_return(type,__sc0); \
509#define __ARCH_WANT_SYS_SIGPENDING 510#define __ARCH_WANT_SYS_SIGPENDING
510#define __ARCH_WANT_SYS_SIGPROCMASK 511#define __ARCH_WANT_SYS_SIGPROCMASK
511#define __ARCH_WANT_SYS_RT_SIGACTION 512#define __ARCH_WANT_SYS_RT_SIGACTION
512#endif
513 513
514#ifdef __KERNEL_SYSCALLS__ 514#ifdef __KERNEL_SYSCALLS__
515 515
@@ -550,7 +550,7 @@ static inline pid_t wait(int * wait_stat)
550{ 550{
551 return waitpid(-1,wait_stat,0); 551 return waitpid(-1,wait_stat,0);
552} 552}
553#endif 553#endif /* __KERNEL_SYSCALLS__ */
554 554
555/* 555/*
556 * "Conditional" syscalls 556 * "Conditional" syscalls
@@ -562,4 +562,5 @@ static inline pid_t wait(int * wait_stat)
562#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 562#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
563#endif 563#endif
564 564
565#endif /* __KERNEL__ */
565#endif /* __ASM_SH64_UNISTD_H */ 566#endif /* __ASM_SH64_UNISTD_H */
diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h
index 0d4b65bd252b..a619a4d97aae 100644
--- a/include/asm-sparc/asmmacro.h
+++ b/include/asm-sparc/asmmacro.h
@@ -6,7 +6,6 @@
6#ifndef _SPARC_ASMMACRO_H 6#ifndef _SPARC_ASMMACRO_H
7#define _SPARC_ASMMACRO_H 7#define _SPARC_ASMMACRO_H
8 8
9#include <linux/config.h>
10#include <asm/btfixup.h> 9#include <asm/btfixup.h>
11#include <asm/asi.h> 10#include <asm/asi.h>
12 11
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
index e1033170bd3a..731fa56e0c37 100644
--- a/include/asm-sparc/atomic.h
+++ b/include/asm-sparc/atomic.h
@@ -10,7 +10,6 @@
10#ifndef __ARCH_SPARC_ATOMIC__ 10#ifndef __ARCH_SPARC_ATOMIC__
11#define __ARCH_SPARC_ATOMIC__ 11#define __ARCH_SPARC_ATOMIC__
12 12
13#include <linux/config.h>
14 13
15typedef struct { volatile int counter; } atomic_t; 14typedef struct { volatile int counter; } atomic_t;
16 15
diff --git a/include/asm-sparc/bugs.h b/include/asm-sparc/bugs.h
index e652f89e0eff..a0f939beeea1 100644
--- a/include/asm-sparc/bugs.h
+++ b/include/asm-sparc/bugs.h
@@ -5,7 +5,6 @@
5 */ 5 */
6 6
7#include <asm/cpudata.h> 7#include <asm/cpudata.h>
8#include <linux/config.h>
9 8
10extern unsigned long loops_per_jiffy; 9extern unsigned long loops_per_jiffy;
11 10
diff --git a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h
index 4901217008c0..fc632f811cd8 100644
--- a/include/asm-sparc/cacheflush.h
+++ b/include/asm-sparc/cacheflush.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC_CACHEFLUSH_H 1#ifndef _SPARC_CACHEFLUSH_H
2#define _SPARC_CACHEFLUSH_H 2#define _SPARC_CACHEFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> /* Common for other includes */ 4#include <linux/mm.h> /* Common for other includes */
6// #include <linux/kernel.h> from pgalloc.h 5// #include <linux/kernel.h> from pgalloc.h
7// #include <linux/sched.h> from pgalloc.h 6// #include <linux/sched.h> from pgalloc.h
diff --git a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h
index 7ec8e9f7ad4f..48aa70eef997 100644
--- a/include/asm-sparc/delay.h
+++ b/include/asm-sparc/delay.h
@@ -7,7 +7,6 @@
7#ifndef __SPARC_DELAY_H 7#ifndef __SPARC_DELAY_H
8#define __SPARC_DELAY_H 8#define __SPARC_DELAY_H
9 9
10#include <linux/config.h>
11#include <asm/cpudata.h> 10#include <asm/cpudata.h>
12 11
13static inline void __delay(unsigned long loops) 12static inline void __delay(unsigned long loops)
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index d7c3b0f0a901..6db83dc93cb7 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_SPARC_DMA_MAPPING_H 1#ifndef _ASM_SPARC_DMA_MAPPING_H
2#define _ASM_SPARC_DMA_MAPPING_H 2#define _ASM_SPARC_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7#include <asm-generic/dma-mapping.h> 6#include <asm-generic/dma-mapping.h>
diff --git a/include/asm-sparc/dma.h b/include/asm-sparc/dma.h
index 8ec206aa5f2e..407b3614468a 100644
--- a/include/asm-sparc/dma.h
+++ b/include/asm-sparc/dma.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_SPARC_DMA_H 7#ifndef _ASM_SPARC_DMA_H
8#define _ASM_SPARC_DMA_H 8#define _ASM_SPARC_DMA_H
9 9
10#include <linux/config.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/types.h> 11#include <linux/types.h>
13 12
diff --git a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
index 4a71d7c1eace..83a3dd15a6ed 100644
--- a/include/asm-sparc/elf.h
+++ b/include/asm-sparc/elf.h
@@ -6,7 +6,6 @@
6 * ELF register definitions.. 6 * ELF register definitions..
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <asm/ptrace.h> 9#include <asm/ptrace.h>
11 10
12#ifdef __KERNEL__ 11#ifdef __KERNEL__
diff --git a/include/asm-sparc/fixmap.h b/include/asm-sparc/fixmap.h
index 9de52b4d2cfb..f18fc0755adf 100644
--- a/include/asm-sparc/fixmap.h
+++ b/include/asm-sparc/fixmap.h
@@ -13,7 +13,6 @@
13#ifndef _ASM_FIXMAP_H 13#ifndef _ASM_FIXMAP_H
14#define _ASM_FIXMAP_H 14#define _ASM_FIXMAP_H
15 15
16#include <linux/config.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <asm/page.h> 17#include <asm/page.h>
19#ifdef CONFIG_HIGHMEM 18#ifdef CONFIG_HIGHMEM
diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h
index 2a668c479f68..4f63ed8df551 100644
--- a/include/asm-sparc/hardirq.h
+++ b/include/asm-sparc/hardirq.h
@@ -7,7 +7,6 @@
7#ifndef __SPARC_HARDIRQ_H 7#ifndef __SPARC_HARDIRQ_H
8#define __SPARC_HARDIRQ_H 8#define __SPARC_HARDIRQ_H
9 9
10#include <linux/config.h>
11#include <linux/threads.h> 10#include <linux/threads.h>
12#include <linux/spinlock.h> 11#include <linux/spinlock.h>
13#include <linux/cache.h> 12#include <linux/cache.h>
diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
index 64d810385ea4..a6d735a1310e 100644
--- a/include/asm-sparc/ide.h
+++ b/include/asm-sparc/ide.h
@@ -11,7 +11,6 @@
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <asm/pgtable.h> 14#include <asm/pgtable.h>
16#include <asm/io.h> 15#include <asm/io.h>
17#include <asm/psr.h> 16#include <asm/psr.h>
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index cee356b0dae3..dbc687403208 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -7,7 +7,6 @@
7#ifndef _SPARC_IRQ_H 7#ifndef _SPARC_IRQ_H
8#define _SPARC_IRQ_H 8#define _SPARC_IRQ_H
9 9
10#include <linux/config.h>
11#include <linux/linkage.h> 10#include <linux/linkage.h>
12#include <linux/threads.h> /* For NR_CPUS */ 11#include <linux/threads.h> /* For NR_CPUS */
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h
index 59b86bc793bf..bd92a78f4937 100644
--- a/include/asm-sparc/mostek.h
+++ b/include/asm-sparc/mostek.h
@@ -9,7 +9,6 @@
9#ifndef _SPARC_MOSTEK_H 9#ifndef _SPARC_MOSTEK_H
10#define _SPARC_MOSTEK_H 10#define _SPARC_MOSTEK_H
11 11
12#include <linux/config.h>
13#include <asm/idprom.h> 12#include <asm/idprom.h>
14#include <asm/io.h> 13#include <asm/io.h>
15 14
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h
index ec3274b7ddf4..5bab8a7c25ce 100644
--- a/include/asm-sparc/page.h
+++ b/include/asm-sparc/page.h
@@ -8,7 +8,6 @@
8#ifndef _SPARC_PAGE_H 8#ifndef _SPARC_PAGE_H
9#define _SPARC_PAGE_H 9#define _SPARC_PAGE_H
10 10
11#include <linux/config.h>
12#ifdef CONFIG_SUN4 11#ifdef CONFIG_SUN4
13#define PAGE_SHIFT 13 12#define PAGE_SHIFT 13
14#else 13#else
diff --git a/include/asm-sparc/pgalloc.h b/include/asm-sparc/pgalloc.h
index 126800acd10d..a449cd4912d1 100644
--- a/include/asm-sparc/pgalloc.h
+++ b/include/asm-sparc/pgalloc.h
@@ -2,7 +2,6 @@
2#ifndef _SPARC_PGALLOC_H 2#ifndef _SPARC_PGALLOC_H
3#define _SPARC_PGALLOC_H 3#define _SPARC_PGALLOC_H
4 4
5#include <linux/config.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/sched.h> 6#include <linux/sched.h>
8 7
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index 9eea8f4d41f0..226c6475c9a2 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -11,7 +11,6 @@
11 11
12#include <asm-generic/4level-fixup.h> 12#include <asm-generic/4level-fixup.h>
13 13
14#include <linux/config.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
16#include <linux/swap.h> 15#include <linux/swap.h>
17#include <asm/types.h> 16#include <asm/types.h>
diff --git a/include/asm-sparc/sfp-machine.h b/include/asm-sparc/sfp-machine.h
index b4ca2d94bf08..ecfc86a4a725 100644
--- a/include/asm-sparc/sfp-machine.h
+++ b/include/asm-sparc/sfp-machine.h
@@ -25,7 +25,6 @@
25#ifndef _SFP_MACHINE_H 25#ifndef _SFP_MACHINE_H
26#define _SFP_MACHINE_H 26#define _SFP_MACHINE_H
27 27
28#include <linux/config.h>
29 28
30#define _FP_W_TYPE_SIZE 32 29#define _FP_W_TYPE_SIZE 32
31#define _FP_W_TYPE unsigned long 30#define _FP_W_TYPE unsigned long
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
index 98c46e3fbe8a..5a1b7e4e7cc9 100644
--- a/include/asm-sparc/smp.h
+++ b/include/asm-sparc/smp.h
@@ -6,7 +6,6 @@
6#ifndef _SPARC_SMP_H 6#ifndef _SPARC_SMP_H
7#define _SPARC_SMP_H 7#define _SPARC_SMP_H
8 8
9#include <linux/config.h>
10#include <linux/threads.h> 9#include <linux/threads.h>
11#include <asm/head.h> 10#include <asm/head.h>
12#include <asm/btfixup.h> 11#include <asm/btfixup.h>
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 58dd162927bb..cb7dda1e5e91 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -1,10 +1,8 @@
1/* $Id: system.h,v 1.86 2001/10/30 04:57:10 davem Exp $ */ 1/* $Id: system.h,v 1.86 2001/10/30 04:57:10 davem Exp $ */
2#include <linux/config.h>
3 2
4#ifndef __SPARC_SYSTEM_H 3#ifndef __SPARC_SYSTEM_H
5#define __SPARC_SYSTEM_H 4#define __SPARC_SYSTEM_H
6 5
7#include <linux/config.h>
8#include <linux/kernel.h> 6#include <linux/kernel.h>
9#include <linux/threads.h> /* NR_CPUS */ 7#include <linux/threads.h> /* NR_CPUS */
10#include <linux/thread_info.h> 8#include <linux/thread_info.h>
diff --git a/include/asm-sparc/timer.h b/include/asm-sparc/timer.h
index b16eb739dddb..cb1fa1d1f184 100644
--- a/include/asm-sparc/timer.h
+++ b/include/asm-sparc/timer.h
@@ -4,7 +4,6 @@
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */ 5 */
6 6
7#include <linux/config.h>
8 7
9#ifndef _SPARC_TIMER_H 8#ifndef _SPARC_TIMER_H
10#define _SPARC_TIMER_H 9#define _SPARC_TIMER_H
diff --git a/include/asm-sparc/tlbflush.h b/include/asm-sparc/tlbflush.h
index 5643ca31ead9..4a3b66618e75 100644
--- a/include/asm-sparc/tlbflush.h
+++ b/include/asm-sparc/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC_TLBFLUSH_H 1#ifndef _SPARC_TLBFLUSH_H
2#define _SPARC_TLBFLUSH_H 2#define _SPARC_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6// #include <asm/processor.h> 5// #include <asm/processor.h>
7 6
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 45a576507785..2553762465ca 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -319,6 +319,7 @@
319#define __NR_set_robust_list 300 319#define __NR_set_robust_list 300
320#define __NR_get_robust_list 301 320#define __NR_get_robust_list 301
321 321
322#ifdef __KERNEL__
322/* WARNING: You MAY NOT add syscall numbers larger than 301, since 323/* WARNING: You MAY NOT add syscall numbers larger than 301, since
323 * all of the syscall tables in the Sparc kernel are 324 * all of the syscall tables in the Sparc kernel are
324 * sized to have 301 entries (starting at zero). Therefore 325 * sized to have 301 entries (starting at zero). Therefore
@@ -455,7 +456,6 @@ errno = -__res; \
455return -1; \ 456return -1; \
456} 457}
457 458
458#ifdef __KERNEL__
459#define __ARCH_WANT_IPC_PARSE_VERSION 459#define __ARCH_WANT_IPC_PARSE_VERSION
460#define __ARCH_WANT_OLD_READDIR 460#define __ARCH_WANT_OLD_READDIR
461#define __ARCH_WANT_STAT64 461#define __ARCH_WANT_STAT64
@@ -477,7 +477,6 @@ return -1; \
477#define __ARCH_WANT_SYS_SIGPENDING 477#define __ARCH_WANT_SYS_SIGPENDING
478#define __ARCH_WANT_SYS_SIGPROCMASK 478#define __ARCH_WANT_SYS_SIGPROCMASK
479#define __ARCH_WANT_SYS_RT_SIGSUSPEND 479#define __ARCH_WANT_SYS_RT_SIGSUSPEND
480#endif
481 480
482#ifdef __KERNEL_SYSCALLS__ 481#ifdef __KERNEL_SYSCALLS__
483 482
@@ -534,4 +533,5 @@ asmlinkage long sys_rt_sigaction(int sig,
534 */ 533 */
535#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 534#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
536 535
536#endif /* __KERNEL__ */
537#endif /* _SPARC_UNISTD_H */ 537#endif /* _SPARC_UNISTD_H */
diff --git a/include/asm-sparc/vac-ops.h b/include/asm-sparc/vac-ops.h
index 9e0172323042..ab6f53b913ea 100644
--- a/include/asm-sparc/vac-ops.h
+++ b/include/asm-sparc/vac-ops.h
@@ -8,7 +8,6 @@
8 * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) 8 * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <asm/sysen.h> 11#include <asm/sysen.h>
13#include <asm/contregs.h> 12#include <asm/contregs.h>
14#include <asm/asi.h> 13#include <asm/asi.h>
diff --git a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h
index 557257eef3f9..096f3d3d90c3 100644
--- a/include/asm-sparc/winmacro.h
+++ b/include/asm-sparc/winmacro.h
@@ -7,7 +7,6 @@
7#ifndef _SPARC_WINMACRO_H 7#ifndef _SPARC_WINMACRO_H
8#define _SPARC_WINMACRO_H 8#define _SPARC_WINMACRO_H
9 9
10#include <linux/config.h>
11#include <asm/ptrace.h> 10#include <asm/ptrace.h>
12 11
13/* Store the register window onto the 8-byte aligned area starting 12/* Store the register window onto the 8-byte aligned area starting
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 468eb48d8142..2f0bec26a695 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -8,7 +8,6 @@
8#ifndef __ARCH_SPARC64_ATOMIC__ 8#ifndef __ARCH_SPARC64_ATOMIC__
9#define __ARCH_SPARC64_ATOMIC__ 9#define __ARCH_SPARC64_ATOMIC__
10 10
11#include <linux/config.h>
12#include <linux/types.h> 11#include <linux/types.h>
13 12
14typedef struct { volatile int counter; } atomic_t; 13typedef struct { volatile int counter; } atomic_t;
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index 71944b0f09de..3d5e1af84723 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -7,7 +7,6 @@
7#ifndef _SPARC64_BITOPS_H 7#ifndef _SPARC64_BITOPS_H
8#define _SPARC64_BITOPS_H 8#define _SPARC64_BITOPS_H
9 9
10#include <linux/config.h>
11#include <linux/compiler.h> 10#include <linux/compiler.h>
12#include <asm/byteorder.h> 11#include <asm/byteorder.h>
13 12
diff --git a/include/asm-sparc64/bugs.h b/include/asm-sparc64/bugs.h
index 360dd04ed8e4..120422fdb02f 100644
--- a/include/asm-sparc64/bugs.h
+++ b/include/asm-sparc64/bugs.h
@@ -4,7 +4,6 @@
4 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) 4 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5 */ 5 */
6 6
7#include <linux/config.h>
8 7
9extern unsigned long loops_per_jiffy; 8extern unsigned long loops_per_jiffy;
10 9
diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h
index b3f61659ba81..745d1ab60371 100644
--- a/include/asm-sparc64/cacheflush.h
+++ b/include/asm-sparc64/cacheflush.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC64_CACHEFLUSH_H 1#ifndef _SPARC64_CACHEFLUSH_H
2#define _SPARC64_CACHEFLUSH_H 2#define _SPARC64_CACHEFLUSH_H
3 3
4#include <linux/config.h>
5#include <asm/page.h> 4#include <asm/page.h>
6 5
7#ifndef __ASSEMBLY__ 6#ifndef __ASSEMBLY__
diff --git a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h
index 2901ea0c342d..a4aae6f80627 100644
--- a/include/asm-sparc64/delay.h
+++ b/include/asm-sparc64/delay.h
@@ -11,7 +11,6 @@
11#ifndef __SPARC64_DELAY_H 11#ifndef __SPARC64_DELAY_H
12#define __SPARC64_DELAY_H 12#define __SPARC64_DELAY_H
13 13
14#include <linux/config.h>
15#include <linux/param.h> 14#include <linux/param.h>
16#include <asm/cpudata.h> 15#include <asm/cpudata.h>
17 16
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a8d39f23d43b..3c2b5bc8650b 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_SPARC64_DMA_MAPPING_H 1#ifndef _ASM_SPARC64_DMA_MAPPING_H
2#define _ASM_SPARC64_DMA_MAPPING_H 2#define _ASM_SPARC64_DMA_MAPPING_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7 6
diff --git a/include/asm-sparc64/dma.h b/include/asm-sparc64/dma.h
index 1aab3c8dce2b..27f65972b3bb 100644
--- a/include/asm-sparc64/dma.h
+++ b/include/asm-sparc64/dma.h
@@ -7,7 +7,6 @@
7#ifndef _ASM_SPARC64_DMA_H 7#ifndef _ASM_SPARC64_DMA_H
8#define _ASM_SPARC64_DMA_H 8#define _ASM_SPARC64_DMA_H
9 9
10#include <linux/config.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/types.h> 11#include <linux/types.h>
13#include <linux/spinlock.h> 12#include <linux/spinlock.h>
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
index 6a95d5d0c576..07ccd6f04b52 100644
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -10,7 +10,6 @@
10#ifndef __ASM_SPARC64_FLOPPY_H 10#ifndef __ASM_SPARC64_FLOPPY_H
11#define __ASM_SPARC64_FLOPPY_H 11#define __ASM_SPARC64_FLOPPY_H
12 12
13#include <linux/config.h>
14#include <linux/init.h> 13#include <linux/init.h>
15 14
16#include <asm/page.h> 15#include <asm/page.h>
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
index c393f815b0be..55149cf933c2 100644
--- a/include/asm-sparc64/ide.h
+++ b/include/asm-sparc64/ide.h
@@ -10,7 +10,6 @@
10 10
11#ifdef __KERNEL__ 11#ifdef __KERNEL__
12 12
13#include <linux/config.h>
14#include <asm/pgalloc.h> 13#include <asm/pgalloc.h>
15#include <asm/io.h> 14#include <asm/io.h>
16#include <asm/spitfire.h> 15#include <asm/spitfire.h>
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
index de33d6e1afb5..fa164d37ee3f 100644
--- a/include/asm-sparc64/irq.h
+++ b/include/asm-sparc64/irq.h
@@ -8,7 +8,6 @@
8#ifndef _SPARC64_IRQ_H 8#ifndef _SPARC64_IRQ_H
9#define _SPARC64_IRQ_H 9#define _SPARC64_IRQ_H
10 10
11#include <linux/config.h>
12#include <linux/linkage.h> 11#include <linux/linkage.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index e4efe652b54b..e9bb26f770ed 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC64_KPROBES_H 1#ifndef _SPARC64_KPROBES_H
2#define _SPARC64_KPROBES_H 2#define _SPARC64_KPROBES_H
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6#include <linux/percpu.h> 5#include <linux/percpu.h>
7 6
diff --git a/include/asm-sparc64/mc146818rtc.h b/include/asm-sparc64/mc146818rtc.h
index 75bd572b35fe..e9c0fcc25c6f 100644
--- a/include/asm-sparc64/mc146818rtc.h
+++ b/include/asm-sparc64/mc146818rtc.h
@@ -4,7 +4,6 @@
4#ifndef __ASM_SPARC64_MC146818RTC_H 4#ifndef __ASM_SPARC64_MC146818RTC_H
5#define __ASM_SPARC64_MC146818RTC_H 5#define __ASM_SPARC64_MC146818RTC_H
6 6
7#include <linux/config.h>
8#include <asm/io.h> 7#include <asm/io.h>
9 8
10#ifndef RTC_PORT 9#ifndef RTC_PORT
diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h
index 2d4f2ea9568a..70af4b6ce136 100644
--- a/include/asm-sparc64/mmu.h
+++ b/include/asm-sparc64/mmu.h
@@ -1,7 +1,6 @@
1#ifndef __MMU_H 1#ifndef __MMU_H
2#define __MMU_H 2#define __MMU_H
3 3
4#include <linux/config.h>
5#include <asm/page.h> 4#include <asm/page.h>
6#include <asm/const.h> 5#include <asm/const.h>
7#include <asm/hypervisor.h> 6#include <asm/hypervisor.h>
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index c754676e13ef..dea3e73f0955 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -9,7 +9,6 @@
9#ifndef __SPARC64_OPLIB_H 9#ifndef __SPARC64_OPLIB_H
10#define __SPARC64_OPLIB_H 10#define __SPARC64_OPLIB_H
11 11
12#include <linux/config.h>
13#include <asm/openprom.h> 12#include <asm/openprom.h>
14 13
15/* OBP version string. */ 14/* OBP version string. */
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index aabb21906724..fdf0ceb76028 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -3,7 +3,6 @@
3#ifndef _SPARC64_PAGE_H 3#ifndef _SPARC64_PAGE_H
4#define _SPARC64_PAGE_H 4#define _SPARC64_PAGE_H
5 5
6#include <linux/config.h>
7#include <asm/const.h> 6#include <asm/const.h>
8 7
9#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB) 8#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
diff --git a/include/asm-sparc64/param.h b/include/asm-sparc64/param.h
index a1cd4974630b..f0125cf5a9df 100644
--- a/include/asm-sparc64/param.h
+++ b/include/asm-sparc64/param.h
@@ -1,7 +1,6 @@
1#ifndef _ASMSPARC64_PARAM_H 1#ifndef _ASMSPARC64_PARAM_H
2#define _ASMSPARC64_PARAM_H 2#define _ASMSPARC64_PARAM_H
3 3
4#include <linux/config.h>
5 4
6#ifdef __KERNEL__ 5#ifdef __KERNEL__
7# define HZ CONFIG_HZ /* Internal kernel timer frequency */ 6# define HZ CONFIG_HZ /* Internal kernel timer frequency */
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
index 12e4a273bd43..010f9cd0a672 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -2,7 +2,6 @@
2#ifndef _SPARC64_PGALLOC_H 2#ifndef _SPARC64_PGALLOC_H
3#define _SPARC64_PGALLOC_H 3#define _SPARC64_PGALLOC_H
4 4
5#include <linux/config.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/sched.h> 6#include <linux/sched.h>
8#include <linux/mm.h> 7#include <linux/mm.h>
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index cd464f469a2c..4e218814bb3c 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -14,7 +14,6 @@
14 14
15#include <asm-generic/pgtable-nopud.h> 15#include <asm-generic/pgtable-nopud.h>
16 16
17#include <linux/config.h>
18#include <linux/compiler.h> 17#include <linux/compiler.h>
19#include <asm/types.h> 18#include <asm/types.h>
20#include <asm/spitfire.h> 19#include <asm/spitfire.h>
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index c6896b88283e..66dd2fa0e319 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -13,7 +13,6 @@
13 */ 13 */
14#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; }) 14#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; })
15 15
16#include <linux/config.h>
17#include <asm/asi.h> 16#include <asm/asi.h>
18#include <asm/a.out.h> 17#include <asm/a.out.h>
19#include <asm/pstate.h> 18#include <asm/pstate.h>
diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h
index df17e47abc1c..c96e6c30f8b0 100644
--- a/include/asm-sparc64/siginfo.h
+++ b/include/asm-sparc64/siginfo.h
@@ -11,7 +11,6 @@
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <linux/compat.h> 14#include <linux/compat.h>
16 15
17#ifdef CONFIG_COMPAT 16#ifdef CONFIG_COMPAT
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index e3059bb4a465..fdc42a14d4e6 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -6,7 +6,6 @@
6 6
7#ifdef __KERNEL__ 7#ifdef __KERNEL__
8#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
9#include <linux/config.h>
10#include <linux/personality.h> 9#include <linux/personality.h>
11#include <linux/types.h> 10#include <linux/types.h>
12#include <linux/compat.h> 11#include <linux/compat.h>
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 89d86ecaab24..388249b751c3 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -6,7 +6,6 @@
6#ifndef _SPARC64_SMP_H 6#ifndef _SPARC64_SMP_H
7#define _SPARC64_SMP_H 7#define _SPARC64_SMP_H
8 8
9#include <linux/config.h>
10#include <linux/threads.h> 9#include <linux/threads.h>
11#include <asm/asi.h> 10#include <asm/asi.h>
12#include <asm/starfire.h> 11#include <asm/starfire.h>
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index 508c416e9d6a..bd5ffc76bc7e 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -6,7 +6,6 @@
6#ifndef __SPARC64_SPINLOCK_H 6#ifndef __SPARC64_SPINLOCK_H
7#define __SPARC64_SPINLOCK_H 7#define __SPARC64_SPINLOCK_H
8 8
9#include <linux/config.h>
10#include <linux/threads.h> /* For NR_CPUS */ 9#include <linux/threads.h> /* For NR_CPUS */
11 10
12#ifndef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index a18ec87a52c1..4ca68600c670 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -2,7 +2,6 @@
2#ifndef __SPARC64_SYSTEM_H 2#ifndef __SPARC64_SYSTEM_H
3#define __SPARC64_SYSTEM_H 3#define __SPARC64_SYSTEM_H
4 4
5#include <linux/config.h>
6#include <asm/ptrace.h> 5#include <asm/ptrace.h>
7#include <asm/processor.h> 6#include <asm/processor.h>
8#include <asm/visasm.h> 7#include <asm/visasm.h>
diff --git a/include/asm-sparc64/timer.h b/include/asm-sparc64/timer.h
index edc8e08c3a39..d435594df786 100644
--- a/include/asm-sparc64/timer.h
+++ b/include/asm-sparc64/timer.h
@@ -9,7 +9,6 @@
9 9
10#include <linux/types.h> 10#include <linux/types.h>
11 11
12#include <linux/config.h>
13 12
14struct sparc64_tick_ops { 13struct sparc64_tick_ops {
15 void (*init_tick)(unsigned long); 14 void (*init_tick)(unsigned long);
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
index 61c01882b562..7af1e1109c49 100644
--- a/include/asm-sparc64/tlb.h
+++ b/include/asm-sparc64/tlb.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC64_TLB_H 1#ifndef _SPARC64_TLB_H
2#define _SPARC64_TLB_H 2#define _SPARC64_TLB_H
3 3
4#include <linux/config.h>
5#include <linux/swap.h> 4#include <linux/swap.h>
6#include <asm/pgalloc.h> 5#include <asm/pgalloc.h>
7#include <asm/tlbflush.h> 6#include <asm/tlbflush.h>
diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h
index e3a7c453b500..3487328570ed 100644
--- a/include/asm-sparc64/tlbflush.h
+++ b/include/asm-sparc64/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _SPARC64_TLBFLUSH_H 1#ifndef _SPARC64_TLBFLUSH_H
2#define _SPARC64_TLBFLUSH_H 2#define _SPARC64_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/mmu_context.h> 5#include <asm/mmu_context.h>
7 6
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
index 2d5e3c464df5..f2352606a79f 100644
--- a/include/asm-sparc64/ttable.h
+++ b/include/asm-sparc64/ttable.h
@@ -2,7 +2,6 @@
2#ifndef _SPARC64_TTABLE_H 2#ifndef _SPARC64_TTABLE_H
3#define _SPARC64_TTABLE_H 3#define _SPARC64_TTABLE_H
4 4
5#include <linux/config.h>
6#include <asm/utrap.h> 5#include <asm/utrap.h>
7 6
8#ifdef __ASSEMBLY__ 7#ifdef __ASSEMBLY__
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 998ef4ab0e06..badc73fdcb97 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -321,6 +321,7 @@
321#define __NR_set_robust_list 300 321#define __NR_set_robust_list 300
322#define __NR_get_robust_list 301 322#define __NR_get_robust_list 301
323 323
324#ifdef __KERNEL__
324/* WARNING: You MAY NOT add syscall numbers larger than 301, since 325/* WARNING: You MAY NOT add syscall numbers larger than 301, since
325 * all of the syscall tables in the Sparc kernel are 326 * all of the syscall tables in the Sparc kernel are
326 * sized to have 301 entries (starting at zero). Therefore 327 * sized to have 301 entries (starting at zero). Therefore
@@ -487,7 +488,6 @@ asmlinkage long sys_rt_sigaction(int sig,
487 488
488#endif /* __KERNEL_SYSCALLS__ */ 489#endif /* __KERNEL_SYSCALLS__ */
489 490
490#ifdef __KERNEL__
491/* sysconf options, for SunOS compatibility */ 491/* sysconf options, for SunOS compatibility */
492#define _SC_ARG_MAX 1 492#define _SC_ARG_MAX 1
493#define _SC_CHILD_MAX 2 493#define _SC_CHILD_MAX 2
@@ -521,7 +521,6 @@ asmlinkage long sys_rt_sigaction(int sig,
521#define __ARCH_WANT_SYS_SIGPROCMASK 521#define __ARCH_WANT_SYS_SIGPROCMASK
522#define __ARCH_WANT_SYS_RT_SIGSUSPEND 522#define __ARCH_WANT_SYS_RT_SIGSUSPEND
523#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 523#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
524#endif
525 524
526/* 525/*
527 * "Conditional" syscalls 526 * "Conditional" syscalls
@@ -531,4 +530,5 @@ asmlinkage long sys_rt_sigaction(int sig,
531 */ 530 */
532#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 531#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
533 532
533#endif /* __KERNEL__ */
534#endif /* _SPARC64_UNISTD_H */ 534#endif /* _SPARC64_UNISTD_H */
diff --git a/include/asm-um/a.out.h b/include/asm-um/a.out.h
index 7c26265e1d7a..50cee7b296f4 100644
--- a/include/asm-um/a.out.h
+++ b/include/asm-um/a.out.h
@@ -1,7 +1,6 @@
1#ifndef __UM_A_OUT_H 1#ifndef __UM_A_OUT_H
2#define __UM_A_OUT_H 2#define __UM_A_OUT_H
3 3
4#include "linux/config.h"
5#include "asm/arch/a.out.h" 4#include "asm/arch/a.out.h"
6#include "choose-mode.h" 5#include "choose-mode.h"
7 6
diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
index 3d0587075521..19e1bdd67416 100644
--- a/include/asm-um/cache.h
+++ b/include/asm-um/cache.h
@@ -1,7 +1,6 @@
1#ifndef __UM_CACHE_H 1#ifndef __UM_CACHE_H
2#define __UM_CACHE_H 2#define __UM_CACHE_H
3 3
4#include <linux/config.h>
5 4
6#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT) 5#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
7# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 6# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
diff --git a/include/asm-um/elf-ppc.h b/include/asm-um/elf-ppc.h
index 2998cf925042..99711134e477 100644
--- a/include/asm-um/elf-ppc.h
+++ b/include/asm-um/elf-ppc.h
@@ -1,7 +1,6 @@
1#ifndef __UM_ELF_PPC_H 1#ifndef __UM_ELF_PPC_H
2#define __UM_ELF_PPC_H 2#define __UM_ELF_PPC_H
3 3
4#include "linux/config.h"
5 4
6extern long elf_aux_hwcap; 5extern long elf_aux_hwcap;
7#define ELF_HWCAP (elf_aux_hwcap) 6#define ELF_HWCAP (elf_aux_hwcap)
diff --git a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
index ae0ca3932d50..d352a35cfafb 100644
--- a/include/asm-um/fixmap.h
+++ b/include/asm-um/fixmap.h
@@ -1,7 +1,6 @@
1#ifndef __UM_FIXMAP_H 1#ifndef __UM_FIXMAP_H
2#define __UM_FIXMAP_H 2#define __UM_FIXMAP_H
3 3
4#include <linux/config.h>
5#include <asm/kmap_types.h> 4#include <asm/kmap_types.h>
6#include <asm/archparam.h> 5#include <asm/archparam.h>
7#include <asm/elf.h> 6#include <asm/elf.h>
diff --git a/include/asm-um/hardirq.h b/include/asm-um/hardirq.h
index 1224b2690a23..313ebb8a2566 100644
--- a/include/asm-um/hardirq.h
+++ b/include/asm-um/hardirq.h
@@ -3,7 +3,6 @@
3#ifndef __ASM_UM_HARDIRQ_H 3#ifndef __ASM_UM_HARDIRQ_H
4#define __ASM_UM_HARDIRQ_H 4#define __ASM_UM_HARDIRQ_H
5 5
6#include <linux/config.h>
7#include <linux/threads.h> 6#include <linux/threads.h>
8#include <linux/irq.h> 7#include <linux/irq.h>
9 8
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
index e3d62dcbd356..78b862472b36 100644
--- a/include/asm-um/linkage.h
+++ b/include/asm-um/linkage.h
@@ -3,7 +3,6 @@
3 3
4#include "asm/arch/linkage.h" 4#include "asm/arch/linkage.h"
5 5
6#include <linux/config.h>
7 6
8/* <linux/linkage.h> will pick sane defaults */ 7/* <linux/linkage.h> will pick sane defaults */
9#ifdef CONFIG_GPROF 8#ifdef CONFIG_GPROF
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 9a0e48eb542e..f709c784bf12 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -7,7 +7,6 @@
7#define __UM_MMU_CONTEXT_H 7#define __UM_MMU_CONTEXT_H
8 8
9#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/config.h"
11#include "choose-mode.h" 10#include "choose-mode.h"
12#include "um_mmu.h" 11#include "um_mmu.h"
13 12
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 41364330aff1..4296d3135aa9 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -9,7 +9,6 @@
9 9
10struct page; 10struct page;
11 11
12#include <linux/config.h>
13#include <asm/vm-flags.h> 12#include <asm/vm-flags.h>
14 13
15/* PAGE_SHIFT determines the page size */ 14/* PAGE_SHIFT determines the page size */
diff --git a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h
index ea49411236dc..34ab268ef40e 100644
--- a/include/asm-um/pgalloc.h
+++ b/include/asm-um/pgalloc.h
@@ -8,7 +8,6 @@
8#ifndef __UM_PGALLOC_H 8#ifndef __UM_PGALLOC_H
9#define __UM_PGALLOC_H 9#define __UM_PGALLOC_H
10 10
11#include "linux/config.h"
12#include "linux/mm.h" 11#include "linux/mm.h"
13#include "asm/fixmap.h" 12#include "asm/fixmap.h"
14 13
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index da07a69ce82a..824c28896382 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -10,7 +10,6 @@ struct pt_regs;
10 10
11struct task_struct; 11struct task_struct;
12 12
13#include "linux/config.h"
14#include "asm/ptrace.h" 13#include "asm/ptrace.h"
15#include "choose-mode.h" 14#include "choose-mode.h"
16#include "registers.h" 15#include "registers.h"
diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
index 503484305e67..a36f5371b36b 100644
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -8,7 +8,6 @@
8 8
9#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
10 10
11#include "linux/config.h"
12 11
13#define pt_regs pt_regs_subarch 12#define pt_regs pt_regs_subarch
14#define show_regs show_regs_subarch 13#define show_regs show_regs_subarch
diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h
index aeda6657f366..ca552261ed1f 100644
--- a/include/asm-um/smp.h
+++ b/include/asm-um/smp.h
@@ -3,7 +3,6 @@
3 3
4#ifdef CONFIG_SMP 4#ifdef CONFIG_SMP
5 5
6#include "linux/config.h"
7#include "linux/bitops.h" 6#include "linux/bitops.h"
8#include "asm/current.h" 7#include "asm/current.h"
9#include "linux/cpumask.h" 8#include "linux/cpumask.h"
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index f166b9837c6a..261e2f4528f6 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -8,7 +8,6 @@
8 8
9#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
10 10
11#include <linux/config.h>
12#include <asm/processor.h> 11#include <asm/processor.h>
13#include <asm/types.h> 12#include <asm/types.h>
14 13
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index 166df00457ea..e4e57de08f73 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -14,7 +14,6 @@
14#ifndef __V850_ATOMIC_H__ 14#ifndef __V850_ATOMIC_H__
15#define __V850_ATOMIC_H__ 15#define __V850_ATOMIC_H__
16 16
17#include <linux/config.h>
18 17
19#include <asm/system.h> 18#include <asm/system.h>
20 19
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 1f6fd5ab4177..1fa99baf4e25 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -14,7 +14,6 @@
14#define __V850_BITOPS_H__ 14#define __V850_BITOPS_H__
15 15
16 16
17#include <linux/config.h>
18#include <linux/compiler.h> /* unlikely */ 17#include <linux/compiler.h> /* unlikely */
19#include <asm/byteorder.h> /* swab32 */ 18#include <asm/byteorder.h> /* swab32 */
20#include <asm/system.h> /* interrupt enable/disable */ 19#include <asm/system.h> /* interrupt enable/disable */
diff --git a/include/asm-v850/dma-mapping.h b/include/asm-v850/dma-mapping.h
index c63fb50ec9ef..1cc42c603a1b 100644
--- a/include/asm-v850/dma-mapping.h
+++ b/include/asm-v850/dma-mapping.h
@@ -1,7 +1,6 @@
1#ifndef __V850_DMA_MAPPING_H__ 1#ifndef __V850_DMA_MAPPING_H__
2#define __V850_DMA_MAPPING_H__ 2#define __V850_DMA_MAPPING_H__
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PCI 5#ifdef CONFIG_PCI
7#include <asm-generic/dma-mapping.h> 6#include <asm-generic/dma-mapping.h>
diff --git a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
index d98488cd5af1..04e20127c5af 100644
--- a/include/asm-v850/hardirq.h
+++ b/include/asm-v850/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __V850_HARDIRQ_H__ 1#ifndef __V850_HARDIRQ_H__
2#define __V850_HARDIRQ_H__ 2#define __V850_HARDIRQ_H__
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/cache.h> 5#include <linux/cache.h>
7 6
diff --git a/include/asm-v850/machdep.h b/include/asm-v850/machdep.h
index 98d8bf63970e..f1e3b8b91508 100644
--- a/include/asm-v850/machdep.h
+++ b/include/asm-v850/machdep.h
@@ -14,7 +14,6 @@
14#ifndef __V850_MACHDEP_H__ 14#ifndef __V850_MACHDEP_H__
15#define __V850_MACHDEP_H__ 15#define __V850_MACHDEP_H__
16 16
17#include <linux/config.h>
18 17
19/* chips */ 18/* chips */
20#ifdef CONFIG_V850E_MA1 19#ifdef CONFIG_V850E_MA1
diff --git a/include/asm-v850/pgtable.h b/include/asm-v850/pgtable.h
index 3cf8775ce85f..1ea2a900f0f8 100644
--- a/include/asm-v850/pgtable.h
+++ b/include/asm-v850/pgtable.h
@@ -3,7 +3,6 @@
3 3
4#include <asm-generic/4level-fixup.h> 4#include <asm-generic/4level-fixup.h>
5 5
6#include <linux/config.h>
7#include <asm/page.h> 6#include <asm/page.h>
8 7
9 8
diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h
index 2d31308935a0..6965b66ccaed 100644
--- a/include/asm-v850/processor.h
+++ b/include/asm-v850/processor.h
@@ -14,7 +14,6 @@
14#ifndef __V850_PROCESSOR_H__ 14#ifndef __V850_PROCESSOR_H__
15#define __V850_PROCESSOR_H__ 15#define __V850_PROCESSOR_H__
16 16
17#include <linux/config.h>
18#ifndef __ASSEMBLY__ /* <linux/thread_info.h> is not asm-safe. */ 17#ifndef __ASSEMBLY__ /* <linux/thread_info.h> is not asm-safe. */
19#include <linux/thread_info.h> 18#include <linux/thread_info.h>
20#endif 19#endif
diff --git a/include/asm-v850/serial.h b/include/asm-v850/serial.h
index 8c2a609ba2b0..36d8f4cbbf39 100644
--- a/include/asm-v850/serial.h
+++ b/include/asm-v850/serial.h
@@ -6,7 +6,6 @@
6 * Copyright (C) 1999 by Ralf Baechle 6 * Copyright (C) 1999 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 */ 8 */
9#include <linux/config.h>
10 9
11#ifdef CONFIG_RTE_CB_ME2 10#ifdef CONFIG_RTE_CB_ME2
12 11
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 82460a7bb233..bcb44bfe577a 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -14,8 +14,6 @@
14#ifndef __V850_UNISTD_H__ 14#ifndef __V850_UNISTD_H__
15#define __V850_UNISTD_H__ 15#define __V850_UNISTD_H__
16 16
17#include <asm/clinkage.h>
18
19#define __NR_restart_syscall 0 17#define __NR_restart_syscall 0
20#define __NR_exit 1 18#define __NR_exit 1
21#define __NR_fork 2 19#define __NR_fork 2
@@ -237,10 +235,9 @@
237 except the syscall number (r12). */ 235 except the syscall number (r12). */
238#define SYSCALL_SHORT_CLOBBERS SYSCALL_CLOBBERS, "r13", "r14" 236#define SYSCALL_SHORT_CLOBBERS SYSCALL_CLOBBERS, "r13", "r14"
239 237
238#ifdef __KERNEL__
240 239
241/* User programs sometimes end up including this header file 240#include <asm/clinkage.h>
242 (indirectly, via uClibc header files), so I'm a bit nervous just
243 including <linux/compiler.h>. */
244 241
245#define __syscall_return(type, res) \ 242#define __syscall_return(type, res) \
246 do { \ 243 do { \
@@ -368,7 +365,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \
368} 365}
369 366
370 367
371#ifdef __KERNEL__
372#define __ARCH_WANT_IPC_PARSE_VERSION 368#define __ARCH_WANT_IPC_PARSE_VERSION
373#define __ARCH_WANT_OLD_READDIR 369#define __ARCH_WANT_OLD_READDIR
374#define __ARCH_WANT_STAT64 370#define __ARCH_WANT_STAT64
@@ -389,7 +385,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \
389#define __ARCH_WANT_SYS_SIGPENDING 385#define __ARCH_WANT_SYS_SIGPENDING
390#define __ARCH_WANT_SYS_SIGPROCMASK 386#define __ARCH_WANT_SYS_SIGPROCMASK
391#define __ARCH_WANT_SYS_RT_SIGACTION 387#define __ARCH_WANT_SYS_RT_SIGACTION
392#endif
393 388
394#ifdef __KERNEL_SYSCALLS__ 389#ifdef __KERNEL_SYSCALLS__
395 390
@@ -440,7 +435,7 @@ asmlinkage long sys_rt_sigaction(int sig,
440 struct sigaction __user *oact, 435 struct sigaction __user *oact,
441 size_t sigsetsize); 436 size_t sigsetsize);
442 437
443#endif 438#endif /* __KERNEL_SYSCALLS__ */
444 439
445/* 440/*
446 * "Conditional" syscalls 441 * "Conditional" syscalls
@@ -455,4 +450,5 @@ asmlinkage long sys_rt_sigaction(int sig,
455 void name (void) __attribute__ ((weak, alias ("sys_ni_syscall"))); 450 void name (void) __attribute__ ((weak, alias ("sys_ni_syscall")));
456#endif 451#endif
457 452
453#endif /* __KERNEL__ */
458#endif /* __V850_UNISTD_H__ */ 454#endif /* __V850_UNISTD_H__ */
diff --git a/include/asm-v850/v850e_uart.h b/include/asm-v850/v850e_uart.h
index 5930d5990b19..5182fb4cc989 100644
--- a/include/asm-v850/v850e_uart.h
+++ b/include/asm-v850/v850e_uart.h
@@ -19,7 +19,6 @@
19#ifndef __V850_V850E_UART_H__ 19#ifndef __V850_V850E_UART_H__
20#define __V850_V850E_UART_H__ 20#define __V850_V850E_UART_H__
21 21
22#include <linux/config.h>
23#include <linux/termios.h> 22#include <linux/termios.h>
24 23
25#include <asm/v850e_utils.h> 24#include <asm/v850e_utils.h>
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
index bdbd8935612a..a731be2204d2 100644
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_APIC_H 1#ifndef __ASM_APIC_H
2#define __ASM_APIC_H 2#define __ASM_APIC_H
3 3
4#include <linux/config.h>
5#include <linux/pm.h> 4#include <linux/pm.h>
6#include <asm/fixmap.h> 5#include <asm/fixmap.h>
7#include <asm/apicdef.h> 6#include <asm/apicdef.h>
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index cecbf7baa6aa..bd3fa67ed835 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -1,7 +1,6 @@
1#ifndef __ARCH_X86_64_ATOMIC__ 1#ifndef __ARCH_X86_64_ATOMIC__
2#define __ARCH_X86_64_ATOMIC__ 2#define __ARCH_X86_64_ATOMIC__
3 3
4#include <linux/config.h>
5#include <asm/types.h> 4#include <asm/types.h>
6 5
7/* atomic_t should be 32 bit signed type */ 6/* atomic_t should be 32 bit signed type */
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 79212128d0f7..e9bf933d25d0 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -5,7 +5,6 @@
5 * Copyright 1992, Linus Torvalds. 5 * Copyright 1992, Linus Torvalds.
6 */ 6 */
7 7
8#include <linux/config.h>
9 8
10#ifdef CONFIG_SMP 9#ifdef CONFIG_SMP
11#define LOCK_PREFIX "lock ; " 10#define LOCK_PREFIX "lock ; "
diff --git a/include/asm-x86_64/bugs.h b/include/asm-x86_64/bugs.h
index 59bc68925d0f..d86c5dd689fa 100644
--- a/include/asm-x86_64/bugs.h
+++ b/include/asm-x86_64/bugs.h
@@ -10,7 +10,6 @@
10 * void check_bugs(void); 10 * void check_bugs(void);
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <asm/processor.h> 13#include <asm/processor.h>
15#include <asm/i387.h> 14#include <asm/i387.h>
16#include <asm/msr.h> 15#include <asm/msr.h>
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index f8dff1c67538..ed8a9d25272d 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -4,7 +4,6 @@
4#ifndef __ARCH_X8664_CACHE_H 4#ifndef __ARCH_X8664_CACHE_H
5#define __ARCH_X8664_CACHE_H 5#define __ARCH_X8664_CACHE_H
6 6
7#include <linux/config.h>
8 7
9/* L1 cache line size */ 8/* L1 cache line size */
10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 9#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
diff --git a/include/asm-x86_64/calling.h b/include/asm-x86_64/calling.h
index fc2c5a6c262a..6f4f63af96e1 100644
--- a/include/asm-x86_64/calling.h
+++ b/include/asm-x86_64/calling.h
@@ -2,7 +2,6 @@
2 * Some macros to handle stack frames in assembly. 2 * Some macros to handle stack frames in assembly.
3 */ 3 */
4 4
5#include <linux/config.h>
6 5
7#define R15 0 6#define R15 0
8#define R14 8 7#define R14 8
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index 49a81a66516e..498f66df36b9 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -6,7 +6,6 @@
6 * documentation. 6 * documentation.
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#include <asm/scatterlist.h> 10#include <asm/scatterlist.h>
12#include <asm/io.h> 11#include <asm/io.h>
diff --git a/include/asm-x86_64/dma.h b/include/asm-x86_64/dma.h
index 6f2a817b6a7c..c556208d3dd7 100644
--- a/include/asm-x86_64/dma.h
+++ b/include/asm-x86_64/dma.h
@@ -8,7 +8,6 @@
8#ifndef _ASM_DMA_H 8#ifndef _ASM_DMA_H
9#define _ASM_DMA_H 9#define _ASM_DMA_H
10 10
11#include <linux/config.h>
12#include <linux/spinlock.h> /* And spinlocks */ 11#include <linux/spinlock.h> /* And spinlocks */
13#include <asm/io.h> /* need byte IO */ 12#include <asm/io.h> /* need byte IO */
14#include <linux/delay.h> 13#include <linux/delay.h>
diff --git a/include/asm-x86_64/dwarf2.h b/include/asm-x86_64/dwarf2.h
index 07654bd155bf..0744db777676 100644
--- a/include/asm-x86_64/dwarf2.h
+++ b/include/asm-x86_64/dwarf2.h
@@ -1,7 +1,6 @@
1#ifndef _DWARF2_H 1#ifndef _DWARF2_H
2#define _DWARF2_H 1 2#define _DWARF2_H 1
3 3
4#include <linux/config.h>
5 4
6#ifndef __ASSEMBLY__ 5#ifndef __ASSEMBLY__
7#warning "asm/dwarf2.h should be only included in pure assembly files" 6#warning "asm/dwarf2.h should be only included in pure assembly files"
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h
index 7b286bd21d1d..0b4ffbd1a125 100644
--- a/include/asm-x86_64/fixmap.h
+++ b/include/asm-x86_64/fixmap.h
@@ -11,7 +11,6 @@
11#ifndef _ASM_FIXMAP_H 11#ifndef _ASM_FIXMAP_H
12#define _ASM_FIXMAP_H 12#define _ASM_FIXMAP_H
13 13
14#include <linux/config.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <asm/apicdef.h> 15#include <asm/apicdef.h>
17#include <asm/page.h> 16#include <asm/page.h>
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
index 8689951e3503..64a65ce2f41f 100644
--- a/include/asm-x86_64/hardirq.h
+++ b/include/asm-x86_64/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_HARDIRQ_H 1#ifndef __ASM_HARDIRQ_H
2#define __ASM_HARDIRQ_H 2#define __ASM_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/threads.h> 4#include <linux/threads.h>
6#include <linux/irq.h> 5#include <linux/irq.h>
7#include <asm/pda.h> 6#include <asm/pda.h>
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 0df1715dee71..3de96fd86a70 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -17,7 +17,6 @@
17 */ 17 */
18 18
19#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
20#include <linux/config.h>
21#include <asm/atomic.h> 20#include <asm/atomic.h>
22#include <asm/irq.h> 21#include <asm/irq.h>
23#include <linux/profile.h> 22#include <linux/profile.h>
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
index e6b7f2234e43..0190b7c4e319 100644
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_X86_64_IA32_H 1#ifndef _ASM_X86_64_IA32_H
2#define _ASM_X86_64_IA32_H 2#define _ASM_X86_64_IA32_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_IA32_EMULATION 5#ifdef CONFIG_IA32_EMULATION
7 6
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index a05da8a50bfd..70e91fe76344 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_IO_H 1#ifndef _ASM_IO_H
2#define _ASM_IO_H 2#define _ASM_IO_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * This file contains the definitions for the x86 IO instructions 6 * This file contains the definitions for the x86 IO instructions
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 52484e82c641..fb7a0909a174 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_IO_APIC_H 1#ifndef __ASM_IO_APIC_H
2#define __ASM_IO_APIC_H 2#define __ASM_IO_APIC_H
3 3
4#include <linux/config.h>
5#include <asm/types.h> 4#include <asm/types.h>
6#include <asm/mpspec.h> 5#include <asm/mpspec.h>
7 6
diff --git a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h
index 19f0c83d0792..af03b9f852d6 100644
--- a/include/asm-x86_64/mmu_context.h
+++ b/include/asm-x86_64/mmu_context.h
@@ -1,7 +1,6 @@
1#ifndef __X86_64_MMU_CONTEXT_H 1#ifndef __X86_64_MMU_CONTEXT_H
2#define __X86_64_MMU_CONTEXT_H 2#define __X86_64_MMU_CONTEXT_H
3 3
4#include <linux/config.h>
5#include <asm/desc.h> 4#include <asm/desc.h>
6#include <asm/atomic.h> 5#include <asm/atomic.h>
7#include <asm/pgalloc.h> 6#include <asm/pgalloc.h>
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 6944e7122df5..70bb9969766e 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -4,7 +4,6 @@
4#ifndef _ASM_X86_64_MMZONE_H 4#ifndef _ASM_X86_64_MMZONE_H
5#define _ASM_X86_64_MMZONE_H 1 5#define _ASM_X86_64_MMZONE_H 1
6 6
7#include <linux/config.h>
8 7
9#ifdef CONFIG_NUMA 8#ifdef CONFIG_NUMA
10 9
diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
index 66ac1c0f27e1..d6135b2549bf 100644
--- a/include/asm-x86_64/mtrr.h
+++ b/include/asm-x86_64/mtrr.h
@@ -23,9 +23,7 @@
23#ifndef _LINUX_MTRR_H 23#ifndef _LINUX_MTRR_H
24#define _LINUX_MTRR_H 24#define _LINUX_MTRR_H
25 25
26#include <linux/config.h>
27#include <linux/ioctl.h> 26#include <linux/ioctl.h>
28#include <linux/compat.h>
29 27
30#define MTRR_IOCTL_BASE 'M' 28#define MTRR_IOCTL_BASE 'M'
31 29
@@ -102,11 +100,10 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base,
102 return -ENODEV; 100 return -ENODEV;
103} 101}
104 102
105# endif 103#endif /* CONFIG_MTRR */
106
107#endif
108 104
109#ifdef CONFIG_COMPAT 105#ifdef CONFIG_COMPAT
106#include <linux/compat.h>
110 107
111struct mtrr_sentry32 108struct mtrr_sentry32
112{ 109{
@@ -138,4 +135,6 @@ struct mtrr_gentry32
138 135
139#endif /* CONFIG_COMPAT */ 136#endif /* CONFIG_COMPAT */
140 137
138#endif /* __KERNEL__ */
139
141#endif /* _LINUX_MTRR_H */ 140#endif /* _LINUX_MTRR_H */
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index 408185bac351..f7bf875aae40 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -1,7 +1,6 @@
1#ifndef _X86_64_PAGE_H 1#ifndef _X86_64_PAGE_H
2#define _X86_64_PAGE_H 2#define _X86_64_PAGE_H
3 3
4#include <linux/config.h>
5 4
6/* PAGE_SHIFT determines the page size */ 5/* PAGE_SHIFT determines the page size */
7#define PAGE_SHIFT 12 6#define PAGE_SHIFT 12
@@ -136,9 +135,9 @@ typedef struct { unsigned long pgprot; } pgprot_t;
136 135
137#define __HAVE_ARCH_GATE_AREA 1 136#define __HAVE_ARCH_GATE_AREA 1
138 137
139#endif /* __KERNEL__ */
140
141#include <asm-generic/memory_model.h> 138#include <asm-generic/memory_model.h>
142#include <asm-generic/page.h> 139#include <asm-generic/page.h>
143 140
141#endif /* __KERNEL__ */
142
144#endif /* _X86_64_PAGE_H */ 143#endif /* _X86_64_PAGE_H */
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h
index 5956b23b57c2..a728786c3c7c 100644
--- a/include/asm-x86_64/param.h
+++ b/include/asm-x86_64/param.h
@@ -2,7 +2,6 @@
2#define _ASMx86_64_PARAM_H 2#define _ASMx86_64_PARAM_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5# include <linux/config.h>
6# define HZ CONFIG_HZ /* Internal kernel timer frequency */ 5# define HZ CONFIG_HZ /* Internal kernel timer frequency */
7# define USER_HZ 100 /* .. some user interfaces are in "ticks */ 6# define USER_HZ 100 /* .. some user interfaces are in "ticks */
8#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ 7#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index 8a05af264d18..2db0620d5449 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -1,7 +1,6 @@
1#ifndef __x8664_PCI_H 1#ifndef __x8664_PCI_H
2#define __x8664_PCI_H 2#define __x8664_PCI_H
3 3
4#include <linux/config.h>
5#include <asm/io.h> 4#include <asm/io.h>
6 5
7#ifdef __KERNEL__ 6#ifdef __KERNEL__
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 37a3ec433ee5..3061a38a3b1d 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -12,7 +12,6 @@
12#include <asm/types.h> 12#include <asm/types.h>
13#include <asm/sigcontext.h> 13#include <asm/sigcontext.h>
14#include <asm/cpufeature.h> 14#include <asm/cpufeature.h>
15#include <linux/config.h>
16#include <linux/threads.h> 15#include <linux/threads.h>
17#include <asm/msr.h> 16#include <asm/msr.h>
18#include <asm/current.h> 17#include <asm/current.h>
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h
index dc752eafa681..b0496e0d72a6 100644
--- a/include/asm-x86_64/serial.h
+++ b/include/asm-x86_64/serial.h
@@ -2,7 +2,6 @@
2 * include/asm-x86_64/serial.h 2 * include/asm-x86_64/serial.h
3 */ 3 */
4 4
5#include <linux/config.h>
6 5
7/* 6/*
8 * This assumes you have a 1.8432 MHz clock for your UART. 7 * This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index a4fdaeb5c397..7686b9b25aef 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -5,7 +5,6 @@
5 * We need the APIC definitions automatically as part of 'smp.h' 5 * We need the APIC definitions automatically as part of 'smp.h'
6 */ 6 */
7#ifndef __ASSEMBLY__ 7#ifndef __ASSEMBLY__
8#include <linux/config.h>
9#include <linux/threads.h> 8#include <linux/threads.h>
10#include <linux/cpumask.h> 9#include <linux/cpumask.h>
11#include <linux/bitops.h> 10#include <linux/bitops.h>
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index fe484a699cc3..5d8a5e3589ff 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -4,7 +4,6 @@
4#include <asm/atomic.h> 4#include <asm/atomic.h>
5#include <asm/rwlock.h> 5#include <asm/rwlock.h>
6#include <asm/page.h> 6#include <asm/page.h>
7#include <linux/config.h>
8 7
9/* 8/*
10 * Your basic SMP spinlocks, allowing only a single CPU anywhere 9 * Your basic SMP spinlocks, allowing only a single CPU anywhere
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h
index 60757efd1353..5f9a01805821 100644
--- a/include/asm-x86_64/swiotlb.h
+++ b/include/asm-x86_64/swiotlb.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_SWIOTLB_H 1#ifndef _ASM_SWIOTLB_H
2#define _ASM_SWTIOLB_H 1 2#define _ASM_SWTIOLB_H 1
3 3
4#include <linux/config.h>
5 4
6#include <asm/dma-mapping.h> 5#include <asm/dma-mapping.h>
7 6
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 397598980228..f48e0dad8b3d 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_SYSTEM_H 1#ifndef __ASM_SYSTEM_H
2#define __ASM_SYSTEM_H 2#define __ASM_SYSTEM_H
3 3
4#include <linux/config.h>
5#include <linux/kernel.h> 4#include <linux/kernel.h>
6#include <asm/segment.h> 5#include <asm/segment.h>
7 6
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h
index 4a9c20ea9b10..d16d5b60f419 100644
--- a/include/asm-x86_64/tlbflush.h
+++ b/include/asm-x86_64/tlbflush.h
@@ -1,7 +1,6 @@
1#ifndef _X8664_TLBFLUSH_H 1#ifndef _X8664_TLBFLUSH_H
2#define _X8664_TLBFLUSH_H 2#define _X8664_TLBFLUSH_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <asm/processor.h> 5#include <asm/processor.h>
7 6
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 9db54e9d17bb..80c4e44d011c 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_X86_64_TOPOLOGY_H 1#ifndef _ASM_X86_64_TOPOLOGY_H
2#define _ASM_X86_64_TOPOLOGY_H 2#define _ASM_X86_64_TOPOLOGY_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_NUMA 5#ifdef CONFIG_NUMA
7 6
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index bddffcb591b8..1e1fa003daa3 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -4,7 +4,6 @@
4/* 4/*
5 * User space memory access functions 5 * User space memory access functions
6 */ 6 */
7#include <linux/config.h>
8#include <linux/compiler.h> 7#include <linux/compiler.h>
9#include <linux/errno.h> 8#include <linux/errno.h>
10#include <linux/sched.h> 9#include <linux/sched.h>
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index feb77cb8c044..0aff22bdbb21 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -618,6 +618,8 @@ __SYSCALL(__NR_sync_file_range, sys_sync_file_range)
618#define __NR_vmsplice 278 618#define __NR_vmsplice 278
619__SYSCALL(__NR_vmsplice, sys_vmsplice) 619__SYSCALL(__NR_vmsplice, sys_vmsplice)
620 620
621#ifdef __KERNEL__
622
621#define __NR_syscall_max __NR_vmsplice 623#define __NR_syscall_max __NR_vmsplice
622 624
623#ifndef __NO_STUBS 625#ifndef __NO_STUBS
@@ -635,7 +637,6 @@ do { \
635 return (type) (res); \ 637 return (type) (res); \
636} while (0) 638} while (0)
637 639
638#ifdef __KERNEL__
639#define __ARCH_WANT_OLD_READDIR 640#define __ARCH_WANT_OLD_READDIR
640#define __ARCH_WANT_OLD_STAT 641#define __ARCH_WANT_OLD_STAT
641#define __ARCH_WANT_SYS_ALARM 642#define __ARCH_WANT_SYS_ALARM
@@ -657,7 +658,6 @@ do { \
657#define __ARCH_WANT_SYS_RT_SIGACTION 658#define __ARCH_WANT_SYS_RT_SIGACTION
658#define __ARCH_WANT_SYS_TIME 659#define __ARCH_WANT_SYS_TIME
659#define __ARCH_WANT_COMPAT_SYS_TIME 660#define __ARCH_WANT_COMPAT_SYS_TIME
660#endif
661 661
662#ifndef __KERNEL_SYSCALLS__ 662#ifndef __KERNEL_SYSCALLS__
663 663
@@ -821,7 +821,7 @@ asmlinkage long sys_pipe(int *fildes);
821 821
822#endif /* __KERNEL_SYSCALLS__ */ 822#endif /* __KERNEL_SYSCALLS__ */
823 823
824#if !defined(__ASSEMBLY__) && defined(__KERNEL__) 824#ifndef __ASSEMBLY__
825 825
826#include <linux/linkage.h> 826#include <linux/linkage.h>
827#include <linux/compiler.h> 827#include <linux/compiler.h>
@@ -848,4 +848,5 @@ asmlinkage long sys_rt_sigaction(int sig,
848 */ 848 */
849#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 849#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
850 850
851#endif /* __KERNEL__ */
851#endif 852#endif
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index fe105a123924..5c2672021068 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -13,7 +13,6 @@
13#ifndef _XTENSA_ATOMIC_H 13#ifndef _XTENSA_ATOMIC_H
14#define _XTENSA_ATOMIC_H 14#define _XTENSA_ATOMIC_H
15 15
16#include <linux/config.h>
17#include <linux/stringify.h> 16#include <linux/stringify.h>
18 17
19typedef struct { volatile int counter; } atomic_t; 18typedef struct { volatile int counter; } atomic_t;
diff --git a/include/asm-xtensa/checksum.h b/include/asm-xtensa/checksum.h
index 81a797ae3abe..bdc00ae9be48 100644
--- a/include/asm-xtensa/checksum.h
+++ b/include/asm-xtensa/checksum.h
@@ -11,7 +11,6 @@
11#ifndef _XTENSA_CHECKSUM_H 11#ifndef _XTENSA_CHECKSUM_H
12#define _XTENSA_CHECKSUM_H 12#define _XTENSA_CHECKSUM_H
13 13
14#include <linux/config.h>
15#include <linux/in6.h> 14#include <linux/in6.h>
16#include <xtensa/config/core.h> 15#include <xtensa/config/core.h>
17 16
diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h
index 1bc601ec3621..e1d8c9e010c1 100644
--- a/include/asm-xtensa/delay.h
+++ b/include/asm-xtensa/delay.h
@@ -12,7 +12,6 @@
12#ifndef _XTENSA_DELAY_H 12#ifndef _XTENSA_DELAY_H
13#define _XTENSA_DELAY_H 13#define _XTENSA_DELAY_H
14 14
15#include <linux/config.h>
16#include <asm/processor.h> 15#include <asm/processor.h>
17#include <asm/param.h> 16#include <asm/param.h>
18 17
diff --git a/include/asm-xtensa/dma.h b/include/asm-xtensa/dma.h
index 1c22b0234586..db2633f67789 100644
--- a/include/asm-xtensa/dma.h
+++ b/include/asm-xtensa/dma.h
@@ -11,7 +11,6 @@
11#ifndef _XTENSA_DMA_H 11#ifndef _XTENSA_DMA_H
12#define _XTENSA_DMA_H 12#define _XTENSA_DMA_H
13 13
14#include <linux/config.h>
15#include <asm/io.h> /* need byte IO */ 14#include <asm/io.h> /* need byte IO */
16#include <xtensa/config/core.h> 15#include <xtensa/config/core.h>
17 16
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h
index aa9c1adf68d7..87cb19d1b10c 100644
--- a/include/asm-xtensa/hardirq.h
+++ b/include/asm-xtensa/hardirq.h
@@ -11,7 +11,6 @@
11#ifndef _XTENSA_HARDIRQ_H 11#ifndef _XTENSA_HARDIRQ_H
12#define _XTENSA_HARDIRQ_H 12#define _XTENSA_HARDIRQ_H
13 13
14#include <linux/config.h>
15#include <linux/cache.h> 14#include <linux/cache.h>
16#include <asm/irq.h> 15#include <asm/irq.h>
17 16
diff --git a/include/asm-xtensa/ide.h b/include/asm-xtensa/ide.h
index b523cd4a486e..6b912742a42d 100644
--- a/include/asm-xtensa/ide.h
+++ b/include/asm-xtensa/ide.h
@@ -14,7 +14,6 @@
14 14
15#ifdef __KERNEL__ 15#ifdef __KERNEL__
16 16
17#include <linux/config.h>
18 17
19#ifndef MAX_HWIFS 18#ifndef MAX_HWIFS
20# define MAX_HWIFS 1 19# define MAX_HWIFS 1
diff --git a/include/asm-xtensa/io.h b/include/asm-xtensa/io.h
index c5c13985bbe1..556e5eed34f5 100644
--- a/include/asm-xtensa/io.h
+++ b/include/asm-xtensa/io.h
@@ -12,7 +12,6 @@
12#define _XTENSA_IO_H 12#define _XTENSA_IO_H
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15#include <linux/config.h>
16#include <asm/byteorder.h> 15#include <asm/byteorder.h>
17 16
18#include <linux/types.h> 17#include <linux/types.h>
diff --git a/include/asm-xtensa/irq.h b/include/asm-xtensa/irq.h
index d984e955938f..049fde7e752d 100644
--- a/include/asm-xtensa/irq.h
+++ b/include/asm-xtensa/irq.h
@@ -11,7 +11,6 @@
11#ifndef _XTENSA_IRQ_H 11#ifndef _XTENSA_IRQ_H
12#define _XTENSA_IRQ_H 12#define _XTENSA_IRQ_H
13 13
14#include <linux/config.h>
15#include <asm/platform/hardware.h> 14#include <asm/platform/hardware.h>
16 15
17#include <xtensa/config/core.h> 16#include <xtensa/config/core.h>
diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h
index 364a7b057bfa..af683a74a4ec 100644
--- a/include/asm-xtensa/mmu_context.h
+++ b/include/asm-xtensa/mmu_context.h
@@ -13,7 +13,6 @@
13#ifndef _XTENSA_MMU_CONTEXT_H 13#ifndef _XTENSA_MMU_CONTEXT_H
14#define _XTENSA_MMU_CONTEXT_H 14#define _XTENSA_MMU_CONTEXT_H
15 15
16#include <linux/config.h>
17#include <linux/stringify.h> 16#include <linux/stringify.h>
18 17
19#include <asm/pgtable.h> 18#include <asm/pgtable.h>
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
index 992bac5c1258..40f4c6c3f580 100644
--- a/include/asm-xtensa/page.h
+++ b/include/asm-xtensa/page.h
@@ -14,7 +14,6 @@
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <linux/config.h>
18 17
19/* 18/*
20 * PAGE_SHIFT determines the page size 19 * PAGE_SHIFT determines the page size
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
index 734a8d060395..d56ddf2055e1 100644
--- a/include/asm-xtensa/pgalloc.h
+++ b/include/asm-xtensa/pgalloc.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17#include <linux/threads.h> 16#include <linux/threads.h>
18#include <linux/highmem.h> 17#include <linux/highmem.h>
19#include <asm/processor.h> 18#include <asm/processor.h>
diff --git a/include/asm-xtensa/platform.h b/include/asm-xtensa/platform.h
index 36163894bc20..48135a9718b0 100644
--- a/include/asm-xtensa/platform.h
+++ b/include/asm-xtensa/platform.h
@@ -13,7 +13,6 @@
13#ifndef _XTENSA_PLATFORM_H 13#ifndef _XTENSA_PLATFORM_H
14#define _XTENSA_PLATFORM_H 14#define _XTENSA_PLATFORM_H
15 15
16#include <linux/config.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
19 18
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index b29f7ae6a08a..f986170bd2a1 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -11,7 +11,6 @@
11#ifndef _XTENSA_SYSTEM_H 11#ifndef _XTENSA_SYSTEM_H
12#define _XTENSA_SYSTEM_H 12#define _XTENSA_SYSTEM_H
13 13
14#include <linux/config.h>
15#include <linux/stringify.h> 14#include <linux/stringify.h>
16 15
17#include <asm/processor.h> 16#include <asm/processor.h>
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
index 6b39d6609d9c..5e1b99dc4ab3 100644
--- a/include/asm-xtensa/unistd.h
+++ b/include/asm-xtensa/unistd.h
@@ -11,8 +11,6 @@
11#ifndef _XTENSA_UNISTD_H 11#ifndef _XTENSA_UNISTD_H
12#define _XTENSA_UNISTD_H 12#define _XTENSA_UNISTD_H
13 13
14#include <linux/linkage.h>
15
16#define __NR_spill 0 14#define __NR_spill 0
17#define __NR_exit 1 15#define __NR_exit 1
18#define __NR_read 3 16#define __NR_read 3
@@ -221,21 +219,9 @@
221#define SYSXTENSA_COUNT 5 /* count of syscall0 functions*/ 219#define SYSXTENSA_COUNT 5 /* count of syscall0 functions*/
222 220
223#ifdef __KERNEL__ 221#ifdef __KERNEL__
224#define __syscall_return(type, res) return ((type)(res)) 222#include <linux/linkage.h>
225#else
226#define __syscall_return(type, res) \
227do { \
228 if ((unsigned long)(res) >= (unsigned long)(-125)) { \
229 /* Avoid using "res" which is declared to be in register r2; \
230 * errno might expand to a function call and clobber it. */ \
231 int __err = -(res); \
232 errno = __err; \
233 res = -1; \
234 } \
235 return (type) (res); \
236} while (0)
237#endif
238 223
224#define __syscall_return(type, res) return ((type)(res))
239 225
240/* Tensilica's xt-xcc compiler is much more agressive at code 226/* Tensilica's xt-xcc compiler is much more agressive at code
241 * optimization than gcc. Multiple __asm__ statements are 227 * optimization than gcc. Multiple __asm__ statements are
@@ -429,11 +415,10 @@ static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
429 */ 415 */
430#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); 416#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
431 417
432#ifdef __KERNEL__
433#define __ARCH_WANT_STAT64 418#define __ARCH_WANT_STAT64
434#define __ARCH_WANT_SYS_UTIME 419#define __ARCH_WANT_SYS_UTIME
435#define __ARCH_WANT_SYS_LLSEEK 420#define __ARCH_WANT_SYS_LLSEEK
436#define __ARCH_WANT_SYS_RT_SIGACTION 421#define __ARCH_WANT_SYS_RT_SIGACTION
437#endif 422#endif /* __KERNEL__ */
438 423
439#endif /* _XTENSA_UNISTD_H */ 424#endif /* _XTENSA_UNISTD_H */
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 9a66401073fc..3d54fbcf969e 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -16,7 +16,6 @@
16#define _LINUX_ACCT_H 16#define _LINUX_ACCT_H
17 17
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/jiffies.h>
20 19
21#include <asm/param.h> 20#include <asm/param.h>
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
@@ -116,7 +115,6 @@ struct acct_v3
116 115
117#ifdef __KERNEL__ 116#ifdef __KERNEL__
118 117
119#include <linux/config.h>
120 118
121#ifdef CONFIG_BSD_PROCESS_ACCT 119#ifdef CONFIG_BSD_PROCESS_ACCT
122struct vfsmount; 120struct vfsmount;
@@ -165,6 +163,7 @@ typedef struct acct acct_t;
165#endif /* __KERNEL */ 163#endif /* __KERNEL */
166 164
167#ifdef __KERNEL__ 165#ifdef __KERNEL__
166#include <linux/jiffies.h>
168/* 167/*
169 * Yet another set of HZ to *HZ helper functions. 168 * Yet another set of HZ to *HZ helper functions.
170 * See <linux/jiffies.h> for the original. 169 * See <linux/jiffies.h> for the original.
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d3bc25e6d27d..1cf0b91d05bd 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,7 +25,6 @@
25#ifndef _LINUX_ACPI_H 25#ifndef _LINUX_ACPI_H
26#define _LINUX_ACPI_H 26#define _LINUX_ACPI_H
27 27
28#include <linux/config.h>
29 28
30#ifdef CONFIG_ACPI 29#ifdef CONFIG_ACPI
31 30
diff --git a/include/linux/affs_hardblocks.h b/include/linux/affs_hardblocks.h
index 3fb869939d82..f1b948c1f592 100644
--- a/include/linux/affs_hardblocks.h
+++ b/include/linux/affs_hardblocks.h
@@ -1,45 +1,47 @@
1#ifndef AFFS_HARDBLOCKS_H 1#ifndef AFFS_HARDBLOCKS_H
2#define AFFS_HARDBLOCKS_H 2#define AFFS_HARDBLOCKS_H
3 3
4#include <linux/types.h>
5
4/* Just the needed definitions for the RDB of an Amiga HD. */ 6/* Just the needed definitions for the RDB of an Amiga HD. */
5 7
6struct RigidDiskBlock { 8struct RigidDiskBlock {
7 u32 rdb_ID; 9 __u32 rdb_ID;
8 __be32 rdb_SummedLongs; 10 __be32 rdb_SummedLongs;
9 s32 rdb_ChkSum; 11 __s32 rdb_ChkSum;
10 u32 rdb_HostID; 12 __u32 rdb_HostID;
11 __be32 rdb_BlockBytes; 13 __be32 rdb_BlockBytes;
12 u32 rdb_Flags; 14 __u32 rdb_Flags;
13 u32 rdb_BadBlockList; 15 __u32 rdb_BadBlockList;
14 __be32 rdb_PartitionList; 16 __be32 rdb_PartitionList;
15 u32 rdb_FileSysHeaderList; 17 __u32 rdb_FileSysHeaderList;
16 u32 rdb_DriveInit; 18 __u32 rdb_DriveInit;
17 u32 rdb_Reserved1[6]; 19 __u32 rdb_Reserved1[6];
18 u32 rdb_Cylinders; 20 __u32 rdb_Cylinders;
19 u32 rdb_Sectors; 21 __u32 rdb_Sectors;
20 u32 rdb_Heads; 22 __u32 rdb_Heads;
21 u32 rdb_Interleave; 23 __u32 rdb_Interleave;
22 u32 rdb_Park; 24 __u32 rdb_Park;
23 u32 rdb_Reserved2[3]; 25 __u32 rdb_Reserved2[3];
24 u32 rdb_WritePreComp; 26 __u32 rdb_WritePreComp;
25 u32 rdb_ReducedWrite; 27 __u32 rdb_ReducedWrite;
26 u32 rdb_StepRate; 28 __u32 rdb_StepRate;
27 u32 rdb_Reserved3[5]; 29 __u32 rdb_Reserved3[5];
28 u32 rdb_RDBBlocksLo; 30 __u32 rdb_RDBBlocksLo;
29 u32 rdb_RDBBlocksHi; 31 __u32 rdb_RDBBlocksHi;
30 u32 rdb_LoCylinder; 32 __u32 rdb_LoCylinder;
31 u32 rdb_HiCylinder; 33 __u32 rdb_HiCylinder;
32 u32 rdb_CylBlocks; 34 __u32 rdb_CylBlocks;
33 u32 rdb_AutoParkSeconds; 35 __u32 rdb_AutoParkSeconds;
34 u32 rdb_HighRDSKBlock; 36 __u32 rdb_HighRDSKBlock;
35 u32 rdb_Reserved4; 37 __u32 rdb_Reserved4;
36 char rdb_DiskVendor[8]; 38 char rdb_DiskVendor[8];
37 char rdb_DiskProduct[16]; 39 char rdb_DiskProduct[16];
38 char rdb_DiskRevision[4]; 40 char rdb_DiskRevision[4];
39 char rdb_ControllerVendor[8]; 41 char rdb_ControllerVendor[8];
40 char rdb_ControllerProduct[16]; 42 char rdb_ControllerProduct[16];
41 char rdb_ControllerRevision[4]; 43 char rdb_ControllerRevision[4];
42 u32 rdb_Reserved5[10]; 44 __u32 rdb_Reserved5[10];
43}; 45};
44 46
45#define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ 47#define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */
@@ -47,16 +49,16 @@ struct RigidDiskBlock {
47struct PartitionBlock { 49struct PartitionBlock {
48 __be32 pb_ID; 50 __be32 pb_ID;
49 __be32 pb_SummedLongs; 51 __be32 pb_SummedLongs;
50 s32 pb_ChkSum; 52 __s32 pb_ChkSum;
51 u32 pb_HostID; 53 __u32 pb_HostID;
52 __be32 pb_Next; 54 __be32 pb_Next;
53 u32 pb_Flags; 55 __u32 pb_Flags;
54 u32 pb_Reserved1[2]; 56 __u32 pb_Reserved1[2];
55 u32 pb_DevFlags; 57 __u32 pb_DevFlags;
56 u8 pb_DriveName[32]; 58 __u8 pb_DriveName[32];
57 u32 pb_Reserved2[15]; 59 __u32 pb_Reserved2[15];
58 __be32 pb_Environment[17]; 60 __be32 pb_Environment[17];
59 u32 pb_EReserved[15]; 61 __u32 pb_EReserved[15];
60}; 62};
61 63
62#define IDNAME_PARTITION 0x50415254 /* "PART" */ 64#define IDNAME_PARTITION 0x50415254 /* "PART" */
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
index 6d59c8efe3be..bfb8ec791b7b 100644
--- a/include/linux/agpgart.h
+++ b/include/linux/agpgart.h
@@ -27,8 +27,6 @@
27#ifndef _AGP_H 27#ifndef _AGP_H
28#define _AGP_H 1 28#define _AGP_H 1
29 29
30#include <linux/agp_backend.h>
31
32#define AGPIOC_BASE 'A' 30#define AGPIOC_BASE 'A'
33#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, struct agp_info*) 31#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, struct agp_info*)
34#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1) 32#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
@@ -112,6 +110,7 @@ typedef struct _agp_unbind {
112 110
113#else /* __KERNEL__ */ 111#else /* __KERNEL__ */
114#include <linux/mutex.h> 112#include <linux/mutex.h>
113#include <linux/agp_backend.h>
115 114
116#define AGPGART_MINOR 175 115#define AGPGART_MINOR 175
117 116
diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h
index 9cf64b1b688b..29c0448265cf 100644
--- a/include/linux/amba/clcd.h
+++ b/include/linux/amba/clcd.h
@@ -9,7 +9,6 @@
9 * License. See the file COPYING in the main directory of this archive 9 * License. See the file COPYING in the main directory of this archive
10 * for more details. 10 * for more details.
11 */ 11 */
12#include <linux/config.h>
13#include <linux/fb.h> 12#include <linux/fb.h>
14 13
15/* 14/*
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index b203ea82a0a8..1eb238affb12 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -209,7 +209,6 @@ struct atm_cirange {
209 209
210#ifdef __KERNEL__ 210#ifdef __KERNEL__
211 211
212#include <linux/config.h>
213#include <linux/wait.h> /* wait_queue_head_t */ 212#include <linux/wait.h> /* wait_queue_head_t */
214#include <linux/time.h> /* struct timeval */ 213#include <linux/time.h> /* struct timeval */
215#include <linux/net.h> 214#include <linux/net.h>
diff --git a/include/linux/audit.h b/include/linux/audit.h
index b74c148f14e3..e051ff9c5b50 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -24,8 +24,7 @@
24#ifndef _LINUX_AUDIT_H_ 24#ifndef _LINUX_AUDIT_H_
25#define _LINUX_AUDIT_H_ 25#define _LINUX_AUDIT_H_
26 26
27#include <linux/sched.h> 27#include <linux/elf-em.h>
28#include <linux/elf.h>
29 28
30/* The netlink messages for the audit system is divided into blocks: 29/* The netlink messages for the audit system is divided into blocks:
31 * 1000 - 1099 are for commanding the audit system 30 * 1000 - 1099 are for commanding the audit system
@@ -83,7 +82,12 @@
83#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ 82#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
84#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ 83#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
85#define AUDIT_CWD 1307 /* Current working directory */ 84#define AUDIT_CWD 1307 /* Current working directory */
85#define AUDIT_EXECVE 1309 /* execve arguments */
86#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */ 86#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
87#define AUDIT_MQ_OPEN 1312 /* POSIX MQ open record type */
88#define AUDIT_MQ_SENDRECV 1313 /* POSIX MQ send/receive record type */
89#define AUDIT_MQ_NOTIFY 1314 /* POSIX MQ notify record type */
90#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */
87 91
88#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ 92#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
89#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ 93#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -151,6 +155,7 @@
151#define AUDIT_SE_TYPE 15 /* security label type */ 155#define AUDIT_SE_TYPE 15 /* security label type */
152#define AUDIT_SE_SEN 16 /* security label sensitivity label */ 156#define AUDIT_SE_SEN 16 /* security label sensitivity label */
153#define AUDIT_SE_CLR 17 /* security label clearance label */ 157#define AUDIT_SE_CLR 17 /* security label clearance label */
158#define AUDIT_PPID 18
154 159
155 /* These are ONLY useful when checking 160 /* These are ONLY useful when checking
156 * at syscall exit time (AUDIT_AT_EXIT). */ 161 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -159,6 +164,7 @@
159#define AUDIT_INODE 102 164#define AUDIT_INODE 102
160#define AUDIT_EXIT 103 165#define AUDIT_EXIT 103
161#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */ 166#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
167#define AUDIT_WATCH 105
162 168
163#define AUDIT_ARG0 200 169#define AUDIT_ARG0 200
164#define AUDIT_ARG1 (AUDIT_ARG0+1) 170#define AUDIT_ARG1 (AUDIT_ARG0+1)
@@ -273,16 +279,21 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
273}; 279};
274 280
275#ifdef __KERNEL__ 281#ifdef __KERNEL__
282#include <linux/sched.h>
276 283
277struct audit_sig_info { 284struct audit_sig_info {
278 uid_t uid; 285 uid_t uid;
279 pid_t pid; 286 pid_t pid;
287 char ctx[0];
280}; 288};
281 289
282struct audit_buffer; 290struct audit_buffer;
283struct audit_context; 291struct audit_context;
284struct inode; 292struct inode;
285struct netlink_skb_parms; 293struct netlink_skb_parms;
294struct linux_binprm;
295struct mq_attr;
296struct mqstat;
286 297
287#define AUDITSC_INVALID 0 298#define AUDITSC_INVALID 0
288#define AUDITSC_SUCCESS 1 299#define AUDITSC_SUCCESS 1
@@ -297,15 +308,19 @@ extern void audit_syscall_entry(int arch,
297 int major, unsigned long a0, unsigned long a1, 308 int major, unsigned long a0, unsigned long a1,
298 unsigned long a2, unsigned long a3); 309 unsigned long a2, unsigned long a3);
299extern void audit_syscall_exit(int failed, long return_code); 310extern void audit_syscall_exit(int failed, long return_code);
300extern void audit_getname(const char *name); 311extern void __audit_getname(const char *name);
301extern void audit_putname(const char *name); 312extern void audit_putname(const char *name);
302extern void __audit_inode(const char *name, const struct inode *inode, unsigned flags); 313extern void __audit_inode(const char *name, const struct inode *inode);
303extern void __audit_inode_child(const char *dname, const struct inode *inode, 314extern void __audit_inode_child(const char *dname, const struct inode *inode,
304 unsigned long pino); 315 unsigned long pino);
305static inline void audit_inode(const char *name, const struct inode *inode, 316static inline void audit_getname(const char *name)
306 unsigned flags) { 317{
307 if (unlikely(current->audit_context)) 318 if (unlikely(current->audit_context))
308 __audit_inode(name, inode, flags); 319 __audit_getname(name);
320}
321static inline void audit_inode(const char *name, const struct inode *inode) {
322 if (unlikely(current->audit_context))
323 __audit_inode(name, inode);
309} 324}
310static inline void audit_inode_child(const char *dname, 325static inline void audit_inode_child(const char *dname,
311 const struct inode *inode, 326 const struct inode *inode,
@@ -320,13 +335,61 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
320 struct timespec *t, unsigned int *serial); 335 struct timespec *t, unsigned int *serial);
321extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 336extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
322extern uid_t audit_get_loginuid(struct audit_context *ctx); 337extern uid_t audit_get_loginuid(struct audit_context *ctx);
323extern int audit_ipc_obj(struct kern_ipc_perm *ipcp); 338extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
324extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); 339extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
340extern int audit_bprm(struct linux_binprm *bprm);
325extern int audit_socketcall(int nargs, unsigned long *args); 341extern int audit_socketcall(int nargs, unsigned long *args);
326extern int audit_sockaddr(int len, void *addr); 342extern int audit_sockaddr(int len, void *addr);
327extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 343extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
328extern void audit_signal_info(int sig, struct task_struct *t);
329extern int audit_set_macxattr(const char *name); 344extern int audit_set_macxattr(const char *name);
345extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
346extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout);
347extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout);
348extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
349extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
350
351static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
352{
353 if (unlikely(current->audit_context))
354 return __audit_ipc_obj(ipcp);
355 return 0;
356}
357static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
358{
359 if (unlikely(current->audit_context))
360 return __audit_ipc_set_perm(qbytes, uid, gid, mode);
361 return 0;
362}
363static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
364{
365 if (unlikely(current->audit_context))
366 return __audit_mq_open(oflag, mode, u_attr);
367 return 0;
368}
369static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout)
370{
371 if (unlikely(current->audit_context))
372 return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
373 return 0;
374}
375static inline int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout)
376{
377 if (unlikely(current->audit_context))
378 return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
379 return 0;
380}
381static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
382{
383 if (unlikely(current->audit_context))
384 return __audit_mq_notify(mqdes, u_notification);
385 return 0;
386}
387static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
388{
389 if (unlikely(current->audit_context))
390 return __audit_mq_getsetattr(mqdes, mqstat);
391 return 0;
392}
330#else 393#else
331#define audit_alloc(t) ({ 0; }) 394#define audit_alloc(t) ({ 0; })
332#define audit_free(t) do { ; } while (0) 395#define audit_free(t) do { ; } while (0)
@@ -334,19 +397,24 @@ extern int audit_set_macxattr(const char *name);
334#define audit_syscall_exit(f,r) do { ; } while (0) 397#define audit_syscall_exit(f,r) do { ; } while (0)
335#define audit_getname(n) do { ; } while (0) 398#define audit_getname(n) do { ; } while (0)
336#define audit_putname(n) do { ; } while (0) 399#define audit_putname(n) do { ; } while (0)
337#define __audit_inode(n,i,f) do { ; } while (0) 400#define __audit_inode(n,i) do { ; } while (0)
338#define __audit_inode_child(d,i,p) do { ; } while (0) 401#define __audit_inode_child(d,i,p) do { ; } while (0)
339#define audit_inode(n,i,f) do { ; } while (0) 402#define audit_inode(n,i) do { ; } while (0)
340#define audit_inode_child(d,i,p) do { ; } while (0) 403#define audit_inode_child(d,i,p) do { ; } while (0)
341#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) 404#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
342#define audit_get_loginuid(c) ({ -1; }) 405#define audit_get_loginuid(c) ({ -1; })
343#define audit_ipc_obj(i) ({ 0; }) 406#define audit_ipc_obj(i) ({ 0; })
344#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; }) 407#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
408#define audit_bprm(p) ({ 0; })
345#define audit_socketcall(n,a) ({ 0; }) 409#define audit_socketcall(n,a) ({ 0; })
346#define audit_sockaddr(len, addr) ({ 0; }) 410#define audit_sockaddr(len, addr) ({ 0; })
347#define audit_avc_path(dentry, mnt) ({ 0; }) 411#define audit_avc_path(dentry, mnt) ({ 0; })
348#define audit_signal_info(s,t) do { ; } while (0)
349#define audit_set_macxattr(n) do { ; } while (0) 412#define audit_set_macxattr(n) do { ; } while (0)
413#define audit_mq_open(o,m,a) ({ 0; })
414#define audit_mq_timedsend(d,l,p,t) ({ 0; })
415#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
416#define audit_mq_notify(d,n) ({ 0; })
417#define audit_mq_getsetattr(d,s) ({ 0; })
350#endif 418#endif
351 419
352#ifdef CONFIG_AUDIT 420#ifdef CONFIG_AUDIT
@@ -364,8 +432,11 @@ extern void audit_log_end(struct audit_buffer *ab);
364extern void audit_log_hex(struct audit_buffer *ab, 432extern void audit_log_hex(struct audit_buffer *ab,
365 const unsigned char *buf, 433 const unsigned char *buf,
366 size_t len); 434 size_t len);
367extern void audit_log_untrustedstring(struct audit_buffer *ab, 435extern const char * audit_log_untrustedstring(struct audit_buffer *ab,
368 const char *string); 436 const char *string);
437extern const char * audit_log_n_untrustedstring(struct audit_buffer *ab,
438 size_t n,
439 const char *string);
369extern void audit_log_d_path(struct audit_buffer *ab, 440extern void audit_log_d_path(struct audit_buffer *ab,
370 const char *prefix, 441 const char *prefix,
371 struct dentry *dentry, 442 struct dentry *dentry,
@@ -383,8 +454,8 @@ extern int audit_receive_filter(int type, int pid, int uid, int seq,
383#define audit_log_end(b) do { ; } while (0) 454#define audit_log_end(b) do { ; } while (0)
384#define audit_log_hex(a,b,l) do { ; } while (0) 455#define audit_log_hex(a,b,l) do { ; } while (0)
385#define audit_log_untrustedstring(a,s) do { ; } while (0) 456#define audit_log_untrustedstring(a,s) do { ; } while (0)
457#define audit_log_n_untrustedstring(a,n,s) do { ; } while (0)
386#define audit_log_d_path(b,p,d,v) do { ; } while (0) 458#define audit_log_d_path(b,p,d,v) do { ; } while (0)
387#define audit_panic(m) do { ; } while (0)
388#endif 459#endif
389#endif 460#endif
390#endif 461#endif
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 59e1259b1c40..5d327313a9f7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_BLKDEV_H 1#ifndef _LINUX_BLKDEV_H
2#define _LINUX_BLKDEV_H 2#define _LINUX_BLKDEV_H
3 3
4#include <linux/config.h>
5#include <linux/major.h> 4#include <linux/major.h>
6#include <linux/genhd.h> 5#include <linux/genhd.h>
7#include <linux/list.h> 6#include <linux/list.h>
diff --git a/include/linux/blkpg.h b/include/linux/blkpg.h
index be5d0f4ad24c..faf8a45af210 100644
--- a/include/linux/blkpg.h
+++ b/include/linux/blkpg.h
@@ -24,6 +24,7 @@
24 * 24 *
25 * For today, only the partition stuff - aeb, 990515 25 * For today, only the partition stuff - aeb, 990515
26 */ 26 */
27#include <linux/compiler.h>
27#include <linux/ioctl.h> 28#include <linux/ioctl.h>
28 29
29#define BLKPG _IO(0x12,105) 30#define BLKPG _IO(0x12,105)
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index b34d3e73d5ea..eb1a867ed245 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -1,7 +1,6 @@
1#ifndef BLKTRACE_H 1#ifndef BLKTRACE_H
2#define BLKTRACE_H 2#define BLKTRACE_H
3 3
4#include <linux/config.h>
5#include <linux/blkdev.h> 4#include <linux/blkdev.h>
6#include <linux/relay.h> 5#include <linux/relay.h>
7 6
diff --git a/include/linux/blockgroup_lock.h b/include/linux/blockgroup_lock.h
index 0137ee5dd43c..8607312983bd 100644
--- a/include/linux/blockgroup_lock.h
+++ b/include/linux/blockgroup_lock.h
@@ -6,7 +6,6 @@
6 * Simple hashed spinlocking. 6 * Simple hashed spinlocking.
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/spinlock.h> 9#include <linux/spinlock.h>
11#include <linux/cache.h> 10#include <linux/cache.h>
12 11
diff --git a/include/linux/cache.h b/include/linux/cache.h
index cc4b3aafad9a..4552504c0228 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -2,7 +2,6 @@
2#define __LINUX_CACHE_H 2#define __LINUX_CACHE_H
3 3
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/config.h>
6#include <asm/cache.h> 5#include <asm/cache.h>
7 6
8#ifndef L1_CACHE_ALIGN 7#ifndef L1_CACHE_ALIGN
diff --git a/include/linux/coda.h b/include/linux/coda.h
index bbc5afcd7db6..b5cf0780c51a 100644
--- a/include/linux/coda.h
+++ b/include/linux/coda.h
@@ -59,7 +59,6 @@ Mellon the rights to redistribute these changes without encumbrance.
59#ifndef _CODA_HEADER_ 59#ifndef _CODA_HEADER_
60#define _CODA_HEADER_ 60#define _CODA_HEADER_
61 61
62#include <linux/config.h>
63 62
64/* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */ 63/* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */
65#if defined(__NetBSD__) || \ 64#if defined(__NetBSD__) || \
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6d3a654be1ae..dda1697ec753 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -4,7 +4,6 @@
4 * These are the type definitions for the architecture specific 4 * These are the type definitions for the architecture specific
5 * syscall compatibility layer. 5 * syscall compatibility layer.
6 */ 6 */
7#include <linux/config.h>
8 7
9#ifdef CONFIG_COMPAT 8#ifdef CONFIG_COMPAT
10 9
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index f23d3c6fc2c0..9b4f11094937 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -78,6 +78,7 @@ extern void __chk_io_ptr(void __iomem *);
78 78
79#endif /* __ASSEMBLY__ */ 79#endif /* __ASSEMBLY__ */
80 80
81#ifdef __KERNEL__
81/* 82/*
82 * Allow us to mark functions as 'deprecated' and have gcc emit a nice 83 * Allow us to mark functions as 'deprecated' and have gcc emit a nice
83 * warning for each use, in hopes of speeding the functions removal. 84 * warning for each use, in hopes of speeding the functions removal.
@@ -127,6 +128,16 @@ extern void __chk_io_ptr(void __iomem *);
127# define __attribute_pure__ /* unimplemented */ 128# define __attribute_pure__ /* unimplemented */
128#endif 129#endif
129 130
131#ifndef noinline
132#define noinline
133#endif
134
135#ifndef __always_inline
136#define __always_inline inline
137#endif
138
139#endif /* __KERNEL__ */
140
130/* 141/*
131 * From the GCC manual: 142 * From the GCC manual:
132 * 143 *
@@ -145,12 +156,4 @@ extern void __chk_io_ptr(void __iomem *);
145# define __attribute_const__ /* unimplemented */ 156# define __attribute_const__ /* unimplemented */
146#endif 157#endif
147 158
148#ifndef noinline
149#define noinline
150#endif
151
152#ifndef __always_inline
153#define __always_inline inline
154#endif
155
156#endif /* __LINUX_COMPILER_H */ 159#endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 17866d7e2b71..5aa95011f7e6 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -15,7 +15,6 @@
15#define _LINUX_CPUFREQ_H 15#define _LINUX_CPUFREQ_H
16 16
17#include <linux/mutex.h> 17#include <linux/mutex.h>
18#include <linux/config.h>
19#include <linux/notifier.h> 18#include <linux/notifier.h>
20#include <linux/threads.h> 19#include <linux/threads.h>
21#include <linux/device.h> 20#include <linux/device.h>
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index a8948f34b776..a41f38428c37 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -1,13 +1,7 @@
1#ifndef __CRAMFS_H 1#ifndef __CRAMFS_H
2#define __CRAMFS_H 2#define __CRAMFS_H
3 3
4#ifndef __KERNEL__ 4#include <linux/types.h>
5
6typedef unsigned char u8;
7typedef unsigned short u16;
8typedef unsigned int u32;
9
10#endif
11 5
12#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */ 6#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
13#define CRAMFS_SIGNATURE "Compressed ROMFS" 7#define CRAMFS_SIGNATURE "Compressed ROMFS"
@@ -33,9 +27,9 @@ typedef unsigned int u32;
33 * Reasonably terse representation of the inode data. 27 * Reasonably terse representation of the inode data.
34 */ 28 */
35struct cramfs_inode { 29struct cramfs_inode {
36 u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH; 30 __u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
37 /* SIZE for device files is i_rdev */ 31 /* SIZE for device files is i_rdev */
38 u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH; 32 __u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
39 /* NAMELEN is the length of the file name, divided by 4 and 33 /* NAMELEN is the length of the file name, divided by 4 and
40 rounded up. (cramfs doesn't support hard links.) */ 34 rounded up. (cramfs doesn't support hard links.) */
41 /* OFFSET: For symlinks and non-empty regular files, this 35 /* OFFSET: For symlinks and non-empty regular files, this
@@ -44,27 +38,27 @@ struct cramfs_inode {
44 see README). For non-empty directories it is the offset 38 see README). For non-empty directories it is the offset
45 (divided by 4) of the inode of the first file in that 39 (divided by 4) of the inode of the first file in that
46 directory. For anything else, offset is zero. */ 40 directory. For anything else, offset is zero. */
47 u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH; 41 __u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
48}; 42};
49 43
50struct cramfs_info { 44struct cramfs_info {
51 u32 crc; 45 __u32 crc;
52 u32 edition; 46 __u32 edition;
53 u32 blocks; 47 __u32 blocks;
54 u32 files; 48 __u32 files;
55}; 49};
56 50
57/* 51/*
58 * Superblock information at the beginning of the FS. 52 * Superblock information at the beginning of the FS.
59 */ 53 */
60struct cramfs_super { 54struct cramfs_super {
61 u32 magic; /* 0x28cd3d45 - random number */ 55 __u32 magic; /* 0x28cd3d45 - random number */
62 u32 size; /* length in bytes */ 56 __u32 size; /* length in bytes */
63 u32 flags; /* feature flags */ 57 __u32 flags; /* feature flags */
64 u32 future; /* reserved for future use */ 58 __u32 future; /* reserved for future use */
65 u8 signature[16]; /* "Compressed ROMFS" */ 59 __u8 signature[16]; /* "Compressed ROMFS" */
66 struct cramfs_info fsid; /* unique filesystem info */ 60 struct cramfs_info fsid; /* unique filesystem info */
67 u8 name[16]; /* user-defined name */ 61 __u8 name[16]; /* user-defined name */
68 struct cramfs_inode root; /* root inode data */ 62 struct cramfs_inode root; /* root inode data */
69}; 63};
70 64
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 0ab1bc1152ca..5a0470e36111 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -17,7 +17,6 @@
17#ifndef _LINUX_CRYPTO_H 17#ifndef _LINUX_CRYPTO_H
18#define _LINUX_CRYPTO_H 18#define _LINUX_CRYPTO_H
19 19
20#include <linux/config.h>
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/types.h> 22#include <linux/types.h>
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
index 300d704bdb9a..b88f7f428e58 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -24,7 +24,6 @@
24* 1998/08/08 acme Version 0.0.1 24* 1998/08/08 acme Version 0.0.1
25*/ 25*/
26 26
27#include <linux/config.h>
28#include <linux/wanrouter.h> 27#include <linux/wanrouter.h>
29#include <linux/spinlock.h> 28#include <linux/spinlock.h>
30 29
diff --git a/include/linux/dcookies.h b/include/linux/dcookies.h
index 1d68428c925d..0fe7cdf326f7 100644
--- a/include/linux/dcookies.h
+++ b/include/linux/dcookies.h
@@ -9,7 +9,6 @@
9#ifndef DCOOKIES_H 9#ifndef DCOOKIES_H
10#define DCOOKIES_H 10#define DCOOKIES_H
11 11
12#include <linux/config.h>
13 12
14#ifdef CONFIG_PROFILING 13#ifdef CONFIG_PROFILING
15 14
diff --git a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
index 89810e73d256..0d74a6f22abc 100644
--- a/include/linux/devfs_fs_kernel.h
+++ b/include/linux/devfs_fs_kernel.h
@@ -2,7 +2,6 @@
2#define _LINUX_DEVFS_FS_KERNEL_H 2#define _LINUX_DEVFS_FS_KERNEL_H
3 3
4#include <linux/fs.h> 4#include <linux/fs.h>
5#include <linux/config.h>
6#include <linux/spinlock.h> 5#include <linux/spinlock.h>
7#include <linux/types.h> 6#include <linux/types.h>
8 7
diff --git a/include/linux/device.h b/include/linux/device.h
index e8e53b9accc6..b2e5da2b637b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -11,7 +11,6 @@
11#ifndef _DEVICE_H_ 11#ifndef _DEVICE_H_
12#define _DEVICE_H_ 12#define _DEVICE_H_
13 13
14#include <linux/config.h>
15#include <linux/ioport.h> 14#include <linux/ioport.h>
16#include <linux/kobject.h> 15#include <linux/kobject.h>
17#include <linux/klist.h> 16#include <linux/klist.h>
diff --git a/include/linux/divert.h b/include/linux/divert.h
index 6919b09133d4..8fb4e9de6843 100644
--- a/include/linux/divert.h
+++ b/include/linux/divert.h
@@ -27,10 +27,10 @@ struct divert_blk
27{ 27{
28 int divert; /* are we active */ 28 int divert; /* are we active */
29 unsigned int protos; /* protocols */ 29 unsigned int protos; /* protocols */
30 u16 tcp_dst[MAX_DIVERT_PORTS]; /* specific tcp dst ports to divert */ 30 __u16 tcp_dst[MAX_DIVERT_PORTS]; /* specific tcp dst ports to divert */
31 u16 tcp_src[MAX_DIVERT_PORTS]; /* specific tcp src ports to divert */ 31 __u16 tcp_src[MAX_DIVERT_PORTS]; /* specific tcp src ports to divert */
32 u16 udp_dst[MAX_DIVERT_PORTS]; /* specific udp dst ports to divert */ 32 __u16 udp_dst[MAX_DIVERT_PORTS]; /* specific udp dst ports to divert */
33 u16 udp_src[MAX_DIVERT_PORTS]; /* specific udp src ports to divert */ 33 __u16 udp_src[MAX_DIVERT_PORTS]; /* specific udp src ports to divert */
34}; 34};
35 35
36/* 36/*
@@ -40,12 +40,12 @@ struct divert_blk
40 40
41typedef union _divert_cf_arg 41typedef union _divert_cf_arg
42{ 42{
43 s16 int16; 43 __s16 int16;
44 u16 uint16; 44 __u16 uint16;
45 s32 int32; 45 __s32 int32;
46 u32 uint32; 46 __u32 uint32;
47 s64 int64; 47 __s64 int64;
48 u64 uint64; 48 __u64 uint64;
49 void __user *ptr; 49 void __user *ptr;
50} divert_cf_arg; 50} divert_cf_arg;
51 51
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 64fd6c366604..b2cd2071d432 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -2,7 +2,6 @@
2#define __DMI_H__ 2#define __DMI_H__
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/config.h>
6 5
7enum dmi_field { 6enum dmi_field {
8 DMI_NONE, 7 DMI_NONE,
diff --git a/include/linux/dnotify.h b/include/linux/dnotify.h
index f134a01975c7..102a902b4396 100644
--- a/include/linux/dnotify.h
+++ b/include/linux/dnotify.h
@@ -18,7 +18,6 @@ struct dnotify_struct {
18 18
19#ifdef __KERNEL__ 19#ifdef __KERNEL__
20 20
21#include <linux/config.h>
22 21
23#ifdef CONFIG_DNOTIFY 22#ifdef CONFIG_DNOTIFY
24 23
diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h
new file mode 100644
index 000000000000..114a96d25652
--- /dev/null
+++ b/include/linux/elf-em.h
@@ -0,0 +1,44 @@
1#ifndef _LINUX_ELF_EM_H
2#define _LINUX_ELF_EM_H
3
4/* These constants define the various ELF target machines */
5#define EM_NONE 0
6#define EM_M32 1
7#define EM_SPARC 2
8#define EM_386 3
9#define EM_68K 4
10#define EM_88K 5
11#define EM_486 6 /* Perhaps disused */
12#define EM_860 7
13#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
14#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
15#define EM_PARISC 15 /* HPPA */
16#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
17#define EM_PPC 20 /* PowerPC */
18#define EM_PPC64 21 /* PowerPC64 */
19#define EM_SH 42 /* SuperH */
20#define EM_SPARCV9 43 /* SPARC v9 64-bit */
21#define EM_IA_64 50 /* HP/Intel IA-64 */
22#define EM_X86_64 62 /* AMD x86-64 */
23#define EM_S390 22 /* IBM S/390 */
24#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
25#define EM_V850 87 /* NEC v850 */
26#define EM_M32R 88 /* Renesas M32R */
27#define EM_H8_300 46 /* Renesas H8/300,300H,H8S */
28#define EM_FRV 0x5441 /* Fujitsu FR-V */
29
30/*
31 * This is an interim value that we will use until the committee comes
32 * up with a final number.
33 */
34#define EM_ALPHA 0x9026
35
36/* Bogus old v850 magic number, used by old tools. */
37#define EM_CYGNUS_V850 0x9080
38/* Bogus old m32r magic number, used by old tools. */
39#define EM_CYGNUS_M32R 0x9041
40/* This is the old interim value for S/390 architecture */
41#define EM_S390_OLD 0xA390
42
43
44#endif /* _LINUX_ELF_EM_H */
diff --git a/include/linux/elf.h b/include/linux/elf.h
index d3bfacb24496..b70d1d2c8d28 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/auxvec.h> 5#include <linux/auxvec.h>
6#include <linux/elf-em.h>
6#include <asm/elf.h> 7#include <asm/elf.h>
7 8
8#ifndef elf_read_implies_exec 9#ifndef elf_read_implies_exec
@@ -55,64 +56,6 @@ typedef __s64 Elf64_Sxword;
55#define ET_LOPROC 0xff00 56#define ET_LOPROC 0xff00
56#define ET_HIPROC 0xffff 57#define ET_HIPROC 0xffff
57 58
58/* These constants define the various ELF target machines */
59#define EM_NONE 0
60#define EM_M32 1
61#define EM_SPARC 2
62#define EM_386 3
63#define EM_68K 4
64#define EM_88K 5
65#define EM_486 6 /* Perhaps disused */
66#define EM_860 7
67
68#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
69
70#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
71
72#define EM_PARISC 15 /* HPPA */
73
74#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
75
76#define EM_PPC 20 /* PowerPC */
77#define EM_PPC64 21 /* PowerPC64 */
78
79#define EM_SH 42 /* SuperH */
80
81#define EM_SPARCV9 43 /* SPARC v9 64-bit */
82
83#define EM_IA_64 50 /* HP/Intel IA-64 */
84
85#define EM_X86_64 62 /* AMD x86-64 */
86
87#define EM_S390 22 /* IBM S/390 */
88
89#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
90
91#define EM_V850 87 /* NEC v850 */
92
93#define EM_M32R 88 /* Renesas M32R */
94
95#define EM_H8_300 46 /* Renesas H8/300,300H,H8S */
96
97/*
98 * This is an interim value that we will use until the committee comes
99 * up with a final number.
100 */
101#define EM_ALPHA 0x9026
102
103/* Bogus old v850 magic number, used by old tools. */
104#define EM_CYGNUS_V850 0x9080
105
106/* Bogus old m32r magic number, used by old tools. */
107#define EM_CYGNUS_M32R 0x9041
108
109/*
110 * This is the old interim value for S/390 architecture
111 */
112#define EM_S390_OLD 0xA390
113
114#define EM_FRV 0x5441 /* Fujitsu FR-V */
115
116/* This is the info that is needed to parse the dynamic section of the file */ 59/* This is the info that is needed to parse the dynamic section of the file */
117#define DT_NULL 0 60#define DT_NULL 0
118#define DT_NEEDED 1 61#define DT_NEEDED 1
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h
index 174582fedb8b..408118a07763 100644
--- a/include/linux/errqueue.h
+++ b/include/linux/errqueue.h
@@ -21,7 +21,6 @@ struct sock_extended_err
21 21
22#ifdef __KERNEL__ 22#ifdef __KERNEL__
23 23
24#include <linux/config.h>
25#include <net/ip.h> 24#include <net/ip.h>
26#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 25#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
27#include <linux/ipv6.h> 26#include <linux/ipv6.h>
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 93535f093216..cf2abeca92a0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -15,24 +15,24 @@
15 15
16/* This should work for both 32 and 64 bit userland. */ 16/* This should work for both 32 and 64 bit userland. */
17struct ethtool_cmd { 17struct ethtool_cmd {
18 u32 cmd; 18 __u32 cmd;
19 u32 supported; /* Features this interface supports */ 19 __u32 supported; /* Features this interface supports */
20 u32 advertising; /* Features this interface advertises */ 20 __u32 advertising; /* Features this interface advertises */
21 u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ 21 __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
22 u8 duplex; /* Duplex, half or full */ 22 __u8 duplex; /* Duplex, half or full */
23 u8 port; /* Which connector port */ 23 __u8 port; /* Which connector port */
24 u8 phy_address; 24 __u8 phy_address;
25 u8 transceiver; /* Which transceiver to use */ 25 __u8 transceiver; /* Which transceiver to use */
26 u8 autoneg; /* Enable or disable autonegotiation */ 26 __u8 autoneg; /* Enable or disable autonegotiation */
27 u32 maxtxpkt; /* Tx pkts before generating tx int */ 27 __u32 maxtxpkt; /* Tx pkts before generating tx int */
28 u32 maxrxpkt; /* Rx pkts before generating rx int */ 28 __u32 maxrxpkt; /* Rx pkts before generating rx int */
29 u32 reserved[4]; 29 __u32 reserved[4];
30}; 30};
31 31
32#define ETHTOOL_BUSINFO_LEN 32 32#define ETHTOOL_BUSINFO_LEN 32
33/* these strings are set to whatever the driver author decides... */ 33/* these strings are set to whatever the driver author decides... */
34struct ethtool_drvinfo { 34struct ethtool_drvinfo {
35 u32 cmd; 35 __u32 cmd;
36 char driver[32]; /* driver short name, "tulip", "eepro100" */ 36 char driver[32]; /* driver short name, "tulip", "eepro100" */
37 char version[32]; /* driver version string */ 37 char version[32]; /* driver version string */
38 char fw_version[32]; /* firmware version string, if applicable */ 38 char fw_version[32]; /* firmware version string, if applicable */
@@ -40,53 +40,53 @@ struct ethtool_drvinfo {
40 /* For PCI devices, use pci_name(pci_dev). */ 40 /* For PCI devices, use pci_name(pci_dev). */
41 char reserved1[32]; 41 char reserved1[32];
42 char reserved2[16]; 42 char reserved2[16];
43 u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ 43 __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
44 u32 testinfo_len; 44 __u32 testinfo_len;
45 u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ 45 __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
46 u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ 46 __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
47}; 47};
48 48
49#define SOPASS_MAX 6 49#define SOPASS_MAX 6
50/* wake-on-lan settings */ 50/* wake-on-lan settings */
51struct ethtool_wolinfo { 51struct ethtool_wolinfo {
52 u32 cmd; 52 __u32 cmd;
53 u32 supported; 53 __u32 supported;
54 u32 wolopts; 54 __u32 wolopts;
55 u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */ 55 __u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
56}; 56};
57 57
58/* for passing single values */ 58/* for passing single values */
59struct ethtool_value { 59struct ethtool_value {
60 u32 cmd; 60 __u32 cmd;
61 u32 data; 61 __u32 data;
62}; 62};
63 63
64/* for passing big chunks of data */ 64/* for passing big chunks of data */
65struct ethtool_regs { 65struct ethtool_regs {
66 u32 cmd; 66 __u32 cmd;
67 u32 version; /* driver-specific, indicates different chips/revs */ 67 __u32 version; /* driver-specific, indicates different chips/revs */
68 u32 len; /* bytes */ 68 __u32 len; /* bytes */
69 u8 data[0]; 69 __u8 data[0];
70}; 70};
71 71
72/* for passing EEPROM chunks */ 72/* for passing EEPROM chunks */
73struct ethtool_eeprom { 73struct ethtool_eeprom {
74 u32 cmd; 74 __u32 cmd;
75 u32 magic; 75 __u32 magic;
76 u32 offset; /* in bytes */ 76 __u32 offset; /* in bytes */
77 u32 len; /* in bytes */ 77 __u32 len; /* in bytes */
78 u8 data[0]; 78 __u8 data[0];
79}; 79};
80 80
81/* for configuring coalescing parameters of chip */ 81/* for configuring coalescing parameters of chip */
82struct ethtool_coalesce { 82struct ethtool_coalesce {
83 u32 cmd; /* ETHTOOL_{G,S}COALESCE */ 83 __u32 cmd; /* ETHTOOL_{G,S}COALESCE */
84 84
85 /* How many usecs to delay an RX interrupt after 85 /* How many usecs to delay an RX interrupt after
86 * a packet arrives. If 0, only rx_max_coalesced_frames 86 * a packet arrives. If 0, only rx_max_coalesced_frames
87 * is used. 87 * is used.
88 */ 88 */
89 u32 rx_coalesce_usecs; 89 __u32 rx_coalesce_usecs;
90 90
91 /* How many packets to delay an RX interrupt after 91 /* How many packets to delay an RX interrupt after
92 * a packet arrives. If 0, only rx_coalesce_usecs is 92 * a packet arrives. If 0, only rx_coalesce_usecs is
@@ -94,21 +94,21 @@ struct ethtool_coalesce {
94 * to zero as this would cause RX interrupts to never be 94 * to zero as this would cause RX interrupts to never be
95 * generated. 95 * generated.
96 */ 96 */
97 u32 rx_max_coalesced_frames; 97 __u32 rx_max_coalesced_frames;
98 98
99 /* Same as above two parameters, except that these values 99 /* Same as above two parameters, except that these values
100 * apply while an IRQ is being serviced by the host. Not 100 * apply while an IRQ is being serviced by the host. Not
101 * all cards support this feature and the values are ignored 101 * all cards support this feature and the values are ignored
102 * in that case. 102 * in that case.
103 */ 103 */
104 u32 rx_coalesce_usecs_irq; 104 __u32 rx_coalesce_usecs_irq;
105 u32 rx_max_coalesced_frames_irq; 105 __u32 rx_max_coalesced_frames_irq;
106 106
107 /* How many usecs to delay a TX interrupt after 107 /* How many usecs to delay a TX interrupt after
108 * a packet is sent. If 0, only tx_max_coalesced_frames 108 * a packet is sent. If 0, only tx_max_coalesced_frames
109 * is used. 109 * is used.
110 */ 110 */
111 u32 tx_coalesce_usecs; 111 __u32 tx_coalesce_usecs;
112 112
113 /* How many packets to delay a TX interrupt after 113 /* How many packets to delay a TX interrupt after
114 * a packet is sent. If 0, only tx_coalesce_usecs is 114 * a packet is sent. If 0, only tx_coalesce_usecs is
@@ -116,22 +116,22 @@ struct ethtool_coalesce {
116 * to zero as this would cause TX interrupts to never be 116 * to zero as this would cause TX interrupts to never be
117 * generated. 117 * generated.
118 */ 118 */
119 u32 tx_max_coalesced_frames; 119 __u32 tx_max_coalesced_frames;
120 120
121 /* Same as above two parameters, except that these values 121 /* Same as above two parameters, except that these values
122 * apply while an IRQ is being serviced by the host. Not 122 * apply while an IRQ is being serviced by the host. Not
123 * all cards support this feature and the values are ignored 123 * all cards support this feature and the values are ignored
124 * in that case. 124 * in that case.
125 */ 125 */
126 u32 tx_coalesce_usecs_irq; 126 __u32 tx_coalesce_usecs_irq;
127 u32 tx_max_coalesced_frames_irq; 127 __u32 tx_max_coalesced_frames_irq;
128 128
129 /* How many usecs to delay in-memory statistics 129 /* How many usecs to delay in-memory statistics
130 * block updates. Some drivers do not have an in-memory 130 * block updates. Some drivers do not have an in-memory
131 * statistic block, and in such cases this value is ignored. 131 * statistic block, and in such cases this value is ignored.
132 * This value must not be zero. 132 * This value must not be zero.
133 */ 133 */
134 u32 stats_block_coalesce_usecs; 134 __u32 stats_block_coalesce_usecs;
135 135
136 /* Adaptive RX/TX coalescing is an algorithm implemented by 136 /* Adaptive RX/TX coalescing is an algorithm implemented by
137 * some drivers to improve latency under low packet rates and 137 * some drivers to improve latency under low packet rates and
@@ -140,18 +140,18 @@ struct ethtool_coalesce {
140 * not implemented by the driver causes these values to be 140 * not implemented by the driver causes these values to be
141 * silently ignored. 141 * silently ignored.
142 */ 142 */
143 u32 use_adaptive_rx_coalesce; 143 __u32 use_adaptive_rx_coalesce;
144 u32 use_adaptive_tx_coalesce; 144 __u32 use_adaptive_tx_coalesce;
145 145
146 /* When the packet rate (measured in packets per second) 146 /* When the packet rate (measured in packets per second)
147 * is below pkt_rate_low, the {rx,tx}_*_low parameters are 147 * is below pkt_rate_low, the {rx,tx}_*_low parameters are
148 * used. 148 * used.
149 */ 149 */
150 u32 pkt_rate_low; 150 __u32 pkt_rate_low;
151 u32 rx_coalesce_usecs_low; 151 __u32 rx_coalesce_usecs_low;
152 u32 rx_max_coalesced_frames_low; 152 __u32 rx_max_coalesced_frames_low;
153 u32 tx_coalesce_usecs_low; 153 __u32 tx_coalesce_usecs_low;
154 u32 tx_max_coalesced_frames_low; 154 __u32 tx_max_coalesced_frames_low;
155 155
156 /* When the packet rate is below pkt_rate_high but above 156 /* When the packet rate is below pkt_rate_high but above
157 * pkt_rate_low (both measured in packets per second) the 157 * pkt_rate_low (both measured in packets per second) the
@@ -162,43 +162,43 @@ struct ethtool_coalesce {
162 * is above pkt_rate_high, the {rx,tx}_*_high parameters are 162 * is above pkt_rate_high, the {rx,tx}_*_high parameters are
163 * used. 163 * used.
164 */ 164 */
165 u32 pkt_rate_high; 165 __u32 pkt_rate_high;
166 u32 rx_coalesce_usecs_high; 166 __u32 rx_coalesce_usecs_high;
167 u32 rx_max_coalesced_frames_high; 167 __u32 rx_max_coalesced_frames_high;
168 u32 tx_coalesce_usecs_high; 168 __u32 tx_coalesce_usecs_high;
169 u32 tx_max_coalesced_frames_high; 169 __u32 tx_max_coalesced_frames_high;
170 170
171 /* How often to do adaptive coalescing packet rate sampling, 171 /* How often to do adaptive coalescing packet rate sampling,
172 * measured in seconds. Must not be zero. 172 * measured in seconds. Must not be zero.
173 */ 173 */
174 u32 rate_sample_interval; 174 __u32 rate_sample_interval;
175}; 175};
176 176
177/* for configuring RX/TX ring parameters */ 177/* for configuring RX/TX ring parameters */
178struct ethtool_ringparam { 178struct ethtool_ringparam {
179 u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ 179 __u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
180 180
181 /* Read only attributes. These indicate the maximum number 181 /* Read only attributes. These indicate the maximum number
182 * of pending RX/TX ring entries the driver will allow the 182 * of pending RX/TX ring entries the driver will allow the
183 * user to set. 183 * user to set.
184 */ 184 */
185 u32 rx_max_pending; 185 __u32 rx_max_pending;
186 u32 rx_mini_max_pending; 186 __u32 rx_mini_max_pending;
187 u32 rx_jumbo_max_pending; 187 __u32 rx_jumbo_max_pending;
188 u32 tx_max_pending; 188 __u32 tx_max_pending;
189 189
190 /* Values changeable by the user. The valid values are 190 /* Values changeable by the user. The valid values are
191 * in the range 1 to the "*_max_pending" counterpart above. 191 * in the range 1 to the "*_max_pending" counterpart above.
192 */ 192 */
193 u32 rx_pending; 193 __u32 rx_pending;
194 u32 rx_mini_pending; 194 __u32 rx_mini_pending;
195 u32 rx_jumbo_pending; 195 __u32 rx_jumbo_pending;
196 u32 tx_pending; 196 __u32 tx_pending;
197}; 197};
198 198
199/* for configuring link flow control parameters */ 199/* for configuring link flow control parameters */
200struct ethtool_pauseparam { 200struct ethtool_pauseparam {
201 u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ 201 __u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
202 202
203 /* If the link is being auto-negotiated (via ethtool_cmd.autoneg 203 /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
204 * being true) the user may set 'autonet' here non-zero to have the 204 * being true) the user may set 'autonet' here non-zero to have the
@@ -210,9 +210,9 @@ struct ethtool_pauseparam {
210 * then {rx,tx}_pause force the driver to use/not-use pause 210 * then {rx,tx}_pause force the driver to use/not-use pause
211 * flow control. 211 * flow control.
212 */ 212 */
213 u32 autoneg; 213 __u32 autoneg;
214 u32 rx_pause; 214 __u32 rx_pause;
215 u32 tx_pause; 215 __u32 tx_pause;
216}; 216};
217 217
218#define ETH_GSTRING_LEN 32 218#define ETH_GSTRING_LEN 32
@@ -223,10 +223,10 @@ enum ethtool_stringset {
223 223
224/* for passing string sets for data tagging */ 224/* for passing string sets for data tagging */
225struct ethtool_gstrings { 225struct ethtool_gstrings {
226 u32 cmd; /* ETHTOOL_GSTRINGS */ 226 __u32 cmd; /* ETHTOOL_GSTRINGS */
227 u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ 227 __u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
228 u32 len; /* number of strings in the string set */ 228 __u32 len; /* number of strings in the string set */
229 u8 data[0]; 229 __u8 data[0];
230}; 230};
231 231
232enum ethtool_test_flags { 232enum ethtool_test_flags {
@@ -236,26 +236,28 @@ enum ethtool_test_flags {
236 236
237/* for requesting NIC test and getting results*/ 237/* for requesting NIC test and getting results*/
238struct ethtool_test { 238struct ethtool_test {
239 u32 cmd; /* ETHTOOL_TEST */ 239 __u32 cmd; /* ETHTOOL_TEST */
240 u32 flags; /* ETH_TEST_FL_xxx */ 240 __u32 flags; /* ETH_TEST_FL_xxx */
241 u32 reserved; 241 __u32 reserved;
242 u32 len; /* result length, in number of u64 elements */ 242 __u32 len; /* result length, in number of u64 elements */
243 u64 data[0]; 243 __u64 data[0];
244}; 244};
245 245
246/* for dumping NIC-specific statistics */ 246/* for dumping NIC-specific statistics */
247struct ethtool_stats { 247struct ethtool_stats {
248 u32 cmd; /* ETHTOOL_GSTATS */ 248 __u32 cmd; /* ETHTOOL_GSTATS */
249 u32 n_stats; /* number of u64's being returned */ 249 __u32 n_stats; /* number of u64's being returned */
250 u64 data[0]; 250 __u64 data[0];
251}; 251};
252 252
253struct ethtool_perm_addr { 253struct ethtool_perm_addr {
254 u32 cmd; /* ETHTOOL_GPERMADDR */ 254 __u32 cmd; /* ETHTOOL_GPERMADDR */
255 u32 size; 255 __u32 size;
256 u8 data[0]; 256 __u8 data[0];
257}; 257};
258 258
259#ifdef __KERNEL__
260
259struct net_device; 261struct net_device;
260 262
261/* Some generic methods drivers may use in their ethtool_ops */ 263/* Some generic methods drivers may use in their ethtool_ops */
@@ -371,6 +373,7 @@ struct ethtool_ops {
371 u32 (*get_ufo)(struct net_device *); 373 u32 (*get_ufo)(struct net_device *);
372 int (*set_ufo)(struct net_device *, u32); 374 int (*set_ufo)(struct net_device *, u32);
373}; 375};
376#endif /* __KERNEL__ */
374 377
375/* CMDs currently supported */ 378/* CMDs currently supported */
376#define ETHTOOL_GSET 0x00000001 /* Get settings. */ 379#define ETHTOOL_GSET 0x00000001 /* Get settings. */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index f7bd1c7ebefb..facf34e98954 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -17,7 +17,6 @@
17#define _LINUX_EXT2_FS_H 17#define _LINUX_EXT2_FS_H
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/ext2_fs_sb.h>
21 20
22/* 21/*
23 * The second extended filesystem constants/structures 22 * The second extended filesystem constants/structures
@@ -70,6 +69,7 @@
70#define EXT2_SUPER_MAGIC 0xEF53 69#define EXT2_SUPER_MAGIC 0xEF53
71 70
72#ifdef __KERNEL__ 71#ifdef __KERNEL__
72#include <linux/ext2_fs_sb.h>
73static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) 73static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
74{ 74{
75 return sb->s_fs_info; 75 return sb->s_fs_info;
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 3ade6a4e3bdd..757d54d8f1a5 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -17,11 +17,6 @@
17#define _LINUX_EXT3_FS_H 17#define _LINUX_EXT3_FS_H
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/ext3_fs_i.h>
21#include <linux/ext3_fs_sb.h>
22
23
24struct statfs;
25 20
26/* 21/*
27 * The second extended filesystem constants/structures 22 * The second extended filesystem constants/structures
@@ -487,6 +482,8 @@ struct ext3_super_block {
487}; 482};
488 483
489#ifdef __KERNEL__ 484#ifdef __KERNEL__
485#include <linux/ext3_fs_i.h>
486#include <linux/ext3_fs_sb.h>
490static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) 487static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb)
491{ 488{
492 return sb->s_fs_info; 489 return sb->s_fs_info;
@@ -664,6 +661,8 @@ struct ext3_dir_entry_2 {
664#define DX_HASH_HALF_MD4 1 661#define DX_HASH_HALF_MD4 1
665#define DX_HASH_TEA 2 662#define DX_HASH_TEA 2
666 663
664#ifdef __KERNEL__
665
667/* hash info structure used by the directory hash */ 666/* hash info structure used by the directory hash */
668struct dx_hash_info 667struct dx_hash_info
669{ 668{
@@ -675,7 +674,6 @@ struct dx_hash_info
675 674
676#define EXT3_HTREE_EOF 0x7fffffff 675#define EXT3_HTREE_EOF 0x7fffffff
677 676
678#ifdef __KERNEL__
679/* 677/*
680 * Control parameters used by ext3_htree_next_block 678 * Control parameters used by ext3_htree_next_block
681 */ 679 */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1d80ba747484..2d5a112e8404 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -6,7 +6,6 @@
6 * structures etc. 6 * structures etc.
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/limits.h> 9#include <linux/limits.h>
11#include <linux/ioctl.h> 10#include <linux/ioctl.h>
12 11
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 11438eff4d44..cc5dec70c32c 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -54,19 +54,20 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
54 54
55 if (isdir) 55 if (isdir)
56 isdir = IN_ISDIR; 56 isdir = IN_ISDIR;
57 inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name); 57 inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name,
58 inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name); 58 source);
59 inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name,
60 source);
59 61
60 if (target) { 62 if (target) {
61 inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL); 63 inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL, NULL);
62 inotify_inode_is_dead(target); 64 inotify_inode_is_dead(target);
63 } 65 }
64 66
65 if (source) { 67 if (source) {
66 inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL); 68 inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
67 } 69 }
68 audit_inode_child(old_name, source, old_dir->i_ino); 70 audit_inode_child(new_name, source, new_dir->i_ino);
69 audit_inode_child(new_name, target, new_dir->i_ino);
70} 71}
71 72
72/* 73/*
@@ -85,7 +86,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
85 */ 86 */
86static inline void fsnotify_inoderemove(struct inode *inode) 87static inline void fsnotify_inoderemove(struct inode *inode)
87{ 88{
88 inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL); 89 inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL, NULL);
89 inotify_inode_is_dead(inode); 90 inotify_inode_is_dead(inode);
90} 91}
91 92
@@ -95,7 +96,8 @@ static inline void fsnotify_inoderemove(struct inode *inode)
95static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) 96static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
96{ 97{
97 inode_dir_notify(inode, DN_CREATE); 98 inode_dir_notify(inode, DN_CREATE);
98 inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name); 99 inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
100 dentry->d_inode);
99 audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); 101 audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
100} 102}
101 103
@@ -106,7 +108,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
106{ 108{
107 inode_dir_notify(inode, DN_CREATE); 109 inode_dir_notify(inode, DN_CREATE);
108 inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, 110 inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0,
109 dentry->d_name.name); 111 dentry->d_name.name, dentry->d_inode);
110 audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); 112 audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
111} 113}
112 114
@@ -123,7 +125,7 @@ static inline void fsnotify_access(struct dentry *dentry)
123 125
124 dnotify_parent(dentry, DN_ACCESS); 126 dnotify_parent(dentry, DN_ACCESS);
125 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); 127 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
126 inotify_inode_queue_event(inode, mask, 0, NULL); 128 inotify_inode_queue_event(inode, mask, 0, NULL, NULL);
127} 129}
128 130
129/* 131/*
@@ -139,7 +141,7 @@ static inline void fsnotify_modify(struct dentry *dentry)
139 141
140 dnotify_parent(dentry, DN_MODIFY); 142 dnotify_parent(dentry, DN_MODIFY);
141 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); 143 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
142 inotify_inode_queue_event(inode, mask, 0, NULL); 144 inotify_inode_queue_event(inode, mask, 0, NULL, NULL);
143} 145}
144 146
145/* 147/*
@@ -154,7 +156,7 @@ static inline void fsnotify_open(struct dentry *dentry)
154 mask |= IN_ISDIR; 156 mask |= IN_ISDIR;
155 157
156 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); 158 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
157 inotify_inode_queue_event(inode, mask, 0, NULL); 159 inotify_inode_queue_event(inode, mask, 0, NULL, NULL);
158} 160}
159 161
160/* 162/*
@@ -172,7 +174,7 @@ static inline void fsnotify_close(struct file *file)
172 mask |= IN_ISDIR; 174 mask |= IN_ISDIR;
173 175
174 inotify_dentry_parent_queue_event(dentry, mask, 0, name); 176 inotify_dentry_parent_queue_event(dentry, mask, 0, name);
175 inotify_inode_queue_event(inode, mask, 0, NULL); 177 inotify_inode_queue_event(inode, mask, 0, NULL, NULL);
176} 178}
177 179
178/* 180/*
@@ -187,7 +189,7 @@ static inline void fsnotify_xattr(struct dentry *dentry)
187 mask |= IN_ISDIR; 189 mask |= IN_ISDIR;
188 190
189 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); 191 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
190 inotify_inode_queue_event(inode, mask, 0, NULL); 192 inotify_inode_queue_event(inode, mask, 0, NULL, NULL);
191} 193}
192 194
193/* 195/*
@@ -234,7 +236,7 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
234 if (in_mask) { 236 if (in_mask) {
235 if (S_ISDIR(inode->i_mode)) 237 if (S_ISDIR(inode->i_mode))
236 in_mask |= IN_ISDIR; 238 in_mask |= IN_ISDIR;
237 inotify_inode_queue_event(inode, in_mask, 0, NULL); 239 inotify_inode_queue_event(inode, in_mask, 0, NULL, NULL);
238 inotify_dentry_parent_queue_event(dentry, in_mask, 0, 240 inotify_dentry_parent_queue_event(dentry, in_mask, 0,
239 dentry->d_name.name); 241 dentry->d_name.name);
240 } 242 }
diff --git a/include/linux/ftape.h b/include/linux/ftape.h
index 72faeec9f6e1..7e7038cba86a 100644
--- a/include/linux/ftape.h
+++ b/include/linux/ftape.h
@@ -35,7 +35,6 @@
35#include <linux/mm.h> 35#include <linux/mm.h>
36#endif 36#endif
37#include <linux/types.h> 37#include <linux/types.h>
38#include <linux/config.h>
39#include <linux/mtio.h> 38#include <linux/mtio.h>
40 39
41#define FT_SECTOR(x) (x+1) /* sector offset into real sector */ 40#define FT_SECTOR(x) (x+1) /* sector offset into real sector */
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index 71e7b2847cb3..2cdba0c23957 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -9,6 +9,7 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 */ 10 */
11 11
12#ifdef __KERNEL__
12#include <asm/io.h> 13#include <asm/io.h>
13#include <linux/list.h> 14#include <linux/list.h>
14#include <linux/mutex.h> 15#include <linux/mutex.h>
@@ -154,6 +155,8 @@ static inline void gameport_register_driver(struct gameport_driver *drv)
154 155
155void gameport_unregister_driver(struct gameport_driver *drv); 156void gameport_unregister_driver(struct gameport_driver *drv);
156 157
158#endif /* __KERNEL__ */
159
157#define GAMEPORT_MODE_DISABLED 0 160#define GAMEPORT_MODE_DISABLED 0
158#define GAMEPORT_MODE_RAW 1 161#define GAMEPORT_MODE_RAW 1
159#define GAMEPORT_MODE_COOKED 2 162#define GAMEPORT_MODE_COOKED 2
@@ -169,6 +172,8 @@ void gameport_unregister_driver(struct gameport_driver *drv);
169#define GAMEPORT_ID_VENDOR_GRAVIS 0x0009 172#define GAMEPORT_ID_VENDOR_GRAVIS 0x0009
170#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a 173#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a
171 174
175#ifdef __KERNEL__
176
172static inline void gameport_trigger(struct gameport *gameport) 177static inline void gameport_trigger(struct gameport *gameport)
173{ 178{
174 if (gameport->trigger) 179 if (gameport->trigger)
@@ -219,4 +224,5 @@ static inline void gameport_set_poll_interval(struct gameport *gameport, unsigne
219void gameport_start_polling(struct gameport *gameport); 224void gameport_start_polling(struct gameport *gameport);
220void gameport_stop_polling(struct gameport *gameport); 225void gameport_stop_polling(struct gameport *gameport);
221 226
227#endif /* __KERNEL__ */
222#endif 228#endif
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
index 652611a4bdcd..e25384561955 100644
--- a/include/linux/generic_serial.h
+++ b/include/linux/generic_serial.h
@@ -12,6 +12,7 @@
12#ifndef GENERIC_SERIAL_H 12#ifndef GENERIC_SERIAL_H
13#define GENERIC_SERIAL_H 13#define GENERIC_SERIAL_H
14 14
15#ifdef __KERNEL__
15#include <linux/mutex.h> 16#include <linux/mutex.h>
16 17
17struct real_driver { 18struct real_driver {
@@ -54,6 +55,7 @@ struct gs_port {
54 spinlock_t driver_lock; 55 spinlock_t driver_lock;
55}; 56};
56 57
58#endif /* __KERNEL__ */
57 59
58/* Flags */ 60/* Flags */
59/* Warning: serial.h defines some ASYNC_ flags, they say they are "only" 61/* Warning: serial.h defines some ASYNC_ flags, they say they are "only"
@@ -75,7 +77,7 @@ struct gs_port {
75#define GS_DEBUG_FLOW 0x00000020 77#define GS_DEBUG_FLOW 0x00000020
76#define GS_DEBUG_WRITE 0x00000040 78#define GS_DEBUG_WRITE 0x00000040
77 79
78 80#ifdef __KERNEL__
79void gs_put_char(struct tty_struct *tty, unsigned char ch); 81void gs_put_char(struct tty_struct *tty, unsigned char ch);
80int gs_write(struct tty_struct *tty, 82int gs_write(struct tty_struct *tty,
81 const unsigned char *buf, int count); 83 const unsigned char *buf, int count);
@@ -94,5 +96,5 @@ int gs_init_port(struct gs_port *port);
94int gs_setserial(struct gs_port *port, struct serial_struct __user *sp); 96int gs_setserial(struct gs_port *port, struct serial_struct __user *sp);
95int gs_getserial(struct gs_port *port, struct serial_struct __user *sp); 97int gs_getserial(struct gs_port *port, struct serial_struct __user *sp);
96void gs_got_break(struct gs_port *port); 98void gs_got_break(struct gs_port *port);
97 99#endif /* __KERNEL__ */
98#endif 100#endif
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 2ef845b35175..3498a0c68184 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -9,13 +9,7 @@
9 * <drew@colorado.edu> 9 * <drew@colorado.edu>
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/types.h> 12#include <linux/types.h>
14#include <linux/major.h>
15#include <linux/device.h>
16#include <linux/smp.h>
17#include <linux/string.h>
18#include <linux/fs.h>
19 13
20enum { 14enum {
21/* These three have identical behaviour; use the second one if DOS FDISK gets 15/* These three have identical behaviour; use the second one if DOS FDISK gets
@@ -61,6 +55,12 @@ struct partition {
61#endif 55#endif
62 56
63#ifdef __KERNEL__ 57#ifdef __KERNEL__
58#include <linux/major.h>
59#include <linux/device.h>
60#include <linux/smp.h>
61#include <linux/string.h>
62#include <linux/fs.h>
63
64struct partition { 64struct partition {
65 unsigned char boot_ind; /* 0x80 - active */ 65 unsigned char boot_ind; /* 0x80 - active */
66 unsigned char head; /* starting head */ 66 unsigned char head; /* starting head */
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 3ac452945a7d..cc9e60844484 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -4,7 +4,6 @@
4#include <linux/mmzone.h> 4#include <linux/mmzone.h>
5#include <linux/stddef.h> 5#include <linux/stddef.h>
6#include <linux/linkage.h> 6#include <linux/linkage.h>
7#include <linux/config.h>
8 7
9struct vm_area_struct; 8struct vm_area_struct;
10 9
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index eab537091f2a..114ae583cca9 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -1,7 +1,6 @@
1#ifndef LINUX_HARDIRQ_H 1#ifndef LINUX_HARDIRQ_H
2#define LINUX_HARDIRQ_H 2#define LINUX_HARDIRQ_H
3 3
4#include <linux/config.h>
5#include <linux/preempt.h> 4#include <linux/preempt.h>
6#include <linux/smp_lock.h> 5#include <linux/smp_lock.h>
7#include <asm/hardirq.h> 6#include <asm/hardirq.h>
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 892c4ea1b425..85ce7ef9a512 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_HIGHMEM_H 1#ifndef _LINUX_HIGHMEM_H
2#define _LINUX_HIGHMEM_H 2#define _LINUX_HIGHMEM_H
3 3
4#include <linux/config.h>
5#include <linux/fs.h> 4#include <linux/fs.h>
6#include <linux/mm.h> 5#include <linux/mm.h>
7 6
diff --git a/include/linux/highuid.h b/include/linux/highuid.h
index 53ecac3905e8..434e56246f67 100644
--- a/include/linux/highuid.h
+++ b/include/linux/highuid.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_HIGHUID_H 1#ifndef _LINUX_HIGHUID_H
2#define _LINUX_HIGHUID_H 2#define _LINUX_HIGHUID_H
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7/* 6/*
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 306acf1dc6d5..7d2a1b974c5e 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -127,7 +127,7 @@ extern ktime_t hrtimer_get_next_event(void);
127 127
128static inline int hrtimer_active(const struct hrtimer *timer) 128static inline int hrtimer_active(const struct hrtimer *timer)
129{ 129{
130 return timer->node.rb_parent != HRTIMER_INACTIVE; 130 return rb_parent(&timer->node) != &timer->node;
131} 131}
132 132
133/* Forward a hrtimer so it expires after now: */ 133/* Forward a hrtimer so it expires after now: */
diff --git a/include/linux/i2c-algo-ite.h b/include/linux/i2c-algo-ite.h
index 26a8b89855f1..0073fe96c76e 100644
--- a/include/linux/i2c-algo-ite.h
+++ b/include/linux/i2c-algo-ite.h
@@ -29,7 +29,7 @@
29#ifndef I2C_ALGO_ITE_H 29#ifndef I2C_ALGO_ITE_H
30#define I2C_ALGO_ITE_H 1 30#define I2C_ALGO_ITE_H 1
31 31
32#include <linux/i2c.h> 32#include <linux/types.h>
33 33
34/* Example of a sequential read request: 34/* Example of a sequential read request:
35 struct i2c_iic_msg s_msg; 35 struct i2c_iic_msg s_msg;
@@ -49,6 +49,9 @@ struct i2c_iic_msg {
49 char *buf; /* pointer to msg data */ 49 char *buf; /* pointer to msg data */
50}; 50};
51 51
52#ifdef __KERNEL__
53struct i2c_adapter;
54
52struct i2c_algo_iic_data { 55struct i2c_algo_iic_data {
53 void *data; /* private data for lolevel routines */ 56 void *data; /* private data for lolevel routines */
54 void (*setiic) (void *data, int ctl, int val); 57 void (*setiic) (void *data, int ctl, int val);
@@ -65,5 +68,5 @@ struct i2c_algo_iic_data {
65 68
66int i2c_iic_add_bus(struct i2c_adapter *); 69int i2c_iic_add_bus(struct i2c_adapter *);
67int i2c_iic_del_bus(struct i2c_adapter *); 70int i2c_iic_del_bus(struct i2c_adapter *);
68 71#endif /* __KERNEL__ */
69#endif /* I2C_ALGO_ITE_H */ 72#endif /* I2C_ALGO_ITE_H */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 1635ee25918f..0510430e00db 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -20,14 +20,15 @@
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21/* ------------------------------------------------------------------------- */ 21/* ------------------------------------------------------------------------- */
22 22
23/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 23/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
24 Frodo Looijaard <frodol@dds.nl> */ 24 Frodo Looijaard <frodol@dds.nl> */
25 25
26#ifndef _LINUX_I2C_H 26#ifndef _LINUX_I2C_H
27#define _LINUX_I2C_H 27#define _LINUX_I2C_H
28 28
29#include <linux/module.h>
30#include <linux/types.h> 29#include <linux/types.h>
30#ifdef __KERNEL__
31#include <linux/module.h>
31#include <linux/i2c-id.h> 32#include <linux/i2c-id.h>
32#include <linux/mod_devicetable.h> 33#include <linux/mod_devicetable.h>
33#include <linux/device.h> /* for struct device */ 34#include <linux/device.h> /* for struct device */
@@ -354,6 +355,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
354{ 355{
355 return adap->nr; 356 return adap->nr;
356} 357}
358#endif /* __KERNEL__ */
357 359
358/* 360/*
359 * I2C Message - used for pure i2c transaction, also from /dev interface 361 * I2C Message - used for pure i2c transaction, also from /dev interface
@@ -469,6 +471,7 @@ union i2c_smbus_data {
469#define I2C_SMBUS 0x0720 /* SMBus-level access */ 471#define I2C_SMBUS 0x0720 /* SMBus-level access */
470 472
471/* ----- I2C-DEV: char device interface stuff ------------------------- */ 473/* ----- I2C-DEV: char device interface stuff ------------------------- */
474#ifdef __KERNEL__
472 475
473#define I2C_MAJOR 89 /* Device major number */ 476#define I2C_MAJOR 89 /* Device major number */
474 477
@@ -646,5 +649,5 @@ static unsigned short *forces[] = { force, force_##chip1, \
646 force_##chip6, force_##chip7, \ 649 force_##chip6, force_##chip7, \
647 force_##chip8, NULL }; \ 650 force_##chip8, NULL }; \
648I2C_CLIENT_INSMOD_COMMON 651I2C_CLIENT_INSMOD_COMMON
649 652#endif /* __KERNEL__ */
650#endif /* _LINUX_I2C_H */ 653#endif /* _LINUX_I2C_H */
diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h
index 36fd18cdad28..c2519df1b6dc 100644
--- a/include/linux/i2o-dev.h
+++ b/include/linux/i2o-dev.h
@@ -13,7 +13,7 @@
13 * This header file defines the I2O APIs that are available to both 13 * This header file defines the I2O APIs that are available to both
14 * the kernel and user level applications. Kernel specific structures 14 * the kernel and user level applications. Kernel specific structures
15 * are defined in i2o_osm. OSMs should include _only_ i2o_osm.h which 15 * are defined in i2o_osm. OSMs should include _only_ i2o_osm.h which
16 * automatically includs this file. 16 * automatically includes this file.
17 * 17 *
18 */ 18 */
19 19
@@ -23,14 +23,7 @@
23/* How many controllers are we allowing */ 23/* How many controllers are we allowing */
24#define MAX_I2O_CONTROLLERS 32 24#define MAX_I2O_CONTROLLERS 32
25 25
26//#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#ifndef __KERNEL__
28
29typedef unsigned char u8;
30typedef unsigned short u16;
31typedef unsigned int u32;
32
33#endif /* __KERNEL__ */
34 27
35/* 28/*
36 * I2O Control IOCTLs and structures 29 * I2O Control IOCTLs and structures
@@ -53,7 +46,7 @@ typedef unsigned int u32;
53 46
54struct i2o_cmd_passthru32 { 47struct i2o_cmd_passthru32 {
55 unsigned int iop; /* IOP unit number */ 48 unsigned int iop; /* IOP unit number */
56 u32 msg; /* message */ 49 __u32 msg; /* message */
57}; 50};
58 51
59struct i2o_cmd_passthru { 52struct i2o_cmd_passthru {
@@ -138,53 +131,53 @@ typedef struct i2o_sg_io_hdr {
138#define I2O_BUS_UNKNOWN 0x80 131#define I2O_BUS_UNKNOWN 0x80
139 132
140typedef struct _i2o_pci_bus { 133typedef struct _i2o_pci_bus {
141 u8 PciFunctionNumber; 134 __u8 PciFunctionNumber;
142 u8 PciDeviceNumber; 135 __u8 PciDeviceNumber;
143 u8 PciBusNumber; 136 __u8 PciBusNumber;
144 u8 reserved; 137 __u8 reserved;
145 u16 PciVendorID; 138 __u16 PciVendorID;
146 u16 PciDeviceID; 139 __u16 PciDeviceID;
147} i2o_pci_bus; 140} i2o_pci_bus;
148 141
149typedef struct _i2o_local_bus { 142typedef struct _i2o_local_bus {
150 u16 LbBaseIOPort; 143 __u16 LbBaseIOPort;
151 u16 reserved; 144 __u16 reserved;
152 u32 LbBaseMemoryAddress; 145 __u32 LbBaseMemoryAddress;
153} i2o_local_bus; 146} i2o_local_bus;
154 147
155typedef struct _i2o_isa_bus { 148typedef struct _i2o_isa_bus {
156 u16 IsaBaseIOPort; 149 __u16 IsaBaseIOPort;
157 u8 CSN; 150 __u8 CSN;
158 u8 reserved; 151 __u8 reserved;
159 u32 IsaBaseMemoryAddress; 152 __u32 IsaBaseMemoryAddress;
160} i2o_isa_bus; 153} i2o_isa_bus;
161 154
162typedef struct _i2o_eisa_bus_info { 155typedef struct _i2o_eisa_bus_info {
163 u16 EisaBaseIOPort; 156 __u16 EisaBaseIOPort;
164 u8 reserved; 157 __u8 reserved;
165 u8 EisaSlotNumber; 158 __u8 EisaSlotNumber;
166 u32 EisaBaseMemoryAddress; 159 __u32 EisaBaseMemoryAddress;
167} i2o_eisa_bus; 160} i2o_eisa_bus;
168 161
169typedef struct _i2o_mca_bus { 162typedef struct _i2o_mca_bus {
170 u16 McaBaseIOPort; 163 __u16 McaBaseIOPort;
171 u8 reserved; 164 __u8 reserved;
172 u8 McaSlotNumber; 165 __u8 McaSlotNumber;
173 u32 McaBaseMemoryAddress; 166 __u32 McaBaseMemoryAddress;
174} i2o_mca_bus; 167} i2o_mca_bus;
175 168
176typedef struct _i2o_other_bus { 169typedef struct _i2o_other_bus {
177 u16 BaseIOPort; 170 __u16 BaseIOPort;
178 u16 reserved; 171 __u16 reserved;
179 u32 BaseMemoryAddress; 172 __u32 BaseMemoryAddress;
180} i2o_other_bus; 173} i2o_other_bus;
181 174
182typedef struct _i2o_hrt_entry { 175typedef struct _i2o_hrt_entry {
183 u32 adapter_id; 176 __u32 adapter_id;
184 u32 parent_tid:12; 177 __u32 parent_tid:12;
185 u32 state:4; 178 __u32 state:4;
186 u32 bus_num:8; 179 __u32 bus_num:8;
187 u32 bus_type:8; 180 __u32 bus_type:8;
188 union { 181 union {
189 i2o_pci_bus pci_bus; 182 i2o_pci_bus pci_bus;
190 i2o_local_bus local_bus; 183 i2o_local_bus local_bus;
@@ -196,66 +189,66 @@ typedef struct _i2o_hrt_entry {
196} i2o_hrt_entry; 189} i2o_hrt_entry;
197 190
198typedef struct _i2o_hrt { 191typedef struct _i2o_hrt {
199 u16 num_entries; 192 __u16 num_entries;
200 u8 entry_len; 193 __u8 entry_len;
201 u8 hrt_version; 194 __u8 hrt_version;
202 u32 change_ind; 195 __u32 change_ind;
203 i2o_hrt_entry hrt_entry[1]; 196 i2o_hrt_entry hrt_entry[1];
204} i2o_hrt; 197} i2o_hrt;
205 198
206typedef struct _i2o_lct_entry { 199typedef struct _i2o_lct_entry {
207 u32 entry_size:16; 200 __u32 entry_size:16;
208 u32 tid:12; 201 __u32 tid:12;
209 u32 reserved:4; 202 __u32 reserved:4;
210 u32 change_ind; 203 __u32 change_ind;
211 u32 device_flags; 204 __u32 device_flags;
212 u32 class_id:12; 205 __u32 class_id:12;
213 u32 version:4; 206 __u32 version:4;
214 u32 vendor_id:16; 207 __u32 vendor_id:16;
215 u32 sub_class; 208 __u32 sub_class;
216 u32 user_tid:12; 209 __u32 user_tid:12;
217 u32 parent_tid:12; 210 __u32 parent_tid:12;
218 u32 bios_info:8; 211 __u32 bios_info:8;
219 u8 identity_tag[8]; 212 __u8 identity_tag[8];
220 u32 event_capabilities; 213 __u32 event_capabilities;
221} i2o_lct_entry; 214} i2o_lct_entry;
222 215
223typedef struct _i2o_lct { 216typedef struct _i2o_lct {
224 u32 table_size:16; 217 __u32 table_size:16;
225 u32 boot_tid:12; 218 __u32 boot_tid:12;
226 u32 lct_ver:4; 219 __u32 lct_ver:4;
227 u32 iop_flags; 220 __u32 iop_flags;
228 u32 change_ind; 221 __u32 change_ind;
229 i2o_lct_entry lct_entry[1]; 222 i2o_lct_entry lct_entry[1];
230} i2o_lct; 223} i2o_lct;
231 224
232typedef struct _i2o_status_block { 225typedef struct _i2o_status_block {
233 u16 org_id; 226 __u16 org_id;
234 u16 reserved; 227 __u16 reserved;
235 u16 iop_id:12; 228 __u16 iop_id:12;
236 u16 reserved1:4; 229 __u16 reserved1:4;
237 u16 host_unit_id; 230 __u16 host_unit_id;
238 u16 segment_number:12; 231 __u16 segment_number:12;
239 u16 i2o_version:4; 232 __u16 i2o_version:4;
240 u8 iop_state; 233 __u8 iop_state;
241 u8 msg_type; 234 __u8 msg_type;
242 u16 inbound_frame_size; 235 __u16 inbound_frame_size;
243 u8 init_code; 236 __u8 init_code;
244 u8 reserved2; 237 __u8 reserved2;
245 u32 max_inbound_frames; 238 __u32 max_inbound_frames;
246 u32 cur_inbound_frames; 239 __u32 cur_inbound_frames;
247 u32 max_outbound_frames; 240 __u32 max_outbound_frames;
248 char product_id[24]; 241 char product_id[24];
249 u32 expected_lct_size; 242 __u32 expected_lct_size;
250 u32 iop_capabilities; 243 __u32 iop_capabilities;
251 u32 desired_mem_size; 244 __u32 desired_mem_size;
252 u32 current_mem_size; 245 __u32 current_mem_size;
253 u32 current_mem_base; 246 __u32 current_mem_base;
254 u32 desired_io_size; 247 __u32 desired_io_size;
255 u32 current_io_size; 248 __u32 current_io_size;
256 u32 current_io_base; 249 __u32 current_io_base;
257 u32 reserved3:24; 250 __u32 reserved3:24;
258 u32 cmd_status:8; 251 __u32 cmd_status:8;
259} i2o_status_block; 252} i2o_status_block;
260 253
261/* Event indicator mask flags */ 254/* Event indicator mask flags */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a8bef1d1371c..77e66d055f5b 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -6,7 +6,6 @@
6 * Copyright (C) 1994-2002 Linus Torvalds & authors 6 * Copyright (C) 1994-2002 Linus Torvalds & authors
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/ioport.h> 10#include <linux/ioport.h>
12#include <linux/hdreg.h> 11#include <linux/hdreg.h>
diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h
index 1288a161bc0b..e0a150046208 100644
--- a/include/linux/if_fddi.h
+++ b/include/linux/if_fddi.h
@@ -102,6 +102,7 @@ struct fddihdr
102 } hdr; 102 } hdr;
103 } __attribute__ ((packed)); 103 } __attribute__ ((packed));
104 104
105#ifdef __KERNEL__
105/* Define FDDI statistics structure */ 106/* Define FDDI statistics structure */
106struct fddi_statistics { 107struct fddi_statistics {
107 108
@@ -193,5 +194,6 @@ struct fddi_statistics {
193 __u32 port_ler_flag[2]; 194 __u32 port_ler_flag[2];
194 __u32 port_hardware_present[2]; 195 __u32 port_hardware_present[2];
195 }; 196 };
197#endif /* __KERNEL__ */
196 198
197#endif /* _LINUX_IF_FDDI_H */ 199#endif /* _LINUX_IF_FDDI_H */
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 395f0aad9cbf..f272a80caa3e 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -24,7 +24,6 @@
24#ifndef _FRAD_H_ 24#ifndef _FRAD_H_
25#define _FRAD_H_ 25#define _FRAD_H_
26 26
27#include <linux/config.h>
28#include <linux/if.h> 27#include <linux/if.h>
29 28
30#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE) 29#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE)
diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h
index 5502f597cf0e..2f94cf2c7abb 100644
--- a/include/linux/if_tr.h
+++ b/include/linux/if_tr.h
@@ -43,7 +43,6 @@ struct trh_hdr {
43}; 43};
44 44
45#ifdef __KERNEL__ 45#ifdef __KERNEL__
46#include <linux/config.h>
47#include <linux/skbuff.h> 46#include <linux/skbuff.h>
48 47
49static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb) 48static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb)
diff --git a/include/linux/init.h b/include/linux/init.h
index 93dcbe1abb4c..6667785dd1ff 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_INIT_H 1#ifndef _LINUX_INIT_H
2#define _LINUX_INIT_H 2#define _LINUX_INIT_H
3 3
4#include <linux/config.h>
5#include <linux/compiler.h> 4#include <linux/compiler.h>
6 5
7/* These macros are used to mark some functions or 6/* These macros are used to mark some functions or
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index 09e00433c78e..d4f48c6402e6 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -67,20 +67,66 @@ struct inotify_event {
67 67
68#include <linux/dcache.h> 68#include <linux/dcache.h>
69#include <linux/fs.h> 69#include <linux/fs.h>
70#include <linux/config.h> 70
71/*
72 * struct inotify_watch - represents a watch request on a specific inode
73 *
74 * h_list is protected by ih->mutex of the associated inotify_handle.
75 * i_list, mask are protected by inode->inotify_mutex of the associated inode.
76 * ih, inode, and wd are never written to once the watch is created.
77 *
78 * Callers must use the established inotify interfaces to access inotify_watch
79 * contents. The content of this structure is private to the inotify
80 * implementation.
81 */
82struct inotify_watch {
83 struct list_head h_list; /* entry in inotify_handle's list */
84 struct list_head i_list; /* entry in inode's list */
85 atomic_t count; /* reference count */
86 struct inotify_handle *ih; /* associated inotify handle */
87 struct inode *inode; /* associated inode */
88 __s32 wd; /* watch descriptor */
89 __u32 mask; /* event mask for this watch */
90};
91
92struct inotify_operations {
93 void (*handle_event)(struct inotify_watch *, u32, u32, u32,
94 const char *, struct inode *);
95 void (*destroy_watch)(struct inotify_watch *);
96};
71 97
72#ifdef CONFIG_INOTIFY 98#ifdef CONFIG_INOTIFY
73 99
100/* Kernel API for producing events */
101
74extern void inotify_d_instantiate(struct dentry *, struct inode *); 102extern void inotify_d_instantiate(struct dentry *, struct inode *);
75extern void inotify_d_move(struct dentry *); 103extern void inotify_d_move(struct dentry *);
76extern void inotify_inode_queue_event(struct inode *, __u32, __u32, 104extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
77 const char *); 105 const char *, struct inode *);
78extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32, 106extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32,
79 const char *); 107 const char *);
80extern void inotify_unmount_inodes(struct list_head *); 108extern void inotify_unmount_inodes(struct list_head *);
81extern void inotify_inode_is_dead(struct inode *); 109extern void inotify_inode_is_dead(struct inode *);
82extern u32 inotify_get_cookie(void); 110extern u32 inotify_get_cookie(void);
83 111
112/* Kernel Consumer API */
113
114extern struct inotify_handle *inotify_init(const struct inotify_operations *);
115extern void inotify_init_watch(struct inotify_watch *);
116extern void inotify_destroy(struct inotify_handle *);
117extern __s32 inotify_find_watch(struct inotify_handle *, struct inode *,
118 struct inotify_watch **);
119extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *,
120 u32);
121extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
122 struct inode *, __u32);
123extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *);
124extern int inotify_rm_wd(struct inotify_handle *, __u32);
125extern void inotify_remove_watch_locked(struct inotify_handle *,
126 struct inotify_watch *);
127extern void get_inotify_watch(struct inotify_watch *);
128extern void put_inotify_watch(struct inotify_watch *);
129
84#else 130#else
85 131
86static inline void inotify_d_instantiate(struct dentry *dentry, 132static inline void inotify_d_instantiate(struct dentry *dentry,
@@ -94,7 +140,8 @@ static inline void inotify_d_move(struct dentry *dentry)
94 140
95static inline void inotify_inode_queue_event(struct inode *inode, 141static inline void inotify_inode_queue_event(struct inode *inode,
96 __u32 mask, __u32 cookie, 142 __u32 mask, __u32 cookie,
97 const char *filename) 143 const char *filename,
144 struct inode *n_inode)
98{ 145{
99} 146}
100 147
@@ -117,6 +164,62 @@ static inline u32 inotify_get_cookie(void)
117 return 0; 164 return 0;
118} 165}
119 166
167static inline struct inotify_handle *inotify_init(const struct inotify_operations *ops)
168{
169 return ERR_PTR(-EOPNOTSUPP);
170}
171
172static inline void inotify_init_watch(struct inotify_watch *watch)
173{
174}
175
176static inline void inotify_destroy(struct inotify_handle *ih)
177{
178}
179
180static inline __s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
181 struct inotify_watch **watchp)
182{
183 return -EOPNOTSUPP;
184}
185
186static inline __s32 inotify_find_update_watch(struct inotify_handle *ih,
187 struct inode *inode, u32 mask)
188{
189 return -EOPNOTSUPP;
190}
191
192static inline __s32 inotify_add_watch(struct inotify_handle *ih,
193 struct inotify_watch *watch,
194 struct inode *inode, __u32 mask)
195{
196 return -EOPNOTSUPP;
197}
198
199static inline int inotify_rm_watch(struct inotify_handle *ih,
200 struct inotify_watch *watch)
201{
202 return -EOPNOTSUPP;
203}
204
205static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd)
206{
207 return -EOPNOTSUPP;
208}
209
210static inline void inotify_remove_watch_locked(struct inotify_handle *ih,
211 struct inotify_watch *watch)
212{
213}
214
215static inline void get_inotify_watch(struct inotify_watch *watch)
216{
217}
218
219static inline void put_inotify_watch(struct inotify_watch *watch)
220{
221}
222
120#endif /* CONFIG_INOTIFY */ 223#endif /* CONFIG_INOTIFY */
121 224
122#endif /* __KERNEL __ */ 225#endif /* __KERNEL __ */
diff --git a/include/linux/input.h b/include/linux/input.h
index ce1a756c4c30..b32c2b6e53f6 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -15,6 +15,7 @@
15#else 15#else
16#include <sys/time.h> 16#include <sys/time.h>
17#include <sys/ioctl.h> 17#include <sys/ioctl.h>
18#include <sys/types.h>
18#include <asm/types.h> 19#include <asm/types.h>
19#endif 20#endif
20 21
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 2c08fdc2bdf7..9e0fefd7884a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -2,7 +2,6 @@
2#ifndef _LINUX_INTERRUPT_H 2#ifndef _LINUX_INTERRUPT_H
3#define _LINUX_INTERRUPT_H 3#define _LINUX_INTERRUPT_H
4 4
5#include <linux/config.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/linkage.h> 6#include <linux/linkage.h>
8#include <linux/bitops.h> 7#include <linux/bitops.h>
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 0a84b56935c2..5653b2f23b6a 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -36,7 +36,6 @@
36 36
37#include <linux/ipmi_msgdefs.h> 37#include <linux/ipmi_msgdefs.h>
38#include <linux/compiler.h> 38#include <linux/compiler.h>
39#include <linux/device.h>
40 39
41/* 40/*
42 * This file describes an interface to an IPMI driver. You have to 41 * This file describes an interface to an IPMI driver. You have to
@@ -210,6 +209,7 @@ struct kernel_ipmi_msg
210 */ 209 */
211#include <linux/list.h> 210#include <linux/list.h>
212#include <linux/module.h> 211#include <linux/module.h>
212#include <linux/device.h>
213 213
214#ifdef CONFIG_PROC_FS 214#ifdef CONFIG_PROC_FS
215#include <linux/proc_fs.h> 215#include <linux/proc_fs.h>
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 1263d8cb3c18..297853c841b4 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -1,7 +1,6 @@
1#ifndef _IPV6_H 1#ifndef _IPV6_H
2#define _IPV6_H 2#define _IPV6_H
3 3
4#include <linux/config.h>
5#include <linux/in6.h> 4#include <linux/in6.h>
6#include <asm/byteorder.h> 5#include <asm/byteorder.h>
7 6
diff --git a/include/linux/irq.h b/include/linux/irq.h
index ee2a82a572f7..42c9cd562860 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -9,7 +9,6 @@
9 * Thanks. --rmk 9 * Thanks. --rmk
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/smp.h> 12#include <linux/smp.h>
14 13
15#if !defined(CONFIG_S390) 14#if !defined(CONFIG_S390)
diff --git a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h
index af93505ec2ec..77e4bac29287 100644
--- a/include/linux/irq_cpustat.h
+++ b/include/linux/irq_cpustat.h
@@ -9,7 +9,6 @@
9 * Keith Owens <kaos@ocs.com.au> July 2000. 9 * Keith Owens <kaos@ocs.com.au> July 2000.
10 */ 10 */
11 11
12#include <linux/config.h>
13 12
14/* 13/*
15 * Simple wrappers reducing source bloat. Define all irq_stat fields 14 * Simple wrappers reducing source bloat. Define all irq_stat fields
diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h
index 26c64c286f42..1e8728a9ee8a 100644
--- a/include/linux/isapnp.h
+++ b/include/linux/isapnp.h
@@ -22,7 +22,6 @@
22#ifndef LINUX_ISAPNP_H 22#ifndef LINUX_ISAPNP_H
23#define LINUX_ISAPNP_H 23#define LINUX_ISAPNP_H
24 24
25#include <linux/config.h>
26#include <linux/errno.h> 25#include <linux/errno.h>
27#include <linux/pnp.h> 26#include <linux/pnp.h>
28 27
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 53eaee96065b..62991148d5a5 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -146,7 +146,6 @@ typedef struct {
146 146
147#ifdef __KERNEL__ 147#ifdef __KERNEL__
148 148
149#include <linux/config.h>
150#include <linux/errno.h> 149#include <linux/errno.h>
151#include <linux/fs.h> 150#include <linux/fs.h>
152#include <linux/major.h> 151#include <linux/major.h>
diff --git a/include/linux/isdn/tpam.h b/include/linux/isdn/tpam.h
index 9f65bea49d11..d18dd0dc570d 100644
--- a/include/linux/isdn/tpam.h
+++ b/include/linux/isdn/tpam.h
@@ -26,7 +26,6 @@
26#define _TPAM_H_ 26#define _TPAM_H_
27 27
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/pci.h>
30 29
31/* IOCTL commands */ 30/* IOCTL commands */
32#define TPAM_CMD_DSPLOAD 0x0001 31#define TPAM_CMD_DSPLOAD 0x0001
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h
index 26b00a76e135..8687a7dc0632 100644
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -67,7 +67,6 @@ struct isdn_ppp_comp_data {
67#ifdef __KERNEL__ 67#ifdef __KERNEL__
68 68
69 69
70#include <linux/config.h>
71 70
72#ifdef CONFIG_IPPP_FILTER 71#ifdef CONFIG_IPPP_FILTER
73#include <linux/filter.h> 72#include <linux/filter.h>
diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h
index 04e10f9f14f8..b9b5a684ed69 100644
--- a/include/linux/isdnif.h
+++ b/include/linux/isdnif.h
@@ -54,7 +54,6 @@
54 54
55#ifdef __KERNEL__ 55#ifdef __KERNEL__
56 56
57#include <linux/config.h>
58#include <linux/skbuff.h> 57#include <linux/skbuff.h>
59 58
60/***************************************************************************/ 59/***************************************************************************/
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index cf792bb3c726..c6f70660b371 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -65,6 +65,18 @@
65 65
66#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6) 66#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6)
67 67
68#define JFFS2_NODETYPE_XATTR (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 8)
69#define JFFS2_NODETYPE_XREF (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 9)
70
71/* XATTR Related */
72#define JFFS2_XPREFIX_USER 1 /* for "user." */
73#define JFFS2_XPREFIX_SECURITY 2 /* for "security." */
74#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */
75#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */
76#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */
77
78#define JFFS2_ACL_VERSION 0x0001
79
68// Maybe later... 80// Maybe later...
69//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) 81//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
70//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) 82//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
@@ -82,11 +94,11 @@
82 94
83typedef struct { 95typedef struct {
84 uint32_t v32; 96 uint32_t v32;
85} __attribute__((packed)) jint32_t; 97} __attribute__((packed)) jint32_t;
86 98
87typedef struct { 99typedef struct {
88 uint32_t m; 100 uint32_t m;
89} __attribute__((packed)) jmode_t; 101} __attribute__((packed)) jmode_t;
90 102
91typedef struct { 103typedef struct {
92 uint16_t v16; 104 uint16_t v16;
@@ -99,7 +111,7 @@ struct jffs2_unknown_node
99 jint16_t nodetype; 111 jint16_t nodetype;
100 jint32_t totlen; /* So we can skip over nodes we don't grok */ 112 jint32_t totlen; /* So we can skip over nodes we don't grok */
101 jint32_t hdr_crc; 113 jint32_t hdr_crc;
102} __attribute__((packed)); 114};
103 115
104struct jffs2_raw_dirent 116struct jffs2_raw_dirent
105{ 117{
@@ -117,7 +129,7 @@ struct jffs2_raw_dirent
117 jint32_t node_crc; 129 jint32_t node_crc;
118 jint32_t name_crc; 130 jint32_t name_crc;
119 uint8_t name[0]; 131 uint8_t name[0];
120} __attribute__((packed)); 132};
121 133
122/* The JFFS2 raw inode structure: Used for storage on physical media. */ 134/* The JFFS2 raw inode structure: Used for storage on physical media. */
123/* The uid, gid, atime, mtime and ctime members could be longer, but 135/* The uid, gid, atime, mtime and ctime members could be longer, but
@@ -149,6 +161,32 @@ struct jffs2_raw_inode
149 jint32_t data_crc; /* CRC for the (compressed) data. */ 161 jint32_t data_crc; /* CRC for the (compressed) data. */
150 jint32_t node_crc; /* CRC for the raw inode (excluding data) */ 162 jint32_t node_crc; /* CRC for the raw inode (excluding data) */
151 uint8_t data[0]; 163 uint8_t data[0];
164};
165
166struct jffs2_raw_xattr {
167 jint16_t magic;
168 jint16_t nodetype; /* = JFFS2_NODETYPE_XATTR */
169 jint32_t totlen;
170 jint32_t hdr_crc;
171 jint32_t xid; /* XATTR identifier number */
172 jint32_t version;
173 uint8_t xprefix;
174 uint8_t name_len;
175 jint16_t value_len;
176 jint32_t data_crc;
177 jint32_t node_crc;
178 uint8_t data[0];
179} __attribute__((packed));
180
181struct jffs2_raw_xref
182{
183 jint16_t magic;
184 jint16_t nodetype; /* = JFFS2_NODETYPE_XREF */
185 jint32_t totlen;
186 jint32_t hdr_crc;
187 jint32_t ino; /* inode number */
188 jint32_t xid; /* XATTR identifier number */
189 jint32_t node_crc;
152} __attribute__((packed)); 190} __attribute__((packed));
153 191
154struct jffs2_raw_summary 192struct jffs2_raw_summary
@@ -163,14 +201,22 @@ struct jffs2_raw_summary
163 jint32_t sum_crc; /* summary information crc */ 201 jint32_t sum_crc; /* summary information crc */
164 jint32_t node_crc; /* node crc */ 202 jint32_t node_crc; /* node crc */
165 jint32_t sum[0]; /* inode summary info */ 203 jint32_t sum[0]; /* inode summary info */
166} __attribute__((packed)); 204};
167 205
168union jffs2_node_union 206union jffs2_node_union
169{ 207{
170 struct jffs2_raw_inode i; 208 struct jffs2_raw_inode i;
171 struct jffs2_raw_dirent d; 209 struct jffs2_raw_dirent d;
210 struct jffs2_raw_xattr x;
211 struct jffs2_raw_xref r;
172 struct jffs2_raw_summary s; 212 struct jffs2_raw_summary s;
173 struct jffs2_unknown_node u; 213 struct jffs2_unknown_node u;
174}; 214};
175 215
216/* Data payload for device nodes. */
217union jffs2_device_node {
218 jint16_t old;
219 jint32_t new;
220};
221
176#endif /* __LINUX_JFFS2_H__ */ 222#endif /* __LINUX_JFFS2_H__ */
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
index 5fd20ddd7ae3..e2d3a18af456 100644
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -111,25 +111,25 @@ struct js_corr {
111#define JS_SET_ALL 8 111#define JS_SET_ALL 8
112 112
113struct JS_DATA_TYPE { 113struct JS_DATA_TYPE {
114 int32_t buttons; 114 __s32 buttons;
115 int32_t x; 115 __s32 x;
116 int32_t y; 116 __s32 y;
117}; 117};
118 118
119struct JS_DATA_SAVE_TYPE_32 { 119struct JS_DATA_SAVE_TYPE_32 {
120 int32_t JS_TIMEOUT; 120 __s32 JS_TIMEOUT;
121 int32_t BUSY; 121 __s32 BUSY;
122 int32_t JS_EXPIRETIME; 122 __s32 JS_EXPIRETIME;
123 int32_t JS_TIMELIMIT; 123 __s32 JS_TIMELIMIT;
124 struct JS_DATA_TYPE JS_SAVE; 124 struct JS_DATA_TYPE JS_SAVE;
125 struct JS_DATA_TYPE JS_CORR; 125 struct JS_DATA_TYPE JS_CORR;
126}; 126};
127 127
128struct JS_DATA_SAVE_TYPE_64 { 128struct JS_DATA_SAVE_TYPE_64 {
129 int32_t JS_TIMEOUT; 129 __s32 JS_TIMEOUT;
130 int32_t BUSY; 130 __s32 BUSY;
131 int64_t JS_EXPIRETIME; 131 __s64 JS_EXPIRETIME;
132 int64_t JS_TIMELIMIT; 132 __s64 JS_TIMELIMIT;
133 struct JS_DATA_TYPE JS_SAVE; 133 struct JS_DATA_TYPE JS_SAVE;
134 struct JS_DATA_TYPE JS_CORR; 134 struct JS_DATA_TYPE JS_CORR;
135}; 135};
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 9bbd04092365..54e2549f96ba 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -5,7 +5,6 @@
5#ifndef _LINUX_KALLSYMS_H 5#ifndef _LINUX_KALLSYMS_H
6#define _LINUX_KALLSYMS_H 6#define _LINUX_KALLSYMS_H
7 7
8#include <linux/config.h>
9 8
10#define KSYM_NAME_LEN 127 9#define KSYM_NAME_LEN 127
11 10
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index b46249082cca..43e895f1cabe 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_KERNEL_STAT_H 1#ifndef _LINUX_KERNEL_STAT_H
2#define _LINUX_KERNEL_STAT_H 2#define _LINUX_KERNEL_STAT_H
3 3
4#include <linux/config.h>
5#include <asm/irq.h> 4#include <asm/irq.h>
6#include <linux/smp.h> 5#include <linux/smp.h>
7#include <linux/threads.h> 6#include <linux/threads.h>
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index e4a231549407..0db22a1ab474 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -20,7 +20,6 @@
20 */ 20 */
21 21
22#include <linux/stddef.h> 22#include <linux/stddef.h>
23#include <linux/config.h>
24#include <linux/errno.h> 23#include <linux/errno.h>
25#include <linux/compiler.h> 24#include <linux/compiler.h>
26 25
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 778adc0fa640..8bf6702da2a0 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -29,7 +29,6 @@
29 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi 29 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
30 * <prasanna@in.ibm.com> added function-return probes. 30 * <prasanna@in.ibm.com> added function-return probes.
31 */ 31 */
32#include <linux/config.h>
33#include <linux/list.h> 32#include <linux/list.h>
34#include <linux/notifier.h> 33#include <linux/notifier.h>
35#include <linux/smp.h> 34#include <linux/smp.h>
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index c08c9983e840..932021f872d5 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_LINKAGE_H 1#ifndef _LINUX_LINKAGE_H
2#define _LINUX_LINKAGE_H 2#define _LINUX_LINKAGE_H
3 3
4#include <linux/config.h>
5#include <asm/linkage.h> 4#include <asm/linkage.h>
6 5
7#ifdef __cplusplus 6#ifdef __cplusplus
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 6b2684763fc7..aa4fe905bb4d 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -11,7 +11,6 @@
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <linux/in.h> 14#include <linux/in.h>
16#include <linux/fs.h> 15#include <linux/fs.h>
17#include <linux/kref.h> 16#include <linux/kref.h>
diff --git a/include/linux/lockd/nlm.h b/include/linux/lockd/nlm.h
index 869b630cba24..d9d46e442538 100644
--- a/include/linux/lockd/nlm.h
+++ b/include/linux/lockd/nlm.h
@@ -9,7 +9,6 @@
9#ifndef LINUX_LOCKD_NLM_H 9#ifndef LINUX_LOCKD_NLM_H
10#define LINUX_LOCKD_NLM_H 10#define LINUX_LOCKD_NLM_H
11 11
12#include <linux/config.h>
13 12
14/* Maximum file offset in file_lock.fl_end */ 13/* Maximum file offset in file_lock.fl_end */
15# define NLM_OFFSET_MAX ((s32) 0x7fffffff) 14# define NLM_OFFSET_MAX ((s32) 0x7fffffff)
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index f5fdca1d67e6..72440f0a443d 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -28,7 +28,6 @@
28 28
29#ifdef __KERNEL__ 29#ifdef __KERNEL__
30 30
31#include <linux/config.h>
32#include <linux/mmzone.h> 31#include <linux/mmzone.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include <linux/rbtree.h> 33#include <linux/rbtree.h>
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index ff0a64073ebc..6789c4940c9c 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_MIGRATE_H 1#ifndef _LINUX_MIGRATE_H
2#define _LINUX_MIGRATE_H 2#define _LINUX_MIGRATE_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6 5
7#ifdef CONFIG_MIGRATION 6#ifdef CONFIG_MIGRATION
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 68f5a0f392dd..beddc6d3b0f6 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -9,7 +9,6 @@
9#define __LINUX_MII_H__ 9#define __LINUX_MII_H__
10 10
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/if.h>
13 12
14/* Generic MII registers. */ 13/* Generic MII registers. */
15 14
@@ -136,6 +135,20 @@
136#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ 135#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
137#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ 136#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
138 137
138/* This structure is used in all SIOCxMIIxxx ioctl calls */
139struct mii_ioctl_data {
140 __u16 phy_id;
141 __u16 reg_num;
142 __u16 val_in;
143 __u16 val_out;
144};
145
146#ifdef __KERNEL__
147
148#include <linux/if.h>
149
150struct ethtool_cmd;
151
139struct mii_if_info { 152struct mii_if_info {
140 int phy_id; 153 int phy_id;
141 int advertising; 154 int advertising;
@@ -151,9 +164,6 @@ struct mii_if_info {
151 void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val); 164 void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
152}; 165};
153 166
154struct ethtool_cmd;
155struct mii_ioctl_data;
156
157extern int mii_link_ok (struct mii_if_info *mii); 167extern int mii_link_ok (struct mii_if_info *mii);
158extern int mii_nway_restart (struct mii_if_info *mii); 168extern int mii_nway_restart (struct mii_if_info *mii);
159extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd); 169extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
@@ -168,16 +178,6 @@ extern int generic_mii_ioctl(struct mii_if_info *mii_if,
168 unsigned int *duplex_changed); 178 unsigned int *duplex_changed);
169 179
170 180
171
172/* This structure is used in all SIOCxMIIxxx ioctl calls */
173struct mii_ioctl_data {
174 u16 phy_id;
175 u16 reg_num;
176 u16 val_in;
177 u16 val_out;
178};
179
180
181static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) 181static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
182{ 182{
183 return (struct mii_ioctl_data *) &rq->ifr_ifru; 183 return (struct mii_ioctl_data *) &rq->ifr_ifru;
@@ -235,5 +235,5 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
235 return 0; 235 return 0;
236} 236}
237 237
238 238#endif /* __KERNEL__ */
239#endif /* __LINUX_MII_H__ */ 239#endif /* __LINUX_MII_H__ */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1154684209a4..e2fa375e478e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -7,7 +7,6 @@
7 7
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9 9
10#include <linux/config.h>
11#include <linux/gfp.h> 10#include <linux/gfp.h>
12#include <linux/list.h> 11#include <linux/list.h>
13#include <linux/mmzone.h> 12#include <linux/mmzone.h>
diff --git a/include/linux/mman.h b/include/linux/mman.h
index 18a5689ef748..87920a0852a3 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -1,10 +1,6 @@
1#ifndef _LINUX_MMAN_H 1#ifndef _LINUX_MMAN_H
2#define _LINUX_MMAN_H 2#define _LINUX_MMAN_H
3 3
4#include <linux/config.h>
5#include <linux/mm.h>
6
7#include <asm/atomic.h>
8#include <asm/mman.h> 4#include <asm/mman.h>
9 5
10#define MREMAP_MAYMOVE 1 6#define MREMAP_MAYMOVE 1
@@ -13,6 +9,12 @@
13#define OVERCOMMIT_GUESS 0 9#define OVERCOMMIT_GUESS 0
14#define OVERCOMMIT_ALWAYS 1 10#define OVERCOMMIT_ALWAYS 1
15#define OVERCOMMIT_NEVER 2 11#define OVERCOMMIT_NEVER 2
12
13#ifdef __KERNEL__
14#include <linux/mm.h>
15
16#include <asm/atomic.h>
17
16extern int sysctl_overcommit_memory; 18extern int sysctl_overcommit_memory;
17extern int sysctl_overcommit_ratio; 19extern int sysctl_overcommit_ratio;
18extern atomic_t vm_committed_space; 20extern atomic_t vm_committed_space;
@@ -63,5 +65,5 @@ calc_vm_flag_bits(unsigned long flags)
63 _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) | 65 _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
64 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ); 66 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
65} 67}
66 68#endif /* __KERNEL__ */
67#endif /* _LINUX_MMAN_H */ 69#endif /* _LINUX_MMAN_H */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 2d8337150493..9742e3c16222 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -4,7 +4,6 @@
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#ifndef __ASSEMBLY__ 5#ifndef __ASSEMBLY__
6 6
7#include <linux/config.h>
8#include <linux/spinlock.h> 7#include <linux/spinlock.h>
9#include <linux/list.h> 8#include <linux/list.h>
10#include <linux/wait.h> 9#include <linux/wait.h>
diff --git a/include/linux/module.h b/include/linux/module.h
index eaec13ddd667..c2d89e037af0 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -6,7 +6,6 @@
6 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996 6 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
7 * Rewritten again by Rusty Russell, 2002 7 * Rewritten again by Rusty Russell, 2002
8 */ 8 */
9#include <linux/config.h>
10#include <linux/sched.h> 9#include <linux/sched.h>
11#include <linux/spinlock.h> 10#include <linux/spinlock.h>
12#include <linux/list.h> 11#include <linux/list.h>
@@ -557,13 +556,4 @@ static inline void module_remove_driver(struct device_driver *driver)
557 556
558#define __MODULE_STRING(x) __stringify(x) 557#define __MODULE_STRING(x) __stringify(x)
559 558
560/* Use symbol_get and symbol_put instead. You'll thank me. */
561#define HAVE_INTER_MODULE
562extern void __deprecated inter_module_register(const char *,
563 struct module *, const void *);
564extern void __deprecated inter_module_unregister(const char *);
565extern const void * __deprecated inter_module_get_request(const char *,
566 const char *);
567extern void __deprecated inter_module_put(const char *);
568
569#endif /* _LINUX_MODULE_H */ 559#endif /* _LINUX_MODULE_H */
diff --git a/include/linux/msg.h b/include/linux/msg.h
index 903e0ab8101f..acc7c174ff00 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -2,7 +2,6 @@
2#define _LINUX_MSG_H 2#define _LINUX_MSG_H
3 3
4#include <linux/ipc.h> 4#include <linux/ipc.h>
5#include <linux/list.h>
6 5
7/* ipcs ctl commands */ 6/* ipcs ctl commands */
8#define MSG_STAT 11 7#define MSG_STAT 11
@@ -63,6 +62,7 @@ struct msginfo {
63#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff) 62#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
64 63
65#ifdef __KERNEL__ 64#ifdef __KERNEL__
65#include <linux/list.h>
66 66
67/* one msg_msg structure for each message */ 67/* one msg_msg structure for each message */
68struct msg_msg { 68struct msg_msg {
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 23a568910341..09bfae6938b3 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -7,7 +7,6 @@
7#ifndef __MTD_CFI_H__ 7#ifndef __MTD_CFI_H__
8#define __MTD_CFI_H__ 8#define __MTD_CFI_H__
9 9
10#include <linux/config.h>
11#include <linux/delay.h> 10#include <linux/delay.h>
12#include <linux/types.h> 11#include <linux/types.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
index d7eaa40e5ab0..6977780e548f 100644
--- a/include/linux/mtd/inftl.h
+++ b/include/linux/mtd/inftl.h
@@ -46,7 +46,7 @@ struct INFTLrecord {
46 unsigned int nb_blocks; /* number of physical blocks */ 46 unsigned int nb_blocks; /* number of physical blocks */
47 unsigned int nb_boot_blocks; /* number of blocks used by the bios */ 47 unsigned int nb_boot_blocks; /* number of blocks used by the bios */
48 struct erase_info instr; 48 struct erase_info instr;
49 struct nand_oobinfo oobinfo; 49 struct nand_ecclayout oobinfo;
50}; 50};
51 51
52int INFTL_mount(struct INFTLrecord *s); 52int INFTL_mount(struct INFTLrecord *s);
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 7dfd6e1fcde7..28d461d862bd 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -5,7 +5,6 @@
5#ifndef __LINUX_MTD_MAP_H__ 5#ifndef __LINUX_MTD_MAP_H__
6#define __LINUX_MTD_MAP_H__ 6#define __LINUX_MTD_MAP_H__
7 7
8#include <linux/config.h>
9#include <linux/types.h> 8#include <linux/types.h>
10#include <linux/list.h> 9#include <linux/list.h>
11#include <linux/string.h> 10#include <linux/string.h>
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index b6f2fdae65c6..9b7a2b525d63 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -13,7 +13,6 @@
13#error This is a kernel header. Perhaps include mtd-user.h instead? 13#error This is a kernel header. Perhaps include mtd-user.h instead?
14#endif 14#endif
15 15
16#include <linux/config.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/uio.h> 18#include <linux/uio.h>
@@ -56,18 +55,69 @@ struct mtd_erase_region_info {
56 u_int32_t numblocks; /* Number of blocks of erasesize in this region */ 55 u_int32_t numblocks; /* Number of blocks of erasesize in this region */
57}; 56};
58 57
58/*
59 * oob operation modes
60 *
61 * MTD_OOB_PLACE: oob data are placed at the given offset
62 * MTD_OOB_AUTO: oob data are automatically placed at the free areas
63 * which are defined by the ecclayout
64 * MTD_OOB_RAW: mode to read raw data+oob in one chunk. The oob data
65 * is inserted into the data. Thats a raw image of the
66 * flash contents.
67 */
68typedef enum {
69 MTD_OOB_PLACE,
70 MTD_OOB_AUTO,
71 MTD_OOB_RAW,
72} mtd_oob_mode_t;
73
74/**
75 * struct mtd_oob_ops - oob operation operands
76 * @mode: operation mode
77 *
78 * @len: number of bytes to write/read. When a data buffer is given
79 * (datbuf != NULL) this is the number of data bytes. When
80 + no data buffer is available this is the number of oob bytes.
81 *
82 * @retlen: number of bytes written/read. When a data buffer is given
83 * (datbuf != NULL) this is the number of data bytes. When
84 + no data buffer is available this is the number of oob bytes.
85 *
86 * @ooblen: number of oob bytes per page
87 * @ooboffs: offset of oob data in the oob area (only relevant when
88 * mode = MTD_OOB_PLACE)
89 * @datbuf: data buffer - if NULL only oob data are read/written
90 * @oobbuf: oob data buffer
91 */
92struct mtd_oob_ops {
93 mtd_oob_mode_t mode;
94 size_t len;
95 size_t retlen;
96 size_t ooblen;
97 uint32_t ooboffs;
98 uint8_t *datbuf;
99 uint8_t *oobbuf;
100};
101
59struct mtd_info { 102struct mtd_info {
60 u_char type; 103 u_char type;
61 u_int32_t flags; 104 u_int32_t flags;
62 u_int32_t size; // Total size of the MTD 105 u_int32_t size; // Total size of the MTD
63 106
64 /* "Major" erase size for the device. Naïve users may take this 107 /* "Major" erase size for the device. Naïve users may take this
65 * to be the only erase size available, or may use the more detailed 108 * to be the only erase size available, or may use the more detailed
66 * information below if they desire 109 * information below if they desire
67 */ 110 */
68 u_int32_t erasesize; 111 u_int32_t erasesize;
112 /* Minimal writable flash unit size. In case of NOR flash it is 1 (even
113 * though individual bits can be cleared), in case of NAND flash it is
114 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
115 * it is of ECC block size, etc. It is illegal to have writesize = 0.
116 * Any driver registering a struct mtd_info must ensure a writesize of
117 * 1 or larger.
118 */
119 u_int32_t writesize;
69 120
70 u_int32_t oobblock; // Size of OOB blocks (e.g. 512)
71 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 121 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
72 u_int32_t ecctype; 122 u_int32_t ecctype;
73 u_int32_t eccsize; 123 u_int32_t eccsize;
@@ -79,7 +129,6 @@ struct mtd_info {
79 * MTD_PROGRAM_REGIONS flag is set. 129 * MTD_PROGRAM_REGIONS flag is set.
80 * (Maybe we should have an union for those?) 130 * (Maybe we should have an union for those?)
81 */ 131 */
82#define MTD_PROGREGION_SIZE(mtd) (mtd)->oobblock
83#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize 132#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
84#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype 133#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
85 134
@@ -87,9 +136,8 @@ struct mtd_info {
87 char *name; 136 char *name;
88 int index; 137 int index;
89 138
90 // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) 139 /* ecc layout structure pointer - read only ! */
91 struct nand_oobinfo oobinfo; 140 struct nand_ecclayout *ecclayout;
92 u_int32_t oobavail; // Number of bytes in OOB area available for fs
93 141
94 /* Data for variable erase regions. If numeraseregions is zero, 142 /* Data for variable erase regions. If numeraseregions is zero,
95 * it means that the whole device has erasesize as given above. 143 * it means that the whole device has erasesize as given above.
@@ -112,11 +160,10 @@ struct mtd_info {
112 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 160 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
113 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 161 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
114 162
115 int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 163 int (*read_oob) (struct mtd_info *mtd, loff_t from,
116 int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 164 struct mtd_oob_ops *ops);
117 165 int (*write_oob) (struct mtd_info *mtd, loff_t to,
118 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 166 struct mtd_oob_ops *ops);
119 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
120 167
121 /* 168 /*
122 * Methods to access the protection register area, present in some 169 * Methods to access the protection register area, present in some
@@ -130,17 +177,11 @@ struct mtd_info {
130 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 177 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
131 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); 178 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
132 179
133 /* kvec-based read/write methods. We need these especially for NAND flash, 180 /* kvec-based read/write methods.
134 with its limited number of write cycles per erase.
135 NB: The 'count' parameter is the number of _vectors_, each of 181 NB: The 'count' parameter is the number of _vectors_, each of
136 which contains an (ofs, len) tuple. 182 which contains an (ofs, len) tuple.
137 */ 183 */
138 int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
139 int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
140 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
141 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); 184 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
142 int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
143 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
144 185
145 /* Sync */ 186 /* Sync */
146 void (*sync) (struct mtd_info *mtd); 187 void (*sync) (struct mtd_info *mtd);
@@ -159,6 +200,9 @@ struct mtd_info {
159 200
160 struct notifier_block reboot_notifier; /* default mode before reboot */ 201 struct notifier_block reboot_notifier; /* default mode before reboot */
161 202
203 /* ECC status information */
204 struct mtd_ecc_stats ecc_stats;
205
162 void *priv; 206 void *priv;
163 207
164 struct module *owner; 208 struct module *owner;
@@ -192,20 +236,6 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
192int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, 236int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
193 unsigned long count, loff_t from, size_t *retlen); 237 unsigned long count, loff_t from, size_t *retlen);
194 238
195#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
196#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
197#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
198#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args)
199#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args)
200#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args)
201#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args)
202#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args)
203#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args)
204#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
205#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
206#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
207
208
209#ifdef CONFIG_MTD_PARTITIONS 239#ifdef CONFIG_MTD_PARTITIONS
210void mtd_erase_callback(struct erase_info *instr); 240void mtd_erase_callback(struct erase_info *instr);
211#else 241#else
@@ -226,7 +256,7 @@ static inline void mtd_erase_callback(struct erase_info *instr)
226 256
227#ifdef CONFIG_MTD_DEBUG 257#ifdef CONFIG_MTD_DEBUG
228#define DEBUG(n, args...) \ 258#define DEBUG(n, args...) \
229 do { \ 259 do { \
230 if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ 260 if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
231 printk(KERN_INFO args); \ 261 printk(KERN_INFO args); \
232 } while(0) 262 } while(0)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index da5e67b3fc70..66559272ebcb 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -11,52 +11,15 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 * 13 *
14 * Info: 14 * Info:
15 * Contains standard defines and IDs for NAND flash devices 15 * Contains standard defines and IDs for NAND flash devices
16 * 16 *
17 * Changelog: 17 * Changelog:
18 * 01-31-2000 DMW Created 18 * See git changelog.
19 * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers
20 * so it can be used by other NAND flash device
21 * drivers. I also changed the copyright since none
22 * of the original contents of this file are specific
23 * to DoC devices. David can whack me with a baseball
24 * bat later if I did something naughty.
25 * 10-11-2000 SJH Added private NAND flash structure for driver
26 * 10-24-2000 SJH Added prototype for 'nand_scan' function
27 * 10-29-2001 TG changed nand_chip structure to support
28 * hardwarespecific function for accessing control lines
29 * 02-21-2002 TG added support for different read/write adress and
30 * ready/busy line access function
31 * 02-26-2002 TG added chip_delay to nand_chip structure to optimize
32 * command delay times for different chips
33 * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate
34 * defines in jffs2/wbuf.c
35 * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if
36 * CONFIG_MTD_NAND_ECC_JFFS2 is not set
37 * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC
38 *
39 * 08-29-2002 tglx nand_chip structure: data_poi for selecting
40 * internal / fs-driver buffer
41 * support for 6byte/512byte hardware ECC
42 * read_ecc, write_ecc extended for different oob-layout
43 * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
44 * NAND_YAFFS_OOB
45 * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
46 * Split manufacturer and device ID structures
47 *
48 * 02-08-2004 tglx added option field to nand structure for chip anomalities
49 * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
50 * update of nand_chip structure description
51 * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
52 * for BBT_AUTO_REFRESH.
53 * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
54 * extra error status checks.
55 */ 19 */
56#ifndef __LINUX_MTD_NAND_H 20#ifndef __LINUX_MTD_NAND_H
57#define __LINUX_MTD_NAND_H 21#define __LINUX_MTD_NAND_H
58 22
59#include <linux/config.h>
60#include <linux/wait.h> 23#include <linux/wait.h>
61#include <linux/spinlock.h> 24#include <linux/spinlock.h>
62#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
@@ -67,10 +30,6 @@ extern int nand_scan (struct mtd_info *mtd, int max_chips);
67/* Free resources held by the NAND device */ 30/* Free resources held by the NAND device */
68extern void nand_release (struct mtd_info *mtd); 31extern void nand_release (struct mtd_info *mtd);
69 32
70/* Read raw data from the device without ECC */
71extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen);
72
73
74/* The maximum number of NAND chips in an array */ 33/* The maximum number of NAND chips in an array */
75#define NAND_MAX_CHIPS 8 34#define NAND_MAX_CHIPS 8
76 35
@@ -79,44 +38,45 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
79 * adjust this accordingly. 38 * adjust this accordingly.
80 */ 39 */
81#define NAND_MAX_OOBSIZE 64 40#define NAND_MAX_OOBSIZE 64
41#define NAND_MAX_PAGESIZE 2048
82 42
83/* 43/*
84 * Constants for hardware specific CLE/ALE/NCE function 44 * Constants for hardware specific CLE/ALE/NCE function
85*/ 45 *
46 * These are bits which can be or'ed to set/clear multiple
47 * bits in one go.
48 */
86/* Select the chip by setting nCE to low */ 49/* Select the chip by setting nCE to low */
87#define NAND_CTL_SETNCE 1 50#define NAND_NCE 0x01
88/* Deselect the chip by setting nCE to high */
89#define NAND_CTL_CLRNCE 2
90/* Select the command latch by setting CLE to high */ 51/* Select the command latch by setting CLE to high */
91#define NAND_CTL_SETCLE 3 52#define NAND_CLE 0x02
92/* Deselect the command latch by setting CLE to low */
93#define NAND_CTL_CLRCLE 4
94/* Select the address latch by setting ALE to high */ 53/* Select the address latch by setting ALE to high */
95#define NAND_CTL_SETALE 5 54#define NAND_ALE 0x04
96/* Deselect the address latch by setting ALE to low */ 55
97#define NAND_CTL_CLRALE 6 56#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
98/* Set write protection by setting WP to high. Not used! */ 57#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
99#define NAND_CTL_SETWP 7 58#define NAND_CTRL_CHANGE 0x80
100/* Clear write protection by setting WP to low. Not used! */
101#define NAND_CTL_CLRWP 8
102 59
103/* 60/*
104 * Standard NAND flash commands 61 * Standard NAND flash commands
105 */ 62 */
106#define NAND_CMD_READ0 0 63#define NAND_CMD_READ0 0
107#define NAND_CMD_READ1 1 64#define NAND_CMD_READ1 1
65#define NAND_CMD_RNDOUT 5
108#define NAND_CMD_PAGEPROG 0x10 66#define NAND_CMD_PAGEPROG 0x10
109#define NAND_CMD_READOOB 0x50 67#define NAND_CMD_READOOB 0x50
110#define NAND_CMD_ERASE1 0x60 68#define NAND_CMD_ERASE1 0x60
111#define NAND_CMD_STATUS 0x70 69#define NAND_CMD_STATUS 0x70
112#define NAND_CMD_STATUS_MULTI 0x71 70#define NAND_CMD_STATUS_MULTI 0x71
113#define NAND_CMD_SEQIN 0x80 71#define NAND_CMD_SEQIN 0x80
72#define NAND_CMD_RNDIN 0x85
114#define NAND_CMD_READID 0x90 73#define NAND_CMD_READID 0x90
115#define NAND_CMD_ERASE2 0xd0 74#define NAND_CMD_ERASE2 0xd0
116#define NAND_CMD_RESET 0xff 75#define NAND_CMD_RESET 0xff
117 76
118/* Extended commands for large page devices */ 77/* Extended commands for large page devices */
119#define NAND_CMD_READSTART 0x30 78#define NAND_CMD_READSTART 0x30
79#define NAND_CMD_RNDOUTSTART 0xE0
120#define NAND_CMD_CACHEDPROG 0x15 80#define NAND_CMD_CACHEDPROG 0x15
121 81
122/* Extended commands for AG-AND device */ 82/* Extended commands for AG-AND device */
@@ -138,6 +98,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
138#define NAND_CMD_STATUS_RESET 0x7f 98#define NAND_CMD_STATUS_RESET 0x7f
139#define NAND_CMD_STATUS_CLEAR 0xff 99#define NAND_CMD_STATUS_CLEAR 0xff
140 100
101#define NAND_CMD_NONE -1
102
141/* Status bits */ 103/* Status bits */
142#define NAND_STATUS_FAIL 0x01 104#define NAND_STATUS_FAIL 0x01
143#define NAND_STATUS_FAIL_N1 0x02 105#define NAND_STATUS_FAIL_N1 0x02
@@ -148,21 +110,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
148/* 110/*
149 * Constants for ECC_MODES 111 * Constants for ECC_MODES
150 */ 112 */
151 113typedef enum {
152/* No ECC. Usage is not recommended ! */ 114 NAND_ECC_NONE,
153#define NAND_ECC_NONE 0 115 NAND_ECC_SOFT,
154/* Software ECC 3 byte ECC per 256 Byte data */ 116 NAND_ECC_HW,
155#define NAND_ECC_SOFT 1 117 NAND_ECC_HW_SYNDROME,
156/* Hardware ECC 3 byte ECC per 256 Byte data */ 118} nand_ecc_modes_t;
157#define NAND_ECC_HW3_256 2
158/* Hardware ECC 3 byte ECC per 512 Byte data */
159#define NAND_ECC_HW3_512 3
160/* Hardware ECC 3 byte ECC per 512 Byte data */
161#define NAND_ECC_HW6_512 4
162/* Hardware ECC 8 byte ECC per 512 Byte data */
163#define NAND_ECC_HW8_512 6
164/* Hardware ECC 12 byte ECC per 2048 Byte data */
165#define NAND_ECC_HW12_2048 7
166 119
167/* 120/*
168 * Constants for Hardware ECC 121 * Constants for Hardware ECC
@@ -201,6 +154,10 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
201 * bits from adjacent blocks from 'leaking' in altering data. 154 * bits from adjacent blocks from 'leaking' in altering data.
202 * This happens with the Renesas AG-AND chips, possibly others. */ 155 * This happens with the Renesas AG-AND chips, possibly others. */
203#define BBT_AUTO_REFRESH 0x00000080 156#define BBT_AUTO_REFRESH 0x00000080
157/* Chip does not require ready check on read. True
158 * for all large page devices, as they do not support
159 * autoincrement.*/
160#define NAND_NO_READRDY 0x00000100
204 161
205/* Options valid for Samsung large page devices */ 162/* Options valid for Samsung large page devices */
206#define NAND_SAMSUNG_LP_OPTIONS \ 163#define NAND_SAMSUNG_LP_OPTIONS \
@@ -219,18 +176,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
219/* Use a flash based bad block table. This option is passed to the 176/* Use a flash based bad block table. This option is passed to the
220 * default bad block table function. */ 177 * default bad block table function. */
221#define NAND_USE_FLASH_BBT 0x00010000 178#define NAND_USE_FLASH_BBT 0x00010000
222/* The hw ecc generator provides a syndrome instead a ecc value on read
223 * This can only work if we have the ecc bytes directly behind the
224 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
225#define NAND_HWECC_SYNDROME 0x00020000
226/* This option skips the bbt scan during initialization. */ 179/* This option skips the bbt scan during initialization. */
227#define NAND_SKIP_BBTSCAN 0x00040000 180#define NAND_SKIP_BBTSCAN 0x00020000
228 181
229/* Options set by nand scan */ 182/* Options set by nand scan */
230/* Nand scan has allocated oob_buf */ 183/* Nand scan has allocated controller struct */
231#define NAND_OOBBUF_ALLOC 0x40000000 184#define NAND_CONTROLLER_ALLOC 0x80000000
232/* Nand scan has allocated data_buf */
233#define NAND_DATABUF_ALLOC 0x80000000
234 185
235 186
236/* 187/*
@@ -264,45 +215,102 @@ struct nand_hw_control {
264}; 215};
265 216
266/** 217/**
218 * struct nand_ecc_ctrl - Control structure for ecc
219 * @mode: ecc mode
220 * @steps: number of ecc steps per page
221 * @size: data bytes per ecc step
222 * @bytes: ecc bytes per step
223 * @total: total number of ecc bytes per page
224 * @prepad: padding information for syndrome based ecc generators
225 * @postpad: padding information for syndrome based ecc generators
226 * @hwctl: function to control hardware ecc generator. Must only
227 * be provided if an hardware ECC is available
228 * @calculate: function for ecc calculation or readback from ecc hardware
229 * @correct: function for ecc correction, matching to ecc generator (sw/hw)
230 * @read_page: function to read a page according to the ecc generator requirements
231 * @write_page: function to write a page according to the ecc generator requirements
232 */
233struct nand_ecc_ctrl {
234 nand_ecc_modes_t mode;
235 int steps;
236 int size;
237 int bytes;
238 int total;
239 int prepad;
240 int postpad;
241 struct nand_ecclayout *layout;
242 void (*hwctl)(struct mtd_info *mtd, int mode);
243 int (*calculate)(struct mtd_info *mtd,
244 const uint8_t *dat,
245 uint8_t *ecc_code);
246 int (*correct)(struct mtd_info *mtd, uint8_t *dat,
247 uint8_t *read_ecc,
248 uint8_t *calc_ecc);
249 int (*read_page)(struct mtd_info *mtd,
250 struct nand_chip *chip,
251 uint8_t *buf);
252 void (*write_page)(struct mtd_info *mtd,
253 struct nand_chip *chip,
254 const uint8_t *buf);
255 int (*read_oob)(struct mtd_info *mtd,
256 struct nand_chip *chip,
257 int page,
258 int sndcmd);
259 int (*write_oob)(struct mtd_info *mtd,
260 struct nand_chip *chip,
261 int page);
262};
263
264/**
265 * struct nand_buffers - buffer structure for read/write
266 * @ecccalc: buffer for calculated ecc
267 * @ecccode: buffer for ecc read from flash
268 * @oobwbuf: buffer for write oob data
269 * @databuf: buffer for data - dynamically sized
270 * @oobrbuf: buffer to read oob data
271 *
272 * Do not change the order of buffers. databuf and oobrbuf must be in
273 * consecutive order.
274 */
275struct nand_buffers {
276 uint8_t ecccalc[NAND_MAX_OOBSIZE];
277 uint8_t ecccode[NAND_MAX_OOBSIZE];
278 uint8_t oobwbuf[NAND_MAX_OOBSIZE];
279 uint8_t databuf[NAND_MAX_PAGESIZE];
280 uint8_t oobrbuf[NAND_MAX_OOBSIZE];
281};
282
283/**
267 * struct nand_chip - NAND Private Flash Chip Data 284 * struct nand_chip - NAND Private Flash Chip Data
268 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device 285 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
269 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device 286 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
270 * @read_byte: [REPLACEABLE] read one byte from the chip 287 * @read_byte: [REPLACEABLE] read one byte from the chip
271 * @write_byte: [REPLACEABLE] write one byte to the chip
272 * @read_word: [REPLACEABLE] read one word from the chip 288 * @read_word: [REPLACEABLE] read one word from the chip
273 * @write_word: [REPLACEABLE] write one word to the chip
274 * @write_buf: [REPLACEABLE] write data from the buffer to the chip 289 * @write_buf: [REPLACEABLE] write data from the buffer to the chip
275 * @read_buf: [REPLACEABLE] read data from the chip into the buffer 290 * @read_buf: [REPLACEABLE] read data from the chip into the buffer
276 * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data 291 * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
277 * @select_chip: [REPLACEABLE] select chip nr 292 * @select_chip: [REPLACEABLE] select chip nr
278 * @block_bad: [REPLACEABLE] check, if the block is bad 293 * @block_bad: [REPLACEABLE] check, if the block is bad
279 * @block_markbad: [REPLACEABLE] mark the block bad 294 * @block_markbad: [REPLACEABLE] mark the block bad
280 * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines 295 * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling
296 * ALE/CLE/nCE. Also used to write command and address
281 * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line 297 * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
282 * If set to NULL no access to ready/busy is available and the ready/busy information 298 * If set to NULL no access to ready/busy is available and the ready/busy information
283 * is read from the chip status register 299 * is read from the chip status register
284 * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip 300 * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip
285 * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready 301 * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready
286 * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware 302 * @ecc: [BOARDSPECIFIC] ecc control ctructure
287 * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw)
288 * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only
289 * be provided if a hardware ECC is available
290 * @erase_cmd: [INTERN] erase command write function, selectable due to AND support 303 * @erase_cmd: [INTERN] erase command write function, selectable due to AND support
291 * @scan_bbt: [REPLACEABLE] function to scan bad block table 304 * @scan_bbt: [REPLACEABLE] function to scan bad block table
292 * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
293 * @eccsize: [INTERN] databytes used per ecc-calculation
294 * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step
295 * @eccsteps: [INTERN] number of ecc calculation steps per page
296 * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) 305 * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
297 * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip
298 * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress 306 * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
299 * @state: [INTERN] the current state of the NAND device 307 * @state: [INTERN] the current state of the NAND device
300 * @page_shift: [INTERN] number of address bits in a page (column address bits) 308 * @page_shift: [INTERN] number of address bits in a page (column address bits)
301 * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock 309 * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
302 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry 310 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
303 * @chip_shift: [INTERN] number of address bits in one chip 311 * @chip_shift: [INTERN] number of address bits in one chip
304 * @data_buf: [INTERN] internal buffer for one page + oob 312 * @datbuf: [INTERN] internal buffer for one page + oob
305 * @oob_buf: [INTERN] oob buffer for one eraseblock 313 * @oobbuf: [INTERN] oob buffer for one eraseblock
306 * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized 314 * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
307 * @data_poi: [INTERN] pointer to a data buffer 315 * @data_poi: [INTERN] pointer to a data buffer
308 * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about 316 * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
@@ -312,12 +320,13 @@ struct nand_hw_control {
312 * @chipsize: [INTERN] the size of one chip for multichip arrays 320 * @chipsize: [INTERN] the size of one chip for multichip arrays
313 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 321 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
314 * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf 322 * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
315 * @autooob: [REPLACEABLE] the default (auto)placement scheme 323 * @ecclayout: [REPLACEABLE] the default ecc placement scheme
316 * @bbt: [INTERN] bad block table pointer 324 * @bbt: [INTERN] bad block table pointer
317 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup 325 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
318 * @bbt_md: [REPLACEABLE] bad block table mirror descriptor 326 * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
319 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan 327 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
320 * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices 328 * @controller: [REPLACEABLE] a pointer to a hardware controller structure
329 * which is shared among multiple independend devices
321 * @priv: [OPTIONAL] pointer to private chip date 330 * @priv: [OPTIONAL] pointer to private chip date
322 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks 331 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
323 * (determine if errors are correctable) 332 * (determine if errors are correctable)
@@ -325,58 +334,57 @@ struct nand_hw_control {
325 334
326struct nand_chip { 335struct nand_chip {
327 void __iomem *IO_ADDR_R; 336 void __iomem *IO_ADDR_R;
328 void __iomem *IO_ADDR_W; 337 void __iomem *IO_ADDR_W;
329 338
330 u_char (*read_byte)(struct mtd_info *mtd); 339 uint8_t (*read_byte)(struct mtd_info *mtd);
331 void (*write_byte)(struct mtd_info *mtd, u_char byte);
332 u16 (*read_word)(struct mtd_info *mtd); 340 u16 (*read_word)(struct mtd_info *mtd);
333 void (*write_word)(struct mtd_info *mtd, u16 word); 341 void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
334 342 void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
335 void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); 343 int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
336 void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
337 int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
338 void (*select_chip)(struct mtd_info *mtd, int chip); 344 void (*select_chip)(struct mtd_info *mtd, int chip);
339 int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); 345 int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
340 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); 346 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
341 void (*hwcontrol)(struct mtd_info *mtd, int cmd); 347 void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
342 int (*dev_ready)(struct mtd_info *mtd); 348 unsigned int ctrl);
343 void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); 349 int (*dev_ready)(struct mtd_info *mtd);
344 int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); 350 void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
345 int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); 351 int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
346 int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
347 void (*enable_hwecc)(struct mtd_info *mtd, int mode);
348 void (*erase_cmd)(struct mtd_info *mtd, int page); 352 void (*erase_cmd)(struct mtd_info *mtd, int page);
349 int (*scan_bbt)(struct mtd_info *mtd); 353 int (*scan_bbt)(struct mtd_info *mtd);
350 int eccmode; 354 int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
351 int eccsize; 355
352 int eccbytes; 356 int chip_delay;
353 int eccsteps; 357 unsigned int options;
354 int chip_delay; 358
355 spinlock_t chip_lock; 359 int page_shift;
356 wait_queue_head_t wq;
357 nand_state_t state;
358 int page_shift;
359 int phys_erase_shift; 360 int phys_erase_shift;
360 int bbt_erase_shift; 361 int bbt_erase_shift;
361 int chip_shift; 362 int chip_shift;
362 u_char *data_buf;
363 u_char *oob_buf;
364 int oobdirty;
365 u_char *data_poi;
366 unsigned int options;
367 int badblockpos;
368 int numchips; 363 int numchips;
369 unsigned long chipsize; 364 unsigned long chipsize;
370 int pagemask; 365 int pagemask;
371 int pagebuf; 366 int pagebuf;
372 struct nand_oobinfo *autooob; 367 int badblockpos;
368
369 nand_state_t state;
370
371 uint8_t *oob_poi;
372 struct nand_hw_control *controller;
373 struct nand_ecclayout *ecclayout;
374
375 struct nand_ecc_ctrl ecc;
376 struct nand_buffers buffers;
377 struct nand_hw_control hwcontrol;
378
379 struct mtd_oob_ops ops;
380
373 uint8_t *bbt; 381 uint8_t *bbt;
374 struct nand_bbt_descr *bbt_td; 382 struct nand_bbt_descr *bbt_td;
375 struct nand_bbt_descr *bbt_md; 383 struct nand_bbt_descr *bbt_md;
384
376 struct nand_bbt_descr *badblock_pattern; 385 struct nand_bbt_descr *badblock_pattern;
377 struct nand_hw_control *controller; 386
378 void *priv; 387 void *priv;
379 int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
380}; 388};
381 389
382/* 390/*
@@ -388,19 +396,19 @@ struct nand_chip {
388#define NAND_MFR_NATIONAL 0x8f 396#define NAND_MFR_NATIONAL 0x8f
389#define NAND_MFR_RENESAS 0x07 397#define NAND_MFR_RENESAS 0x07
390#define NAND_MFR_STMICRO 0x20 398#define NAND_MFR_STMICRO 0x20
391#define NAND_MFR_HYNIX 0xad 399#define NAND_MFR_HYNIX 0xad
392 400
393/** 401/**
394 * struct nand_flash_dev - NAND Flash Device ID Structure 402 * struct nand_flash_dev - NAND Flash Device ID Structure
395 * 403 *
396 * @name: Identify the device type 404 * @name: Identify the device type
397 * @id: device ID code 405 * @id: device ID code
398 * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 406 * @pagesize: Pagesize in bytes. Either 256 or 512 or 0
399 * If the pagesize is 0, then the real pagesize 407 * If the pagesize is 0, then the real pagesize
400 * and the eraseize are determined from the 408 * and the eraseize are determined from the
401 * extended id bytes in the chip 409 * extended id bytes in the chip
402 * @erasesize: Size of an erase block in the flash device. 410 * @erasesize: Size of an erase block in the flash device.
403 * @chipsize: Total chipsize in Mega Bytes 411 * @chipsize: Total chipsize in Mega Bytes
404 * @options: Bitfield to store chip relevant options 412 * @options: Bitfield to store chip relevant options
405 */ 413 */
406struct nand_flash_dev { 414struct nand_flash_dev {
@@ -415,7 +423,7 @@ struct nand_flash_dev {
415/** 423/**
416 * struct nand_manufacturers - NAND Flash Manufacturer ID Structure 424 * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
417 * @name: Manufacturer name 425 * @name: Manufacturer name
418 * @id: manufacturer ID code of device. 426 * @id: manufacturer ID code of device.
419*/ 427*/
420struct nand_manufacturers { 428struct nand_manufacturers {
421 int id; 429 int id;
@@ -455,7 +463,7 @@ struct nand_bbt_descr {
455 int veroffs; 463 int veroffs;
456 uint8_t version[NAND_MAX_CHIPS]; 464 uint8_t version[NAND_MAX_CHIPS];
457 int len; 465 int len;
458 int maxblocks; 466 int maxblocks;
459 int reserved_block_code; 467 int reserved_block_code;
460 uint8_t *pattern; 468 uint8_t *pattern;
461}; 469};
@@ -494,14 +502,14 @@ struct nand_bbt_descr {
494/* The maximum number of blocks to scan for a bbt */ 502/* The maximum number of blocks to scan for a bbt */
495#define NAND_BBT_SCAN_MAXBLOCKS 4 503#define NAND_BBT_SCAN_MAXBLOCKS 4
496 504
497extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); 505extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd);
498extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); 506extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
499extern int nand_default_bbt (struct mtd_info *mtd); 507extern int nand_default_bbt(struct mtd_info *mtd);
500extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); 508extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
501extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); 509extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
502extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 510 int allowbbt);
503 size_t * retlen, u_char * buf, u_char * oob_buf, 511extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
504 struct nand_oobinfo *oobsel, int flags); 512 size_t * retlen, uint8_t * buf);
505 513
506/* 514/*
507* Constants for oob configuration 515* Constants for oob configuration
@@ -509,4 +517,53 @@ extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
509#define NAND_SMALL_BADBLOCK_POS 5 517#define NAND_SMALL_BADBLOCK_POS 5
510#define NAND_LARGE_BADBLOCK_POS 0 518#define NAND_LARGE_BADBLOCK_POS 0
511 519
520/**
521 * struct platform_nand_chip - chip level device structure
522 *
523 * @nr_chips: max. number of chips to scan for
524 * @chip_offs: chip number offset
525 * @nr_partitions: number of partitions pointed to by partitions (or zero)
526 * @partitions: mtd partition list
527 * @chip_delay: R/B delay value in us
528 * @options: Option flags, e.g. 16bit buswidth
529 * @ecclayout: ecc layout info structure
530 * @priv: hardware controller specific settings
531 */
532struct platform_nand_chip {
533 int nr_chips;
534 int chip_offset;
535 int nr_partitions;
536 struct mtd_partition *partitions;
537 struct nand_ecclayout *ecclayout;
538 int chip_delay;
539 unsigned int options;
540 void *priv;
541};
542
543/**
544 * struct platform_nand_ctrl - controller level device structure
545 *
546 * @hwcontrol: platform specific hardware control structure
547 * @dev_ready: platform specific function to read ready/busy pin
548 * @select_chip: platform specific chip select function
549 * @priv_data: private data to transport driver specific settings
550 *
551 * All fields are optional and depend on the hardware driver requirements
552 */
553struct platform_nand_ctrl {
554 void (*hwcontrol)(struct mtd_info *mtd, int cmd);
555 int (*dev_ready)(struct mtd_info *mtd);
556 void (*select_chip)(struct mtd_info *mtd, int chip);
557 void *priv;
558};
559
560/* Some helpers to access the data structures */
561static inline
562struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd)
563{
564 struct nand_chip *chip = mtd->priv;
565
566 return chip->priv;
567}
568
512#endif /* __LINUX_MTD_NAND_H */ 569#endif /* __LINUX_MTD_NAND_H */
diff --git a/include/linux/mtd/ndfc.h b/include/linux/mtd/ndfc.h
new file mode 100644
index 000000000000..d0558a982628
--- /dev/null
+++ b/include/linux/mtd/ndfc.h
@@ -0,0 +1,67 @@
1/*
2 * linux/include/linux/mtd/ndfc.h
3 *
4 * Copyright (c) 2006 Thomas Gleixner <tglx@linutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Info:
11 * Contains defines, datastructures for ndfc nand controller
12 *
13 */
14#ifndef __LINUX_MTD_NDFC_H
15#define __LINUX_MTD_NDFC_H
16
17/* NDFC Register definitions */
18#define NDFC_CMD 0x00
19#define NDFC_ALE 0x04
20#define NDFC_DATA 0x08
21#define NDFC_ECC 0x10
22#define NDFC_BCFG0 0x30
23#define NDFC_BCFG1 0x34
24#define NDFC_BCFG2 0x38
25#define NDFC_BCFG3 0x3c
26#define NDFC_CCR 0x40
27#define NDFC_STAT 0x44
28#define NDFC_HWCTL 0x48
29#define NDFC_REVID 0x50
30
31#define NDFC_STAT_IS_READY 0x01000000
32
33#define NDFC_CCR_RESET_CE 0x80000000 /* CE Reset */
34#define NDFC_CCR_RESET_ECC 0x40000000 /* ECC Reset */
35#define NDFC_CCR_RIE 0x20000000 /* Interrupt Enable on Device Rdy */
36#define NDFC_CCR_REN 0x10000000 /* Enable wait for Rdy in LinearR */
37#define NDFC_CCR_ROMEN 0x08000000 /* Enable ROM In LinearR */
38#define NDFC_CCR_ARE 0x04000000 /* Auto-Read Enable */
39#define NDFC_CCR_BS(x) (((x) & 0x3) << 24) /* Select Bank on CE[x] */
40#define NDFC_CCR_BS_MASK 0x03000000 /* Select Bank */
41#define NDFC_CCR_ARAC0 0x00000000 /* 3 Addr, 1 Col 2 Row 512b page */
42#define NDFC_CCR_ARAC1 0x00001000 /* 4 Addr, 1 Col 3 Row 512b page */
43#define NDFC_CCR_ARAC2 0x00002000 /* 4 Addr, 2 Col 2 Row 2K page */
44#define NDFC_CCR_ARAC3 0x00003000 /* 5 Addr, 2 Col 3 Row 2K page */
45#define NDFC_CCR_ARAC_MASK 0x00003000 /* Auto-Read mode Addr Cycles */
46#define NDFC_CCR_RPG 0x0000C000 /* Auto-Read Page */
47#define NDFC_CCR_EBCC 0x00000004 /* EBC Configuration Completed */
48#define NDFC_CCR_DHC 0x00000002 /* Direct Hardware Control Enable */
49
50#define NDFC_BxCFG_EN 0x80000000 /* Bank Enable */
51#define NDFC_BxCFG_CED 0x40000000 /* nCE Style */
52#define NDFC_BxCFG_SZ_MASK 0x08000000 /* Bank Size */
53#define NDFC_BxCFG_SZ_8BIT 0x00000000 /* 8bit */
54#define NDFC_BxCFG_SZ_16BIT 0x08000000 /* 16bit */
55
56#define NDFC_MAX_BANKS 4
57
58struct ndfc_controller_settings {
59 uint32_t ccr_settings;
60 uint64_t ndfc_erpn;
61};
62
63struct ndfc_chip_settings {
64 uint32_t bank_settings;
65};
66
67#endif
diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h
index d35d2c21ff3e..bcf2fb3fa4a7 100644
--- a/include/linux/mtd/nftl.h
+++ b/include/linux/mtd/nftl.h
@@ -37,7 +37,7 @@ struct NFTLrecord {
37 unsigned int nb_blocks; /* number of physical blocks */ 37 unsigned int nb_blocks; /* number of physical blocks */
38 unsigned int nb_boot_blocks; /* number of blocks used by the bios */ 38 unsigned int nb_boot_blocks; /* number of blocks used by the bios */
39 struct erase_info instr; 39 struct erase_info instr;
40 struct nand_oobinfo oobinfo; 40 struct nand_ecclayout oobinfo;
41}; 41};
42 42
43int NFTL_mount(struct NFTLrecord *s); 43int NFTL_mount(struct NFTLrecord *s);
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 7419b5fab133..9ce9a48db444 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -35,6 +35,8 @@ typedef enum {
35 FL_SYNCING, 35 FL_SYNCING,
36 FL_UNLOCKING, 36 FL_UNLOCKING,
37 FL_LOCKING, 37 FL_LOCKING,
38 FL_RESETING,
39 FL_OTPING,
38 FL_PM_SUSPENDED, 40 FL_PM_SUSPENDED,
39} onenand_state_t; 41} onenand_state_t;
40 42
@@ -75,7 +77,7 @@ struct onenand_bufferram {
75 * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip 77 * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip
76 * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress 78 * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress
77 * @param state [INTERN] the current state of the OneNAND device 79 * @param state [INTERN] the current state of the OneNAND device
78 * @param autooob [REPLACEABLE] the default (auto)placement scheme 80 * @param ecclayout [REPLACEABLE] the default ecc placement scheme
79 * @param bbm [REPLACEABLE] pointer to Bad Block Management 81 * @param bbm [REPLACEABLE] pointer to Bad Block Management
80 * @param priv [OPTIONAL] pointer to private chip date 82 * @param priv [OPTIONAL] pointer to private chip date
81 */ 83 */
@@ -111,9 +113,9 @@ struct onenand_chip {
111 onenand_state_t state; 113 onenand_state_t state;
112 unsigned char *page_buf; 114 unsigned char *page_buf;
113 115
114 struct nand_oobinfo *autooob; 116 struct nand_ecclayout *ecclayout;
115 117
116 void *bbm; 118 void *bbm;
117 119
118 void *priv; 120 void *priv;
119}; 121};
@@ -130,6 +132,9 @@ struct onenand_chip {
130#define ONENAND_SET_SYS_CFG1(v, this) \ 132#define ONENAND_SET_SYS_CFG1(v, this) \
131 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) 133 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
132 134
135/* Check byte access in OneNAND */
136#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
137
133/* 138/*
134 * Options bits 139 * Options bits
135 */ 140 */
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index d7832ef8ed63..4a72818d2545 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -112,6 +112,7 @@
112#define ONENAND_CMD_LOCK_TIGHT (0x2C) 112#define ONENAND_CMD_LOCK_TIGHT (0x2C)
113#define ONENAND_CMD_ERASE (0x94) 113#define ONENAND_CMD_ERASE (0x94)
114#define ONENAND_CMD_RESET (0xF0) 114#define ONENAND_CMD_RESET (0xF0)
115#define ONENAND_CMD_OTP_ACCESS (0x65)
115#define ONENAND_CMD_READID (0x90) 116#define ONENAND_CMD_READID (0x90)
116 117
117/* NOTE: Those are not *REAL* commands */ 118/* NOTE: Those are not *REAL* commands */
@@ -152,6 +153,8 @@
152#define ONENAND_CTRL_ERASE (1 << 11) 153#define ONENAND_CTRL_ERASE (1 << 11)
153#define ONENAND_CTRL_ERROR (1 << 10) 154#define ONENAND_CTRL_ERROR (1 << 10)
154#define ONENAND_CTRL_RSTB (1 << 7) 155#define ONENAND_CTRL_RSTB (1 << 7)
156#define ONENAND_CTRL_OTP_L (1 << 6)
157#define ONENAND_CTRL_OTP_BL (1 << 5)
155 158
156/* 159/*
157 * Interrupt Status Register F241h (R) 160 * Interrupt Status Register F241h (R)
@@ -177,4 +180,9 @@
177#define ONENAND_ECC_2BIT (1 << 1) 180#define ONENAND_ECC_2BIT (1 << 1)
178#define ONENAND_ECC_2BIT_ALL (0xAAAA) 181#define ONENAND_ECC_2BIT_ALL (0xAAAA)
179 182
183/*
184 * One-Time Programmable (OTP)
185 */
186#define ONENAND_OTP_LOCK_OFFSET (14)
187
180#endif /* __ONENAND_REG_H */ 188#endif /* __ONENAND_REG_H */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index b03f512d51b9..da6b3d6f12a7 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -41,7 +41,7 @@ struct mtd_partition {
41 u_int32_t size; /* partition size */ 41 u_int32_t size; /* partition size */
42 u_int32_t offset; /* offset within the master MTD space */ 42 u_int32_t offset; /* offset within the master MTD space */
43 u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ 43 u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
44 struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ 44 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/
45 struct mtd_info **mtdp; /* pointer to store the MTD object */ 45 struct mtd_info **mtdp; /* pointer to store the MTD object */
46}; 46};
47 47
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index c7b8bcdef013..86831e3594f6 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -15,33 +15,26 @@
15 */ 15 */
16 16
17#ifndef __LINUX_MTD_PHYSMAP__ 17#ifndef __LINUX_MTD_PHYSMAP__
18 18#define __LINUX_MTD_PHYSMAP__
19#include <linux/config.h>
20
21#if defined(CONFIG_MTD_PHYSMAP)
22 19
23#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
24#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
25#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
26 23
27/* 24struct physmap_flash_data {
28 * The map_info for physmap. Board can override size, buswidth, phys, 25 unsigned int width;
29 * (*set_vpp)(), etc in their initial setup routine. 26 void (*set_vpp)(struct map_info *, int);
30 */ 27 unsigned int nr_parts;
31extern struct map_info physmap_map; 28 struct mtd_partition *parts;
29};
32 30
33/* 31/*
34 * Board needs to specify the exact mapping during their setup time. 32 * Board needs to specify the exact mapping during their setup time.
35 */ 33 */
36static inline void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) ) 34void physmap_configure(unsigned long addr, unsigned long size,
37{ 35 int bankwidth, void (*set_vpp)(struct map_info *, int) );
38 physmap_map.phys = addr;
39 physmap_map.size = size;
40 physmap_map.bankwidth = bankwidth;
41 physmap_map.set_vpp = set_vpp;
42}
43 36
44#if defined(CONFIG_MTD_PARTITIONS) 37#ifdef CONFIG_MTD_PARTITIONS
45 38
46/* 39/*
47 * Machines that wish to do flash partition may want to call this function in 40 * Machines that wish to do flash partition may want to call this function in
@@ -55,7 +48,5 @@ static inline void physmap_configure(unsigned long addr, unsigned long size, int
55void physmap_set_partitions(struct mtd_partition *parts, int num_parts); 48void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
56 49
57#endif /* defined(CONFIG_MTD_PARTITIONS) */ 50#endif /* defined(CONFIG_MTD_PARTITIONS) */
58#endif /* defined(CONFIG_MTD) */
59 51
60#endif /* __LINUX_MTD_PHYSMAP__ */ 52#endif /* __LINUX_MTD_PHYSMAP__ */
61
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h
index 220d50bb71cd..e9d40bdde48c 100644
--- a/include/linux/mtd/xip.h
+++ b/include/linux/mtd/xip.h
@@ -18,7 +18,6 @@
18#ifndef __LINUX_MTD_XIP_H__ 18#ifndef __LINUX_MTD_XIP_H__
19#define __LINUX_MTD_XIP_H__ 19#define __LINUX_MTD_XIP_H__
20 20
21#include <linux/config.h>
22 21
23#ifdef CONFIG_MTD_XIP 22#ifdef CONFIG_MTD_XIP
24 23
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index a6ce409ec6fc..1d7cdd20b553 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -77,11 +77,11 @@ struct nbd_device {
77 * server. All data are in network byte order. 77 * server. All data are in network byte order.
78 */ 78 */
79struct nbd_request { 79struct nbd_request {
80 u32 magic; 80 __u32 magic;
81 u32 type; /* == READ || == WRITE */ 81 __u32 type; /* == READ || == WRITE */
82 char handle[8]; 82 char handle[8];
83 u64 from; 83 __u64 from;
84 u32 len; 84 __u32 len;
85} 85}
86#ifdef __GNUC__ 86#ifdef __GNUC__
87 __attribute__ ((packed)) 87 __attribute__ ((packed))
@@ -93,8 +93,8 @@ struct nbd_request {
93 * it has completed an I/O request (or an error occurs). 93 * it has completed an I/O request (or an error occurs).
94 */ 94 */
95struct nbd_reply { 95struct nbd_reply {
96 u32 magic; 96 __u32 magic;
97 u32 error; /* 0 = ok, else error */ 97 __u32 error; /* 0 = ok, else error */
98 char handle[8]; /* handle you got from request */ 98 char handle[8]; /* handle you got from request */
99}; 99};
100#endif 100#endif
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index 96dc237b8f03..b208f0cd556b 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -12,8 +12,6 @@
12#include <linux/in.h> 12#include <linux/in.h>
13#include <linux/types.h> 13#include <linux/types.h>
14 14
15#include <linux/ncp_fs_i.h>
16#include <linux/ncp_fs_sb.h>
17#include <linux/ipx.h> 15#include <linux/ipx.h>
18#include <linux/ncp_no.h> 16#include <linux/ncp_no.h>
19 17
@@ -146,7 +144,8 @@ struct ncp_nls_ioctl
146 144
147#ifdef __KERNEL__ 145#ifdef __KERNEL__
148 146
149#include <linux/config.h> 147#include <linux/ncp_fs_i.h>
148#include <linux/ncp_fs_sb.h>
150 149
151/* undef because public define in umsdos_fs.h (ncp_fs.h isn't public) */ 150/* undef because public define in umsdos_fs.h (ncp_fs.h isn't public) */
152#undef PRINTK 151#undef PRINTK
diff --git a/include/linux/net.h b/include/linux/net.h
index 84a490e5f0a1..385e68f5bd93 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -18,9 +18,7 @@
18#ifndef _LINUX_NET_H 18#ifndef _LINUX_NET_H
19#define _LINUX_NET_H 19#define _LINUX_NET_H
20 20
21#include <linux/config.h>
22#include <linux/wait.h> 21#include <linux/wait.h>
23#include <linux/stringify.h>
24#include <asm/socket.h> 22#include <asm/socket.h>
25 23
26struct poll_table_struct; 24struct poll_table_struct;
@@ -57,6 +55,7 @@ typedef enum {
57#define __SO_ACCEPTCON (1 << 16) /* performed a listen */ 55#define __SO_ACCEPTCON (1 << 16) /* performed a listen */
58 56
59#ifdef __KERNEL__ 57#ifdef __KERNEL__
58#include <linux/stringify.h>
60 59
61#define SOCK_ASYNC_NOSPACE 0 60#define SOCK_ASYNC_NOSPACE 0
62#define SOCK_ASYNC_WAITDATA 1 61#define SOCK_ASYNC_WAITDATA 1
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e432b743dda2..5e8e2d50429a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -34,7 +34,6 @@
34#include <asm/cache.h> 34#include <asm/cache.h>
35#include <asm/byteorder.h> 35#include <asm/byteorder.h>
36 36
37#include <linux/config.h>
38#include <linux/device.h> 37#include <linux/device.h>
39#include <linux/percpu.h> 38#include <linux/percpu.h>
40#include <linux/dmaengine.h> 39#include <linux/dmaengine.h>
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index b31a9bca9361..10168e26a846 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -40,7 +40,6 @@
40#endif 40#endif
41 41
42#ifdef __KERNEL__ 42#ifdef __KERNEL__
43#include <linux/config.h>
44#ifdef CONFIG_NETFILTER 43#ifdef CONFIG_NETFILTER
45 44
46extern void netfilter_init(void); 45extern void netfilter_init(void);
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index 34f63cf2e293..4c2d9945ca54 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -42,7 +42,7 @@ struct ip_conntrack_old_tuple
42 } u; 42 } u;
43 43
44 /* The protocol. */ 44 /* The protocol. */
45 u16 protonum; 45 __u16 protonum;
46 } dst; 46 } dst;
47}; 47};
48 48
diff --git a/include/linux/netfilter_arp.h b/include/linux/netfilter_arp.h
index a3f8977f7f12..92bc6ddcbf73 100644
--- a/include/linux/netfilter_arp.h
+++ b/include/linux/netfilter_arp.h
@@ -5,7 +5,6 @@
5 * (C)2002 Rusty Russell IBM -- This code is GPL. 5 * (C)2002 Rusty Russell IBM -- This code is GPL.
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/netfilter.h> 8#include <linux/netfilter.h>
10 9
11/* There is no PF_ARP. */ 10/* There is no PF_ARP. */
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index a75b84bb9a88..87764022cc67 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -4,7 +4,6 @@
4/* bridge-specific defines for netfilter. 4/* bridge-specific defines for netfilter.
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/netfilter.h> 7#include <linux/netfilter.h>
9#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) 8#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER)
10#include <asm/atomic.h> 9#include <asm/atomic.h>
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index 85301c5e8d24..ce02c984f3ba 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -5,7 +5,6 @@
5 * (C)1998 Rusty Russell -- This code is GPL. 5 * (C)1998 Rusty Russell -- This code is GPL.
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/netfilter.h> 8#include <linux/netfilter.h>
10 9
11/* only for userspace compatibility */ 10/* only for userspace compatibility */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index e0e9951eb8c3..51dbec1892c8 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -4,7 +4,6 @@
4#include <linux/netfilter/nf_conntrack_common.h> 4#include <linux/netfilter/nf_conntrack_common.h>
5 5
6#ifdef __KERNEL__ 6#ifdef __KERNEL__
7#include <linux/config.h>
8#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 7#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
9#include <linux/bitops.h> 8#include <linux/bitops.h>
10#include <linux/compiler.h> 9#include <linux/compiler.h>
diff --git a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h
index 360429f48737..5d92cf044d91 100644
--- a/include/linux/netfilter_ipv4/listhelp.h
+++ b/include/linux/netfilter_ipv4/listhelp.h
@@ -1,6 +1,5 @@
1#ifndef _LISTHELP_H 1#ifndef _LISTHELP_H
2#define _LISTHELP_H 2#define _LISTHELP_H
3#include <linux/config.h>
4#include <linux/list.h> 3#include <linux/list.h>
5 4
6/* Header to do more comprehensive job than linux/list.h; assume list 5/* Header to do more comprehensive job than linux/list.h; assume list
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
index ca2ffa6ae1d5..54af92c1c70b 100644
--- a/include/linux/nfs.h
+++ b/include/linux/nfs.h
@@ -7,9 +7,6 @@
7#ifndef _LINUX_NFS_H 7#ifndef _LINUX_NFS_H
8#define _LINUX_NFS_H 8#define _LINUX_NFS_H
9 9
10#include <linux/sunrpc/msg_prot.h>
11#include <linux/string.h>
12
13#define NFS_PROGRAM 100003 10#define NFS_PROGRAM 100003
14#define NFS_PORT 2049 11#define NFS_PORT 2049
15#define NFS_MAXDATA 8192 12#define NFS_MAXDATA 8192
@@ -129,7 +126,10 @@ enum nfs_ftype {
129 NFFIFO = 8 126 NFFIFO = 8
130}; 127};
131 128
132#if defined(__KERNEL__) 129#ifdef __KERNEL__
130#include <linux/sunrpc/msg_prot.h>
131#include <linux/string.h>
132
133/* 133/*
134 * This is the kernel NFS client file handle representation 134 * This is the kernel NFS client file handle representation
135 */ 135 */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 1477fc857f6b..5f681d534295 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -14,7 +14,6 @@
14#define _LINUX_NFS4_H 14#define _LINUX_NFS4_H
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/list.h>
18 17
19#define NFS4_VERIFIER_SIZE 8 18#define NFS4_VERIFIER_SIZE 8
20#define NFS4_FHSIZE 128 19#define NFS4_FHSIZE 128
@@ -97,6 +96,9 @@ enum nfs4_acl_whotype {
97 NFS4_ACL_WHO_EVERYONE, 96 NFS4_ACL_WHO_EVERYONE,
98}; 97};
99 98
99#ifdef __KERNEL__
100#include <linux/list.h>
101
100struct nfs4_ace { 102struct nfs4_ace {
101 uint32_t type; 103 uint32_t type;
102 uint32_t flag; 104 uint32_t flag;
@@ -345,8 +347,6 @@ enum lock_type4 {
345#define NFS4_MINOR_VERSION 0 347#define NFS4_MINOR_VERSION 0
346#define NFS4_DEBUG 1 348#define NFS4_DEBUG 1
347 349
348#ifdef __KERNEL__
349
350/* Index of predefined Linux client operations */ 350/* Index of predefined Linux client operations */
351 351
352enum { 352enum {
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index ec7c2e872d72..2dcad295fece 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -10,7 +10,6 @@
10#ifndef LINUX_NFSD_NFSD_H 10#ifndef LINUX_NFSD_NFSD_H
11#define LINUX_NFSD_NFSD_H 11#define LINUX_NFSD_NFSD_H
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/unistd.h> 14#include <linux/unistd.h>
16#include <linux/dirent.h> 15#include <linux/dirent.h>
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index 0798b7781a6e..f9edcd2ff3c8 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -16,7 +16,6 @@
16 16
17#include <asm/types.h> 17#include <asm/types.h>
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19# include <linux/config.h>
20# include <linux/types.h> 19# include <linux/types.h>
21# include <linux/string.h> 20# include <linux/string.h>
22# include <linux/fs.h> 21# include <linux/fs.h>
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index 781efbf94ed3..dae0faea2807 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -11,7 +11,6 @@
11 11
12#include <asm/types.h> 12#include <asm/types.h>
13#ifdef __KERNEL__ 13#ifdef __KERNEL__
14# include <linux/config.h>
15# include <linux/types.h> 14# include <linux/types.h>
16# include <linux/in.h> 15# include <linux/in.h>
17#endif 16#endif
diff --git a/include/linux/numa.h b/include/linux/numa.h
index e481feb1bfd8..a31a7301b159 100644
--- a/include/linux/numa.h
+++ b/include/linux/numa.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_NUMA_H 1#ifndef _LINUX_NUMA_H
2#define _LINUX_NUMA_H 2#define _LINUX_NUMA_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_NODES_SHIFT 5#ifdef CONFIG_NODES_SHIFT
7#define NODES_SHIFT CONFIG_NODES_SHIFT 6#define NODES_SHIFT CONFIG_NODES_SHIFT
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 008d736a6c9a..d42737eeee06 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -96,7 +96,6 @@ typedef enum {
96/* The rest is for the kernel only */ 96/* The rest is for the kernel only */
97#ifdef __KERNEL__ 97#ifdef __KERNEL__
98 98
99#include <linux/config.h>
100#include <linux/jiffies.h> 99#include <linux/jiffies.h>
101#include <linux/proc_fs.h> 100#include <linux/proc_fs.h>
102#include <linux/spinlock.h> 101#include <linux/spinlock.h>
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6fd36cb09160..6c4bc773f7b7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -17,8 +17,6 @@
17#ifndef LINUX_PCI_H 17#ifndef LINUX_PCI_H
18#define LINUX_PCI_H 18#define LINUX_PCI_H
19 19
20#include <linux/mod_devicetable.h>
21
22/* Include the pci register defines */ 20/* Include the pci register defines */
23#include <linux/pci_regs.h> 21#include <linux/pci_regs.h>
24 22
@@ -46,8 +44,9 @@
46 44
47#ifdef __KERNEL__ 45#ifdef __KERNEL__
48 46
47#include <linux/mod_devicetable.h>
48
49#include <linux/types.h> 49#include <linux/types.h>
50#include <linux/config.h>
51#include <linux/ioport.h> 50#include <linux/ioport.h>
52#include <linux/list.h> 51#include <linux/list.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h
index 682525511c9e..66b5de404f22 100644
--- a/include/linux/percpu_counter.h
+++ b/include/linux/percpu_counter.h
@@ -6,7 +6,6 @@
6 * WARNING: these things are HUGE. 4 kbytes per counter on 32-way P4. 6 * WARNING: these things are HUGE. 4 kbytes per counter on 32-way P4.
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/spinlock.h> 9#include <linux/spinlock.h>
11#include <linux/smp.h> 10#include <linux/smp.h>
12#include <linux/threads.h> 11#include <linux/threads.h>
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 66be58902b17..658c1b93d5bb 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -23,7 +23,6 @@
23 23
24#ifdef __KERNEL__ 24#ifdef __KERNEL__
25 25
26#include <linux/config.h>
27#include <linux/list.h> 26#include <linux/list.h>
28#include <asm/atomic.h> 27#include <asm/atomic.h>
29 28
diff --git a/include/linux/pm_legacy.h b/include/linux/pm_legacy.h
index 008932d73c35..78027c533b94 100644
--- a/include/linux/pm_legacy.h
+++ b/include/linux/pm_legacy.h
@@ -1,7 +1,6 @@
1#ifndef __LINUX_PM_LEGACY_H__ 1#ifndef __LINUX_PM_LEGACY_H__
2#define __LINUX_PM_LEGACY_H__ 2#define __LINUX_PM_LEGACY_H__
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_PM_LEGACY 5#ifdef CONFIG_PM_LEGACY
7 6
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index 217d3daf7336..ecce5912f4d6 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -6,7 +6,6 @@
6 * Copyright (C) 1998 Paul Mackerras. 6 * Copyright (C) 1998 Paul Mackerras.
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11#define PMU_DRIVER_VERSION 2 10#define PMU_DRIVER_VERSION 2
12 11
diff --git a/include/linux/ppp_defs.h b/include/linux/ppp_defs.h
index 402056cd049d..c6b13ff85028 100644
--- a/include/linux/ppp_defs.h
+++ b/include/linux/ppp_defs.h
@@ -42,8 +42,6 @@
42#ifndef _PPP_DEFS_H_ 42#ifndef _PPP_DEFS_H_
43#define _PPP_DEFS_H_ 43#define _PPP_DEFS_H_
44 44
45#include <linux/crc-ccitt.h>
46
47/* 45/*
48 * The basic PPP frame. 46 * The basic PPP frame.
49 */ 47 */
@@ -97,7 +95,11 @@
97 95
98#define PPP_INITFCS 0xffff /* Initial FCS value */ 96#define PPP_INITFCS 0xffff /* Initial FCS value */
99#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ 97#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
98
99#ifdef __KERNEL__
100#include <linux/crc-ccitt.h>
100#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c) 101#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c)
102#endif
101 103
102/* 104/*
103 * Extended asyncmap - allows any character to be escaped. 105 * Extended asyncmap - allows any character to be escaped.
@@ -179,12 +181,4 @@ struct ppp_idle {
179 time_t recv_idle; /* time since last NP packet received */ 181 time_t recv_idle; /* time since last NP packet received */
180}; 182};
181 183
182#ifndef __P
183#ifdef __STDC__
184#define __P(x) x
185#else
186#define __P(x) ()
187#endif
188#endif
189
190#endif /* _PPP_DEFS_H_ */ 184#endif /* _PPP_DEFS_H_ */
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 5769d14d1e6a..d0926d63406c 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -6,7 +6,6 @@
6 * preempt_count (used for kernel preemption, interrupt count, etc.) 6 * preempt_count (used for kernel preemption, interrupt count, etc.)
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/thread_info.h> 9#include <linux/thread_info.h>
11#include <linux/linkage.h> 10#include <linux/linkage.h>
12 11
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 4b47a0253425..5810d28fbed9 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_PROC_FS_H 1#ifndef _LINUX_PROC_FS_H
2#define _LINUX_PROC_FS_H 2#define _LINUX_PROC_FS_H
3 3
4#include <linux/config.h>
5#include <linux/slab.h> 4#include <linux/slab.h>
6#include <linux/fs.h> 5#include <linux/fs.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/include/linux/profile.h b/include/linux/profile.h
index 1f2fea6640a4..e633004ae052 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -4,7 +4,6 @@
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/config.h>
8#include <linux/init.h> 7#include <linux/init.h>
9#include <linux/cpumask.h> 8#include <linux/cpumask.h>
10#include <asm/errno.h> 9#include <asm/errno.h>
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 2dab71e1c3d1..b8fbf26eb885 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -37,8 +37,6 @@
37 37
38#include <linux/errno.h> 38#include <linux/errno.h>
39#include <linux/types.h> 39#include <linux/types.h>
40#include <linux/spinlock.h>
41#include <linux/mutex.h>
42 40
43#define __DQUOT_VERSION__ "dquot_6.5.1" 41#define __DQUOT_VERSION__ "dquot_6.5.1"
44#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1 42#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
@@ -133,6 +131,8 @@ struct if_dqinfo {
133}; 131};
134 132
135#ifdef __KERNEL__ 133#ifdef __KERNEL__
134#include <linux/spinlock.h>
135#include <linux/mutex.h>
136 136
137#include <linux/dqblk_xfs.h> 137#include <linux/dqblk_xfs.h>
138#include <linux/dqblk_v1.h> 138#include <linux/dqblk_v1.h>
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 21e5a9124856..5110201a4159 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -10,7 +10,6 @@
10#ifndef _LINUX_QUOTAOPS_ 10#ifndef _LINUX_QUOTAOPS_
11#define _LINUX_QUOTAOPS_ 11#define _LINUX_QUOTAOPS_
12 12
13#include <linux/config.h>
14#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
15 14
16#include <linux/fs.h> 15#include <linux/fs.h>
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 4b7cc4fe366d..f37006f21664 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -99,19 +99,36 @@ static inline struct page * rb_insert_page_cache(struct inode * inode,
99 99
100struct rb_node 100struct rb_node
101{ 101{
102 struct rb_node *rb_parent; 102 unsigned long rb_parent_color;
103 int rb_color;
104#define RB_RED 0 103#define RB_RED 0
105#define RB_BLACK 1 104#define RB_BLACK 1
106 struct rb_node *rb_right; 105 struct rb_node *rb_right;
107 struct rb_node *rb_left; 106 struct rb_node *rb_left;
108}; 107} __attribute__((aligned(sizeof(long))));
108 /* The alignment might seem pointless, but allegedly CRIS needs it */
109 109
110struct rb_root 110struct rb_root
111{ 111{
112 struct rb_node *rb_node; 112 struct rb_node *rb_node;
113}; 113};
114 114
115
116#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
117#define rb_color(r) ((r)->rb_parent_color & 1)
118#define rb_is_red(r) (!rb_color(r))
119#define rb_is_black(r) rb_color(r)
120#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
121#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
122
123static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
124{
125 rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
126}
127static inline void rb_set_color(struct rb_node *rb, int color)
128{
129 rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
130}
131
115#define RB_ROOT (struct rb_root) { NULL, } 132#define RB_ROOT (struct rb_root) { NULL, }
116#define rb_entry(ptr, type, member) container_of(ptr, type, member) 133#define rb_entry(ptr, type, member) container_of(ptr, type, member)
117 134
@@ -131,8 +148,7 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
131static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, 148static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
132 struct rb_node ** rb_link) 149 struct rb_node ** rb_link)
133{ 150{
134 node->rb_parent = parent; 151 node->rb_parent_color = (unsigned long )parent;
135 node->rb_color = RB_RED;
136 node->rb_left = node->rb_right = NULL; 152 node->rb_left = node->rb_right = NULL;
137 153
138 *rb_link = node; 154 *rb_link = node;
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index 5353afb11db3..5e961035c725 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -2,8 +2,6 @@
2 File: linux/reiserfs_xattr.h 2 File: linux/reiserfs_xattr.h
3*/ 3*/
4 4
5#include <linux/config.h>
6#include <linux/init.h>
7#include <linux/xattr.h> 5#include <linux/xattr.h>
8 6
9/* Magic value in header */ 7/* Magic value in header */
@@ -15,6 +13,7 @@ struct reiserfs_xattr_header {
15}; 13};
16 14
17#ifdef __KERNEL__ 15#ifdef __KERNEL__
16#include <linux/init.h>
18 17
19struct reiserfs_xattr_handler { 18struct reiserfs_xattr_handler {
20 char *prefix; 19 char *prefix;
diff --git a/include/linux/relay.h b/include/linux/relay.h
index 4bcc1531d6a9..24accb483849 100644
--- a/include/linux/relay.h
+++ b/include/linux/relay.h
@@ -10,7 +10,6 @@
10#ifndef _LINUX_RELAY_H 10#ifndef _LINUX_RELAY_H
11#define _LINUX_RELAY_H 11#define _LINUX_RELAY_H
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/sched.h> 14#include <linux/sched.h>
16#include <linux/wait.h> 15#include <linux/wait.h>
diff --git a/include/linux/rio.h b/include/linux/rio.h
index c7e907faae9c..d93857056cb9 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -17,7 +17,6 @@
17#ifdef __KERNEL__ 17#ifdef __KERNEL__
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/config.h>
21#include <linux/ioport.h> 20#include <linux/ioport.h>
22#include <linux/list.h> 21#include <linux/list.h>
23#include <linux/errno.h> 22#include <linux/errno.h>
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index f54772d0e7f8..7adb2a1aac92 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -16,7 +16,6 @@
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/config.h>
20#include <linux/ioport.h> 19#include <linux/ioport.h>
21#include <linux/list.h> 20#include <linux/list.h>
22#include <linux/errno.h> 21#include <linux/errno.h>
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index d6b9bcd1384c..2d4c81a220db 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -4,7 +4,6 @@
4 * Declarations for Reverse Mapping functions in mm/rmap.c 4 * Declarations for Reverse Mapping functions in mm/rmap.c
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/list.h> 7#include <linux/list.h>
9#include <linux/slab.h> 8#include <linux/slab.h>
10#include <linux/mm.h> 9#include <linux/mm.h>
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index df0cdd41085c..facd9ee37b76 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -909,7 +909,6 @@ struct tcamsg
909 909
910#ifdef __KERNEL__ 910#ifdef __KERNEL__
911 911
912#include <linux/config.h>
913#include <linux/mutex.h> 912#include <linux/mutex.h>
914 913
915extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size); 914extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index bfb988885002..f99fe90732ab 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -13,7 +13,6 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/config.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <asm/system.h> 18#include <asm/system.h>
diff --git a/include/linux/scc.h b/include/linux/scc.h
index 885a4a02b23c..3495bd953cc6 100644
--- a/include/linux/scc.h
+++ b/include/linux/scc.h
@@ -3,7 +3,6 @@
3#ifndef _SCC_H 3#ifndef _SCC_H
4#define _SCC_H 4#define _SCC_H
5 5
6#include <linux/config.h>
7 6
8/* selection of hardware types */ 7/* selection of hardware types */
9 8
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 29b7d4f87d20..267f15257040 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1,9 +1,46 @@
1#ifndef _LINUX_SCHED_H 1#ifndef _LINUX_SCHED_H
2#define _LINUX_SCHED_H 2#define _LINUX_SCHED_H
3 3
4#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
5
6/*
7 * cloning flags:
8 */
9#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
10#define CLONE_VM 0x00000100 /* set if VM shared between processes */
11#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
12#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
13#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
14#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
15#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
16#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
17#define CLONE_THREAD 0x00010000 /* Same thread group? */
18#define CLONE_NEWNS 0x00020000 /* New namespace group? */
19#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
20#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
21#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
22#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
23#define CLONE_DETACHED 0x00400000 /* Unused, ignored */
24#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
25#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
26#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
27
28/*
29 * Scheduling policies
30 */
31#define SCHED_NORMAL 0
32#define SCHED_FIFO 1
33#define SCHED_RR 2
34#define SCHED_BATCH 3
35
36#ifdef __KERNEL__
37
38struct sched_param {
39 int sched_priority;
40};
41
4#include <asm/param.h> /* for HZ */ 42#include <asm/param.h> /* for HZ */
5 43
6#include <linux/config.h>
7#include <linux/capability.h> 44#include <linux/capability.h>
8#include <linux/threads.h> 45#include <linux/threads.h>
9#include <linux/kernel.h> 46#include <linux/kernel.h>
@@ -37,31 +74,15 @@
37#include <linux/rcupdate.h> 74#include <linux/rcupdate.h>
38#include <linux/futex.h> 75#include <linux/futex.h>
39 76
40#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */ 77#include <linux/time.h>
78#include <linux/param.h>
79#include <linux/resource.h>
80#include <linux/timer.h>
81#include <linux/hrtimer.h>
41 82
42struct exec_domain; 83#include <asm/processor.h>
43 84
44/* 85struct exec_domain;
45 * cloning flags:
46 */
47#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
48#define CLONE_VM 0x00000100 /* set if VM shared between processes */
49#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
50#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
51#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
52#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
53#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
54#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
55#define CLONE_THREAD 0x00010000 /* Same thread group? */
56#define CLONE_NEWNS 0x00020000 /* New namespace group? */
57#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
58#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
59#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
60#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
61#define CLONE_DETACHED 0x00400000 /* Unused, ignored */
62#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
63#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
64#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
65 86
66/* 87/*
67 * List of flags we want to share for kernel threads, 88 * List of flags we want to share for kernel threads,
@@ -103,13 +124,6 @@ extern unsigned long nr_uninterruptible(void);
103extern unsigned long nr_active(void); 124extern unsigned long nr_active(void);
104extern unsigned long nr_iowait(void); 125extern unsigned long nr_iowait(void);
105 126
106#include <linux/time.h>
107#include <linux/param.h>
108#include <linux/resource.h>
109#include <linux/timer.h>
110#include <linux/hrtimer.h>
111
112#include <asm/processor.h>
113 127
114/* 128/*
115 * Task state bitmask. NOTE! These bits are also 129 * Task state bitmask. NOTE! These bits are also
@@ -156,20 +170,6 @@ extern unsigned long nr_iowait(void);
156/* Task command name length */ 170/* Task command name length */
157#define TASK_COMM_LEN 16 171#define TASK_COMM_LEN 16
158 172
159/*
160 * Scheduling policies
161 */
162#define SCHED_NORMAL 0
163#define SCHED_FIFO 1
164#define SCHED_RR 2
165#define SCHED_BATCH 3
166
167struct sched_param {
168 int sched_priority;
169};
170
171#ifdef __KERNEL__
172
173#include <linux/spinlock.h> 173#include <linux/spinlock.h>
174 174
175/* 175/*
@@ -494,7 +494,7 @@ struct user_struct {
494 atomic_t processes; /* How many processes does this user have? */ 494 atomic_t processes; /* How many processes does this user have? */
495 atomic_t files; /* How many open files does this user have? */ 495 atomic_t files; /* How many open files does this user have? */
496 atomic_t sigpending; /* How many pending signals does this user have? */ 496 atomic_t sigpending; /* How many pending signals does this user have? */
497#ifdef CONFIG_INOTIFY 497#ifdef CONFIG_INOTIFY_USER
498 atomic_t inotify_watches; /* How many inotify watches does this user have? */ 498 atomic_t inotify_watches; /* How many inotify watches does this user have? */
499 atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ 499 atomic_t inotify_devs; /* How many inotify devs does this user have opened? */
500#endif 500#endif
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index cd2773b29a64..3e8b1cf54303 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_SECCOMP_H 1#ifndef _LINUX_SECCOMP_H
2#define _LINUX_SECCOMP_H 2#define _LINUX_SECCOMP_H
3 3
4#include <linux/config.h>
5 4
6#ifdef CONFIG_SECCOMP 5#ifdef CONFIG_SECCOMP
7 6
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 3c1f1120fe88..9aaffb0b1d81 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -2,7 +2,6 @@
2#define _LINUX_SEM_H 2#define _LINUX_SEM_H
3 3
4#include <linux/ipc.h> 4#include <linux/ipc.h>
5#include <asm/atomic.h>
6 5
7/* semop flags */ 6/* semop flags */
8#define SEM_UNDO 0x1000 /* undo the operation on exit */ 7#define SEM_UNDO 0x1000 /* undo the operation on exit */
@@ -78,6 +77,7 @@ struct seminfo {
78#define SEMUSZ 20 /* sizeof struct sem_undo */ 77#define SEMUSZ 20 /* sizeof struct sem_undo */
79 78
80#ifdef __KERNEL__ 79#ifdef __KERNEL__
80#include <asm/atomic.h>
81 81
82struct task_struct; 82struct task_struct;
83 83
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 5a095572881d..7bc5c7c12b54 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -26,7 +26,6 @@
26 * by Keith Owens and Andrea Arcangeli 26 * by Keith Owens and Andrea Arcangeli
27 */ 27 */
28 28
29#include <linux/config.h>
30#include <linux/spinlock.h> 29#include <linux/spinlock.h>
31#include <linux/preempt.h> 30#include <linux/preempt.h>
32 31
diff --git a/include/linux/serialP.h b/include/linux/serialP.h
index 2b9e6b9554d5..e811a615f696 100644
--- a/include/linux/serialP.h
+++ b/include/linux/serialP.h
@@ -19,7 +19,6 @@
19 * For definitions of the flags field, see tty.h 19 * For definitions of the flags field, see tty.h
20 */ 20 */
21 21
22#include <linux/config.h>
23#include <linux/termios.h> 22#include <linux/termios.h>
24#include <linux/workqueue.h> 23#include <linux/workqueue.h>
25#include <linux/interrupt.h> 24#include <linux/interrupt.h>
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index bd14858121ea..94b9286cf6bd 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -132,7 +132,6 @@
132 132
133#ifdef __KERNEL__ 133#ifdef __KERNEL__
134 134
135#include <linux/config.h>
136#include <linux/compiler.h> 135#include <linux/compiler.h>
137#include <linux/interrupt.h> 136#include <linux/interrupt.h>
138#include <linux/circ_buf.h> 137#include <linux/circ_buf.h>
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 70739f51a09f..1e4ce7225eee 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -1,12 +1,12 @@
1#ifndef _LINUX_SIGNAL_H 1#ifndef _LINUX_SIGNAL_H
2#define _LINUX_SIGNAL_H 2#define _LINUX_SIGNAL_H
3 3
4#include <linux/list.h>
5#include <linux/spinlock.h>
6#include <asm/signal.h> 4#include <asm/signal.h>
7#include <asm/siginfo.h> 5#include <asm/siginfo.h>
8 6
9#ifdef __KERNEL__ 7#ifdef __KERNEL__
8#include <linux/list.h>
9#include <linux/spinlock.h>
10 10
11/* 11/*
12 * These values of sa_flags are used only by the kernel as part of the 12 * These values of sa_flags are used only by the kernel as part of the
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 93e4db221585..66f8819f9568 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -14,7 +14,6 @@
14#ifndef _LINUX_SKBUFF_H 14#ifndef _LINUX_SKBUFF_H
15#define _LINUX_SKBUFF_H 15#define _LINUX_SKBUFF_H
16 16
17#include <linux/config.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/compiler.h> 18#include <linux/compiler.h>
20#include <linux/time.h> 19#include <linux/time.h>
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 2d985d59c7b8..9dc93163e065 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -11,7 +11,6 @@
11 11
12typedef struct kmem_cache kmem_cache_t; 12typedef struct kmem_cache kmem_cache_t;
13 13
14#include <linux/config.h> /* kmalloc_sizes.h needs CONFIG_ options */
15#include <linux/gfp.h> 14#include <linux/gfp.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/types.h> 16#include <linux/types.h>
diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h
index 621a3d3662f3..367d6c3e8ed4 100644
--- a/include/linux/smb_fs.h
+++ b/include/linux/smb_fs.h
@@ -10,8 +10,6 @@
10#define _LINUX_SMB_FS_H 10#define _LINUX_SMB_FS_H
11 11
12#include <linux/smb.h> 12#include <linux/smb.h>
13#include <linux/smb_fs_i.h>
14#include <linux/smb_fs_sb.h>
15 13
16/* 14/*
17 * ioctl commands 15 * ioctl commands
@@ -24,6 +22,8 @@
24 22
25 23
26#ifdef __KERNEL__ 24#ifdef __KERNEL__
25#include <linux/smb_fs_i.h>
26#include <linux/smb_fs_sb.h>
27 27
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/pagemap.h> 29#include <linux/pagemap.h>
diff --git a/include/linux/smp.h b/include/linux/smp.h
index e2fa3ab4afc5..c93c3fe4308c 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -6,7 +6,6 @@
6 * Alan Cox. <alan@redhat.com> 6 * Alan Cox. <alan@redhat.com>
7 */ 7 */
8 8
9#include <linux/config.h>
10 9
11extern void cpu_idle(void); 10extern void cpu_idle(void);
12 11
diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h
index fa1ff3b165fe..cf715a40d833 100644
--- a/include/linux/smp_lock.h
+++ b/include/linux/smp_lock.h
@@ -1,7 +1,6 @@
1#ifndef __LINUX_SMPLOCK_H 1#ifndef __LINUX_SMPLOCK_H
2#define __LINUX_SMPLOCK_H 2#define __LINUX_SMPLOCK_H
3 3
4#include <linux/config.h>
5#ifdef CONFIG_LOCK_KERNEL 4#ifdef CONFIG_LOCK_KERNEL
6#include <linux/sched.h> 5#include <linux/sched.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 9ab2ddd80221..361409094649 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -18,8 +18,6 @@ struct __kernel_sockaddr_storage {
18 18
19#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) 19#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
20 20
21#include <linux/config.h> /* for CONFIG_COMPAT */
22#include <linux/linkage.h>
23#include <asm/socket.h> /* arch-dependent defines */ 21#include <asm/socket.h> /* arch-dependent defines */
24#include <linux/sockios.h> /* the SIOCxxx I/O controls */ 22#include <linux/sockios.h> /* the SIOCxxx I/O controls */
25#include <linux/uio.h> /* iovec support */ 23#include <linux/uio.h> /* iovec support */
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 799be6747944..ae23beef9cc9 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -46,7 +46,6 @@
46 * linux/spinlock.h: builds the final spin_*() APIs. 46 * linux/spinlock.h: builds the final spin_*() APIs.
47 */ 47 */
48 48
49#include <linux/config.h>
50#include <linux/preempt.h> 49#include <linux/preempt.h>
51#include <linux/linkage.h> 50#include <linux/linkage.h>
52#include <linux/compiler.h> 51#include <linux/compiler.h>
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h
index 151a803ed0ed..5bfc553bdb21 100644
--- a/include/linux/stop_machine.h
+++ b/include/linux/stop_machine.h
@@ -4,7 +4,6 @@
4 very heavy lock, which is equivalent to grabbing every spinlock 4 very heavy lock, which is equivalent to grabbing every spinlock
5 (and more). So the "read" side to such a lock is anything which 5 (and more). So the "read" side to such a lock is anything which
6 diables preeempt. */ 6 diables preeempt. */
7#include <linux/config.h>
8#include <linux/cpu.h> 7#include <linux/cpu.h>
9#include <asm/system.h> 8#include <asm/system.h>
10 9
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index be4772ed43c0..a6de332e57d4 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -11,7 +11,6 @@
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#include <linux/config.h>
15#include <linux/sunrpc/sched.h> 14#include <linux/sunrpc/sched.h>
16#include <linux/sunrpc/msg_prot.h> 15#include <linux/sunrpc/msg_prot.h>
17#include <linux/sunrpc/xdr.h> 16#include <linux/sunrpc/xdr.h>
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 1a42d902bc11..e4729aa67654 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -9,19 +9,6 @@
9#ifndef _LINUX_SUNRPC_DEBUG_H_ 9#ifndef _LINUX_SUNRPC_DEBUG_H_
10#define _LINUX_SUNRPC_DEBUG_H_ 10#define _LINUX_SUNRPC_DEBUG_H_
11 11
12#include <linux/config.h>
13
14#include <linux/timer.h>
15#include <linux/workqueue.h>
16
17/*
18 * Enable RPC debugging/profiling.
19 */
20#ifdef CONFIG_SYSCTL
21#define RPC_DEBUG
22#endif
23/* #define RPC_PROFILE */
24
25/* 12/*
26 * RPC debug facilities 13 * RPC debug facilities
27 */ 14 */
@@ -41,6 +28,17 @@
41 28
42#ifdef __KERNEL__ 29#ifdef __KERNEL__
43 30
31#include <linux/timer.h>
32#include <linux/workqueue.h>
33
34/*
35 * Enable RPC debugging/profiling.
36 */
37#ifdef CONFIG_SYSCTL
38#define RPC_DEBUG
39#endif
40/* #define RPC_PROFILE */
41
44/* 42/*
45 * Debugging macros etc 43 * Debugging macros etc
46 */ 44 */
diff --git a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h
index d93c24b47f3f..5fa0f2084307 100644
--- a/include/linux/sunrpc/stats.h
+++ b/include/linux/sunrpc/stats.h
@@ -9,7 +9,6 @@
9#ifndef _LINUX_SUNRPC_STATS_H 9#ifndef _LINUX_SUNRPC_STATS_H
10#define _LINUX_SUNRPC_STATS_H 10#define _LINUX_SUNRPC_STATS_H
11 11
12#include <linux/config.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
14 13
15struct rpc_stat { 14struct rpc_stat {
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 37c1c76fd547..96e31aa64cc7 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -6,7 +6,6 @@
6#endif 6#endif
7#include <linux/swap.h> 7#include <linux/swap.h>
8#include <linux/notifier.h> 8#include <linux/notifier.h>
9#include <linux/config.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/pm.h> 10#include <linux/pm.h>
12 11
diff --git a/include/linux/swap.h b/include/linux/swap.h
index f03c24719302..aca9bfae208f 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_SWAP_H 1#ifndef _LINUX_SWAP_H
2#define _LINUX_SWAP_H 2#define _LINUX_SWAP_H
3 3
4#include <linux/config.h>
5#include <linux/spinlock.h> 4#include <linux/spinlock.h>
6#include <linux/linkage.h> 5#include <linux/linkage.h>
7#include <linux/mmzone.h> 6#include <linux/mmzone.h>
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 60d49e5456e7..bd67a4413df7 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -54,7 +54,6 @@ struct compat_stat;
54struct compat_timeval; 54struct compat_timeval;
55struct robust_list_head; 55struct robust_list_head;
56 56
57#include <linux/config.h>
58#include <linux/types.h> 57#include <linux/types.h>
59#include <linux/aio_abi.h> 58#include <linux/aio_abi.h>
60#include <linux/capability.h> 59#include <linux/capability.h>
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index ea819b89c235..4812ff60561c 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -11,7 +11,6 @@
11 * based upon discusions in irc://irc.openprojects.net/#kernelnewbies 11 * based upon discusions in irc://irc.openprojects.net/#kernelnewbies
12 */ 12 */
13 13
14#include <linux/config.h>
15 14
16struct pt_regs; 15struct pt_regs;
17struct tty_struct; 16struct tty_struct;
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index c90daa5da6c3..420a689c3fb4 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -160,7 +160,6 @@ struct tcp_info
160 160
161#ifdef __KERNEL__ 161#ifdef __KERNEL__
162 162
163#include <linux/config.h>
164#include <linux/skbuff.h> 163#include <linux/skbuff.h>
165#include <net/sock.h> 164#include <net/sock.h>
166#include <net/inet_connection_sock.h> 165#include <net/inet_connection_sock.h>
diff --git a/include/linux/threads.h b/include/linux/threads.h
index e646bcdf2614..38d1a5d6568e 100644
--- a/include/linux/threads.h
+++ b/include/linux/threads.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_THREADS_H 1#ifndef _LINUX_THREADS_H
2#define _LINUX_THREADS_H 2#define _LINUX_THREADS_H
3 3
4#include <linux/config.h>
5 4
6/* 5/*
7 * The default limit for the nr of threads is now in 6 * The default limit for the nr of threads is now in
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 0a485beba9f5..c982304dbafd 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -1,7 +1,6 @@
1#ifndef _LINUX_TIMER_H 1#ifndef _LINUX_TIMER_H
2#define _LINUX_TIMER_H 2#define _LINUX_TIMER_H
3 3
4#include <linux/config.h>
5#include <linux/list.h> 4#include <linux/list.h>
6#include <linux/spinlock.h> 5#include <linux/spinlock.h>
7#include <linux/stddef.h> 6#include <linux/stddef.h>
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 03914b7e41b1..34d3ccff7bbb 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -53,7 +53,6 @@
53#ifndef _LINUX_TIMEX_H 53#ifndef _LINUX_TIMEX_H
54#define _LINUX_TIMEX_H 54#define _LINUX_TIMEX_H
55 55
56#include <linux/config.h>
57#include <linux/compiler.h> 56#include <linux/compiler.h>
58#include <linux/time.h> 57#include <linux/time.h>
59 58
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f13f49afe198..e898eeb94166 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -16,7 +16,6 @@
16 consoles 16 and higher (since it returns a short) */ 16 consoles 16 and higher (since it returns a short) */
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19#include <linux/config.h>
20#include <linux/fs.h> 19#include <linux/fs.h>
21#include <linux/major.h> 20#include <linux/major.h>
22#include <linux/termios.h> 21#include <linux/termios.h>
diff --git a/include/linux/types.h b/include/linux/types.h
index 1046c7ad86d9..a5e46e783ffa 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -2,7 +2,6 @@
2#define _LINUX_TYPES_H 2#define _LINUX_TYPES_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5#include <linux/config.h>
6 5
7#define BITS_TO_LONGS(bits) \ 6#define BITS_TO_LONGS(bits) \
8 (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) 7 (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 85a55658831c..bdd39be09406 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -35,7 +35,6 @@ struct udphdr {
35#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ 35#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
36 36
37#ifdef __KERNEL__ 37#ifdef __KERNEL__
38#include <linux/config.h>
39#include <linux/types.h> 38#include <linux/types.h>
40 39
41#include <net/inet_sock.h> 40#include <net/inet_sock.h>
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index 843aeaaa79d4..86b5b4271b5a 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -32,7 +32,6 @@
32 32
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/time.h>
36#include <linux/stat.h> 35#include <linux/stat.h>
37#include <linux/fs.h> 36#include <linux/fs.h>
38 37
diff --git a/include/linux/unistd.h b/include/linux/unistd.h
index 10ed9834b822..c18c60f3254e 100644
--- a/include/linux/unistd.h
+++ b/include/linux/unistd.h
@@ -1,7 +1,9 @@
1#ifndef _LINUX_UNISTD_H_ 1#ifndef _LINUX_UNISTD_H_
2#define _LINUX_UNISTD_H_ 2#define _LINUX_UNISTD_H_
3 3
4#ifdef __KERNEL__
4extern int errno; 5extern int errno;
6#endif
5 7
6/* 8/*
7 * Include machine specific syscallX macros 9 * Include machine specific syscallX macros
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e34e5e3dce52..1f492c0c7047 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -10,7 +10,6 @@
10 10
11#ifdef __KERNEL__ 11#ifdef __KERNEL__
12 12
13#include <linux/config.h>
14#include <linux/errno.h> /* for -ENODEV */ 13#include <linux/errno.h> /* for -ENODEV */
15#include <linux/delay.h> /* for mdelay() */ 14#include <linux/delay.h> /* for mdelay() */
16#include <linux/interrupt.h> /* for in_interrupt() */ 15#include <linux/interrupt.h> /* for in_interrupt() */
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
index b2d08984a9f7..608487a62c98 100644
--- a/include/linux/usb_usual.h
+++ b/include/linux/usb_usual.h
@@ -9,7 +9,6 @@
9#ifndef __LINUX_USB_USUAL_H 9#ifndef __LINUX_USB_USUAL_H
10#define __LINUX_USB_USUAL_H 10#define __LINUX_USB_USUAL_H
11 11
12#include <linux/config.h>
13 12
14/* We should do this for cleanliness... But other usb_foo.h do not do this. */ 13/* We should do this for cleanliness... But other usb_foo.h do not do this. */
15/* #include <linux/usb.h> */ 14/* #include <linux/usb.h> */
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 8859f0b41543..7b7aadb69092 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -123,6 +123,7 @@ struct usbdevfs_hub_portinfo {
123 char port [127]; /* e.g. port 3 connects to device 27 */ 123 char port [127]; /* e.g. port 3 connects to device 27 */
124}; 124};
125 125
126#ifdef __KERNEL__
126#ifdef CONFIG_COMPAT 127#ifdef CONFIG_COMPAT
127#include <linux/compat.h> 128#include <linux/compat.h>
128struct usbdevfs_urb32 { 129struct usbdevfs_urb32 {
@@ -147,6 +148,7 @@ struct usbdevfs_ioctl32 {
147 compat_caddr_t data; 148 compat_caddr_t data;
148}; 149};
149#endif 150#endif
151#endif /* __KERNEL__ */
150 152
151#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) 153#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
152#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) 154#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h
index 1f7ba3629053..057db7d2f448 100644
--- a/include/linux/vt_buffer.h
+++ b/include/linux/vt_buffer.h
@@ -13,7 +13,6 @@
13#ifndef _LINUX_VT_BUFFER_H_ 13#ifndef _LINUX_VT_BUFFER_H_
14#define _LINUX_VT_BUFFER_H_ 14#define _LINUX_VT_BUFFER_H_
15 15
16#include <linux/config.h>
17 16
18#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) 17#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
19#include <asm/vga.h> 18#include <asm/vga.h>
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index fab5aed8ca31..940d0261a545 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -6,7 +6,6 @@
6 * with information needed by the vt package 6 * with information needed by the vt package
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/vt.h> 9#include <linux/vt.h>
11#include <linux/kd.h> 10#include <linux/kd.h>
12#include <linux/tty.h> 11#include <linux/tty.h>
diff --git a/include/linux/wait.h b/include/linux/wait.h
index d28518236b62..544e855c7c02 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -19,7 +19,6 @@
19 19
20#ifdef __KERNEL__ 20#ifdef __KERNEL__
21 21
22#include <linux/config.h>
23#include <linux/list.h> 22#include <linux/list.h>
24#include <linux/stddef.h> 23#include <linux/stddef.h>
25#include <linux/spinlock.h> 24#include <linux/spinlock.h>
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
index 1b6b76a4eb54..2cd05013edfc 100644
--- a/include/linux/wanrouter.h
+++ b/include/linux/wanrouter.h
@@ -44,8 +44,6 @@
44* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h). 44* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
45*****************************************************************************/ 45*****************************************************************************/
46 46
47#include <linux/spinlock.h> /* Support for SMP Locking */
48
49#ifndef _ROUTER_H 47#ifndef _ROUTER_H
50#define _ROUTER_H 48#define _ROUTER_H
51 49
@@ -457,6 +455,8 @@ typedef struct wanif_conf
457#include <linux/fs.h> /* support for device drivers */ 455#include <linux/fs.h> /* support for device drivers */
458#include <linux/proc_fs.h> /* proc filesystem pragmatics */ 456#include <linux/proc_fs.h> /* proc filesystem pragmatics */
459#include <linux/netdevice.h> /* support for network drivers */ 457#include <linux/netdevice.h> /* support for network drivers */
458#include <linux/spinlock.h> /* Support for SMP Locking */
459
460/*---------------------------------------------------------------------------- 460/*----------------------------------------------------------------------------
461 * WAN device data space. 461 * WAN device data space.
462 */ 462 */
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index b5994ea56a5a..31329fce1ff5 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -7,8 +7,9 @@
7#ifndef __MTD_ABI_H__ 7#ifndef __MTD_ABI_H__
8#define __MTD_ABI_H__ 8#define __MTD_ABI_H__
9 9
10#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into 10#ifndef __KERNEL__
11 separate files was to avoid #ifdef __KERNEL__ */ 11/* Urgh. The whole point of splitting this out into
12 separate files was to avoid #ifdef __KERNEL__ */
12#define __user 13#define __user
13#endif 14#endif
14 15
@@ -28,28 +29,17 @@ struct mtd_oob_buf {
28#define MTD_ROM 2 29#define MTD_ROM 2
29#define MTD_NORFLASH 3 30#define MTD_NORFLASH 3
30#define MTD_NANDFLASH 4 31#define MTD_NANDFLASH 4
31#define MTD_PEROM 5
32#define MTD_DATAFLASH 6 32#define MTD_DATAFLASH 6
33#define MTD_OTHER 14 33
34#define MTD_UNKNOWN 15 34#define MTD_WRITEABLE 0x400 /* Device is writeable */
35 35#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */
36#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) 36#define MTD_NO_ERASE 0x1000 /* No erase necessary */
37#define MTD_SET_BITS 2 // Bits can be set
38#define MTD_ERASEABLE 4 // Has an erase function
39#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible
40#define MTD_VOLATILE 16 // Set for RAMs
41#define MTD_XIP 32 // eXecute-In-Place possible
42#define MTD_OOB 64 // Out-of-band data (NAND flash)
43#define MTD_ECC 128 // Device capable of automatic ECC
44#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed
45#define MTD_PROGRAM_REGIONS 512 // Configurable Programming Regions
46 37
47// Some common devices / combinations of capabilities 38// Some common devices / combinations of capabilities
48#define MTD_CAP_ROM 0 39#define MTD_CAP_ROM 0
49#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) 40#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
50#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) 41#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE)
51#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) 42#define MTD_CAP_NANDFLASH (MTD_WRITEABLE)
52#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS)
53 43
54 44
55// Types of automatic ECC/Checksum available 45// Types of automatic ECC/Checksum available
@@ -74,7 +64,7 @@ struct mtd_info_user {
74 uint32_t flags; 64 uint32_t flags;
75 uint32_t size; // Total size of the MTD 65 uint32_t size; // Total size of the MTD
76 uint32_t erasesize; 66 uint32_t erasesize;
77 uint32_t oobblock; // Size of OOB blocks (e.g. 512) 67 uint32_t writesize;
78 uint32_t oobsize; // Amount of OOB data per block (e.g. 16) 68 uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
79 uint32_t ecctype; 69 uint32_t ecctype;
80 uint32_t eccsize; 70 uint32_t eccsize;
@@ -94,12 +84,12 @@ struct otp_info {
94 uint32_t locked; 84 uint32_t locked;
95}; 85};
96 86
97#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) 87#define MEMGETINFO _IOR('M', 1, struct mtd_info_user)
98#define MEMERASE _IOW('M', 2, struct erase_info_user) 88#define MEMERASE _IOW('M', 2, struct erase_info_user)
99#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) 89#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf)
100#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) 90#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf)
101#define MEMLOCK _IOW('M', 5, struct erase_info_user) 91#define MEMLOCK _IOW('M', 5, struct erase_info_user)
102#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) 92#define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
103#define MEMGETREGIONCOUNT _IOR('M', 7, int) 93#define MEMGETREGIONCOUNT _IOR('M', 7, int)
104#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) 94#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
105#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) 95#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
@@ -109,8 +99,15 @@ struct otp_info {
109#define OTPSELECT _IOR('M', 13, int) 99#define OTPSELECT _IOR('M', 13, int)
110#define OTPGETREGIONCOUNT _IOW('M', 14, int) 100#define OTPGETREGIONCOUNT _IOW('M', 14, int)
111#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) 101#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
112#define OTPLOCK _IOR('M', 16, struct otp_info) 102#define OTPLOCK _IOR('M', 16, struct otp_info)
103#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
104#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
105#define MTDFILEMODE _IO('M', 19)
113 106
107/*
108 * Obsolete legacy interface. Keep it in order not to break userspace
109 * interfaces
110 */
114struct nand_oobinfo { 111struct nand_oobinfo {
115 uint32_t useecc; 112 uint32_t useecc;
116 uint32_t eccbytes; 113 uint32_t eccbytes;
@@ -118,4 +115,46 @@ struct nand_oobinfo {
118 uint32_t eccpos[32]; 115 uint32_t eccpos[32];
119}; 116};
120 117
118struct nand_oobfree {
119 uint32_t offset;
120 uint32_t length;
121};
122
123#define MTD_MAX_OOBFREE_ENTRIES 8
124/*
125 * ECC layout control structure. Exported to userspace for
126 * diagnosis and to allow creation of raw images
127 */
128struct nand_ecclayout {
129 uint32_t eccbytes;
130 uint32_t eccpos[64];
131 uint32_t oobavail;
132 struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
133};
134
135/**
136 * struct mtd_ecc_stats - error correction status
137 *
138 * @corrected: number of corrected bits
139 * @failed: number of uncorrectable errors
140 * @badblocks: number of bad blocks in this partition
141 * @bbtblocks: number of blocks reserved for bad block tables
142 */
143struct mtd_ecc_stats {
144 uint32_t corrected;
145 uint32_t failed;
146 uint32_t badblocks;
147 uint32_t bbtblocks;
148};
149
150/*
151 * Read/write file modes for access to MTD
152 */
153enum mtd_file_modes {
154 MTD_MODE_NORMAL = MTD_OTP_OFF,
155 MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY,
156 MTD_MODE_OTP_USER = MTD_OTP_USER,
157 MTD_MODE_RAW,
158};
159
121#endif /* __MTD_ABI_H__ */ 160#endif /* __MTD_ABI_H__ */
diff --git a/include/mtd/mtd-user.h b/include/mtd/mtd-user.h
index 1c13fc7161fe..713f34d3e62e 100644
--- a/include/mtd/mtd-user.h
+++ b/include/mtd/mtd-user.h
@@ -16,5 +16,6 @@ typedef struct mtd_info_user mtd_info_t;
16typedef struct erase_info_user erase_info_t; 16typedef struct erase_info_user erase_info_t;
17typedef struct region_info_user region_info_t; 17typedef struct region_info_user region_info_t;
18typedef struct nand_oobinfo nand_oobinfo_t; 18typedef struct nand_oobinfo nand_oobinfo_t;
19typedef struct nand_ecclayout nand_ecclayout_t;
19 20
20#endif /* __MTD_USER_H__ */ 21#endif /* __MTD_USER_H__ */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 750e2508dd90..3d71251b3eca 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -45,7 +45,6 @@ struct prefix_info {
45 45
46#ifdef __KERNEL__ 46#ifdef __KERNEL__
47 47
48#include <linux/config.h>
49#include <linux/netdevice.h> 48#include <linux/netdevice.h>
50#include <net/if_inet6.h> 49#include <net/if_inet6.h>
51#include <net/ipv6.h> 50#include <net/ipv6.h>
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 427dac94bc7e..795f81f9ec7f 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -1,7 +1,6 @@
1#ifndef __LINUX_NET_AFUNIX_H 1#ifndef __LINUX_NET_AFUNIX_H
2#define __LINUX_NET_AFUNIX_H 2#define __LINUX_NET_AFUNIX_H
3 3
4#include <linux/config.h>
5#include <linux/socket.h> 4#include <linux/socket.h>
6#include <linux/un.h> 5#include <linux/un.h>
7#include <linux/mutex.h> 6#include <linux/mutex.h>
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 5bd997487054..7cd528e9d668 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -6,7 +6,6 @@
6#ifndef _AX25_H 6#ifndef _AX25_H
7#define _AX25_H 7#define _AX25_H
8 8
9#include <linux/config.h>
10#include <linux/ax25.h> 9#include <linux/ax25.h>
11#include <linux/spinlock.h> 10#include <linux/spinlock.h>
12#include <linux/timer.h> 11#include <linux/timer.h>
diff --git a/include/net/compat.h b/include/net/compat.h
index e65cbedb6abc..9859b60280d5 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -1,7 +1,6 @@
1#ifndef NET_COMPAT_H 1#ifndef NET_COMPAT_H
2#define NET_COMPAT_H 2#define NET_COMPAT_H
3 3
4#include <linux/config.h>
5 4
6struct sock; 5struct sock;
7 6
diff --git a/include/net/dst.h b/include/net/dst.h
index 5161e89017f9..36d54fc248b0 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -8,7 +8,6 @@
8#ifndef _NET_DST_H 8#ifndef _NET_DST_H
9#define _NET_DST_H 9#define _NET_DST_H
10 10
11#include <linux/config.h>
12#include <linux/netdevice.h> 11#include <linux/netdevice.h>
13#include <linux/rtnetlink.h> 12#include <linux/rtnetlink.h>
14#include <linux/rcupdate.h> 13#include <linux/rcupdate.h>
diff --git a/include/net/icmp.h b/include/net/icmp.h
index e7c3f20fbafc..05f8ff7d9316 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -18,7 +18,6 @@
18#ifndef _ICMP_H 18#ifndef _ICMP_H
19#define _ICMP_H 19#define _ICMP_H
20 20
21#include <linux/config.h>
22#include <linux/icmp.h> 21#include <linux/icmp.h>
23 22
24#include <net/inet_sock.h> 23#include <net/inet_sock.h>
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 59f0c83d55a2..bc6a71dce984 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -14,7 +14,6 @@
14#ifndef _INET6_HASHTABLES_H 14#ifndef _INET6_HASHTABLES_H
15#define _INET6_HASHTABLES_H 15#define _INET6_HASHTABLES_H
16 16
17#include <linux/config.h>
18 17
19#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 18#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
20#include <linux/in6.h> 19#include <linux/in6.h>
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 135d80fd658e..98e0bb3014fe 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -14,7 +14,6 @@
14#ifndef _INET_HASHTABLES_H 14#ifndef _INET_HASHTABLES_H
15#define _INET_HASHTABLES_H 15#define _INET_HASHTABLES_H
16 16
17#include <linux/config.h>
18 17
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/ipv6.h> 19#include <linux/ipv6.h>
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 883eb529ef8e..1f4a9a60d4cc 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -16,7 +16,6 @@
16#ifndef _INET_SOCK_H 16#ifndef _INET_SOCK_H
17#define _INET_SOCK_H 17#define _INET_SOCK_H
18 18
19#include <linux/config.h>
20 19
21#include <linux/string.h> 20#include <linux/string.h>
22#include <linux/types.h> 21#include <linux/types.h>
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index e837f98fdb50..600cb543550d 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -15,7 +15,6 @@
15#ifndef _INET_TIMEWAIT_SOCK_ 15#ifndef _INET_TIMEWAIT_SOCK_
16#define _INET_TIMEWAIT_SOCK_ 16#define _INET_TIMEWAIT_SOCK_
17 17
18#include <linux/config.h>
19 18
20#include <linux/list.h> 19#include <linux/list.h>
21#include <linux/module.h> 20#include <linux/module.h>
diff --git a/include/net/ip.h b/include/net/ip.h
index ead233c9540d..98f908400771 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -22,7 +22,6 @@
22#ifndef _IP_H 22#ifndef _IP_H
23#define _IP_H 23#define _IP_H
24 24
25#include <linux/config.h>
26#include <linux/types.h> 25#include <linux/types.h>
27#include <linux/ip.h> 26#include <linux/ip.h>
28#include <linux/in.h> 27#include <linux/in.h>
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e000fa2cd5f6..a095d1dec7a4 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -16,7 +16,6 @@
16#ifndef _NET_IP_FIB_H 16#ifndef _NET_IP_FIB_H
17#define _NET_IP_FIB_H 17#define _NET_IP_FIB_H
18 18
19#include <linux/config.h>
20#include <net/flow.h> 19#include <net/flow.h>
21#include <linux/seq_file.h> 20#include <linux/seq_file.h>
22 21
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h
index 77225735cbd4..ac747b64734c 100644
--- a/include/net/ip_mp_alg.h
+++ b/include/net/ip_mp_alg.h
@@ -7,7 +7,6 @@
7#ifndef _NET_IP_MP_ALG_H 7#ifndef _NET_IP_MP_ALG_H
8#define _NET_IP_MP_ALG_H 8#define _NET_IP_MP_ALG_H
9 9
10#include <linux/config.h>
11#include <linux/ip_mp_alg.h> 10#include <linux/ip_mp_alg.h>
12#include <net/flow.h> 11#include <net/flow.h>
13#include <net/route.h> 12#include <net/route.h>
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 7d2674fde19a..3b57b159b653 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -248,7 +248,6 @@ struct ip_vs_daemon_user {
248 248
249#ifdef __KERNEL__ 249#ifdef __KERNEL__
250 250
251#include <linux/config.h>
252#include <linux/list.h> /* for struct list_head */ 251#include <linux/list.h> /* for struct list_head */
253#include <linux/spinlock.h> /* for struct rwlock_t */ 252#include <linux/spinlock.h> /* for struct rwlock_t */
254#include <asm/atomic.h> /* for struct atomic_t */ 253#include <asm/atomic.h> /* for struct atomic_t */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4abedb8eaece..a8fdf7970b37 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -104,7 +104,6 @@ struct frag_hdr {
104 104
105#ifdef __KERNEL__ 105#ifdef __KERNEL__
106 106
107#include <linux/config.h>
108#include <net/sock.h> 107#include <net/sock.h>
109 108
110/* sysctls */ 109/* sysctls */
diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h
index 1880e46ecc9b..1cb0607fcbb9 100644
--- a/include/net/irda/irda.h
+++ b/include/net/irda/irda.h
@@ -26,7 +26,6 @@
26#ifndef NET_IRDA_H 26#ifndef NET_IRDA_H
27#define NET_IRDA_H 27#define NET_IRDA_H
28 28
29#include <linux/config.h>
30#include <linux/skbuff.h> /* struct sk_buff */ 29#include <linux/skbuff.h> /* struct sk_buff */
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/if.h> /* sa_family_t in <linux/irda.h> */ 31#include <linux/if.h> /* sa_family_t in <linux/irda.h> */
diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
index 92c828029cd8..0575c59a5c96 100644
--- a/include/net/irda/irda_device.h
+++ b/include/net/irda/irda_device.h
@@ -39,7 +39,6 @@
39#ifndef IRDA_DEVICE_H 39#ifndef IRDA_DEVICE_H
40#define IRDA_DEVICE_H 40#define IRDA_DEVICE_H
41 41
42#include <linux/config.h>
43#include <linux/tty.h> 42#include <linux/tty.h>
44#include <linux/netdevice.h> 43#include <linux/netdevice.h>
45#include <linux/spinlock.h> 44#include <linux/spinlock.h>
diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h
index 2127cae1e0a6..e77eb88d9226 100644
--- a/include/net/irda/irlap.h
+++ b/include/net/irda/irlap.h
@@ -27,7 +27,6 @@
27#ifndef IRLAP_H 27#ifndef IRLAP_H
28#define IRLAP_H 28#define IRLAP_H
29 29
30#include <linux/config.h>
31#include <linux/types.h> 30#include <linux/types.h>
32#include <linux/skbuff.h> 31#include <linux/skbuff.h>
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h
index c0c895d379ba..11ecfa58a648 100644
--- a/include/net/irda/irlmp.h
+++ b/include/net/irda/irlmp.h
@@ -29,7 +29,6 @@
29 29
30#include <asm/param.h> /* for HZ */ 30#include <asm/param.h> /* for HZ */
31 31
32#include <linux/config.h>
33#include <linux/types.h> 32#include <linux/types.h>
34 33
35#include <net/irda/irda.h> 34#include <net/irda/irda.h>
diff --git a/include/net/irda/irlmp_frame.h b/include/net/irda/irlmp_frame.h
index eb3ad158c023..c463f8bca856 100644
--- a/include/net/irda/irlmp_frame.h
+++ b/include/net/irda/irlmp_frame.h
@@ -26,7 +26,6 @@
26#ifndef IRMLP_FRAME_H 26#ifndef IRMLP_FRAME_H
27#define IRMLP_FRAME_H 27#define IRMLP_FRAME_H
28 28
29#include <linux/config.h>
30#include <linux/skbuff.h> 29#include <linux/skbuff.h>
31 30
32#include <net/irda/discovery.h> 31#include <net/irda/discovery.h>
diff --git a/include/net/irda/qos.h b/include/net/irda/qos.h
index 9ae3d6bc2423..cc577dc0a0ef 100644
--- a/include/net/irda/qos.h
+++ b/include/net/irda/qos.h
@@ -31,7 +31,6 @@
31#ifndef IRDA_QOS_H 31#ifndef IRDA_QOS_H
32#define IRDA_QOS_H 32#define IRDA_QOS_H
33 33
34#include <linux/config.h>
35#include <linux/skbuff.h> 34#include <linux/skbuff.h>
36 35
37#include <net/irda/parameters.h> 36#include <net/irda/parameters.h>
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 91fa271a0064..d3915dabe6de 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -37,7 +37,6 @@ enum {
37 37
38#ifdef __KERNEL__ 38#ifdef __KERNEL__
39 39
40#include <linux/config.h>
41#include <linux/compiler.h> 40#include <linux/compiler.h>
42#include <linux/icmpv6.h> 41#include <linux/icmpv6.h>
43#include <linux/in6.h> 42#include <linux/in6.h>
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 411117815807..1fbd8193d5f1 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -15,7 +15,6 @@
15#include <linux/netfilter/nf_conntrack_common.h> 15#include <linux/netfilter/nf_conntrack_common.h>
16 16
17#ifdef __KERNEL__ 17#ifdef __KERNEL__
18#include <linux/config.h>
19#include <linux/bitops.h> 18#include <linux/bitops.h>
20#include <linux/compiler.h> 19#include <linux/compiler.h>
21#include <asm/atomic.h> 20#include <asm/atomic.h>
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h
index b225d8472b7e..cf5e4d2e4c21 100644
--- a/include/net/pkt_act.h
+++ b/include/net/pkt_act.h
@@ -4,7 +4,6 @@
4#include <asm/uaccess.h> 4#include <asm/uaccess.h>
5#include <asm/system.h> 5#include <asm/system.h>
6#include <linux/bitops.h> 6#include <linux/bitops.h>
7#include <linux/config.h>
8#include <linux/types.h> 7#include <linux/types.h>
9#include <linux/kernel.h> 8#include <linux/kernel.h>
10#include <linux/sched.h> 9#include <linux/sched.h>
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 6dc5970612d7..bcaee39bd2ff 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -24,7 +24,6 @@
24#ifndef _PROTOCOL_H 24#ifndef _PROTOCOL_H
25#define _PROTOCOL_H 25#define _PROTOCOL_H
26 26
27#include <linux/config.h>
28#include <linux/in6.h> 27#include <linux/in6.h>
29#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 28#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
30#include <linux/ipv6.h> 29#include <linux/ipv6.h>
diff --git a/include/net/raw.h b/include/net/raw.h
index d83571fe4c69..e4af59781949 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -17,7 +17,6 @@
17#ifndef _RAW_H 17#ifndef _RAW_H
18#define _RAW_H 18#define _RAW_H
19 19
20#include <linux/config.h>
21 20
22#include <net/protocol.h> 21#include <net/protocol.h>
23 22
diff --git a/include/net/red.h b/include/net/red.h
index 2ed4358e3295..5ccdbb3d4722 100644
--- a/include/net/red.h
+++ b/include/net/red.h
@@ -1,7 +1,6 @@
1#ifndef __NET_SCHED_RED_H 1#ifndef __NET_SCHED_RED_H
2#define __NET_SCHED_RED_H 2#define __NET_SCHED_RED_H
3 3
4#include <linux/config.h>
5#include <linux/types.h> 4#include <linux/types.h>
6#include <net/pkt_sched.h> 5#include <net/pkt_sched.h>
7#include <net/inet_ecn.h> 6#include <net/inet_ecn.h>
diff --git a/include/net/route.h b/include/net/route.h
index 98c915abdec8..c4a068692dcc 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -24,7 +24,6 @@
24#ifndef _ROUTE_H 24#ifndef _ROUTE_H
25#define _ROUTE_H 25#define _ROUTE_H
26 26
27#include <linux/config.h>
28#include <net/dst.h> 27#include <net/dst.h>
29#include <net/inetpeer.h> 28#include <net/inetpeer.h>
30#include <net/flow.h> 29#include <net/flow.h>
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 7b6ec9986715..b0e9108a4e18 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -1,7 +1,6 @@
1#ifndef __NET_SCHED_GENERIC_H 1#ifndef __NET_SCHED_GENERIC_H
2#define __NET_SCHED_GENERIC_H 2#define __NET_SCHED_GENERIC_H
3 3
4#include <linux/config.h>
5#include <linux/netdevice.h> 4#include <linux/netdevice.h>
6#include <linux/types.h> 5#include <linux/types.h>
7#include <linux/rcupdate.h> 6#include <linux/rcupdate.h>
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index b2b40f951ae6..237f82b05e40 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -63,7 +63,6 @@
63 */ 63 */
64 64
65 65
66#include <linux/config.h>
67 66
68#ifdef TEST_FRAME 67#ifdef TEST_FRAME
69#undef CONFIG_PROC_FS 68#undef CONFIG_PROC_FS
diff --git a/include/net/sock.h b/include/net/sock.h
index 96565ff0de6a..d10dfecb6cbd 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -40,7 +40,6 @@
40#ifndef _SOCK_H 40#ifndef _SOCK_H
41#define _SOCK_H 41#define _SOCK_H
42 42
43#include <linux/config.h>
44#include <linux/list.h> 43#include <linux/list.h>
45#include <linux/timer.h> 44#include <linux/timer.h>
46#include <linux/cache.h> 45#include <linux/cache.h>
diff --git a/include/net/tcp.h b/include/net/tcp.h
index bfc71f954bbe..5f4eb5c79689 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -21,7 +21,6 @@
21#define TCP_DEBUG 1 21#define TCP_DEBUG 1
22#define FASTRETRANS_DEBUG 1 22#define FASTRETRANS_DEBUG 1
23 23
24#include <linux/config.h>
25#include <linux/list.h> 24#include <linux/list.h>
26#include <linux/tcp.h> 25#include <linux/tcp.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 5e0a01ab2216..ede639812f8a 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -15,7 +15,6 @@
15#ifndef _LINUX_SS_H 15#ifndef _LINUX_SS_H
16#define _LINUX_SS_H 16#define _LINUX_SS_H
17 17
18#include <linux/config.h>
19#include <linux/device.h> 18#include <linux/device.h>
20#include <linux/sched.h> /* task_struct, completion */ 19#include <linux/sched.h> /* task_struct, completion */
21#include <linux/mutex.h> 20#include <linux/mutex.h>
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 5626225bd3ae..6d28b0317657 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -27,7 +27,6 @@
27#ifndef SCSI_TRANSPORT_FC_H 27#ifndef SCSI_TRANSPORT_FC_H
28#define SCSI_TRANSPORT_FC_H 28#define SCSI_TRANSPORT_FC_H
29 29
30#include <linux/config.h>
31#include <linux/sched.h> 30#include <linux/sched.h>
32#include <scsi/scsi.h> 31#include <scsi/scsi.h>
33 32
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 5e1d61913d4e..302680c0c0de 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -20,7 +20,6 @@
20#ifndef SCSI_TRANSPORT_SPI_H 20#ifndef SCSI_TRANSPORT_SPI_H
21#define SCSI_TRANSPORT_SPI_H 21#define SCSI_TRANSPORT_SPI_H
22 22
23#include <linux/config.h>
24#include <linux/transport_class.h> 23#include <linux/transport_class.h>
25#include <linux/mutex.h> 24#include <linux/mutex.h>
26 25
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 89c6a73f3920..3c522e59a33c 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -26,7 +26,6 @@
26#include "config.h" 26#include "config.h"
27#endif 27#endif
28 28
29#include <linux/config.h>
30 29
31/* number of supported soundcards */ 30/* number of supported soundcards */
32#ifdef CONFIG_SND_DYNAMIC_MINORS 31#ifdef CONFIG_SND_DYNAMIC_MINORS
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
index 25e1951a9955..dec6b1dc37ea 100644
--- a/include/sound/hdsp.h
+++ b/include/sound/hdsp.h
@@ -30,13 +30,13 @@ enum HDSP_IO_Type {
30}; 30};
31 31
32struct hdsp_peak_rms { 32struct hdsp_peak_rms {
33 u32 input_peaks[26]; 33 __u32 input_peaks[26];
34 u32 playback_peaks[26]; 34 __u32 playback_peaks[26];
35 u32 output_peaks[28]; 35 __u32 output_peaks[28];
36 u64 input_rms[26]; 36 __u64 input_rms[26];
37 u64 playback_rms[26]; 37 __u64 playback_rms[26];
38 /* These are only used for H96xx cards */ 38 /* These are only used for H96xx cards */
39 u64 output_rms[26]; 39 __u64 output_rms[26];
40}; 40};
41 41
42#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct hdsp_peak_rms) 42#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct hdsp_peak_rms)
diff --git a/include/video/edid.h b/include/video/edid.h
index b913f196131d..f6a42d6c2e2d 100644
--- a/include/video/edid.h
+++ b/include/video/edid.h
@@ -3,7 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/config.h>
7 6
8#ifdef CONFIG_X86 7#ifdef CONFIG_X86
9struct edid_info { 8struct edid_info {
diff --git a/include/video/vga.h b/include/video/vga.h
index 700d6c8eb736..b49a5120ca2d 100644
--- a/include/video/vga.h
+++ b/include/video/vga.h
@@ -17,7 +17,6 @@
17#ifndef __linux_video_vga_h__ 17#ifndef __linux_video_vga_h__
18#define __linux_video_vga_h__ 18#define __linux_video_vga_h__
19 19
20#include <linux/config.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/io.h> 21#include <asm/io.h>
23#ifndef CONFIG_AMIGA 22#ifndef CONFIG_AMIGA
diff --git a/init/Kconfig b/init/Kconfig
index 3b36a1d53656..df864a358221 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -182,7 +182,8 @@ config AUDITSYSCALL
182 help 182 help
183 Enable low-overhead system-call auditing infrastructure that 183 Enable low-overhead system-call auditing infrastructure that
184 can be used independently or with another kernel subsystem, 184 can be used independently or with another kernel subsystem,
185 such as SELinux. 185 such as SELinux. To use audit's filesystem watch feature, please
186 ensure that INOTIFY is configured.
186 187
187config IKCONFIG 188config IKCONFIG
188 bool "Kernel .config support" 189 bool "Kernel .config support"
@@ -389,9 +390,6 @@ config SLOB
389 default !SLAB 390 default !SLAB
390 bool 391 bool
391 392
392config OBSOLETE_INTERMODULE
393 tristate
394
395menu "Loadable module support" 393menu "Loadable module support"
396 394
397config MODULES 395config MODULES
diff --git a/init/do_mounts.c b/init/do_mounts.c
index f4b7b9d278cd..21b3b8f33a72 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -409,6 +409,10 @@ void __init prepare_namespace(void)
409 409
410 if (saved_root_name[0]) { 410 if (saved_root_name[0]) {
411 root_device_name = saved_root_name; 411 root_device_name = saved_root_name;
412 if (!strncmp(root_device_name, "mtd", 3)) {
413 mount_block_root(root_device_name, root_mountflags);
414 goto out;
415 }
412 ROOT_DEV = name_to_dev_t(root_device_name); 416 ROOT_DEV = name_to_dev_t(root_device_name);
413 if (strncmp(root_device_name, "/dev/", 5) == 0) 417 if (strncmp(root_device_name, "/dev/", 5) == 0)
414 root_device_name += 5; 418 root_device_name += 5;
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 41ecbd440fed..1511714a9585 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -8,6 +8,8 @@
8 * Lockless receive & send, fd based notify: 8 * Lockless receive & send, fd based notify:
9 * Manfred Spraul (manfred@colorfullife.com) 9 * Manfred Spraul (manfred@colorfullife.com)
10 * 10 *
11 * Audit: George Wilson (ltcgcw@us.ibm.com)
12 *
11 * This file is released under the GPL. 13 * This file is released under the GPL.
12 */ 14 */
13 15
@@ -24,6 +26,7 @@
24#include <linux/skbuff.h> 26#include <linux/skbuff.h>
25#include <linux/netlink.h> 27#include <linux/netlink.h>
26#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/audit.h>
27#include <linux/signal.h> 30#include <linux/signal.h>
28#include <linux/mutex.h> 31#include <linux/mutex.h>
29 32
@@ -657,6 +660,10 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
657 char *name; 660 char *name;
658 int fd, error; 661 int fd, error;
659 662
663 error = audit_mq_open(oflag, mode, u_attr);
664 if (error != 0)
665 return error;
666
660 if (IS_ERR(name = getname(u_name))) 667 if (IS_ERR(name = getname(u_name)))
661 return PTR_ERR(name); 668 return PTR_ERR(name);
662 669
@@ -814,6 +821,10 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
814 long timeout; 821 long timeout;
815 int ret; 822 int ret;
816 823
824 ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
825 if (ret != 0)
826 return ret;
827
817 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) 828 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
818 return -EINVAL; 829 return -EINVAL;
819 830
@@ -896,6 +907,10 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
896 struct mqueue_inode_info *info; 907 struct mqueue_inode_info *info;
897 struct ext_wait_queue wait; 908 struct ext_wait_queue wait;
898 909
910 ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
911 if (ret != 0)
912 return ret;
913
899 timeout = prepare_timeout(u_abs_timeout); 914 timeout = prepare_timeout(u_abs_timeout);
900 915
901 ret = -EBADF; 916 ret = -EBADF;
@@ -975,6 +990,10 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
975 struct mqueue_inode_info *info; 990 struct mqueue_inode_info *info;
976 struct sk_buff *nc; 991 struct sk_buff *nc;
977 992
993 ret = audit_mq_notify(mqdes, u_notification);
994 if (ret != 0)
995 return ret;
996
978 nc = NULL; 997 nc = NULL;
979 sock = NULL; 998 sock = NULL;
980 if (u_notification != NULL) { 999 if (u_notification != NULL) {
@@ -1115,6 +1134,9 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
1115 omqstat = info->attr; 1134 omqstat = info->attr;
1116 omqstat.mq_flags = filp->f_flags & O_NONBLOCK; 1135 omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
1117 if (u_mqstat) { 1136 if (u_mqstat) {
1137 ret = audit_mq_getsetattr(mqdes, &mqstat);
1138 if (ret != 0)
1139 goto out;
1118 if (mqstat.mq_flags & O_NONBLOCK) 1140 if (mqstat.mq_flags & O_NONBLOCK)
1119 filp->f_flags |= O_NONBLOCK; 1141 filp->f_flags |= O_NONBLOCK;
1120 else 1142 else
diff --git a/ipc/msg.c b/ipc/msg.c
index 7d1340ccb16b..00f015a092d2 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -454,6 +454,11 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
454 err = audit_ipc_obj(ipcp); 454 err = audit_ipc_obj(ipcp);
455 if (err) 455 if (err)
456 goto out_unlock_up; 456 goto out_unlock_up;
457 if (cmd==IPC_SET) {
458 err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
459 if (err)
460 goto out_unlock_up;
461 }
457 462
458 err = -EPERM; 463 err = -EPERM;
459 if (current->euid != ipcp->cuid && 464 if (current->euid != ipcp->cuid &&
@@ -468,10 +473,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
468 switch (cmd) { 473 switch (cmd) {
469 case IPC_SET: 474 case IPC_SET:
470 { 475 {
471 err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
472 if (err)
473 goto out_unlock_up;
474
475 err = -EPERM; 476 err = -EPERM;
476 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) 477 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
477 goto out_unlock_up; 478 goto out_unlock_up;
diff --git a/ipc/sem.c b/ipc/sem.c
index 7919f8ece6ba..fce0bc8b5ad6 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -828,6 +828,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
828 if (err) 828 if (err)
829 goto out_unlock; 829 goto out_unlock;
830 830
831 if (cmd == IPC_SET) {
832 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
833 if (err)
834 goto out_unlock;
835 }
831 if (current->euid != ipcp->cuid && 836 if (current->euid != ipcp->cuid &&
832 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { 837 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
833 err=-EPERM; 838 err=-EPERM;
@@ -844,9 +849,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
844 err = 0; 849 err = 0;
845 break; 850 break;
846 case IPC_SET: 851 case IPC_SET:
847 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp);
848 if (err)
849 goto out_unlock;
850 ipcp->uid = setbuf.uid; 852 ipcp->uid = setbuf.uid;
851 ipcp->gid = setbuf.gid; 853 ipcp->gid = setbuf.gid;
852 ipcp->mode = (ipcp->mode & ~S_IRWXUGO) 854 ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
diff --git a/ipc/shm.c b/ipc/shm.c
index 809896851902..4f133d24030f 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -643,7 +643,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
643 err = audit_ipc_obj(&(shp->shm_perm)); 643 err = audit_ipc_obj(&(shp->shm_perm));
644 if (err) 644 if (err)
645 goto out_unlock_up; 645 goto out_unlock_up;
646 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm)); 646 err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
647 if (err) 647 if (err)
648 goto out_unlock_up; 648 goto out_unlock_up;
649 err=-EPERM; 649 err=-EPERM;
diff --git a/kernel/Makefile b/kernel/Makefile
index 58908f9d156a..f6ef00f4f90f 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SMP) += cpu.o spinlock.o
20obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o 20obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
21obj-$(CONFIG_UID16) += uid16.o 21obj-$(CONFIG_UID16) += uid16.o
22obj-$(CONFIG_MODULES) += module.o 22obj-$(CONFIG_MODULES) += module.o
23obj-$(CONFIG_OBSOLETE_INTERMODULE) += intermodule.o
24obj-$(CONFIG_KALLSYMS) += kallsyms.o 23obj-$(CONFIG_KALLSYMS) += kallsyms.o
25obj-$(CONFIG_PM) += power/ 24obj-$(CONFIG_PM) += power/
26obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 25obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
diff --git a/kernel/audit.c b/kernel/audit.c
index df57b493e1cb..7dfac7031bd7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -56,6 +56,7 @@
56#include <linux/skbuff.h> 56#include <linux/skbuff.h>
57#include <linux/netlink.h> 57#include <linux/netlink.h>
58#include <linux/selinux.h> 58#include <linux/selinux.h>
59#include <linux/inotify.h>
59 60
60#include "audit.h" 61#include "audit.h"
61 62
@@ -89,6 +90,7 @@ static int audit_backlog_wait_overflow = 0;
89/* The identity of the user shutting down the audit system. */ 90/* The identity of the user shutting down the audit system. */
90uid_t audit_sig_uid = -1; 91uid_t audit_sig_uid = -1;
91pid_t audit_sig_pid = -1; 92pid_t audit_sig_pid = -1;
93u32 audit_sig_sid = 0;
92 94
93/* Records can be lost in several ways: 95/* Records can be lost in several ways:
94 0) [suppressed in audit_alloc] 96 0) [suppressed in audit_alloc]
@@ -102,6 +104,12 @@ static atomic_t audit_lost = ATOMIC_INIT(0);
102/* The netlink socket. */ 104/* The netlink socket. */
103static struct sock *audit_sock; 105static struct sock *audit_sock;
104 106
107/* Inotify handle. */
108struct inotify_handle *audit_ih;
109
110/* Hash for inode-based rules */
111struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
112
105/* The audit_freelist is a list of pre-allocated audit buffers (if more 113/* The audit_freelist is a list of pre-allocated audit buffers (if more
106 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of 114 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
107 * being placed on the freelist). */ 115 * being placed on the freelist). */
@@ -114,10 +122,8 @@ static struct task_struct *kauditd_task;
114static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 122static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
115static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 123static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
116 124
117/* The netlink socket is only to be read by 1 CPU, which lets us assume 125/* Serialize requests from userspace. */
118 * that list additions and deletions never happen simultaneously in 126static DEFINE_MUTEX(audit_cmd_mutex);
119 * auditsc.c */
120DEFINE_MUTEX(audit_netlink_mutex);
121 127
122/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting 128/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
123 * audit records. Since printk uses a 1024 byte buffer, this buffer 129 * audit records. Since printk uses a 1024 byte buffer, this buffer
@@ -250,7 +256,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
250 "audit_rate_limit=%d old=%d by auid=%u", 256 "audit_rate_limit=%d old=%d by auid=%u",
251 limit, old, loginuid); 257 limit, old, loginuid);
252 audit_rate_limit = limit; 258 audit_rate_limit = limit;
253 return old; 259 return 0;
254} 260}
255 261
256static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) 262static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
@@ -273,7 +279,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
273 "audit_backlog_limit=%d old=%d by auid=%u", 279 "audit_backlog_limit=%d old=%d by auid=%u",
274 limit, old, loginuid); 280 limit, old, loginuid);
275 audit_backlog_limit = limit; 281 audit_backlog_limit = limit;
276 return old; 282 return 0;
277} 283}
278 284
279static int audit_set_enabled(int state, uid_t loginuid, u32 sid) 285static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
@@ -299,7 +305,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
299 "audit_enabled=%d old=%d by auid=%u", 305 "audit_enabled=%d old=%d by auid=%u",
300 state, old, loginuid); 306 state, old, loginuid);
301 audit_enabled = state; 307 audit_enabled = state;
302 return old; 308 return 0;
303} 309}
304 310
305static int audit_set_failure(int state, uid_t loginuid, u32 sid) 311static int audit_set_failure(int state, uid_t loginuid, u32 sid)
@@ -327,7 +333,7 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sid)
327 "audit_failure=%d old=%d by auid=%u", 333 "audit_failure=%d old=%d by auid=%u",
328 state, old, loginuid); 334 state, old, loginuid);
329 audit_failure = state; 335 audit_failure = state;
330 return old; 336 return 0;
331} 337}
332 338
333static int kauditd_thread(void *dummy) 339static int kauditd_thread(void *dummy)
@@ -363,9 +369,52 @@ static int kauditd_thread(void *dummy)
363 remove_wait_queue(&kauditd_wait, &wait); 369 remove_wait_queue(&kauditd_wait, &wait);
364 } 370 }
365 } 371 }
372}
373
374int audit_send_list(void *_dest)
375{
376 struct audit_netlink_list *dest = _dest;
377 int pid = dest->pid;
378 struct sk_buff *skb;
379
380 /* wait for parent to finish and send an ACK */
381 mutex_lock(&audit_cmd_mutex);
382 mutex_unlock(&audit_cmd_mutex);
383
384 while ((skb = __skb_dequeue(&dest->q)) != NULL)
385 netlink_unicast(audit_sock, skb, pid, 0);
386
387 kfree(dest);
388
366 return 0; 389 return 0;
367} 390}
368 391
392struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
393 int multi, void *payload, int size)
394{
395 struct sk_buff *skb;
396 struct nlmsghdr *nlh;
397 int len = NLMSG_SPACE(size);
398 void *data;
399 int flags = multi ? NLM_F_MULTI : 0;
400 int t = done ? NLMSG_DONE : type;
401
402 skb = alloc_skb(len, GFP_KERNEL);
403 if (!skb)
404 return NULL;
405
406 nlh = NLMSG_PUT(skb, pid, seq, t, size);
407 nlh->nlmsg_flags = flags;
408 data = NLMSG_DATA(nlh);
409 memcpy(data, payload, size);
410 return skb;
411
412nlmsg_failure: /* Used by NLMSG_PUT */
413 if (skb)
414 kfree_skb(skb);
415 return NULL;
416}
417
369/** 418/**
370 * audit_send_reply - send an audit reply message via netlink 419 * audit_send_reply - send an audit reply message via netlink
371 * @pid: process id to send reply to 420 * @pid: process id to send reply to
@@ -383,29 +432,13 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi,
383 void *payload, int size) 432 void *payload, int size)
384{ 433{
385 struct sk_buff *skb; 434 struct sk_buff *skb;
386 struct nlmsghdr *nlh; 435 skb = audit_make_reply(pid, seq, type, done, multi, payload, size);
387 int len = NLMSG_SPACE(size);
388 void *data;
389 int flags = multi ? NLM_F_MULTI : 0;
390 int t = done ? NLMSG_DONE : type;
391
392 skb = alloc_skb(len, GFP_KERNEL);
393 if (!skb) 436 if (!skb)
394 return; 437 return;
395
396 nlh = NLMSG_PUT(skb, pid, seq, t, size);
397 nlh->nlmsg_flags = flags;
398 data = NLMSG_DATA(nlh);
399 memcpy(data, payload, size);
400
401 /* Ignore failure. It'll only happen if the sender goes away, 438 /* Ignore failure. It'll only happen if the sender goes away,
402 because our timeout is set to infinite. */ 439 because our timeout is set to infinite. */
403 netlink_unicast(audit_sock, skb, pid, 0); 440 netlink_unicast(audit_sock, skb, pid, 0);
404 return; 441 return;
405
406nlmsg_failure: /* Used by NLMSG_PUT */
407 if (skb)
408 kfree_skb(skb);
409} 442}
410 443
411/* 444/*
@@ -451,7 +484,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
451 struct audit_buffer *ab; 484 struct audit_buffer *ab;
452 u16 msg_type = nlh->nlmsg_type; 485 u16 msg_type = nlh->nlmsg_type;
453 uid_t loginuid; /* loginuid of sender */ 486 uid_t loginuid; /* loginuid of sender */
454 struct audit_sig_info sig_data; 487 struct audit_sig_info *sig_data;
488 char *ctx;
489 u32 len;
455 490
456 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); 491 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
457 if (err) 492 if (err)
@@ -503,12 +538,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
503 if (status_get->mask & AUDIT_STATUS_PID) { 538 if (status_get->mask & AUDIT_STATUS_PID) {
504 int old = audit_pid; 539 int old = audit_pid;
505 if (sid) { 540 if (sid) {
506 char *ctx = NULL; 541 if ((err = selinux_ctxid_to_string(
507 u32 len;
508 int rc;
509 if ((rc = selinux_ctxid_to_string(
510 sid, &ctx, &len))) 542 sid, &ctx, &len)))
511 return rc; 543 return err;
512 else 544 else
513 audit_log(NULL, GFP_KERNEL, 545 audit_log(NULL, GFP_KERNEL,
514 AUDIT_CONFIG_CHANGE, 546 AUDIT_CONFIG_CHANGE,
@@ -523,10 +555,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
523 audit_pid = status_get->pid; 555 audit_pid = status_get->pid;
524 } 556 }
525 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) 557 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
526 audit_set_rate_limit(status_get->rate_limit, 558 err = audit_set_rate_limit(status_get->rate_limit,
527 loginuid, sid); 559 loginuid, sid);
528 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) 560 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
529 audit_set_backlog_limit(status_get->backlog_limit, 561 err = audit_set_backlog_limit(status_get->backlog_limit,
530 loginuid, sid); 562 loginuid, sid);
531 break; 563 break;
532 case AUDIT_USER: 564 case AUDIT_USER:
@@ -544,8 +576,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
544 "user pid=%d uid=%u auid=%u", 576 "user pid=%d uid=%u auid=%u",
545 pid, uid, loginuid); 577 pid, uid, loginuid);
546 if (sid) { 578 if (sid) {
547 char *ctx = NULL;
548 u32 len;
549 if (selinux_ctxid_to_string( 579 if (selinux_ctxid_to_string(
550 sid, &ctx, &len)) { 580 sid, &ctx, &len)) {
551 audit_log_format(ab, 581 audit_log_format(ab,
@@ -584,10 +614,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
584 loginuid, sid); 614 loginuid, sid);
585 break; 615 break;
586 case AUDIT_SIGNAL_INFO: 616 case AUDIT_SIGNAL_INFO:
587 sig_data.uid = audit_sig_uid; 617 err = selinux_ctxid_to_string(audit_sig_sid, &ctx, &len);
588 sig_data.pid = audit_sig_pid; 618 if (err)
619 return err;
620 sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
621 if (!sig_data) {
622 kfree(ctx);
623 return -ENOMEM;
624 }
625 sig_data->uid = audit_sig_uid;
626 sig_data->pid = audit_sig_pid;
627 memcpy(sig_data->ctx, ctx, len);
628 kfree(ctx);
589 audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 629 audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
590 0, 0, &sig_data, sizeof(sig_data)); 630 0, 0, sig_data, sizeof(*sig_data) + len);
631 kfree(sig_data);
591 break; 632 break;
592 default: 633 default:
593 err = -EINVAL; 634 err = -EINVAL;
@@ -629,20 +670,30 @@ static void audit_receive(struct sock *sk, int length)
629 struct sk_buff *skb; 670 struct sk_buff *skb;
630 unsigned int qlen; 671 unsigned int qlen;
631 672
632 mutex_lock(&audit_netlink_mutex); 673 mutex_lock(&audit_cmd_mutex);
633 674
634 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { 675 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
635 skb = skb_dequeue(&sk->sk_receive_queue); 676 skb = skb_dequeue(&sk->sk_receive_queue);
636 audit_receive_skb(skb); 677 audit_receive_skb(skb);
637 kfree_skb(skb); 678 kfree_skb(skb);
638 } 679 }
639 mutex_unlock(&audit_netlink_mutex); 680 mutex_unlock(&audit_cmd_mutex);
640} 681}
641 682
683#ifdef CONFIG_AUDITSYSCALL
684static const struct inotify_operations audit_inotify_ops = {
685 .handle_event = audit_handle_ievent,
686 .destroy_watch = audit_free_parent,
687};
688#endif
642 689
643/* Initialize audit support at boot time. */ 690/* Initialize audit support at boot time. */
644static int __init audit_init(void) 691static int __init audit_init(void)
645{ 692{
693#ifdef CONFIG_AUDITSYSCALL
694 int i;
695#endif
696
646 printk(KERN_INFO "audit: initializing netlink socket (%s)\n", 697 printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
647 audit_default ? "enabled" : "disabled"); 698 audit_default ? "enabled" : "disabled");
648 audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, 699 audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
@@ -661,6 +712,16 @@ static int __init audit_init(void)
661 selinux_audit_set_callback(&selinux_audit_rule_update); 712 selinux_audit_set_callback(&selinux_audit_rule_update);
662 713
663 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); 714 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
715
716#ifdef CONFIG_AUDITSYSCALL
717 audit_ih = inotify_init(&audit_inotify_ops);
718 if (IS_ERR(audit_ih))
719 audit_panic("cannot initialize inotify handle");
720
721 for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
722 INIT_LIST_HEAD(&audit_inode_hash[i]);
723#endif
724
664 return 0; 725 return 0;
665} 726}
666__initcall(audit_init); 727__initcall(audit_init);
@@ -690,10 +751,12 @@ static void audit_buffer_free(struct audit_buffer *ab)
690 kfree_skb(ab->skb); 751 kfree_skb(ab->skb);
691 752
692 spin_lock_irqsave(&audit_freelist_lock, flags); 753 spin_lock_irqsave(&audit_freelist_lock, flags);
693 if (++audit_freelist_count > AUDIT_MAXFREE) 754 if (audit_freelist_count > AUDIT_MAXFREE)
694 kfree(ab); 755 kfree(ab);
695 else 756 else {
757 audit_freelist_count++;
696 list_add(&ab->list, &audit_freelist); 758 list_add(&ab->list, &audit_freelist);
759 }
697 spin_unlock_irqrestore(&audit_freelist_lock, flags); 760 spin_unlock_irqrestore(&audit_freelist_lock, flags);
698} 761}
699 762
@@ -988,28 +1051,76 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
988 skb_put(skb, len << 1); /* new string is twice the old string */ 1051 skb_put(skb, len << 1); /* new string is twice the old string */
989} 1052}
990 1053
1054/*
1055 * Format a string of no more than slen characters into the audit buffer,
1056 * enclosed in quote marks.
1057 */
1058static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
1059 const char *string)
1060{
1061 int avail, new_len;
1062 unsigned char *ptr;
1063 struct sk_buff *skb;
1064
1065 BUG_ON(!ab->skb);
1066 skb = ab->skb;
1067 avail = skb_tailroom(skb);
1068 new_len = slen + 3; /* enclosing quotes + null terminator */
1069 if (new_len > avail) {
1070 avail = audit_expand(ab, new_len);
1071 if (!avail)
1072 return;
1073 }
1074 ptr = skb->tail;
1075 *ptr++ = '"';
1076 memcpy(ptr, string, slen);
1077 ptr += slen;
1078 *ptr++ = '"';
1079 *ptr = 0;
1080 skb_put(skb, slen + 2); /* don't include null terminator */
1081}
1082
991/** 1083/**
992 * audit_log_unstrustedstring - log a string that may contain random characters 1084 * audit_log_n_unstrustedstring - log a string that may contain random characters
993 * @ab: audit_buffer 1085 * @ab: audit_buffer
1086 * @len: lenth of string (not including trailing null)
994 * @string: string to be logged 1087 * @string: string to be logged
995 * 1088 *
996 * This code will escape a string that is passed to it if the string 1089 * This code will escape a string that is passed to it if the string
997 * contains a control character, unprintable character, double quote mark, 1090 * contains a control character, unprintable character, double quote mark,
998 * or a space. Unescaped strings will start and end with a double quote mark. 1091 * or a space. Unescaped strings will start and end with a double quote mark.
999 * Strings that are escaped are printed in hex (2 digits per char). 1092 * Strings that are escaped are printed in hex (2 digits per char).
1093 *
1094 * The caller specifies the number of characters in the string to log, which may
1095 * or may not be the entire string.
1000 */ 1096 */
1001void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) 1097const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
1098 const char *string)
1002{ 1099{
1003 const unsigned char *p = string; 1100 const unsigned char *p = string;
1004 1101
1005 while (*p) { 1102 while (*p) {
1006 if (*p == '"' || *p < 0x21 || *p > 0x7f) { 1103 if (*p == '"' || *p < 0x21 || *p > 0x7f) {
1007 audit_log_hex(ab, string, strlen(string)); 1104 audit_log_hex(ab, string, len);
1008 return; 1105 return string + len + 1;
1009 } 1106 }
1010 p++; 1107 p++;
1011 } 1108 }
1012 audit_log_format(ab, "\"%s\"", string); 1109 audit_log_n_string(ab, len, string);
1110 return p + 1;
1111}
1112
1113/**
1114 * audit_log_unstrustedstring - log a string that may contain random characters
1115 * @ab: audit_buffer
1116 * @string: string to be logged
1117 *
1118 * Same as audit_log_n_unstrustedstring(), except that strlen is used to
1119 * determine string length.
1120 */
1121const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
1122{
1123 return audit_log_n_untrustedstring(ab, strlen(string), string);
1013} 1124}
1014 1125
1015/* This is a helper-function to print the escaped d_path */ 1126/* This is a helper-function to print the escaped d_path */
diff --git a/kernel/audit.h b/kernel/audit.h
index 6f733920fd32..8323e4132a33 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -19,9 +19,9 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/mutex.h>
23#include <linux/fs.h> 22#include <linux/fs.h>
24#include <linux/audit.h> 23#include <linux/audit.h>
24#include <linux/skbuff.h>
25 25
26/* 0 = no checking 26/* 0 = no checking
27 1 = put_count checking 27 1 = put_count checking
@@ -53,6 +53,18 @@ enum audit_state {
53}; 53};
54 54
55/* Rule lists */ 55/* Rule lists */
56struct audit_parent;
57
58struct audit_watch {
59 atomic_t count; /* reference count */
60 char *path; /* insertion path */
61 dev_t dev; /* associated superblock device */
62 unsigned long ino; /* associated inode number */
63 struct audit_parent *parent; /* associated parent */
64 struct list_head wlist; /* entry in parent->watches list */
65 struct list_head rules; /* associated rules */
66};
67
56struct audit_field { 68struct audit_field {
57 u32 type; 69 u32 type;
58 u32 val; 70 u32 val;
@@ -70,6 +82,9 @@ struct audit_krule {
70 u32 buflen; /* for data alloc on list rules */ 82 u32 buflen; /* for data alloc on list rules */
71 u32 field_count; 83 u32 field_count;
72 struct audit_field *fields; 84 struct audit_field *fields;
85 struct audit_field *inode_f; /* quick access to an inode field */
86 struct audit_watch *watch; /* associated watch */
87 struct list_head rlist; /* entry in audit_watch.rules list */
73}; 88};
74 89
75struct audit_entry { 90struct audit_entry {
@@ -78,15 +93,53 @@ struct audit_entry {
78 struct audit_krule rule; 93 struct audit_krule rule;
79}; 94};
80 95
81
82extern int audit_pid; 96extern int audit_pid;
83extern int audit_comparator(const u32 left, const u32 op, const u32 right);
84 97
98#define AUDIT_INODE_BUCKETS 32
99extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
100
101static inline int audit_hash_ino(u32 ino)
102{
103 return (ino & (AUDIT_INODE_BUCKETS-1));
104}
105
106extern int audit_comparator(const u32 left, const u32 op, const u32 right);
107extern int audit_compare_dname_path(const char *dname, const char *path,
108 int *dirlen);
109extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
110 int done, int multi,
111 void *payload, int size);
85extern void audit_send_reply(int pid, int seq, int type, 112extern void audit_send_reply(int pid, int seq, int type,
86 int done, int multi, 113 int done, int multi,
87 void *payload, int size); 114 void *payload, int size);
88extern void audit_log_lost(const char *message); 115extern void audit_log_lost(const char *message);
89extern void audit_panic(const char *message); 116extern void audit_panic(const char *message);
90extern struct mutex audit_netlink_mutex;
91 117
118struct audit_netlink_list {
119 int pid;
120 struct sk_buff_head q;
121};
122
123int audit_send_list(void *);
124
125struct inotify_watch;
126extern void audit_free_parent(struct inotify_watch *);
127extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
128 const char *, struct inode *);
92extern int selinux_audit_rule_update(void); 129extern int selinux_audit_rule_update(void);
130
131#ifdef CONFIG_AUDITSYSCALL
132extern void __audit_signal_info(int sig, struct task_struct *t);
133static inline void audit_signal_info(int sig, struct task_struct *t)
134{
135 if (unlikely(audit_pid && t->tgid == audit_pid))
136 __audit_signal_info(sig, t);
137}
138extern enum audit_state audit_filter_inodes(struct task_struct *,
139 struct audit_context *);
140extern void audit_set_auditable(struct audit_context *);
141#else
142#define audit_signal_info(s,t)
143#define audit_filter_inodes(t,c) AUDIT_DISABLED
144#define audit_set_auditable(c)
145#endif
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 7c134906d689..4c99d2c586ed 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -22,13 +22,59 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/audit.h> 23#include <linux/audit.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <linux/mutex.h>
26#include <linux/fs.h>
27#include <linux/namei.h>
25#include <linux/netlink.h> 28#include <linux/netlink.h>
29#include <linux/sched.h>
30#include <linux/inotify.h>
26#include <linux/selinux.h> 31#include <linux/selinux.h>
27#include "audit.h" 32#include "audit.h"
28 33
29/* There are three lists of rules -- one to search at task creation 34/*
30 * time, one to search at syscall entry time, and another to search at 35 * Locking model:
31 * syscall exit time. */ 36 *
37 * audit_filter_mutex:
38 * Synchronizes writes and blocking reads of audit's filterlist
39 * data. Rcu is used to traverse the filterlist and access
40 * contents of structs audit_entry, audit_watch and opaque
41 * selinux rules during filtering. If modified, these structures
42 * must be copied and replace their counterparts in the filterlist.
43 * An audit_parent struct is not accessed during filtering, so may
44 * be written directly provided audit_filter_mutex is held.
45 */
46
47/*
48 * Reference counting:
49 *
50 * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED
51 * event. Each audit_watch holds a reference to its associated parent.
52 *
53 * audit_watch: if added to lists, lifetime is from audit_init_watch() to
54 * audit_remove_watch(). Additionally, an audit_watch may exist
55 * temporarily to assist in searching existing filter data. Each
56 * audit_krule holds a reference to its associated watch.
57 */
58
59struct audit_parent {
60 struct list_head ilist; /* entry in inotify registration list */
61 struct list_head watches; /* associated watches */
62 struct inotify_watch wdata; /* inotify watch data */
63 unsigned flags; /* status flags */
64};
65
66/*
67 * audit_parent status flags:
68 *
69 * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to
70 * a filesystem event to ensure we're adding audit watches to a valid parent.
71 * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot
72 * receive them while we have nameidata, but must be used for IN_MOVE_SELF which
73 * we can receive while holding nameidata.
74 */
75#define AUDIT_PARENT_INVALID 0x001
76
77/* Audit filter lists, defined in <linux/audit.h> */
32struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { 78struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
33 LIST_HEAD_INIT(audit_filter_list[0]), 79 LIST_HEAD_INIT(audit_filter_list[0]),
34 LIST_HEAD_INIT(audit_filter_list[1]), 80 LIST_HEAD_INIT(audit_filter_list[1]),
@@ -41,9 +87,53 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
41#endif 87#endif
42}; 88};
43 89
90static DEFINE_MUTEX(audit_filter_mutex);
91
92/* Inotify handle */
93extern struct inotify_handle *audit_ih;
94
95/* Inotify events we care about. */
96#define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF
97
98void audit_free_parent(struct inotify_watch *i_watch)
99{
100 struct audit_parent *parent;
101
102 parent = container_of(i_watch, struct audit_parent, wdata);
103 WARN_ON(!list_empty(&parent->watches));
104 kfree(parent);
105}
106
107static inline void audit_get_watch(struct audit_watch *watch)
108{
109 atomic_inc(&watch->count);
110}
111
112static void audit_put_watch(struct audit_watch *watch)
113{
114 if (atomic_dec_and_test(&watch->count)) {
115 WARN_ON(watch->parent);
116 WARN_ON(!list_empty(&watch->rules));
117 kfree(watch->path);
118 kfree(watch);
119 }
120}
121
122static void audit_remove_watch(struct audit_watch *watch)
123{
124 list_del(&watch->wlist);
125 put_inotify_watch(&watch->parent->wdata);
126 watch->parent = NULL;
127 audit_put_watch(watch); /* match initial get */
128}
129
44static inline void audit_free_rule(struct audit_entry *e) 130static inline void audit_free_rule(struct audit_entry *e)
45{ 131{
46 int i; 132 int i;
133
134 /* some rules don't have associated watches */
135 if (e->rule.watch)
136 audit_put_watch(e->rule.watch);
47 if (e->rule.fields) 137 if (e->rule.fields)
48 for (i = 0; i < e->rule.field_count; i++) { 138 for (i = 0; i < e->rule.field_count; i++) {
49 struct audit_field *f = &e->rule.fields[i]; 139 struct audit_field *f = &e->rule.fields[i];
@@ -60,6 +150,50 @@ static inline void audit_free_rule_rcu(struct rcu_head *head)
60 audit_free_rule(e); 150 audit_free_rule(e);
61} 151}
62 152
153/* Initialize a parent watch entry. */
154static struct audit_parent *audit_init_parent(struct nameidata *ndp)
155{
156 struct audit_parent *parent;
157 s32 wd;
158
159 parent = kzalloc(sizeof(*parent), GFP_KERNEL);
160 if (unlikely(!parent))
161 return ERR_PTR(-ENOMEM);
162
163 INIT_LIST_HEAD(&parent->watches);
164 parent->flags = 0;
165
166 inotify_init_watch(&parent->wdata);
167 /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */
168 get_inotify_watch(&parent->wdata);
169 wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode,
170 AUDIT_IN_WATCH);
171 if (wd < 0) {
172 audit_free_parent(&parent->wdata);
173 return ERR_PTR(wd);
174 }
175
176 return parent;
177}
178
179/* Initialize a watch entry. */
180static struct audit_watch *audit_init_watch(char *path)
181{
182 struct audit_watch *watch;
183
184 watch = kzalloc(sizeof(*watch), GFP_KERNEL);
185 if (unlikely(!watch))
186 return ERR_PTR(-ENOMEM);
187
188 INIT_LIST_HEAD(&watch->rules);
189 atomic_set(&watch->count, 1);
190 watch->path = path;
191 watch->dev = (dev_t)-1;
192 watch->ino = (unsigned long)-1;
193
194 return watch;
195}
196
63/* Initialize an audit filterlist entry. */ 197/* Initialize an audit filterlist entry. */
64static inline struct audit_entry *audit_init_entry(u32 field_count) 198static inline struct audit_entry *audit_init_entry(u32 field_count)
65{ 199{
@@ -107,6 +241,43 @@ static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
107 return str; 241 return str;
108} 242}
109 243
244/* Translate an inode field to kernel respresentation. */
245static inline int audit_to_inode(struct audit_krule *krule,
246 struct audit_field *f)
247{
248 if (krule->listnr != AUDIT_FILTER_EXIT ||
249 krule->watch || krule->inode_f)
250 return -EINVAL;
251
252 krule->inode_f = f;
253 return 0;
254}
255
256/* Translate a watch string to kernel respresentation. */
257static int audit_to_watch(struct audit_krule *krule, char *path, int len,
258 u32 op)
259{
260 struct audit_watch *watch;
261
262 if (!audit_ih)
263 return -EOPNOTSUPP;
264
265 if (path[0] != '/' || path[len-1] == '/' ||
266 krule->listnr != AUDIT_FILTER_EXIT ||
267 op & ~AUDIT_EQUAL ||
268 krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
269 return -EINVAL;
270
271 watch = audit_init_watch(path);
272 if (unlikely(IS_ERR(watch)))
273 return PTR_ERR(watch);
274
275 audit_get_watch(watch);
276 krule->watch = watch;
277
278 return 0;
279}
280
110/* Common user-space to kernel rule translation. */ 281/* Common user-space to kernel rule translation. */
111static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) 282static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
112{ 283{
@@ -128,8 +299,11 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
128#endif 299#endif
129 ; 300 ;
130 } 301 }
131 if (rule->action != AUDIT_NEVER && rule->action != AUDIT_POSSIBLE && 302 if (unlikely(rule->action == AUDIT_POSSIBLE)) {
132 rule->action != AUDIT_ALWAYS) 303 printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
304 goto exit_err;
305 }
306 if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS)
133 goto exit_err; 307 goto exit_err;
134 if (rule->field_count > AUDIT_MAX_FIELDS) 308 if (rule->field_count > AUDIT_MAX_FIELDS)
135 goto exit_err; 309 goto exit_err;
@@ -158,6 +332,7 @@ exit_err:
158static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) 332static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
159{ 333{
160 struct audit_entry *entry; 334 struct audit_entry *entry;
335 struct audit_field *f;
161 int err = 0; 336 int err = 0;
162 int i; 337 int i;
163 338
@@ -172,14 +347,37 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
172 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); 347 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
173 f->val = rule->values[i]; 348 f->val = rule->values[i];
174 349
175 if (f->type & AUDIT_UNUSED_BITS || 350 err = -EINVAL;
176 f->type == AUDIT_SE_USER || 351 switch(f->type) {
177 f->type == AUDIT_SE_ROLE || 352 default:
178 f->type == AUDIT_SE_TYPE ||
179 f->type == AUDIT_SE_SEN ||
180 f->type == AUDIT_SE_CLR) {
181 err = -EINVAL;
182 goto exit_free; 353 goto exit_free;
354 case AUDIT_PID:
355 case AUDIT_UID:
356 case AUDIT_EUID:
357 case AUDIT_SUID:
358 case AUDIT_FSUID:
359 case AUDIT_GID:
360 case AUDIT_EGID:
361 case AUDIT_SGID:
362 case AUDIT_FSGID:
363 case AUDIT_LOGINUID:
364 case AUDIT_PERS:
365 case AUDIT_ARCH:
366 case AUDIT_MSGTYPE:
367 case AUDIT_DEVMAJOR:
368 case AUDIT_DEVMINOR:
369 case AUDIT_EXIT:
370 case AUDIT_SUCCESS:
371 case AUDIT_ARG0:
372 case AUDIT_ARG1:
373 case AUDIT_ARG2:
374 case AUDIT_ARG3:
375 break;
376 case AUDIT_INODE:
377 err = audit_to_inode(&entry->rule, f);
378 if (err)
379 goto exit_free;
380 break;
183 } 381 }
184 382
185 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; 383 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;
@@ -196,6 +394,18 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
196 } 394 }
197 } 395 }
198 396
397 f = entry->rule.inode_f;
398 if (f) {
399 switch(f->op) {
400 case AUDIT_NOT_EQUAL:
401 entry->rule.inode_f = NULL;
402 case AUDIT_EQUAL:
403 break;
404 default:
405 goto exit_free;
406 }
407 }
408
199exit_nofree: 409exit_nofree:
200 return entry; 410 return entry;
201 411
@@ -210,6 +420,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
210{ 420{
211 int err = 0; 421 int err = 0;
212 struct audit_entry *entry; 422 struct audit_entry *entry;
423 struct audit_field *f;
213 void *bufp; 424 void *bufp;
214 size_t remain = datasz - sizeof(struct audit_rule_data); 425 size_t remain = datasz - sizeof(struct audit_rule_data);
215 int i; 426 int i;
@@ -235,6 +446,29 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
235 f->se_str = NULL; 446 f->se_str = NULL;
236 f->se_rule = NULL; 447 f->se_rule = NULL;
237 switch(f->type) { 448 switch(f->type) {
449 case AUDIT_PID:
450 case AUDIT_UID:
451 case AUDIT_EUID:
452 case AUDIT_SUID:
453 case AUDIT_FSUID:
454 case AUDIT_GID:
455 case AUDIT_EGID:
456 case AUDIT_SGID:
457 case AUDIT_FSGID:
458 case AUDIT_LOGINUID:
459 case AUDIT_PERS:
460 case AUDIT_ARCH:
461 case AUDIT_MSGTYPE:
462 case AUDIT_PPID:
463 case AUDIT_DEVMAJOR:
464 case AUDIT_DEVMINOR:
465 case AUDIT_EXIT:
466 case AUDIT_SUCCESS:
467 case AUDIT_ARG0:
468 case AUDIT_ARG1:
469 case AUDIT_ARG2:
470 case AUDIT_ARG3:
471 break;
238 case AUDIT_SE_USER: 472 case AUDIT_SE_USER:
239 case AUDIT_SE_ROLE: 473 case AUDIT_SE_ROLE:
240 case AUDIT_SE_TYPE: 474 case AUDIT_SE_TYPE:
@@ -260,6 +494,37 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
260 } else 494 } else
261 f->se_str = str; 495 f->se_str = str;
262 break; 496 break;
497 case AUDIT_WATCH:
498 str = audit_unpack_string(&bufp, &remain, f->val);
499 if (IS_ERR(str))
500 goto exit_free;
501 entry->rule.buflen += f->val;
502
503 err = audit_to_watch(&entry->rule, str, f->val, f->op);
504 if (err) {
505 kfree(str);
506 goto exit_free;
507 }
508 break;
509 case AUDIT_INODE:
510 err = audit_to_inode(&entry->rule, f);
511 if (err)
512 goto exit_free;
513 break;
514 default:
515 goto exit_free;
516 }
517 }
518
519 f = entry->rule.inode_f;
520 if (f) {
521 switch(f->op) {
522 case AUDIT_NOT_EQUAL:
523 entry->rule.inode_f = NULL;
524 case AUDIT_EQUAL:
525 break;
526 default:
527 goto exit_free;
263 } 528 }
264 } 529 }
265 530
@@ -291,7 +556,7 @@ static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule)
291 556
292 rule = kmalloc(sizeof(*rule), GFP_KERNEL); 557 rule = kmalloc(sizeof(*rule), GFP_KERNEL);
293 if (unlikely(!rule)) 558 if (unlikely(!rule))
294 return ERR_PTR(-ENOMEM); 559 return NULL;
295 memset(rule, 0, sizeof(*rule)); 560 memset(rule, 0, sizeof(*rule));
296 561
297 rule->flags = krule->flags | krule->listnr; 562 rule->flags = krule->flags | krule->listnr;
@@ -322,7 +587,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
322 587
323 data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL); 588 data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL);
324 if (unlikely(!data)) 589 if (unlikely(!data))
325 return ERR_PTR(-ENOMEM); 590 return NULL;
326 memset(data, 0, sizeof(*data)); 591 memset(data, 0, sizeof(*data));
327 592
328 data->flags = krule->flags | krule->listnr; 593 data->flags = krule->flags | krule->listnr;
@@ -343,6 +608,10 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
343 data->buflen += data->values[i] = 608 data->buflen += data->values[i] =
344 audit_pack_string(&bufp, f->se_str); 609 audit_pack_string(&bufp, f->se_str);
345 break; 610 break;
611 case AUDIT_WATCH:
612 data->buflen += data->values[i] =
613 audit_pack_string(&bufp, krule->watch->path);
614 break;
346 default: 615 default:
347 data->values[i] = f->val; 616 data->values[i] = f->val;
348 } 617 }
@@ -378,6 +647,10 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
378 if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) 647 if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
379 return 1; 648 return 1;
380 break; 649 break;
650 case AUDIT_WATCH:
651 if (strcmp(a->watch->path, b->watch->path))
652 return 1;
653 break;
381 default: 654 default:
382 if (a->fields[i].val != b->fields[i].val) 655 if (a->fields[i].val != b->fields[i].val)
383 return 1; 656 return 1;
@@ -391,6 +664,32 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
391 return 0; 664 return 0;
392} 665}
393 666
667/* Duplicate the given audit watch. The new watch's rules list is initialized
668 * to an empty list and wlist is undefined. */
669static struct audit_watch *audit_dupe_watch(struct audit_watch *old)
670{
671 char *path;
672 struct audit_watch *new;
673
674 path = kstrdup(old->path, GFP_KERNEL);
675 if (unlikely(!path))
676 return ERR_PTR(-ENOMEM);
677
678 new = audit_init_watch(path);
679 if (unlikely(IS_ERR(new))) {
680 kfree(path);
681 goto out;
682 }
683
684 new->dev = old->dev;
685 new->ino = old->ino;
686 get_inotify_watch(&old->parent->wdata);
687 new->parent = old->parent;
688
689out:
690 return new;
691}
692
394/* Duplicate selinux field information. The se_rule is opaque, so must be 693/* Duplicate selinux field information. The se_rule is opaque, so must be
395 * re-initialized. */ 694 * re-initialized. */
396static inline int audit_dupe_selinux_field(struct audit_field *df, 695static inline int audit_dupe_selinux_field(struct audit_field *df,
@@ -422,8 +721,11 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
422/* Duplicate an audit rule. This will be a deep copy with the exception 721/* Duplicate an audit rule. This will be a deep copy with the exception
423 * of the watch - that pointer is carried over. The selinux specific fields 722 * of the watch - that pointer is carried over. The selinux specific fields
424 * will be updated in the copy. The point is to be able to replace the old 723 * will be updated in the copy. The point is to be able to replace the old
425 * rule with the new rule in the filterlist, then free the old rule. */ 724 * rule with the new rule in the filterlist, then free the old rule.
426static struct audit_entry *audit_dupe_rule(struct audit_krule *old) 725 * The rlist element is undefined; list manipulations are handled apart from
726 * the initial copy. */
727static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
728 struct audit_watch *watch)
427{ 729{
428 u32 fcount = old->field_count; 730 u32 fcount = old->field_count;
429 struct audit_entry *entry; 731 struct audit_entry *entry;
@@ -442,6 +744,8 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
442 for (i = 0; i < AUDIT_BITMASK_SIZE; i++) 744 for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
443 new->mask[i] = old->mask[i]; 745 new->mask[i] = old->mask[i];
444 new->buflen = old->buflen; 746 new->buflen = old->buflen;
747 new->inode_f = old->inode_f;
748 new->watch = NULL;
445 new->field_count = old->field_count; 749 new->field_count = old->field_count;
446 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); 750 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
447 751
@@ -463,68 +767,409 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
463 } 767 }
464 } 768 }
465 769
770 if (watch) {
771 audit_get_watch(watch);
772 new->watch = watch;
773 }
774
466 return entry; 775 return entry;
467} 776}
468 777
469/* Add rule to given filterlist if not a duplicate. Protected by 778/* Update inode info in audit rules based on filesystem event. */
470 * audit_netlink_mutex. */ 779static void audit_update_watch(struct audit_parent *parent,
780 const char *dname, dev_t dev,
781 unsigned long ino, unsigned invalidating)
782{
783 struct audit_watch *owatch, *nwatch, *nextw;
784 struct audit_krule *r, *nextr;
785 struct audit_entry *oentry, *nentry;
786 struct audit_buffer *ab;
787
788 mutex_lock(&audit_filter_mutex);
789 list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
790 if (audit_compare_dname_path(dname, owatch->path, NULL))
791 continue;
792
793 /* If the update involves invalidating rules, do the inode-based
794 * filtering now, so we don't omit records. */
795 if (invalidating &&
796 audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT)
797 audit_set_auditable(current->audit_context);
798
799 nwatch = audit_dupe_watch(owatch);
800 if (unlikely(IS_ERR(nwatch))) {
801 mutex_unlock(&audit_filter_mutex);
802 audit_panic("error updating watch, skipping");
803 return;
804 }
805 nwatch->dev = dev;
806 nwatch->ino = ino;
807
808 list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) {
809
810 oentry = container_of(r, struct audit_entry, rule);
811 list_del(&oentry->rule.rlist);
812 list_del_rcu(&oentry->list);
813
814 nentry = audit_dupe_rule(&oentry->rule, nwatch);
815 if (unlikely(IS_ERR(nentry)))
816 audit_panic("error updating watch, removing");
817 else {
818 int h = audit_hash_ino((u32)ino);
819 list_add(&nentry->rule.rlist, &nwatch->rules);
820 list_add_rcu(&nentry->list, &audit_inode_hash[h]);
821 }
822
823 call_rcu(&oentry->rcu, audit_free_rule_rcu);
824 }
825
826 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
827 audit_log_format(ab, "audit updated rules specifying watch=");
828 audit_log_untrustedstring(ab, owatch->path);
829 audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
830 audit_log_end(ab);
831
832 audit_remove_watch(owatch);
833 goto add_watch_to_parent; /* event applies to a single watch */
834 }
835 mutex_unlock(&audit_filter_mutex);
836 return;
837
838add_watch_to_parent:
839 list_add(&nwatch->wlist, &parent->watches);
840 mutex_unlock(&audit_filter_mutex);
841 return;
842}
843
844/* Remove all watches & rules associated with a parent that is going away. */
845static void audit_remove_parent_watches(struct audit_parent *parent)
846{
847 struct audit_watch *w, *nextw;
848 struct audit_krule *r, *nextr;
849 struct audit_entry *e;
850
851 mutex_lock(&audit_filter_mutex);
852 parent->flags |= AUDIT_PARENT_INVALID;
853 list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
854 list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
855 e = container_of(r, struct audit_entry, rule);
856 list_del(&r->rlist);
857 list_del_rcu(&e->list);
858 call_rcu(&e->rcu, audit_free_rule_rcu);
859
860 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
861 "audit implicitly removed rule from list=%d\n",
862 AUDIT_FILTER_EXIT);
863 }
864 audit_remove_watch(w);
865 }
866 mutex_unlock(&audit_filter_mutex);
867}
868
869/* Unregister inotify watches for parents on in_list.
870 * Generates an IN_IGNORED event. */
871static void audit_inotify_unregister(struct list_head *in_list)
872{
873 struct audit_parent *p, *n;
874
875 list_for_each_entry_safe(p, n, in_list, ilist) {
876 list_del(&p->ilist);
877 inotify_rm_watch(audit_ih, &p->wdata);
878 /* the put matching the get in audit_do_del_rule() */
879 put_inotify_watch(&p->wdata);
880 }
881}
882
883/* Find an existing audit rule.
884 * Caller must hold audit_filter_mutex to prevent stale rule data. */
885static struct audit_entry *audit_find_rule(struct audit_entry *entry,
886 struct list_head *list)
887{
888 struct audit_entry *e, *found = NULL;
889 int h;
890
891 if (entry->rule.watch) {
892 /* we don't know the inode number, so must walk entire hash */
893 for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
894 list = &audit_inode_hash[h];
895 list_for_each_entry(e, list, list)
896 if (!audit_compare_rule(&entry->rule, &e->rule)) {
897 found = e;
898 goto out;
899 }
900 }
901 goto out;
902 }
903
904 list_for_each_entry(e, list, list)
905 if (!audit_compare_rule(&entry->rule, &e->rule)) {
906 found = e;
907 goto out;
908 }
909
910out:
911 return found;
912}
913
914/* Get path information necessary for adding watches. */
915static int audit_get_nd(char *path, struct nameidata **ndp,
916 struct nameidata **ndw)
917{
918 struct nameidata *ndparent, *ndwatch;
919 int err;
920
921 ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL);
922 if (unlikely(!ndparent))
923 return -ENOMEM;
924
925 ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL);
926 if (unlikely(!ndwatch)) {
927 kfree(ndparent);
928 return -ENOMEM;
929 }
930
931 err = path_lookup(path, LOOKUP_PARENT, ndparent);
932 if (err) {
933 kfree(ndparent);
934 kfree(ndwatch);
935 return err;
936 }
937
938 err = path_lookup(path, 0, ndwatch);
939 if (err) {
940 kfree(ndwatch);
941 ndwatch = NULL;
942 }
943
944 *ndp = ndparent;
945 *ndw = ndwatch;
946
947 return 0;
948}
949
950/* Release resources used for watch path information. */
951static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
952{
953 if (ndp) {
954 path_release(ndp);
955 kfree(ndp);
956 }
957 if (ndw) {
958 path_release(ndw);
959 kfree(ndw);
960 }
961}
962
963/* Associate the given rule with an existing parent inotify_watch.
964 * Caller must hold audit_filter_mutex. */
965static void audit_add_to_parent(struct audit_krule *krule,
966 struct audit_parent *parent)
967{
968 struct audit_watch *w, *watch = krule->watch;
969 int watch_found = 0;
970
971 list_for_each_entry(w, &parent->watches, wlist) {
972 if (strcmp(watch->path, w->path))
973 continue;
974
975 watch_found = 1;
976
977 /* put krule's and initial refs to temporary watch */
978 audit_put_watch(watch);
979 audit_put_watch(watch);
980
981 audit_get_watch(w);
982 krule->watch = watch = w;
983 break;
984 }
985
986 if (!watch_found) {
987 get_inotify_watch(&parent->wdata);
988 watch->parent = parent;
989
990 list_add(&watch->wlist, &parent->watches);
991 }
992 list_add(&krule->rlist, &watch->rules);
993}
994
995/* Find a matching watch entry, or add this one.
996 * Caller must hold audit_filter_mutex. */
997static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
998 struct nameidata *ndw)
999{
1000 struct audit_watch *watch = krule->watch;
1001 struct inotify_watch *i_watch;
1002 struct audit_parent *parent;
1003 int ret = 0;
1004
1005 /* update watch filter fields */
1006 if (ndw) {
1007 watch->dev = ndw->dentry->d_inode->i_sb->s_dev;
1008 watch->ino = ndw->dentry->d_inode->i_ino;
1009 }
1010
1011 /* The audit_filter_mutex must not be held during inotify calls because
1012 * we hold it during inotify event callback processing. If an existing
1013 * inotify watch is found, inotify_find_watch() grabs a reference before
1014 * returning.
1015 */
1016 mutex_unlock(&audit_filter_mutex);
1017
1018 if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
1019 parent = audit_init_parent(ndp);
1020 if (IS_ERR(parent)) {
1021 /* caller expects mutex locked */
1022 mutex_lock(&audit_filter_mutex);
1023 return PTR_ERR(parent);
1024 }
1025 } else
1026 parent = container_of(i_watch, struct audit_parent, wdata);
1027
1028 mutex_lock(&audit_filter_mutex);
1029
1030 /* parent was moved before we took audit_filter_mutex */
1031 if (parent->flags & AUDIT_PARENT_INVALID)
1032 ret = -ENOENT;
1033 else
1034 audit_add_to_parent(krule, parent);
1035
1036 /* match get in audit_init_parent or inotify_find_watch */
1037 put_inotify_watch(&parent->wdata);
1038 return ret;
1039}
1040
1041/* Add rule to given filterlist if not a duplicate. */
471static inline int audit_add_rule(struct audit_entry *entry, 1042static inline int audit_add_rule(struct audit_entry *entry,
472 struct list_head *list) 1043 struct list_head *list)
473{ 1044{
474 struct audit_entry *e; 1045 struct audit_entry *e;
1046 struct audit_field *inode_f = entry->rule.inode_f;
1047 struct audit_watch *watch = entry->rule.watch;
1048 struct nameidata *ndp, *ndw;
1049 int h, err, putnd_needed = 0;
1050
1051 if (inode_f) {
1052 h = audit_hash_ino(inode_f->val);
1053 list = &audit_inode_hash[h];
1054 }
475 1055
476 /* Do not use the _rcu iterator here, since this is the only 1056 mutex_lock(&audit_filter_mutex);
477 * addition routine. */ 1057 e = audit_find_rule(entry, list);
478 list_for_each_entry(e, list, list) { 1058 mutex_unlock(&audit_filter_mutex);
479 if (!audit_compare_rule(&entry->rule, &e->rule)) 1059 if (e) {
480 return -EEXIST; 1060 err = -EEXIST;
1061 goto error;
1062 }
1063
1064 /* Avoid calling path_lookup under audit_filter_mutex. */
1065 if (watch) {
1066 err = audit_get_nd(watch->path, &ndp, &ndw);
1067 if (err)
1068 goto error;
1069 putnd_needed = 1;
1070 }
1071
1072 mutex_lock(&audit_filter_mutex);
1073 if (watch) {
1074 /* audit_filter_mutex is dropped and re-taken during this call */
1075 err = audit_add_watch(&entry->rule, ndp, ndw);
1076 if (err) {
1077 mutex_unlock(&audit_filter_mutex);
1078 goto error;
1079 }
1080 h = audit_hash_ino((u32)watch->ino);
1081 list = &audit_inode_hash[h];
481 } 1082 }
482 1083
483 if (entry->rule.flags & AUDIT_FILTER_PREPEND) { 1084 if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
484 list_add_rcu(&entry->list, list); 1085 list_add_rcu(&entry->list, list);
1086 entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
485 } else { 1087 } else {
486 list_add_tail_rcu(&entry->list, list); 1088 list_add_tail_rcu(&entry->list, list);
487 } 1089 }
1090 mutex_unlock(&audit_filter_mutex);
488 1091
489 return 0; 1092 if (putnd_needed)
1093 audit_put_nd(ndp, ndw);
1094
1095 return 0;
1096
1097error:
1098 if (putnd_needed)
1099 audit_put_nd(ndp, ndw);
1100 if (watch)
1101 audit_put_watch(watch); /* tmp watch, matches initial get */
1102 return err;
490} 1103}
491 1104
492/* Remove an existing rule from filterlist. Protected by 1105/* Remove an existing rule from filterlist. */
493 * audit_netlink_mutex. */
494static inline int audit_del_rule(struct audit_entry *entry, 1106static inline int audit_del_rule(struct audit_entry *entry,
495 struct list_head *list) 1107 struct list_head *list)
496{ 1108{
497 struct audit_entry *e; 1109 struct audit_entry *e;
1110 struct audit_field *inode_f = entry->rule.inode_f;
1111 struct audit_watch *watch, *tmp_watch = entry->rule.watch;
1112 LIST_HEAD(inotify_list);
1113 int h, ret = 0;
1114
1115 if (inode_f) {
1116 h = audit_hash_ino(inode_f->val);
1117 list = &audit_inode_hash[h];
1118 }
498 1119
499 /* Do not use the _rcu iterator here, since this is the only 1120 mutex_lock(&audit_filter_mutex);
500 * deletion routine. */ 1121 e = audit_find_rule(entry, list);
501 list_for_each_entry(e, list, list) { 1122 if (!e) {
502 if (!audit_compare_rule(&entry->rule, &e->rule)) { 1123 mutex_unlock(&audit_filter_mutex);
503 list_del_rcu(&e->list); 1124 ret = -ENOENT;
504 call_rcu(&e->rcu, audit_free_rule_rcu); 1125 goto out;
505 return 0; 1126 }
1127
1128 watch = e->rule.watch;
1129 if (watch) {
1130 struct audit_parent *parent = watch->parent;
1131
1132 list_del(&e->rule.rlist);
1133
1134 if (list_empty(&watch->rules)) {
1135 audit_remove_watch(watch);
1136
1137 if (list_empty(&parent->watches)) {
1138 /* Put parent on the inotify un-registration
1139 * list. Grab a reference before releasing
1140 * audit_filter_mutex, to be released in
1141 * audit_inotify_unregister(). */
1142 list_add(&parent->ilist, &inotify_list);
1143 get_inotify_watch(&parent->wdata);
1144 }
506 } 1145 }
507 } 1146 }
508 return -ENOENT; /* No matching rule */ 1147
1148 list_del_rcu(&e->list);
1149 call_rcu(&e->rcu, audit_free_rule_rcu);
1150
1151 mutex_unlock(&audit_filter_mutex);
1152
1153 if (!list_empty(&inotify_list))
1154 audit_inotify_unregister(&inotify_list);
1155
1156out:
1157 if (tmp_watch)
1158 audit_put_watch(tmp_watch); /* match initial get */
1159
1160 return ret;
509} 1161}
510 1162
511/* List rules using struct audit_rule. Exists for backward 1163/* List rules using struct audit_rule. Exists for backward
512 * compatibility with userspace. */ 1164 * compatibility with userspace. */
513static int audit_list(void *_dest) 1165static void audit_list(int pid, int seq, struct sk_buff_head *q)
514{ 1166{
515 int pid, seq; 1167 struct sk_buff *skb;
516 int *dest = _dest;
517 struct audit_entry *entry; 1168 struct audit_entry *entry;
518 int i; 1169 int i;
519 1170
520 pid = dest[0]; 1171 /* This is a blocking read, so use audit_filter_mutex instead of rcu
521 seq = dest[1]; 1172 * iterator to sync with list writers. */
522 kfree(dest);
523
524 mutex_lock(&audit_netlink_mutex);
525
526 /* The *_rcu iterators not needed here because we are
527 always called with audit_netlink_mutex held. */
528 for (i=0; i<AUDIT_NR_FILTERS; i++) { 1173 for (i=0; i<AUDIT_NR_FILTERS; i++) {
529 list_for_each_entry(entry, &audit_filter_list[i], list) { 1174 list_for_each_entry(entry, &audit_filter_list[i], list) {
530 struct audit_rule *rule; 1175 struct audit_rule *rule;
@@ -532,33 +1177,41 @@ static int audit_list(void *_dest)
532 rule = audit_krule_to_rule(&entry->rule); 1177 rule = audit_krule_to_rule(&entry->rule);
533 if (unlikely(!rule)) 1178 if (unlikely(!rule))
534 break; 1179 break;
535 audit_send_reply(pid, seq, AUDIT_LIST, 0, 1, 1180 skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
536 rule, sizeof(*rule)); 1181 rule, sizeof(*rule));
1182 if (skb)
1183 skb_queue_tail(q, skb);
537 kfree(rule); 1184 kfree(rule);
538 } 1185 }
539 } 1186 }
540 audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); 1187 for (i = 0; i < AUDIT_INODE_BUCKETS; i++) {
541 1188 list_for_each_entry(entry, &audit_inode_hash[i], list) {
542 mutex_unlock(&audit_netlink_mutex); 1189 struct audit_rule *rule;
543 return 0; 1190
1191 rule = audit_krule_to_rule(&entry->rule);
1192 if (unlikely(!rule))
1193 break;
1194 skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
1195 rule, sizeof(*rule));
1196 if (skb)
1197 skb_queue_tail(q, skb);
1198 kfree(rule);
1199 }
1200 }
1201 skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
1202 if (skb)
1203 skb_queue_tail(q, skb);
544} 1204}
545 1205
546/* List rules using struct audit_rule_data. */ 1206/* List rules using struct audit_rule_data. */
547static int audit_list_rules(void *_dest) 1207static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
548{ 1208{
549 int pid, seq; 1209 struct sk_buff *skb;
550 int *dest = _dest;
551 struct audit_entry *e; 1210 struct audit_entry *e;
552 int i; 1211 int i;
553 1212
554 pid = dest[0]; 1213 /* This is a blocking read, so use audit_filter_mutex instead of rcu
555 seq = dest[1]; 1214 * iterator to sync with list writers. */
556 kfree(dest);
557
558 mutex_lock(&audit_netlink_mutex);
559
560 /* The *_rcu iterators not needed here because we are
561 always called with audit_netlink_mutex held. */
562 for (i=0; i<AUDIT_NR_FILTERS; i++) { 1215 for (i=0; i<AUDIT_NR_FILTERS; i++) {
563 list_for_each_entry(e, &audit_filter_list[i], list) { 1216 list_for_each_entry(e, &audit_filter_list[i], list) {
564 struct audit_rule_data *data; 1217 struct audit_rule_data *data;
@@ -566,15 +1219,30 @@ static int audit_list_rules(void *_dest)
566 data = audit_krule_to_data(&e->rule); 1219 data = audit_krule_to_data(&e->rule);
567 if (unlikely(!data)) 1220 if (unlikely(!data))
568 break; 1221 break;
569 audit_send_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, 1222 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
570 data, sizeof(*data)); 1223 data, sizeof(*data) + data->buflen);
1224 if (skb)
1225 skb_queue_tail(q, skb);
571 kfree(data); 1226 kfree(data);
572 } 1227 }
573 } 1228 }
574 audit_send_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); 1229 for (i=0; i< AUDIT_INODE_BUCKETS; i++) {
1230 list_for_each_entry(e, &audit_inode_hash[i], list) {
1231 struct audit_rule_data *data;
575 1232
576 mutex_unlock(&audit_netlink_mutex); 1233 data = audit_krule_to_data(&e->rule);
577 return 0; 1234 if (unlikely(!data))
1235 break;
1236 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
1237 data, sizeof(*data) + data->buflen);
1238 if (skb)
1239 skb_queue_tail(q, skb);
1240 kfree(data);
1241 }
1242 }
1243 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
1244 if (skb)
1245 skb_queue_tail(q, skb);
578} 1246}
579 1247
580/** 1248/**
@@ -592,7 +1260,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
592 size_t datasz, uid_t loginuid, u32 sid) 1260 size_t datasz, uid_t loginuid, u32 sid)
593{ 1261{
594 struct task_struct *tsk; 1262 struct task_struct *tsk;
595 int *dest; 1263 struct audit_netlink_list *dest;
596 int err = 0; 1264 int err = 0;
597 struct audit_entry *entry; 1265 struct audit_entry *entry;
598 1266
@@ -605,18 +1273,22 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
605 * happen if we're actually running in the context of auditctl 1273 * happen if we're actually running in the context of auditctl
606 * trying to _send_ the stuff */ 1274 * trying to _send_ the stuff */
607 1275
608 dest = kmalloc(2 * sizeof(int), GFP_KERNEL); 1276 dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
609 if (!dest) 1277 if (!dest)
610 return -ENOMEM; 1278 return -ENOMEM;
611 dest[0] = pid; 1279 dest->pid = pid;
612 dest[1] = seq; 1280 skb_queue_head_init(&dest->q);
613 1281
1282 mutex_lock(&audit_filter_mutex);
614 if (type == AUDIT_LIST) 1283 if (type == AUDIT_LIST)
615 tsk = kthread_run(audit_list, dest, "audit_list"); 1284 audit_list(pid, seq, &dest->q);
616 else 1285 else
617 tsk = kthread_run(audit_list_rules, dest, 1286 audit_list_rules(pid, seq, &dest->q);
618 "audit_list_rules"); 1287 mutex_unlock(&audit_filter_mutex);
1288
1289 tsk = kthread_run(audit_send_list, dest, "audit_send_list");
619 if (IS_ERR(tsk)) { 1290 if (IS_ERR(tsk)) {
1291 skb_queue_purge(&dest->q);
620 kfree(dest); 1292 kfree(dest);
621 err = PTR_ERR(tsk); 1293 err = PTR_ERR(tsk);
622 } 1294 }
@@ -632,6 +1304,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
632 1304
633 err = audit_add_rule(entry, 1305 err = audit_add_rule(entry,
634 &audit_filter_list[entry->rule.listnr]); 1306 &audit_filter_list[entry->rule.listnr]);
1307
635 if (sid) { 1308 if (sid) {
636 char *ctx = NULL; 1309 char *ctx = NULL;
637 u32 len; 1310 u32 len;
@@ -712,7 +1385,43 @@ int audit_comparator(const u32 left, const u32 op, const u32 right)
712 return 0; 1385 return 0;
713} 1386}
714 1387
1388/* Compare given dentry name with last component in given path,
1389 * return of 0 indicates a match. */
1390int audit_compare_dname_path(const char *dname, const char *path,
1391 int *dirlen)
1392{
1393 int dlen, plen;
1394 const char *p;
715 1395
1396 if (!dname || !path)
1397 return 1;
1398
1399 dlen = strlen(dname);
1400 plen = strlen(path);
1401 if (plen < dlen)
1402 return 1;
1403
1404 /* disregard trailing slashes */
1405 p = path + plen - 1;
1406 while ((*p == '/') && (p > path))
1407 p--;
1408
1409 /* find last path component */
1410 p = p - dlen + 1;
1411 if (p < path)
1412 return 1;
1413 else if (p > path) {
1414 if (*--p != '/')
1415 return 1;
1416 else
1417 p++;
1418 }
1419
1420 /* return length of path's directory component */
1421 if (dirlen)
1422 *dirlen = p - path;
1423 return strncmp(p, dname, dlen);
1424}
716 1425
717static int audit_filter_user_rules(struct netlink_skb_parms *cb, 1426static int audit_filter_user_rules(struct netlink_skb_parms *cb,
718 struct audit_krule *rule, 1427 struct audit_krule *rule,
@@ -744,7 +1453,6 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb,
744 } 1453 }
745 switch (rule->action) { 1454 switch (rule->action) {
746 case AUDIT_NEVER: *state = AUDIT_DISABLED; break; 1455 case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
747 case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT; break;
748 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; 1456 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break;
749 } 1457 }
750 return 1; 1458 return 1;
@@ -826,32 +1534,65 @@ static inline int audit_rule_has_selinux(struct audit_krule *rule)
826int selinux_audit_rule_update(void) 1534int selinux_audit_rule_update(void)
827{ 1535{
828 struct audit_entry *entry, *n, *nentry; 1536 struct audit_entry *entry, *n, *nentry;
1537 struct audit_watch *watch;
829 int i, err = 0; 1538 int i, err = 0;
830 1539
831 /* audit_netlink_mutex synchronizes the writers */ 1540 /* audit_filter_mutex synchronizes the writers */
832 mutex_lock(&audit_netlink_mutex); 1541 mutex_lock(&audit_filter_mutex);
833 1542
834 for (i = 0; i < AUDIT_NR_FILTERS; i++) { 1543 for (i = 0; i < AUDIT_NR_FILTERS; i++) {
835 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { 1544 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
836 if (!audit_rule_has_selinux(&entry->rule)) 1545 if (!audit_rule_has_selinux(&entry->rule))
837 continue; 1546 continue;
838 1547
839 nentry = audit_dupe_rule(&entry->rule); 1548 watch = entry->rule.watch;
1549 nentry = audit_dupe_rule(&entry->rule, watch);
840 if (unlikely(IS_ERR(nentry))) { 1550 if (unlikely(IS_ERR(nentry))) {
841 /* save the first error encountered for the 1551 /* save the first error encountered for the
842 * return value */ 1552 * return value */
843 if (!err) 1553 if (!err)
844 err = PTR_ERR(nentry); 1554 err = PTR_ERR(nentry);
845 audit_panic("error updating selinux filters"); 1555 audit_panic("error updating selinux filters");
1556 if (watch)
1557 list_del(&entry->rule.rlist);
846 list_del_rcu(&entry->list); 1558 list_del_rcu(&entry->list);
847 } else { 1559 } else {
1560 if (watch) {
1561 list_add(&nentry->rule.rlist,
1562 &watch->rules);
1563 list_del(&entry->rule.rlist);
1564 }
848 list_replace_rcu(&entry->list, &nentry->list); 1565 list_replace_rcu(&entry->list, &nentry->list);
849 } 1566 }
850 call_rcu(&entry->rcu, audit_free_rule_rcu); 1567 call_rcu(&entry->rcu, audit_free_rule_rcu);
851 } 1568 }
852 } 1569 }
853 1570
854 mutex_unlock(&audit_netlink_mutex); 1571 mutex_unlock(&audit_filter_mutex);
855 1572
856 return err; 1573 return err;
857} 1574}
1575
1576/* Update watch data in audit rules based on inotify events. */
1577void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask,
1578 u32 cookie, const char *dname, struct inode *inode)
1579{
1580 struct audit_parent *parent;
1581
1582 parent = container_of(i_watch, struct audit_parent, wdata);
1583
1584 if (mask & (IN_CREATE|IN_MOVED_TO) && inode)
1585 audit_update_watch(parent, dname, inode->i_sb->s_dev,
1586 inode->i_ino, 0);
1587 else if (mask & (IN_DELETE|IN_MOVED_FROM))
1588 audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1);
1589 /* inotify automatically removes the watch and sends IN_IGNORED */
1590 else if (mask & (IN_DELETE_SELF|IN_UNMOUNT))
1591 audit_remove_parent_watches(parent);
1592 /* inotify does not remove the watch, so remove it manually */
1593 else if(mask & IN_MOVE_SELF) {
1594 audit_remove_parent_watches(parent);
1595 inotify_remove_watch_locked(audit_ih, i_watch);
1596 } else if (mask & IN_IGNORED)
1597 put_inotify_watch(i_watch);
1598}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 1c03a4ed1b27..b097ccb4eb7e 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
5 * Copyright 2005 Hewlett-Packard Development Company, L.P. 5 * Copyright 2005 Hewlett-Packard Development Company, L.P.
6 * Copyright (C) 2005 IBM Corporation 6 * Copyright (C) 2005, 2006 IBM Corporation
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,9 @@
29 * this file -- see entry.S) is based on a GPL'd patch written by 29 * this file -- see entry.S) is based on a GPL'd patch written by
30 * okir@suse.de and Copyright 2003 SuSE Linux AG. 30 * okir@suse.de and Copyright 2003 SuSE Linux AG.
31 * 31 *
32 * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
33 * 2006.
34 *
32 * The support of additional filter rules compares (>, <, >=, <=) was 35 * The support of additional filter rules compares (>, <, >=, <=) was
33 * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005. 36 * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
34 * 37 *
@@ -49,6 +52,7 @@
49#include <linux/module.h> 52#include <linux/module.h>
50#include <linux/mount.h> 53#include <linux/mount.h>
51#include <linux/socket.h> 54#include <linux/socket.h>
55#include <linux/mqueue.h>
52#include <linux/audit.h> 56#include <linux/audit.h>
53#include <linux/personality.h> 57#include <linux/personality.h>
54#include <linux/time.h> 58#include <linux/time.h>
@@ -59,6 +63,8 @@
59#include <linux/list.h> 63#include <linux/list.h>
60#include <linux/tty.h> 64#include <linux/tty.h>
61#include <linux/selinux.h> 65#include <linux/selinux.h>
66#include <linux/binfmts.h>
67#include <linux/syscalls.h>
62 68
63#include "audit.h" 69#include "audit.h"
64 70
@@ -76,6 +82,9 @@ extern int audit_enabled;
76 * path_lookup. */ 82 * path_lookup. */
77#define AUDIT_NAMES_RESERVED 7 83#define AUDIT_NAMES_RESERVED 7
78 84
85/* Indicates that audit should log the full pathname. */
86#define AUDIT_NAME_FULL -1
87
79/* When fs/namei.c:getname() is called, we store the pointer in name and 88/* When fs/namei.c:getname() is called, we store the pointer in name and
80 * we don't let putname() free it (instead we free all of the saved 89 * we don't let putname() free it (instead we free all of the saved
81 * pointers at syscall exit time). 90 * pointers at syscall exit time).
@@ -83,8 +92,9 @@ extern int audit_enabled;
83 * Further, in fs/namei.c:path_lookup() we store the inode and device. */ 92 * Further, in fs/namei.c:path_lookup() we store the inode and device. */
84struct audit_names { 93struct audit_names {
85 const char *name; 94 const char *name;
95 int name_len; /* number of name's characters to log */
96 unsigned name_put; /* call __putname() for this name */
86 unsigned long ino; 97 unsigned long ino;
87 unsigned long pino;
88 dev_t dev; 98 dev_t dev;
89 umode_t mode; 99 umode_t mode;
90 uid_t uid; 100 uid_t uid;
@@ -100,6 +110,33 @@ struct audit_aux_data {
100 110
101#define AUDIT_AUX_IPCPERM 0 111#define AUDIT_AUX_IPCPERM 0
102 112
113struct audit_aux_data_mq_open {
114 struct audit_aux_data d;
115 int oflag;
116 mode_t mode;
117 struct mq_attr attr;
118};
119
120struct audit_aux_data_mq_sendrecv {
121 struct audit_aux_data d;
122 mqd_t mqdes;
123 size_t msg_len;
124 unsigned int msg_prio;
125 struct timespec abs_timeout;
126};
127
128struct audit_aux_data_mq_notify {
129 struct audit_aux_data d;
130 mqd_t mqdes;
131 struct sigevent notification;
132};
133
134struct audit_aux_data_mq_getsetattr {
135 struct audit_aux_data d;
136 mqd_t mqdes;
137 struct mq_attr mqstat;
138};
139
103struct audit_aux_data_ipcctl { 140struct audit_aux_data_ipcctl {
104 struct audit_aux_data d; 141 struct audit_aux_data d;
105 struct ipc_perm p; 142 struct ipc_perm p;
@@ -110,6 +147,13 @@ struct audit_aux_data_ipcctl {
110 u32 osid; 147 u32 osid;
111}; 148};
112 149
150struct audit_aux_data_execve {
151 struct audit_aux_data d;
152 int argc;
153 int envc;
154 char mem[0];
155};
156
113struct audit_aux_data_socketcall { 157struct audit_aux_data_socketcall {
114 struct audit_aux_data d; 158 struct audit_aux_data d;
115 int nargs; 159 int nargs;
@@ -148,7 +192,7 @@ struct audit_context {
148 struct audit_aux_data *aux; 192 struct audit_aux_data *aux;
149 193
150 /* Save things to print about task_struct */ 194 /* Save things to print about task_struct */
151 pid_t pid; 195 pid_t pid, ppid;
152 uid_t uid, euid, suid, fsuid; 196 uid_t uid, euid, suid, fsuid;
153 gid_t gid, egid, sgid, fsgid; 197 gid_t gid, egid, sgid, fsgid;
154 unsigned long personality; 198 unsigned long personality;
@@ -160,12 +204,13 @@ struct audit_context {
160#endif 204#endif
161}; 205};
162 206
163 207/* Determine if any context name data matches a rule's watch data */
164/* Compare a task_struct with an audit_rule. Return 1 on match, 0 208/* Compare a task_struct with an audit_rule. Return 1 on match, 0
165 * otherwise. */ 209 * otherwise. */
166static int audit_filter_rules(struct task_struct *tsk, 210static int audit_filter_rules(struct task_struct *tsk,
167 struct audit_krule *rule, 211 struct audit_krule *rule,
168 struct audit_context *ctx, 212 struct audit_context *ctx,
213 struct audit_names *name,
169 enum audit_state *state) 214 enum audit_state *state)
170{ 215{
171 int i, j, need_sid = 1; 216 int i, j, need_sid = 1;
@@ -179,6 +224,10 @@ static int audit_filter_rules(struct task_struct *tsk,
179 case AUDIT_PID: 224 case AUDIT_PID:
180 result = audit_comparator(tsk->pid, f->op, f->val); 225 result = audit_comparator(tsk->pid, f->op, f->val);
181 break; 226 break;
227 case AUDIT_PPID:
228 if (ctx)
229 result = audit_comparator(ctx->ppid, f->op, f->val);
230 break;
182 case AUDIT_UID: 231 case AUDIT_UID:
183 result = audit_comparator(tsk->uid, f->op, f->val); 232 result = audit_comparator(tsk->uid, f->op, f->val);
184 break; 233 break;
@@ -224,7 +273,10 @@ static int audit_filter_rules(struct task_struct *tsk,
224 } 273 }
225 break; 274 break;
226 case AUDIT_DEVMAJOR: 275 case AUDIT_DEVMAJOR:
227 if (ctx) { 276 if (name)
277 result = audit_comparator(MAJOR(name->dev),
278 f->op, f->val);
279 else if (ctx) {
228 for (j = 0; j < ctx->name_count; j++) { 280 for (j = 0; j < ctx->name_count; j++) {
229 if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) { 281 if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) {
230 ++result; 282 ++result;
@@ -234,7 +286,10 @@ static int audit_filter_rules(struct task_struct *tsk,
234 } 286 }
235 break; 287 break;
236 case AUDIT_DEVMINOR: 288 case AUDIT_DEVMINOR:
237 if (ctx) { 289 if (name)
290 result = audit_comparator(MINOR(name->dev),
291 f->op, f->val);
292 else if (ctx) {
238 for (j = 0; j < ctx->name_count; j++) { 293 for (j = 0; j < ctx->name_count; j++) {
239 if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) { 294 if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) {
240 ++result; 295 ++result;
@@ -244,16 +299,22 @@ static int audit_filter_rules(struct task_struct *tsk,
244 } 299 }
245 break; 300 break;
246 case AUDIT_INODE: 301 case AUDIT_INODE:
247 if (ctx) { 302 if (name)
303 result = (name->ino == f->val);
304 else if (ctx) {
248 for (j = 0; j < ctx->name_count; j++) { 305 for (j = 0; j < ctx->name_count; j++) {
249 if (audit_comparator(ctx->names[j].ino, f->op, f->val) || 306 if (audit_comparator(ctx->names[j].ino, f->op, f->val)) {
250 audit_comparator(ctx->names[j].pino, f->op, f->val)) {
251 ++result; 307 ++result;
252 break; 308 break;
253 } 309 }
254 } 310 }
255 } 311 }
256 break; 312 break;
313 case AUDIT_WATCH:
314 if (name && rule->watch->ino != (unsigned long)-1)
315 result = (name->dev == rule->watch->dev &&
316 name->ino == rule->watch->ino);
317 break;
257 case AUDIT_LOGINUID: 318 case AUDIT_LOGINUID:
258 result = 0; 319 result = 0;
259 if (ctx) 320 if (ctx)
@@ -294,7 +355,6 @@ static int audit_filter_rules(struct task_struct *tsk,
294 } 355 }
295 switch (rule->action) { 356 switch (rule->action) {
296 case AUDIT_NEVER: *state = AUDIT_DISABLED; break; 357 case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
297 case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT; break;
298 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; 358 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break;
299 } 359 }
300 return 1; 360 return 1;
@@ -311,7 +371,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
311 371
312 rcu_read_lock(); 372 rcu_read_lock();
313 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { 373 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
314 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { 374 if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
315 rcu_read_unlock(); 375 rcu_read_unlock();
316 return state; 376 return state;
317 } 377 }
@@ -341,8 +401,47 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
341 int bit = AUDIT_BIT(ctx->major); 401 int bit = AUDIT_BIT(ctx->major);
342 402
343 list_for_each_entry_rcu(e, list, list) { 403 list_for_each_entry_rcu(e, list, list) {
344 if ((e->rule.mask[word] & bit) == bit 404 if ((e->rule.mask[word] & bit) == bit &&
345 && audit_filter_rules(tsk, &e->rule, ctx, &state)) { 405 audit_filter_rules(tsk, &e->rule, ctx, NULL,
406 &state)) {
407 rcu_read_unlock();
408 return state;
409 }
410 }
411 }
412 rcu_read_unlock();
413 return AUDIT_BUILD_CONTEXT;
414}
415
416/* At syscall exit time, this filter is called if any audit_names[] have been
417 * collected during syscall processing. We only check rules in sublists at hash
418 * buckets applicable to the inode numbers in audit_names[].
419 * Regarding audit_state, same rules apply as for audit_filter_syscall().
420 */
421enum audit_state audit_filter_inodes(struct task_struct *tsk,
422 struct audit_context *ctx)
423{
424 int i;
425 struct audit_entry *e;
426 enum audit_state state;
427
428 if (audit_pid && tsk->tgid == audit_pid)
429 return AUDIT_DISABLED;
430
431 rcu_read_lock();
432 for (i = 0; i < ctx->name_count; i++) {
433 int word = AUDIT_WORD(ctx->major);
434 int bit = AUDIT_BIT(ctx->major);
435 struct audit_names *n = &ctx->names[i];
436 int h = audit_hash_ino((u32)n->ino);
437 struct list_head *list = &audit_inode_hash[h];
438
439 if (list_empty(list))
440 continue;
441
442 list_for_each_entry_rcu(e, list, list) {
443 if ((e->rule.mask[word] & bit) == bit &&
444 audit_filter_rules(tsk, &e->rule, ctx, n, &state)) {
346 rcu_read_unlock(); 445 rcu_read_unlock();
347 return state; 446 return state;
348 } 447 }
@@ -352,6 +451,11 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
352 return AUDIT_BUILD_CONTEXT; 451 return AUDIT_BUILD_CONTEXT;
353} 452}
354 453
454void audit_set_auditable(struct audit_context *ctx)
455{
456 ctx->auditable = 1;
457}
458
355static inline struct audit_context *audit_get_context(struct task_struct *tsk, 459static inline struct audit_context *audit_get_context(struct task_struct *tsk,
356 int return_valid, 460 int return_valid,
357 int return_code) 461 int return_code)
@@ -365,12 +469,22 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
365 469
366 if (context->in_syscall && !context->auditable) { 470 if (context->in_syscall && !context->auditable) {
367 enum audit_state state; 471 enum audit_state state;
472
368 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); 473 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
474 if (state == AUDIT_RECORD_CONTEXT) {
475 context->auditable = 1;
476 goto get_context;
477 }
478
479 state = audit_filter_inodes(tsk, context);
369 if (state == AUDIT_RECORD_CONTEXT) 480 if (state == AUDIT_RECORD_CONTEXT)
370 context->auditable = 1; 481 context->auditable = 1;
482
371 } 483 }
372 484
485get_context:
373 context->pid = tsk->pid; 486 context->pid = tsk->pid;
487 context->ppid = sys_getppid(); /* sic. tsk == current in all cases */
374 context->uid = tsk->uid; 488 context->uid = tsk->uid;
375 context->gid = tsk->gid; 489 context->gid = tsk->gid;
376 context->euid = tsk->euid; 490 context->euid = tsk->euid;
@@ -413,7 +527,7 @@ static inline void audit_free_names(struct audit_context *context)
413#endif 527#endif
414 528
415 for (i = 0; i < context->name_count; i++) { 529 for (i = 0; i < context->name_count; i++) {
416 if (context->names[i].name) 530 if (context->names[i].name && context->names[i].name_put)
417 __putname(context->names[i].name); 531 __putname(context->names[i].name);
418 } 532 }
419 context->name_count = 0; 533 context->name_count = 0;
@@ -606,7 +720,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
606 tty = "(none)"; 720 tty = "(none)";
607 audit_log_format(ab, 721 audit_log_format(ab,
608 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 722 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
609 " pid=%d auid=%u uid=%u gid=%u" 723 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
610 " euid=%u suid=%u fsuid=%u" 724 " euid=%u suid=%u fsuid=%u"
611 " egid=%u sgid=%u fsgid=%u tty=%s", 725 " egid=%u sgid=%u fsgid=%u tty=%s",
612 context->argv[0], 726 context->argv[0],
@@ -614,6 +728,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
614 context->argv[2], 728 context->argv[2],
615 context->argv[3], 729 context->argv[3],
616 context->name_count, 730 context->name_count,
731 context->ppid,
617 context->pid, 732 context->pid,
618 context->loginuid, 733 context->loginuid,
619 context->uid, 734 context->uid,
@@ -630,11 +745,48 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
630 continue; /* audit_panic has been called */ 745 continue; /* audit_panic has been called */
631 746
632 switch (aux->type) { 747 switch (aux->type) {
748 case AUDIT_MQ_OPEN: {
749 struct audit_aux_data_mq_open *axi = (void *)aux;
750 audit_log_format(ab,
751 "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
752 "mq_msgsize=%ld mq_curmsgs=%ld",
753 axi->oflag, axi->mode, axi->attr.mq_flags,
754 axi->attr.mq_maxmsg, axi->attr.mq_msgsize,
755 axi->attr.mq_curmsgs);
756 break; }
757
758 case AUDIT_MQ_SENDRECV: {
759 struct audit_aux_data_mq_sendrecv *axi = (void *)aux;
760 audit_log_format(ab,
761 "mqdes=%d msg_len=%zd msg_prio=%u "
762 "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
763 axi->mqdes, axi->msg_len, axi->msg_prio,
764 axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec);
765 break; }
766
767 case AUDIT_MQ_NOTIFY: {
768 struct audit_aux_data_mq_notify *axi = (void *)aux;
769 audit_log_format(ab,
770 "mqdes=%d sigev_signo=%d",
771 axi->mqdes,
772 axi->notification.sigev_signo);
773 break; }
774
775 case AUDIT_MQ_GETSETATTR: {
776 struct audit_aux_data_mq_getsetattr *axi = (void *)aux;
777 audit_log_format(ab,
778 "mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld "
779 "mq_curmsgs=%ld ",
780 axi->mqdes,
781 axi->mqstat.mq_flags, axi->mqstat.mq_maxmsg,
782 axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
783 break; }
784
633 case AUDIT_IPC: { 785 case AUDIT_IPC: {
634 struct audit_aux_data_ipcctl *axi = (void *)aux; 786 struct audit_aux_data_ipcctl *axi = (void *)aux;
635 audit_log_format(ab, 787 audit_log_format(ab,
636 " qbytes=%lx iuid=%u igid=%u mode=%x", 788 "ouid=%u ogid=%u mode=%x",
637 axi->qbytes, axi->uid, axi->gid, axi->mode); 789 axi->uid, axi->gid, axi->mode);
638 if (axi->osid != 0) { 790 if (axi->osid != 0) {
639 char *ctx = NULL; 791 char *ctx = NULL;
640 u32 len; 792 u32 len;
@@ -652,19 +804,18 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
652 case AUDIT_IPC_SET_PERM: { 804 case AUDIT_IPC_SET_PERM: {
653 struct audit_aux_data_ipcctl *axi = (void *)aux; 805 struct audit_aux_data_ipcctl *axi = (void *)aux;
654 audit_log_format(ab, 806 audit_log_format(ab,
655 " new qbytes=%lx new iuid=%u new igid=%u new mode=%x", 807 "qbytes=%lx ouid=%u ogid=%u mode=%x",
656 axi->qbytes, axi->uid, axi->gid, axi->mode); 808 axi->qbytes, axi->uid, axi->gid, axi->mode);
657 if (axi->osid != 0) { 809 break; }
658 char *ctx = NULL; 810
659 u32 len; 811 case AUDIT_EXECVE: {
660 if (selinux_ctxid_to_string( 812 struct audit_aux_data_execve *axi = (void *)aux;
661 axi->osid, &ctx, &len)) { 813 int i;
662 audit_log_format(ab, " osid=%u", 814 const char *p;
663 axi->osid); 815 for (i = 0, p = axi->mem; i < axi->argc; i++) {
664 call_panic = 1; 816 audit_log_format(ab, "a%d=", i);
665 } else 817 p = audit_log_untrustedstring(ab, p);
666 audit_log_format(ab, " obj=%s", ctx); 818 audit_log_format(ab, "\n");
667 kfree(ctx);
668 } 819 }
669 break; } 820 break; }
670 821
@@ -700,8 +851,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
700 } 851 }
701 } 852 }
702 for (i = 0; i < context->name_count; i++) { 853 for (i = 0; i < context->name_count; i++) {
703 unsigned long ino = context->names[i].ino; 854 struct audit_names *n = &context->names[i];
704 unsigned long pino = context->names[i].pino;
705 855
706 ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); 856 ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
707 if (!ab) 857 if (!ab)
@@ -709,33 +859,47 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
709 859
710 audit_log_format(ab, "item=%d", i); 860 audit_log_format(ab, "item=%d", i);
711 861
712 audit_log_format(ab, " name="); 862 if (n->name) {
713 if (context->names[i].name) 863 switch(n->name_len) {
714 audit_log_untrustedstring(ab, context->names[i].name); 864 case AUDIT_NAME_FULL:
715 else 865 /* log the full path */
716 audit_log_format(ab, "(null)"); 866 audit_log_format(ab, " name=");
717 867 audit_log_untrustedstring(ab, n->name);
718 if (pino != (unsigned long)-1) 868 break;
719 audit_log_format(ab, " parent=%lu", pino); 869 case 0:
720 if (ino != (unsigned long)-1) 870 /* name was specified as a relative path and the
721 audit_log_format(ab, " inode=%lu", ino); 871 * directory component is the cwd */
722 if ((pino != (unsigned long)-1) || (ino != (unsigned long)-1)) 872 audit_log_d_path(ab, " name=", context->pwd,
723 audit_log_format(ab, " dev=%02x:%02x mode=%#o" 873 context->pwdmnt);
724 " ouid=%u ogid=%u rdev=%02x:%02x", 874 break;
725 MAJOR(context->names[i].dev), 875 default:
726 MINOR(context->names[i].dev), 876 /* log the name's directory component */
727 context->names[i].mode, 877 audit_log_format(ab, " name=");
728 context->names[i].uid, 878 audit_log_n_untrustedstring(ab, n->name_len,
729 context->names[i].gid, 879 n->name);
730 MAJOR(context->names[i].rdev), 880 }
731 MINOR(context->names[i].rdev)); 881 } else
732 if (context->names[i].osid != 0) { 882 audit_log_format(ab, " name=(null)");
883
884 if (n->ino != (unsigned long)-1) {
885 audit_log_format(ab, " inode=%lu"
886 " dev=%02x:%02x mode=%#o"
887 " ouid=%u ogid=%u rdev=%02x:%02x",
888 n->ino,
889 MAJOR(n->dev),
890 MINOR(n->dev),
891 n->mode,
892 n->uid,
893 n->gid,
894 MAJOR(n->rdev),
895 MINOR(n->rdev));
896 }
897 if (n->osid != 0) {
733 char *ctx = NULL; 898 char *ctx = NULL;
734 u32 len; 899 u32 len;
735 if (selinux_ctxid_to_string( 900 if (selinux_ctxid_to_string(
736 context->names[i].osid, &ctx, &len)) { 901 n->osid, &ctx, &len)) {
737 audit_log_format(ab, " osid=%u", 902 audit_log_format(ab, " osid=%u", n->osid);
738 context->names[i].osid);
739 call_panic = 2; 903 call_panic = 2;
740 } else 904 } else
741 audit_log_format(ab, " obj=%s", ctx); 905 audit_log_format(ab, " obj=%s", ctx);
@@ -908,11 +1072,11 @@ void audit_syscall_exit(int valid, long return_code)
908 * Add a name to the list of audit names for this context. 1072 * Add a name to the list of audit names for this context.
909 * Called from fs/namei.c:getname(). 1073 * Called from fs/namei.c:getname().
910 */ 1074 */
911void audit_getname(const char *name) 1075void __audit_getname(const char *name)
912{ 1076{
913 struct audit_context *context = current->audit_context; 1077 struct audit_context *context = current->audit_context;
914 1078
915 if (!context || IS_ERR(name) || !name) 1079 if (IS_ERR(name) || !name)
916 return; 1080 return;
917 1081
918 if (!context->in_syscall) { 1082 if (!context->in_syscall) {
@@ -925,6 +1089,8 @@ void audit_getname(const char *name)
925 } 1089 }
926 BUG_ON(context->name_count >= AUDIT_NAMES); 1090 BUG_ON(context->name_count >= AUDIT_NAMES);
927 context->names[context->name_count].name = name; 1091 context->names[context->name_count].name = name;
1092 context->names[context->name_count].name_len = AUDIT_NAME_FULL;
1093 context->names[context->name_count].name_put = 1;
928 context->names[context->name_count].ino = (unsigned long)-1; 1094 context->names[context->name_count].ino = (unsigned long)-1;
929 ++context->name_count; 1095 ++context->name_count;
930 if (!context->pwd) { 1096 if (!context->pwd) {
@@ -991,11 +1157,10 @@ static void audit_inode_context(int idx, const struct inode *inode)
991 * audit_inode - store the inode and device from a lookup 1157 * audit_inode - store the inode and device from a lookup
992 * @name: name being audited 1158 * @name: name being audited
993 * @inode: inode being audited 1159 * @inode: inode being audited
994 * @flags: lookup flags (as used in path_lookup())
995 * 1160 *
996 * Called from fs/namei.c:path_lookup(). 1161 * Called from fs/namei.c:path_lookup().
997 */ 1162 */
998void __audit_inode(const char *name, const struct inode *inode, unsigned flags) 1163void __audit_inode(const char *name, const struct inode *inode)
999{ 1164{
1000 int idx; 1165 int idx;
1001 struct audit_context *context = current->audit_context; 1166 struct audit_context *context = current->audit_context;
@@ -1021,20 +1186,13 @@ void __audit_inode(const char *name, const struct inode *inode, unsigned flags)
1021 ++context->ino_count; 1186 ++context->ino_count;
1022#endif 1187#endif
1023 } 1188 }
1189 context->names[idx].ino = inode->i_ino;
1024 context->names[idx].dev = inode->i_sb->s_dev; 1190 context->names[idx].dev = inode->i_sb->s_dev;
1025 context->names[idx].mode = inode->i_mode; 1191 context->names[idx].mode = inode->i_mode;
1026 context->names[idx].uid = inode->i_uid; 1192 context->names[idx].uid = inode->i_uid;
1027 context->names[idx].gid = inode->i_gid; 1193 context->names[idx].gid = inode->i_gid;
1028 context->names[idx].rdev = inode->i_rdev; 1194 context->names[idx].rdev = inode->i_rdev;
1029 audit_inode_context(idx, inode); 1195 audit_inode_context(idx, inode);
1030 if ((flags & LOOKUP_PARENT) && (strcmp(name, "/") != 0) &&
1031 (strcmp(name, ".") != 0)) {
1032 context->names[idx].ino = (unsigned long)-1;
1033 context->names[idx].pino = inode->i_ino;
1034 } else {
1035 context->names[idx].ino = inode->i_ino;
1036 context->names[idx].pino = (unsigned long)-1;
1037 }
1038} 1196}
1039 1197
1040/** 1198/**
@@ -1056,51 +1214,40 @@ void __audit_inode_child(const char *dname, const struct inode *inode,
1056{ 1214{
1057 int idx; 1215 int idx;
1058 struct audit_context *context = current->audit_context; 1216 struct audit_context *context = current->audit_context;
1217 const char *found_name = NULL;
1218 int dirlen = 0;
1059 1219
1060 if (!context->in_syscall) 1220 if (!context->in_syscall)
1061 return; 1221 return;
1062 1222
1063 /* determine matching parent */ 1223 /* determine matching parent */
1064 if (dname) 1224 if (!dname)
1065 for (idx = 0; idx < context->name_count; idx++) 1225 goto update_context;
1066 if (context->names[idx].pino == pino) { 1226 for (idx = 0; idx < context->name_count; idx++)
1067 const char *n; 1227 if (context->names[idx].ino == pino) {
1068 const char *name = context->names[idx].name; 1228 const char *name = context->names[idx].name;
1069 int dlen = strlen(dname); 1229
1070 int nlen = name ? strlen(name) : 0; 1230 if (!name)
1071 1231 continue;
1072 if (nlen < dlen) 1232
1073 continue; 1233 if (audit_compare_dname_path(dname, name, &dirlen) == 0) {
1074 1234 context->names[idx].name_len = dirlen;
1075 /* disregard trailing slashes */ 1235 found_name = name;
1076 n = name + nlen - 1; 1236 break;
1077 while ((*n == '/') && (n > name))
1078 n--;
1079
1080 /* find last path component */
1081 n = n - dlen + 1;
1082 if (n < name)
1083 continue;
1084 else if (n > name) {
1085 if (*--n != '/')
1086 continue;
1087 else
1088 n++;
1089 }
1090
1091 if (strncmp(n, dname, dlen) == 0)
1092 goto update_context;
1093 } 1237 }
1238 }
1094 1239
1095 /* catch-all in case match not found */ 1240update_context:
1096 idx = context->name_count++; 1241 idx = context->name_count++;
1097 context->names[idx].name = NULL;
1098 context->names[idx].pino = pino;
1099#if AUDIT_DEBUG 1242#if AUDIT_DEBUG
1100 context->ino_count++; 1243 context->ino_count++;
1101#endif 1244#endif
1245 /* Re-use the name belonging to the slot for a matching parent directory.
1246 * All names for this context are relinquished in audit_free_names() */
1247 context->names[idx].name = found_name;
1248 context->names[idx].name_len = AUDIT_NAME_FULL;
1249 context->names[idx].name_put = 0; /* don't call __putname() */
1102 1250
1103update_context:
1104 if (inode) { 1251 if (inode) {
1105 context->names[idx].ino = inode->i_ino; 1252 context->names[idx].ino = inode->i_ino;
1106 context->names[idx].dev = inode->i_sb->s_dev; 1253 context->names[idx].dev = inode->i_sb->s_dev;
@@ -1109,7 +1256,8 @@ update_context:
1109 context->names[idx].gid = inode->i_gid; 1256 context->names[idx].gid = inode->i_gid;
1110 context->names[idx].rdev = inode->i_rdev; 1257 context->names[idx].rdev = inode->i_rdev;
1111 audit_inode_context(idx, inode); 1258 audit_inode_context(idx, inode);
1112 } 1259 } else
1260 context->names[idx].ino = (unsigned long)-1;
1113} 1261}
1114 1262
1115/** 1263/**
@@ -1142,18 +1290,23 @@ void auditsc_get_stamp(struct audit_context *ctx,
1142 */ 1290 */
1143int audit_set_loginuid(struct task_struct *task, uid_t loginuid) 1291int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1144{ 1292{
1145 if (task->audit_context) { 1293 struct audit_context *context = task->audit_context;
1146 struct audit_buffer *ab; 1294
1147 1295 if (context) {
1148 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); 1296 /* Only log if audit is enabled */
1149 if (ab) { 1297 if (context->in_syscall) {
1150 audit_log_format(ab, "login pid=%d uid=%u " 1298 struct audit_buffer *ab;
1151 "old auid=%u new auid=%u", 1299
1152 task->pid, task->uid, 1300 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
1153 task->audit_context->loginuid, loginuid); 1301 if (ab) {
1154 audit_log_end(ab); 1302 audit_log_format(ab, "login pid=%d uid=%u "
1303 "old auid=%u new auid=%u",
1304 task->pid, task->uid,
1305 context->loginuid, loginuid);
1306 audit_log_end(ab);
1307 }
1155 } 1308 }
1156 task->audit_context->loginuid = loginuid; 1309 context->loginuid = loginuid;
1157 } 1310 }
1158 return 0; 1311 return 0;
1159} 1312}
@@ -1170,16 +1323,193 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
1170} 1323}
1171 1324
1172/** 1325/**
1173 * audit_ipc_obj - record audit data for ipc object 1326 * __audit_mq_open - record audit data for a POSIX MQ open
1174 * @ipcp: ipc permissions 1327 * @oflag: open flag
1328 * @mode: mode bits
1329 * @u_attr: queue attributes
1175 * 1330 *
1176 * Returns 0 for success or NULL context or < 0 on error. 1331 * Returns 0 for success or NULL context or < 0 on error.
1177 */ 1332 */
1178int audit_ipc_obj(struct kern_ipc_perm *ipcp) 1333int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
1179{ 1334{
1180 struct audit_aux_data_ipcctl *ax; 1335 struct audit_aux_data_mq_open *ax;
1336 struct audit_context *context = current->audit_context;
1337
1338 if (!audit_enabled)
1339 return 0;
1340
1341 if (likely(!context))
1342 return 0;
1343
1344 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1345 if (!ax)
1346 return -ENOMEM;
1347
1348 if (u_attr != NULL) {
1349 if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
1350 kfree(ax);
1351 return -EFAULT;
1352 }
1353 } else
1354 memset(&ax->attr, 0, sizeof(ax->attr));
1355
1356 ax->oflag = oflag;
1357 ax->mode = mode;
1358
1359 ax->d.type = AUDIT_MQ_OPEN;
1360 ax->d.next = context->aux;
1361 context->aux = (void *)ax;
1362 return 0;
1363}
1364
1365/**
1366 * __audit_mq_timedsend - record audit data for a POSIX MQ timed send
1367 * @mqdes: MQ descriptor
1368 * @msg_len: Message length
1369 * @msg_prio: Message priority
1370 * @abs_timeout: Message timeout in absolute time
1371 *
1372 * Returns 0 for success or NULL context or < 0 on error.
1373 */
1374int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
1375 const struct timespec __user *u_abs_timeout)
1376{
1377 struct audit_aux_data_mq_sendrecv *ax;
1378 struct audit_context *context = current->audit_context;
1379
1380 if (!audit_enabled)
1381 return 0;
1382
1383 if (likely(!context))
1384 return 0;
1385
1386 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1387 if (!ax)
1388 return -ENOMEM;
1389
1390 if (u_abs_timeout != NULL) {
1391 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
1392 kfree(ax);
1393 return -EFAULT;
1394 }
1395 } else
1396 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
1397
1398 ax->mqdes = mqdes;
1399 ax->msg_len = msg_len;
1400 ax->msg_prio = msg_prio;
1401
1402 ax->d.type = AUDIT_MQ_SENDRECV;
1403 ax->d.next = context->aux;
1404 context->aux = (void *)ax;
1405 return 0;
1406}
1407
1408/**
1409 * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
1410 * @mqdes: MQ descriptor
1411 * @msg_len: Message length
1412 * @msg_prio: Message priority
1413 * @abs_timeout: Message timeout in absolute time
1414 *
1415 * Returns 0 for success or NULL context or < 0 on error.
1416 */
1417int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len,
1418 unsigned int __user *u_msg_prio,
1419 const struct timespec __user *u_abs_timeout)
1420{
1421 struct audit_aux_data_mq_sendrecv *ax;
1422 struct audit_context *context = current->audit_context;
1423
1424 if (!audit_enabled)
1425 return 0;
1426
1427 if (likely(!context))
1428 return 0;
1429
1430 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1431 if (!ax)
1432 return -ENOMEM;
1433
1434 if (u_msg_prio != NULL) {
1435 if (get_user(ax->msg_prio, u_msg_prio)) {
1436 kfree(ax);
1437 return -EFAULT;
1438 }
1439 } else
1440 ax->msg_prio = 0;
1441
1442 if (u_abs_timeout != NULL) {
1443 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
1444 kfree(ax);
1445 return -EFAULT;
1446 }
1447 } else
1448 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
1449
1450 ax->mqdes = mqdes;
1451 ax->msg_len = msg_len;
1452
1453 ax->d.type = AUDIT_MQ_SENDRECV;
1454 ax->d.next = context->aux;
1455 context->aux = (void *)ax;
1456 return 0;
1457}
1458
1459/**
1460 * __audit_mq_notify - record audit data for a POSIX MQ notify
1461 * @mqdes: MQ descriptor
1462 * @u_notification: Notification event
1463 *
1464 * Returns 0 for success or NULL context or < 0 on error.
1465 */
1466
1467int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
1468{
1469 struct audit_aux_data_mq_notify *ax;
1470 struct audit_context *context = current->audit_context;
1471
1472 if (!audit_enabled)
1473 return 0;
1474
1475 if (likely(!context))
1476 return 0;
1477
1478 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1479 if (!ax)
1480 return -ENOMEM;
1481
1482 if (u_notification != NULL) {
1483 if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) {
1484 kfree(ax);
1485 return -EFAULT;
1486 }
1487 } else
1488 memset(&ax->notification, 0, sizeof(ax->notification));
1489
1490 ax->mqdes = mqdes;
1491
1492 ax->d.type = AUDIT_MQ_NOTIFY;
1493 ax->d.next = context->aux;
1494 context->aux = (void *)ax;
1495 return 0;
1496}
1497
1498/**
1499 * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
1500 * @mqdes: MQ descriptor
1501 * @mqstat: MQ flags
1502 *
1503 * Returns 0 for success or NULL context or < 0 on error.
1504 */
1505int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
1506{
1507 struct audit_aux_data_mq_getsetattr *ax;
1181 struct audit_context *context = current->audit_context; 1508 struct audit_context *context = current->audit_context;
1182 1509
1510 if (!audit_enabled)
1511 return 0;
1512
1183 if (likely(!context)) 1513 if (likely(!context))
1184 return 0; 1514 return 0;
1185 1515
@@ -1187,6 +1517,30 @@ int audit_ipc_obj(struct kern_ipc_perm *ipcp)
1187 if (!ax) 1517 if (!ax)
1188 return -ENOMEM; 1518 return -ENOMEM;
1189 1519
1520 ax->mqdes = mqdes;
1521 ax->mqstat = *mqstat;
1522
1523 ax->d.type = AUDIT_MQ_GETSETATTR;
1524 ax->d.next = context->aux;
1525 context->aux = (void *)ax;
1526 return 0;
1527}
1528
1529/**
1530 * audit_ipc_obj - record audit data for ipc object
1531 * @ipcp: ipc permissions
1532 *
1533 * Returns 0 for success or NULL context or < 0 on error.
1534 */
1535int __audit_ipc_obj(struct kern_ipc_perm *ipcp)
1536{
1537 struct audit_aux_data_ipcctl *ax;
1538 struct audit_context *context = current->audit_context;
1539
1540 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1541 if (!ax)
1542 return -ENOMEM;
1543
1190 ax->uid = ipcp->uid; 1544 ax->uid = ipcp->uid;
1191 ax->gid = ipcp->gid; 1545 ax->gid = ipcp->gid;
1192 ax->mode = ipcp->mode; 1546 ax->mode = ipcp->mode;
@@ -1207,14 +1561,11 @@ int audit_ipc_obj(struct kern_ipc_perm *ipcp)
1207 * 1561 *
1208 * Returns 0 for success or NULL context or < 0 on error. 1562 * Returns 0 for success or NULL context or < 0 on error.
1209 */ 1563 */
1210int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) 1564int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
1211{ 1565{
1212 struct audit_aux_data_ipcctl *ax; 1566 struct audit_aux_data_ipcctl *ax;
1213 struct audit_context *context = current->audit_context; 1567 struct audit_context *context = current->audit_context;
1214 1568
1215 if (likely(!context))
1216 return 0;
1217
1218 ax = kmalloc(sizeof(*ax), GFP_ATOMIC); 1569 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1219 if (!ax) 1570 if (!ax)
1220 return -ENOMEM; 1571 return -ENOMEM;
@@ -1223,7 +1574,6 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
1223 ax->uid = uid; 1574 ax->uid = uid;
1224 ax->gid = gid; 1575 ax->gid = gid;
1225 ax->mode = mode; 1576 ax->mode = mode;
1226 selinux_get_ipc_sid(ipcp, &ax->osid);
1227 1577
1228 ax->d.type = AUDIT_IPC_SET_PERM; 1578 ax->d.type = AUDIT_IPC_SET_PERM;
1229 ax->d.next = context->aux; 1579 ax->d.next = context->aux;
@@ -1231,6 +1581,39 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
1231 return 0; 1581 return 0;
1232} 1582}
1233 1583
1584int audit_bprm(struct linux_binprm *bprm)
1585{
1586 struct audit_aux_data_execve *ax;
1587 struct audit_context *context = current->audit_context;
1588 unsigned long p, next;
1589 void *to;
1590
1591 if (likely(!audit_enabled || !context))
1592 return 0;
1593
1594 ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p,
1595 GFP_KERNEL);
1596 if (!ax)
1597 return -ENOMEM;
1598
1599 ax->argc = bprm->argc;
1600 ax->envc = bprm->envc;
1601 for (p = bprm->p, to = ax->mem; p < MAX_ARG_PAGES*PAGE_SIZE; p = next) {
1602 struct page *page = bprm->page[p / PAGE_SIZE];
1603 void *kaddr = kmap(page);
1604 next = (p + PAGE_SIZE) & ~(PAGE_SIZE - 1);
1605 memcpy(to, kaddr + (p & (PAGE_SIZE - 1)), next - p);
1606 to += next - p;
1607 kunmap(page);
1608 }
1609
1610 ax->d.type = AUDIT_EXECVE;
1611 ax->d.next = context->aux;
1612 context->aux = (void *)ax;
1613 return 0;
1614}
1615
1616
1234/** 1617/**
1235 * audit_socketcall - record audit data for sys_socketcall 1618 * audit_socketcall - record audit data for sys_socketcall
1236 * @nargs: number of args 1619 * @nargs: number of args
@@ -1325,19 +1708,20 @@ int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
1325 * If the audit subsystem is being terminated, record the task (pid) 1708 * If the audit subsystem is being terminated, record the task (pid)
1326 * and uid that is doing that. 1709 * and uid that is doing that.
1327 */ 1710 */
1328void audit_signal_info(int sig, struct task_struct *t) 1711void __audit_signal_info(int sig, struct task_struct *t)
1329{ 1712{
1330 extern pid_t audit_sig_pid; 1713 extern pid_t audit_sig_pid;
1331 extern uid_t audit_sig_uid; 1714 extern uid_t audit_sig_uid;
1332 1715 extern u32 audit_sig_sid;
1333 if (unlikely(audit_pid && t->tgid == audit_pid)) { 1716
1334 if (sig == SIGTERM || sig == SIGHUP) { 1717 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
1335 struct audit_context *ctx = current->audit_context; 1718 struct task_struct *tsk = current;
1336 audit_sig_pid = current->pid; 1719 struct audit_context *ctx = tsk->audit_context;
1337 if (ctx) 1720 audit_sig_pid = tsk->pid;
1338 audit_sig_uid = ctx->loginuid; 1721 if (ctx)
1339 else 1722 audit_sig_uid = ctx->loginuid;
1340 audit_sig_uid = current->uid; 1723 else
1341 } 1724 audit_sig_uid = tsk->uid;
1725 selinux_get_task_sid(tsk, &audit_sig_sid);
1342 } 1726 }
1343} 1727}
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 01fa2ae98a85..18324305724a 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -393,7 +393,7 @@ static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
393 if (base->first == &timer->node) 393 if (base->first == &timer->node)
394 base->first = rb_next(&timer->node); 394 base->first = rb_next(&timer->node);
395 rb_erase(&timer->node, &base->active); 395 rb_erase(&timer->node, &base->active);
396 timer->node.rb_parent = HRTIMER_INACTIVE; 396 rb_set_parent(&timer->node, &timer->node);
397} 397}
398 398
399/* 399/*
@@ -582,7 +582,7 @@ void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
582 clock_id = CLOCK_MONOTONIC; 582 clock_id = CLOCK_MONOTONIC;
583 583
584 timer->base = &bases[clock_id]; 584 timer->base = &bases[clock_id];
585 timer->node.rb_parent = HRTIMER_INACTIVE; 585 rb_set_parent(&timer->node, &timer->node);
586} 586}
587EXPORT_SYMBOL_GPL(hrtimer_init); 587EXPORT_SYMBOL_GPL(hrtimer_init);
588 588
diff --git a/kernel/intermodule.c b/kernel/intermodule.c
deleted file mode 100644
index 55b1e5b85db9..000000000000
--- a/kernel/intermodule.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/* Deprecated, do not use. Moved from module.c to here. --RR */
2
3/* Written by Keith Owens <kaos@ocs.com.au> Oct 2000 */
4#include <linux/module.h>
5#include <linux/kmod.h>
6#include <linux/spinlock.h>
7#include <linux/list.h>
8#include <linux/slab.h>
9
10/* inter_module functions are always available, even when the kernel is
11 * compiled without modules. Consumers of inter_module_xxx routines
12 * will always work, even when both are built into the kernel, this
13 * approach removes lots of #ifdefs in mainline code.
14 */
15
16static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
17static DEFINE_SPINLOCK(ime_lock);
18static int kmalloc_failed;
19
20struct inter_module_entry {
21 struct list_head list;
22 const char *im_name;
23 struct module *owner;
24 const void *userdata;
25};
26
27/**
28 * inter_module_register - register a new set of inter module data.
29 * @im_name: an arbitrary string to identify the data, must be unique
30 * @owner: module that is registering the data, always use THIS_MODULE
31 * @userdata: pointer to arbitrary userdata to be registered
32 *
33 * Description: Check that the im_name has not already been registered,
34 * complain if it has. For new data, add it to the inter_module_entry
35 * list.
36 */
37void inter_module_register(const char *im_name, struct module *owner, const void *userdata)
38{
39 struct list_head *tmp;
40 struct inter_module_entry *ime, *ime_new;
41
42 if (!(ime_new = kzalloc(sizeof(*ime), GFP_KERNEL))) {
43 /* Overloaded kernel, not fatal */
44 printk(KERN_ERR
45 "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
46 im_name);
47 kmalloc_failed = 1;
48 return;
49 }
50 ime_new->im_name = im_name;
51 ime_new->owner = owner;
52 ime_new->userdata = userdata;
53
54 spin_lock(&ime_lock);
55 list_for_each(tmp, &ime_list) {
56 ime = list_entry(tmp, struct inter_module_entry, list);
57 if (strcmp(ime->im_name, im_name) == 0) {
58 spin_unlock(&ime_lock);
59 kfree(ime_new);
60 /* Program logic error, fatal */
61 printk(KERN_ERR "inter_module_register: duplicate im_name '%s'", im_name);
62 BUG();
63 }
64 }
65 list_add(&(ime_new->list), &ime_list);
66 spin_unlock(&ime_lock);
67}
68
69/**
70 * inter_module_unregister - unregister a set of inter module data.
71 * @im_name: an arbitrary string to identify the data, must be unique
72 *
73 * Description: Check that the im_name has been registered, complain if
74 * it has not. For existing data, remove it from the
75 * inter_module_entry list.
76 */
77void inter_module_unregister(const char *im_name)
78{
79 struct list_head *tmp;
80 struct inter_module_entry *ime;
81
82 spin_lock(&ime_lock);
83 list_for_each(tmp, &ime_list) {
84 ime = list_entry(tmp, struct inter_module_entry, list);
85 if (strcmp(ime->im_name, im_name) == 0) {
86 list_del(&(ime->list));
87 spin_unlock(&ime_lock);
88 kfree(ime);
89 return;
90 }
91 }
92 spin_unlock(&ime_lock);
93 if (kmalloc_failed) {
94 printk(KERN_ERR
95 "inter_module_unregister: no entry for '%s', "
96 "probably caused by previous kmalloc failure\n",
97 im_name);
98 return;
99 }
100 else {
101 /* Program logic error, fatal */
102 printk(KERN_ERR "inter_module_unregister: no entry for '%s'", im_name);
103 BUG();
104 }
105}
106
107/**
108 * inter_module_get - return arbitrary userdata from another module.
109 * @im_name: an arbitrary string to identify the data, must be unique
110 *
111 * Description: If the im_name has not been registered, return NULL.
112 * Try to increment the use count on the owning module, if that fails
113 * then return NULL. Otherwise return the userdata.
114 */
115static const void *inter_module_get(const char *im_name)
116{
117 struct list_head *tmp;
118 struct inter_module_entry *ime;
119 const void *result = NULL;
120
121 spin_lock(&ime_lock);
122 list_for_each(tmp, &ime_list) {
123 ime = list_entry(tmp, struct inter_module_entry, list);
124 if (strcmp(ime->im_name, im_name) == 0) {
125 if (try_module_get(ime->owner))
126 result = ime->userdata;
127 break;
128 }
129 }
130 spin_unlock(&ime_lock);
131 return(result);
132}
133
134/**
135 * inter_module_get_request - im get with automatic request_module.
136 * @im_name: an arbitrary string to identify the data, must be unique
137 * @modname: module that is expected to register im_name
138 *
139 * Description: If inter_module_get fails, do request_module then retry.
140 */
141const void *inter_module_get_request(const char *im_name, const char *modname)
142{
143 const void *result = inter_module_get(im_name);
144 if (!result) {
145 request_module("%s", modname);
146 result = inter_module_get(im_name);
147 }
148 return(result);
149}
150
151/**
152 * inter_module_put - release use of data from another module.
153 * @im_name: an arbitrary string to identify the data, must be unique
154 *
155 * Description: If the im_name has not been registered, complain,
156 * otherwise decrement the use count on the owning module.
157 */
158void inter_module_put(const char *im_name)
159{
160 struct list_head *tmp;
161 struct inter_module_entry *ime;
162
163 spin_lock(&ime_lock);
164 list_for_each(tmp, &ime_list) {
165 ime = list_entry(tmp, struct inter_module_entry, list);
166 if (strcmp(ime->im_name, im_name) == 0) {
167 if (ime->owner)
168 module_put(ime->owner);
169 spin_unlock(&ime_lock);
170 return;
171 }
172 }
173 spin_unlock(&ime_lock);
174 printk(KERN_ERR "inter_module_put: no entry for '%s'", im_name);
175 BUG();
176}
177
178EXPORT_SYMBOL(inter_module_register);
179EXPORT_SYMBOL(inter_module_unregister);
180EXPORT_SYMBOL(inter_module_get_request);
181EXPORT_SYMBOL(inter_module_put);
182
183MODULE_LICENSE("GPL");
184
diff --git a/kernel/signal.c b/kernel/signal.c
index e5f8aea78ffe..1b3c921737e2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -23,12 +23,12 @@
23#include <linux/syscalls.h> 23#include <linux/syscalls.h>
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/signal.h> 25#include <linux/signal.h>
26#include <linux/audit.h>
27#include <linux/capability.h> 26#include <linux/capability.h>
28#include <asm/param.h> 27#include <asm/param.h>
29#include <asm/uaccess.h> 28#include <asm/uaccess.h>
30#include <asm/unistd.h> 29#include <asm/unistd.h>
31#include <asm/siginfo.h> 30#include <asm/siginfo.h>
31#include "audit.h" /* audit_signal_info() */
32 32
33/* 33/*
34 * SLAB caches for signal bits. 34 * SLAB caches for signal bits.
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e82726faeeff..0d656e61621d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -150,7 +150,7 @@ extern ctl_table random_table[];
150#ifdef CONFIG_UNIX98_PTYS 150#ifdef CONFIG_UNIX98_PTYS
151extern ctl_table pty_table[]; 151extern ctl_table pty_table[];
152#endif 152#endif
153#ifdef CONFIG_INOTIFY 153#ifdef CONFIG_INOTIFY_USER
154extern ctl_table inotify_table[]; 154extern ctl_table inotify_table[];
155#endif 155#endif
156 156
@@ -1028,7 +1028,7 @@ static ctl_table fs_table[] = {
1028 .mode = 0644, 1028 .mode = 0644,
1029 .proc_handler = &proc_doulongvec_minmax, 1029 .proc_handler = &proc_doulongvec_minmax,
1030 }, 1030 },
1031#ifdef CONFIG_INOTIFY 1031#ifdef CONFIG_INOTIFY_USER
1032 { 1032 {
1033 .ctl_name = FS_INOTIFY, 1033 .ctl_name = FS_INOTIFY,
1034 .procname = "inotify", 1034 .procname = "inotify",
diff --git a/kernel/user.c b/kernel/user.c
index 2116642f42c6..4b1eb745afa1 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -140,7 +140,7 @@ struct user_struct * alloc_uid(uid_t uid)
140 atomic_set(&new->processes, 0); 140 atomic_set(&new->processes, 0);
141 atomic_set(&new->files, 0); 141 atomic_set(&new->files, 0);
142 atomic_set(&new->sigpending, 0); 142 atomic_set(&new->sigpending, 0);
143#ifdef CONFIG_INOTIFY 143#ifdef CONFIG_INOTIFY_USER
144 atomic_set(&new->inotify_watches, 0); 144 atomic_set(&new->inotify_watches, 0);
145 atomic_set(&new->inotify_devs, 0); 145 atomic_set(&new->inotify_devs, 0);
146#endif 146#endif
diff --git a/lib/rbtree.c b/lib/rbtree.c
index 14b791ac5089..1e55ba1c2edf 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -26,60 +26,66 @@
26static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) 26static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
27{ 27{
28 struct rb_node *right = node->rb_right; 28 struct rb_node *right = node->rb_right;
29 struct rb_node *parent = rb_parent(node);
29 30
30 if ((node->rb_right = right->rb_left)) 31 if ((node->rb_right = right->rb_left))
31 right->rb_left->rb_parent = node; 32 rb_set_parent(right->rb_left, node);
32 right->rb_left = node; 33 right->rb_left = node;
33 34
34 if ((right->rb_parent = node->rb_parent)) 35 rb_set_parent(right, parent);
36
37 if (parent)
35 { 38 {
36 if (node == node->rb_parent->rb_left) 39 if (node == parent->rb_left)
37 node->rb_parent->rb_left = right; 40 parent->rb_left = right;
38 else 41 else
39 node->rb_parent->rb_right = right; 42 parent->rb_right = right;
40 } 43 }
41 else 44 else
42 root->rb_node = right; 45 root->rb_node = right;
43 node->rb_parent = right; 46 rb_set_parent(node, right);
44} 47}
45 48
46static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) 49static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
47{ 50{
48 struct rb_node *left = node->rb_left; 51 struct rb_node *left = node->rb_left;
52 struct rb_node *parent = rb_parent(node);
49 53
50 if ((node->rb_left = left->rb_right)) 54 if ((node->rb_left = left->rb_right))
51 left->rb_right->rb_parent = node; 55 rb_set_parent(left->rb_right, node);
52 left->rb_right = node; 56 left->rb_right = node;
53 57
54 if ((left->rb_parent = node->rb_parent)) 58 rb_set_parent(left, parent);
59
60 if (parent)
55 { 61 {
56 if (node == node->rb_parent->rb_right) 62 if (node == parent->rb_right)
57 node->rb_parent->rb_right = left; 63 parent->rb_right = left;
58 else 64 else
59 node->rb_parent->rb_left = left; 65 parent->rb_left = left;
60 } 66 }
61 else 67 else
62 root->rb_node = left; 68 root->rb_node = left;
63 node->rb_parent = left; 69 rb_set_parent(node, left);
64} 70}
65 71
66void rb_insert_color(struct rb_node *node, struct rb_root *root) 72void rb_insert_color(struct rb_node *node, struct rb_root *root)
67{ 73{
68 struct rb_node *parent, *gparent; 74 struct rb_node *parent, *gparent;
69 75
70 while ((parent = node->rb_parent) && parent->rb_color == RB_RED) 76 while ((parent = rb_parent(node)) && rb_is_red(parent))
71 { 77 {
72 gparent = parent->rb_parent; 78 gparent = rb_parent(parent);
73 79
74 if (parent == gparent->rb_left) 80 if (parent == gparent->rb_left)
75 { 81 {
76 { 82 {
77 register struct rb_node *uncle = gparent->rb_right; 83 register struct rb_node *uncle = gparent->rb_right;
78 if (uncle && uncle->rb_color == RB_RED) 84 if (uncle && rb_is_red(uncle))
79 { 85 {
80 uncle->rb_color = RB_BLACK; 86 rb_set_black(uncle);
81 parent->rb_color = RB_BLACK; 87 rb_set_black(parent);
82 gparent->rb_color = RB_RED; 88 rb_set_red(gparent);
83 node = gparent; 89 node = gparent;
84 continue; 90 continue;
85 } 91 }
@@ -94,17 +100,17 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
94 node = tmp; 100 node = tmp;
95 } 101 }
96 102
97 parent->rb_color = RB_BLACK; 103 rb_set_black(parent);
98 gparent->rb_color = RB_RED; 104 rb_set_red(gparent);
99 __rb_rotate_right(gparent, root); 105 __rb_rotate_right(gparent, root);
100 } else { 106 } else {
101 { 107 {
102 register struct rb_node *uncle = gparent->rb_left; 108 register struct rb_node *uncle = gparent->rb_left;
103 if (uncle && uncle->rb_color == RB_RED) 109 if (uncle && rb_is_red(uncle))
104 { 110 {
105 uncle->rb_color = RB_BLACK; 111 rb_set_black(uncle);
106 parent->rb_color = RB_BLACK; 112 rb_set_black(parent);
107 gparent->rb_color = RB_RED; 113 rb_set_red(gparent);
108 node = gparent; 114 node = gparent;
109 continue; 115 continue;
110 } 116 }
@@ -119,13 +125,13 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
119 node = tmp; 125 node = tmp;
120 } 126 }
121 127
122 parent->rb_color = RB_BLACK; 128 rb_set_black(parent);
123 gparent->rb_color = RB_RED; 129 rb_set_red(gparent);
124 __rb_rotate_left(gparent, root); 130 __rb_rotate_left(gparent, root);
125 } 131 }
126 } 132 }
127 133
128 root->rb_node->rb_color = RB_BLACK; 134 rb_set_black(root->rb_node);
129} 135}
130EXPORT_SYMBOL(rb_insert_color); 136EXPORT_SYMBOL(rb_insert_color);
131 137
@@ -134,43 +140,40 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
134{ 140{
135 struct rb_node *other; 141 struct rb_node *other;
136 142
137 while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node) 143 while ((!node || rb_is_black(node)) && node != root->rb_node)
138 { 144 {
139 if (parent->rb_left == node) 145 if (parent->rb_left == node)
140 { 146 {
141 other = parent->rb_right; 147 other = parent->rb_right;
142 if (other->rb_color == RB_RED) 148 if (rb_is_red(other))
143 { 149 {
144 other->rb_color = RB_BLACK; 150 rb_set_black(other);
145 parent->rb_color = RB_RED; 151 rb_set_red(parent);
146 __rb_rotate_left(parent, root); 152 __rb_rotate_left(parent, root);
147 other = parent->rb_right; 153 other = parent->rb_right;
148 } 154 }
149 if ((!other->rb_left || 155 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
150 other->rb_left->rb_color == RB_BLACK) 156 (!other->rb_right || rb_is_black(other->rb_right)))
151 && (!other->rb_right ||
152 other->rb_right->rb_color == RB_BLACK))
153 { 157 {
154 other->rb_color = RB_RED; 158 rb_set_red(other);
155 node = parent; 159 node = parent;
156 parent = node->rb_parent; 160 parent = rb_parent(node);
157 } 161 }
158 else 162 else
159 { 163 {
160 if (!other->rb_right || 164 if (!other->rb_right || rb_is_black(other->rb_right))
161 other->rb_right->rb_color == RB_BLACK)
162 { 165 {
163 register struct rb_node *o_left; 166 struct rb_node *o_left;
164 if ((o_left = other->rb_left)) 167 if ((o_left = other->rb_left))
165 o_left->rb_color = RB_BLACK; 168 rb_set_black(o_left);
166 other->rb_color = RB_RED; 169 rb_set_red(other);
167 __rb_rotate_right(other, root); 170 __rb_rotate_right(other, root);
168 other = parent->rb_right; 171 other = parent->rb_right;
169 } 172 }
170 other->rb_color = parent->rb_color; 173 rb_set_color(other, rb_color(parent));
171 parent->rb_color = RB_BLACK; 174 rb_set_black(parent);
172 if (other->rb_right) 175 if (other->rb_right)
173 other->rb_right->rb_color = RB_BLACK; 176 rb_set_black(other->rb_right);
174 __rb_rotate_left(parent, root); 177 __rb_rotate_left(parent, root);
175 node = root->rb_node; 178 node = root->rb_node;
176 break; 179 break;
@@ -179,38 +182,35 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
179 else 182 else
180 { 183 {
181 other = parent->rb_left; 184 other = parent->rb_left;
182 if (other->rb_color == RB_RED) 185 if (rb_is_red(other))
183 { 186 {
184 other->rb_color = RB_BLACK; 187 rb_set_black(other);
185 parent->rb_color = RB_RED; 188 rb_set_red(parent);
186 __rb_rotate_right(parent, root); 189 __rb_rotate_right(parent, root);
187 other = parent->rb_left; 190 other = parent->rb_left;
188 } 191 }
189 if ((!other->rb_left || 192 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
190 other->rb_left->rb_color == RB_BLACK) 193 (!other->rb_right || rb_is_black(other->rb_right)))
191 && (!other->rb_right ||
192 other->rb_right->rb_color == RB_BLACK))
193 { 194 {
194 other->rb_color = RB_RED; 195 rb_set_red(other);
195 node = parent; 196 node = parent;
196 parent = node->rb_parent; 197 parent = rb_parent(node);
197 } 198 }
198 else 199 else
199 { 200 {
200 if (!other->rb_left || 201 if (!other->rb_left || rb_is_black(other->rb_left))
201 other->rb_left->rb_color == RB_BLACK)
202 { 202 {
203 register struct rb_node *o_right; 203 register struct rb_node *o_right;
204 if ((o_right = other->rb_right)) 204 if ((o_right = other->rb_right))
205 o_right->rb_color = RB_BLACK; 205 rb_set_black(o_right);
206 other->rb_color = RB_RED; 206 rb_set_red(other);
207 __rb_rotate_left(other, root); 207 __rb_rotate_left(other, root);
208 other = parent->rb_left; 208 other = parent->rb_left;
209 } 209 }
210 other->rb_color = parent->rb_color; 210 rb_set_color(other, rb_color(parent));
211 parent->rb_color = RB_BLACK; 211 rb_set_black(parent);
212 if (other->rb_left) 212 if (other->rb_left)
213 other->rb_left->rb_color = RB_BLACK; 213 rb_set_black(other->rb_left);
214 __rb_rotate_right(parent, root); 214 __rb_rotate_right(parent, root);
215 node = root->rb_node; 215 node = root->rb_node;
216 break; 216 break;
@@ -218,7 +218,7 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
218 } 218 }
219 } 219 }
220 if (node) 220 if (node)
221 node->rb_color = RB_BLACK; 221 rb_set_black(node);
222} 222}
223 223
224void rb_erase(struct rb_node *node, struct rb_root *root) 224void rb_erase(struct rb_node *node, struct rb_root *root)
@@ -238,48 +238,41 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
238 while ((left = node->rb_left) != NULL) 238 while ((left = node->rb_left) != NULL)
239 node = left; 239 node = left;
240 child = node->rb_right; 240 child = node->rb_right;
241 parent = node->rb_parent; 241 parent = rb_parent(node);
242 color = node->rb_color; 242 color = rb_color(node);
243 243
244 if (child) 244 if (child)
245 child->rb_parent = parent; 245 rb_set_parent(child, parent);
246 if (parent) 246 if (parent == old) {
247 { 247 parent->rb_right = child;
248 if (parent->rb_left == node)
249 parent->rb_left = child;
250 else
251 parent->rb_right = child;
252 }
253 else
254 root->rb_node = child;
255
256 if (node->rb_parent == old)
257 parent = node; 248 parent = node;
258 node->rb_parent = old->rb_parent; 249 } else
259 node->rb_color = old->rb_color; 250 parent->rb_left = child;
251
252 node->rb_parent_color = old->rb_parent_color;
260 node->rb_right = old->rb_right; 253 node->rb_right = old->rb_right;
261 node->rb_left = old->rb_left; 254 node->rb_left = old->rb_left;
262 255
263 if (old->rb_parent) 256 if (rb_parent(old))
264 { 257 {
265 if (old->rb_parent->rb_left == old) 258 if (rb_parent(old)->rb_left == old)
266 old->rb_parent->rb_left = node; 259 rb_parent(old)->rb_left = node;
267 else 260 else
268 old->rb_parent->rb_right = node; 261 rb_parent(old)->rb_right = node;
269 } else 262 } else
270 root->rb_node = node; 263 root->rb_node = node;
271 264
272 old->rb_left->rb_parent = node; 265 rb_set_parent(old->rb_left, node);
273 if (old->rb_right) 266 if (old->rb_right)
274 old->rb_right->rb_parent = node; 267 rb_set_parent(old->rb_right, node);
275 goto color; 268 goto color;
276 } 269 }
277 270
278 parent = node->rb_parent; 271 parent = rb_parent(node);
279 color = node->rb_color; 272 color = rb_color(node);
280 273
281 if (child) 274 if (child)
282 child->rb_parent = parent; 275 rb_set_parent(child, parent);
283 if (parent) 276 if (parent)
284 { 277 {
285 if (parent->rb_left == node) 278 if (parent->rb_left == node)
@@ -327,6 +320,8 @@ EXPORT_SYMBOL(rb_last);
327 320
328struct rb_node *rb_next(struct rb_node *node) 321struct rb_node *rb_next(struct rb_node *node)
329{ 322{
323 struct rb_node *parent;
324
330 /* If we have a right-hand child, go down and then left as far 325 /* If we have a right-hand child, go down and then left as far
331 as we can. */ 326 as we can. */
332 if (node->rb_right) { 327 if (node->rb_right) {
@@ -342,15 +337,17 @@ struct rb_node *rb_next(struct rb_node *node)
342 ancestor is a right-hand child of its parent, keep going 337 ancestor is a right-hand child of its parent, keep going
343 up. First time it's a left-hand child of its parent, said 338 up. First time it's a left-hand child of its parent, said
344 parent is our 'next' node. */ 339 parent is our 'next' node. */
345 while (node->rb_parent && node == node->rb_parent->rb_right) 340 while ((parent = rb_parent(node)) && node == parent->rb_right)
346 node = node->rb_parent; 341 node = parent;
347 342
348 return node->rb_parent; 343 return parent;
349} 344}
350EXPORT_SYMBOL(rb_next); 345EXPORT_SYMBOL(rb_next);
351 346
352struct rb_node *rb_prev(struct rb_node *node) 347struct rb_node *rb_prev(struct rb_node *node)
353{ 348{
349 struct rb_node *parent;
350
354 /* If we have a left-hand child, go down and then right as far 351 /* If we have a left-hand child, go down and then right as far
355 as we can. */ 352 as we can. */
356 if (node->rb_left) { 353 if (node->rb_left) {
@@ -362,17 +359,17 @@ struct rb_node *rb_prev(struct rb_node *node)
362 359
363 /* No left-hand children. Go up till we find an ancestor which 360 /* No left-hand children. Go up till we find an ancestor which
364 is a right-hand child of its parent */ 361 is a right-hand child of its parent */
365 while (node->rb_parent && node == node->rb_parent->rb_left) 362 while ((parent = rb_parent(node)) && node == parent->rb_left)
366 node = node->rb_parent; 363 node = parent;
367 364
368 return node->rb_parent; 365 return parent;
369} 366}
370EXPORT_SYMBOL(rb_prev); 367EXPORT_SYMBOL(rb_prev);
371 368
372void rb_replace_node(struct rb_node *victim, struct rb_node *new, 369void rb_replace_node(struct rb_node *victim, struct rb_node *new,
373 struct rb_root *root) 370 struct rb_root *root)
374{ 371{
375 struct rb_node *parent = victim->rb_parent; 372 struct rb_node *parent = rb_parent(victim);
376 373
377 /* Set the surrounding nodes to point to the replacement */ 374 /* Set the surrounding nodes to point to the replacement */
378 if (parent) { 375 if (parent) {
@@ -384,9 +381,9 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new,
384 root->rb_node = new; 381 root->rb_node = new;
385 } 382 }
386 if (victim->rb_left) 383 if (victim->rb_left)
387 victim->rb_left->rb_parent = new; 384 rb_set_parent(victim->rb_left, new);
388 if (victim->rb_right) 385 if (victim->rb_right)
389 victim->rb_right->rb_parent = new; 386 rb_set_parent(victim->rb_right, new);
390 387
391 /* Copy the pointers/colour from the victim to the replacement */ 388 /* Copy the pointers/colour from the victim to the replacement */
392 *new = *victim; 389 *new = *victim;
diff --git a/security/keys/key.c b/security/keys/key.c
index b6061fa29da7..3fdc49c6a02c 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -211,12 +211,12 @@ static inline void key_alloc_serial(struct key *key)
211 key->serial = 2; 211 key->serial = 2;
212 key_serial_next = key->serial + 1; 212 key_serial_next = key->serial + 1;
213 213
214 if (!parent->rb_parent) 214 if (!rb_parent(parent))
215 p = &key_serial_tree.rb_node; 215 p = &key_serial_tree.rb_node;
216 else if (parent->rb_parent->rb_left == parent) 216 else if (rb_parent(parent)->rb_left == parent)
217 p = &parent->rb_parent->rb_left; 217 p = &(rb_parent(parent)->rb_left);
218 else 218 else
219 p = &parent->rb_parent->rb_right; 219 p = &(rb_parent(parent)->rb_right);
220 220
221 parent = rb_next(parent); 221 parent = rb_next(parent);
222 if (!parent) 222 if (!parent)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index c284dbb8b8c0..e9548bc049e1 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1980,7 +1980,7 @@ int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
1980 break; 1980 break;
1981 case AUDIT_SE_SEN: 1981 case AUDIT_SE_SEN:
1982 case AUDIT_SE_CLR: 1982 case AUDIT_SE_CLR:
1983 level = (op == AUDIT_SE_SEN ? 1983 level = (field == AUDIT_SE_SEN ?
1984 &ctxt->range.level[0] : &ctxt->range.level[1]); 1984 &ctxt->range.level[0] : &ctxt->range.level[1]);
1985 switch (op) { 1985 switch (op) {
1986 case AUDIT_EQUAL: 1986 case AUDIT_EQUAL: