Merge tags 'disintegrate-h8300-20121219', 'disintegrate-m32r-20121219' and 'disintegr...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Dec 2012 15:27:44 +0000 (07:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Dec 2012 15:27:44 +0000 (07:27 -0800)
Pull UAPI disintegration for H8/300, M32R and Score from David Howells.

Scripted UAPI patches for architectures that apparently never reacted to
it on their own.

* tag 'disintegrate-h8300-20121219' of git://git.infradead.org/users/dhowells/linux-headers:
  UAPI: (Scripted) Disintegrate arch/h8300/include/asm

* tag 'disintegrate-m32r-20121219' of git://git.infradead.org/users/dhowells/linux-headers:
  UAPI: (Scripted) Disintegrate arch/m32r/include/asm

* tag 'disintegrate-score-20121220' of git://git.infradead.org/users/dhowells/linux-headers:
  UAPI: (Scripted) Disintegrate arch/score/include/asm

533 files changed:
Documentation/ABI/testing/ima_policy
Documentation/devicetree/bindings/arm/davinci/nand.txt
Documentation/devicetree/bindings/mtd/denali-nand.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/flctl-nand.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/fsmc-nand.txt
Documentation/devicetree/bindings/mtd/m25p80.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/mtd-physmap.txt
Documentation/devicetree/bindings/pwm/pwm-tiecap.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm.txt
Documentation/devicetree/bindings/pwm/spear-pwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/vt8500-pwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt
Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt
Documentation/devicetree/bindings/spi/spi_atmel.txt [new file with mode: 0644]
Documentation/hwmon/it87
Documentation/x86/boot.txt
Documentation/xtensa/atomctl.txt [new file with mode: 0644]
Makefile
arch/Kconfig
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/imx27-3ds.dts
arch/arm/boot/dts/imx27-phytec-phycore.dts
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/omap2420-h4.dts
arch/arm/boot/dts/spear13xx.dtsi
arch/arm/boot/dts/spear300.dtsi
arch/arm/boot/dts/spear310.dtsi
arch/arm/boot/dts/spear320.dtsi
arch/arm/boot/dts/spear600.dtsi
arch/arm/boot/dts/sun4i-cubieboard.dts
arch/arm/boot/dts/sun5i-olinuxino.dts
arch/arm/configs/nhk8815_defconfig
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-ep93xx/include/mach/uncompress.h
arch/arm/mach-exynos/common.h
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/devices/platform-mx2-emma.c [moved from arch/arm/plat-mxc/devices/platform-mx2-emma.c with 94% similarity]
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/include/mach/fsmc.h [deleted file]
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/cclock44xx_data.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/common.c
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-omap2/dpll3xxx.c
arch/arm/mach-omap2/dpll44xx.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/mux.h
arch/arm/mach-omap2/mux34xx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/usb-host.c
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/tegra30_clocks.c
arch/arm/mach-u300/core.c
arch/arm/mach-ux500/devices-db8500.h
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/debug-devices.c [deleted file]
arch/arm/plat-omap/include/plat/debug-devices.h [deleted file]
arch/cris/include/arch-v10/arch/Kbuild
arch/cris/include/arch-v32/arch/Kbuild
arch/cris/include/arch-v32/arch/cryptocop.h
arch/cris/include/arch-v32/arch/spinlock.h
arch/cris/include/asm/Kbuild
arch/cris/include/asm/ptrace.h
arch/cris/include/asm/signal.h
arch/cris/include/asm/swab.h
arch/cris/include/asm/termios.h
arch/cris/include/asm/types.h
arch/cris/include/asm/unistd.h
arch/cris/include/uapi/arch-v10/arch/Kbuild
arch/cris/include/uapi/arch-v10/arch/sv_addr.agh [moved from arch/cris/include/arch-v10/arch/sv_addr.agh with 100% similarity]
arch/cris/include/uapi/arch-v10/arch/sv_addr_ag.h [moved from arch/cris/include/arch-v10/arch/sv_addr_ag.h with 100% similarity]
arch/cris/include/uapi/arch-v10/arch/svinto.h [moved from arch/cris/include/arch-v10/arch/svinto.h with 100% similarity]
arch/cris/include/uapi/arch-v10/arch/user.h [moved from arch/cris/include/arch-v10/arch/user.h with 100% similarity]
arch/cris/include/uapi/arch-v32/arch/Kbuild
arch/cris/include/uapi/arch-v32/arch/cryptocop.h [new file with mode: 0644]
arch/cris/include/uapi/arch-v32/arch/user.h [moved from arch/cris/include/arch-v32/arch/user.h with 100% similarity]
arch/cris/include/uapi/asm/Kbuild
arch/cris/include/uapi/asm/auxvec.h [moved from arch/cris/include/asm/auxvec.h with 100% similarity]
arch/cris/include/uapi/asm/bitsperlong.h [moved from arch/m32r/include/asm/bitsperlong.h with 100% similarity]
arch/cris/include/uapi/asm/byteorder.h [moved from arch/cris/include/asm/byteorder.h with 100% similarity]
arch/cris/include/uapi/asm/errno.h [moved from arch/cris/include/asm/errno.h with 100% similarity]
arch/cris/include/uapi/asm/ethernet.h [moved from arch/cris/include/asm/ethernet.h with 100% similarity]
arch/cris/include/uapi/asm/etraxgpio.h [moved from arch/cris/include/asm/etraxgpio.h with 100% similarity]
arch/cris/include/uapi/asm/fcntl.h [moved from arch/m32r/include/asm/fcntl.h with 100% similarity]
arch/cris/include/uapi/asm/ioctl.h [moved from arch/m32r/include/asm/ioctl.h with 100% similarity]
arch/cris/include/uapi/asm/ioctls.h [moved from arch/cris/include/asm/ioctls.h with 100% similarity]
arch/cris/include/uapi/asm/ipcbuf.h [moved from arch/m32r/include/asm/ipcbuf.h with 100% similarity]
arch/cris/include/uapi/asm/mman.h [moved from arch/m32r/include/asm/mman.h with 100% similarity]
arch/cris/include/uapi/asm/msgbuf.h [moved from arch/cris/include/asm/msgbuf.h with 100% similarity]
arch/cris/include/uapi/asm/param.h [moved from arch/cris/include/asm/param.h with 100% similarity]
arch/cris/include/uapi/asm/poll.h [moved from arch/m32r/include/asm/poll.h with 100% similarity]
arch/cris/include/uapi/asm/posix_types.h [moved from arch/cris/include/asm/posix_types.h with 100% similarity]
arch/cris/include/uapi/asm/ptrace.h [new file with mode: 0644]
arch/cris/include/uapi/asm/resource.h [moved from arch/cris/include/asm/resource.h with 100% similarity]
arch/cris/include/uapi/asm/rs485.h [moved from arch/cris/include/asm/rs485.h with 100% similarity]
arch/cris/include/uapi/asm/sembuf.h [moved from arch/cris/include/asm/sembuf.h with 100% similarity]
arch/cris/include/uapi/asm/setup.h [moved from arch/cris/include/asm/setup.h with 100% similarity]
arch/cris/include/uapi/asm/shmbuf.h [moved from arch/cris/include/asm/shmbuf.h with 100% similarity]
arch/cris/include/uapi/asm/sigcontext.h [moved from arch/cris/include/asm/sigcontext.h with 100% similarity]
arch/cris/include/uapi/asm/siginfo.h [moved from arch/cris/include/asm/siginfo.h with 100% similarity]
arch/cris/include/uapi/asm/signal.h [new file with mode: 0644]
arch/cris/include/uapi/asm/socket.h [moved from arch/cris/include/asm/socket.h with 100% similarity]
arch/cris/include/uapi/asm/sockios.h [moved from arch/cris/include/asm/sockios.h with 100% similarity]
arch/cris/include/uapi/asm/stat.h [moved from arch/cris/include/asm/stat.h with 100% similarity]
arch/cris/include/uapi/asm/statfs.h [moved from arch/cris/include/asm/statfs.h with 100% similarity]
arch/cris/include/uapi/asm/swab.h [new file with mode: 0644]
arch/cris/include/uapi/asm/sync_serial.h [moved from arch/cris/include/asm/sync_serial.h with 100% similarity]
arch/cris/include/uapi/asm/termbits.h [moved from arch/cris/include/asm/termbits.h with 100% similarity]
arch/cris/include/uapi/asm/termios.h [new file with mode: 0644]
arch/cris/include/uapi/asm/types.h [new file with mode: 0644]
arch/cris/include/uapi/asm/unistd.h [new file with mode: 0644]
arch/cris/kernel/asm-offsets.c
arch/cris/kernel/module.c
arch/m32r/include/asm/Kbuild
arch/m32r/include/asm/ptrace.h
arch/m32r/include/asm/setup.h
arch/m32r/include/asm/signal.h
arch/m32r/include/asm/termios.h
arch/m32r/include/asm/types.h
arch/m32r/include/asm/unistd.h
arch/m32r/include/uapi/asm/Kbuild
arch/m32r/include/uapi/asm/auxvec.h [moved from arch/m32r/include/asm/auxvec.h with 100% similarity]
arch/m32r/include/uapi/asm/bitsperlong.h [moved from arch/cris/include/asm/bitsperlong.h with 100% similarity]
arch/m32r/include/uapi/asm/byteorder.h [moved from arch/m32r/include/asm/byteorder.h with 100% similarity]
arch/m32r/include/uapi/asm/errno.h [moved from arch/m32r/include/asm/errno.h with 100% similarity]
arch/m32r/include/uapi/asm/fcntl.h [moved from arch/cris/include/asm/fcntl.h with 100% similarity]
arch/m32r/include/uapi/asm/ioctl.h [moved from arch/cris/include/asm/ioctl.h with 100% similarity]
arch/m32r/include/uapi/asm/ioctls.h [moved from arch/m32r/include/asm/ioctls.h with 100% similarity]
arch/m32r/include/uapi/asm/ipcbuf.h [moved from arch/cris/include/asm/ipcbuf.h with 100% similarity]
arch/m32r/include/uapi/asm/mman.h [moved from arch/cris/include/asm/mman.h with 100% similarity]
arch/m32r/include/uapi/asm/msgbuf.h [moved from arch/m32r/include/asm/msgbuf.h with 100% similarity]
arch/m32r/include/uapi/asm/param.h [moved from arch/m32r/include/asm/param.h with 100% similarity]
arch/m32r/include/uapi/asm/poll.h [moved from arch/cris/include/asm/poll.h with 100% similarity]
arch/m32r/include/uapi/asm/posix_types.h [moved from arch/m32r/include/asm/posix_types.h with 100% similarity]
arch/m32r/include/uapi/asm/ptrace.h [new file with mode: 0644]
arch/m32r/include/uapi/asm/resource.h [moved from arch/m32r/include/asm/resource.h with 100% similarity]
arch/m32r/include/uapi/asm/sembuf.h [moved from arch/m32r/include/asm/sembuf.h with 100% similarity]
arch/m32r/include/uapi/asm/setup.h [new file with mode: 0644]
arch/m32r/include/uapi/asm/shmbuf.h [moved from arch/m32r/include/asm/shmbuf.h with 100% similarity]
arch/m32r/include/uapi/asm/sigcontext.h [moved from arch/m32r/include/asm/sigcontext.h with 100% similarity]
arch/m32r/include/uapi/asm/siginfo.h [moved from arch/m32r/include/asm/siginfo.h with 100% similarity]
arch/m32r/include/uapi/asm/signal.h [new file with mode: 0644]
arch/m32r/include/uapi/asm/socket.h [moved from arch/m32r/include/asm/socket.h with 100% similarity]
arch/m32r/include/uapi/asm/sockios.h [moved from arch/m32r/include/asm/sockios.h with 100% similarity]
arch/m32r/include/uapi/asm/stat.h [moved from arch/m32r/include/asm/stat.h with 100% similarity]
arch/m32r/include/uapi/asm/statfs.h [moved from arch/m32r/include/asm/statfs.h with 100% similarity]
arch/m32r/include/uapi/asm/swab.h [moved from arch/m32r/include/asm/swab.h with 100% similarity]
arch/m32r/include/uapi/asm/termbits.h [moved from arch/m32r/include/asm/termbits.h with 100% similarity]
arch/m32r/include/uapi/asm/termios.h [new file with mode: 0644]
arch/m32r/include/uapi/asm/types.h [new file with mode: 0644]
arch/m32r/include/uapi/asm/unistd.h [new file with mode: 0644]
arch/parisc/kernel/module.c
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/include/uapi/asm/unistd.h
arch/score/include/asm/Kbuild
arch/score/include/asm/ptrace.h
arch/score/include/asm/setup.h
arch/score/include/uapi/asm/Kbuild
arch/score/include/uapi/asm/auxvec.h [moved from arch/score/include/asm/auxvec.h with 100% similarity]
arch/score/include/uapi/asm/bitsperlong.h [moved from arch/score/include/asm/bitsperlong.h with 100% similarity]
arch/score/include/uapi/asm/byteorder.h [moved from arch/score/include/asm/byteorder.h with 100% similarity]
arch/score/include/uapi/asm/errno.h [moved from arch/score/include/asm/errno.h with 100% similarity]
arch/score/include/uapi/asm/fcntl.h [moved from arch/score/include/asm/fcntl.h with 100% similarity]
arch/score/include/uapi/asm/ioctl.h [moved from arch/score/include/asm/ioctl.h with 100% similarity]
arch/score/include/uapi/asm/ioctls.h [moved from arch/score/include/asm/ioctls.h with 100% similarity]
arch/score/include/uapi/asm/ipcbuf.h [moved from arch/score/include/asm/ipcbuf.h with 100% similarity]
arch/score/include/uapi/asm/kvm_para.h [moved from arch/score/include/asm/kvm_para.h with 100% similarity]
arch/score/include/uapi/asm/mman.h [moved from arch/score/include/asm/mman.h with 100% similarity]
arch/score/include/uapi/asm/msgbuf.h [moved from arch/score/include/asm/msgbuf.h with 100% similarity]
arch/score/include/uapi/asm/param.h [moved from arch/score/include/asm/param.h with 100% similarity]
arch/score/include/uapi/asm/poll.h [moved from arch/score/include/asm/poll.h with 100% similarity]
arch/score/include/uapi/asm/posix_types.h [moved from arch/score/include/asm/posix_types.h with 100% similarity]
arch/score/include/uapi/asm/ptrace.h [new file with mode: 0644]
arch/score/include/uapi/asm/resource.h [moved from arch/score/include/asm/resource.h with 100% similarity]
arch/score/include/uapi/asm/sembuf.h [moved from arch/score/include/asm/sembuf.h with 100% similarity]
arch/score/include/uapi/asm/setup.h [new file with mode: 0644]
arch/score/include/uapi/asm/shmbuf.h [moved from arch/score/include/asm/shmbuf.h with 100% similarity]
arch/score/include/uapi/asm/sigcontext.h [moved from arch/score/include/asm/sigcontext.h with 100% similarity]
arch/score/include/uapi/asm/siginfo.h [moved from arch/score/include/asm/siginfo.h with 100% similarity]
arch/score/include/uapi/asm/signal.h [moved from arch/score/include/asm/signal.h with 100% similarity]
arch/score/include/uapi/asm/socket.h [moved from arch/score/include/asm/socket.h with 100% similarity]
arch/score/include/uapi/asm/sockios.h [moved from arch/score/include/asm/sockios.h with 100% similarity]
arch/score/include/uapi/asm/stat.h [moved from arch/score/include/asm/stat.h with 100% similarity]
arch/score/include/uapi/asm/statfs.h [moved from arch/score/include/asm/statfs.h with 100% similarity]
arch/score/include/uapi/asm/swab.h [moved from arch/score/include/asm/swab.h with 100% similarity]
arch/score/include/uapi/asm/termbits.h [moved from arch/score/include/asm/termbits.h with 100% similarity]
arch/score/include/uapi/asm/termios.h [moved from arch/score/include/asm/termios.h with 100% similarity]
arch/score/include/uapi/asm/types.h [moved from arch/score/include/asm/types.h with 100% similarity]
arch/score/include/uapi/asm/unistd.h [moved from arch/score/include/asm/unistd.h with 100% similarity]
arch/sparc/crypto/aes_asm.S
arch/sparc/crypto/aes_glue.c
arch/sparc/crypto/camellia_glue.c
arch/sparc/crypto/des_asm.S
arch/sparc/crypto/des_glue.c
arch/sparc/include/asm/hugetlb.h
arch/sparc/include/asm/pgtable_64.h
arch/sparc/kernel/module.c
arch/tile/kernel/module.c
arch/unicore32/kernel/module.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/traps.c
arch/x86/syscalls/syscall_32.tbl
arch/x86/syscalls/syscall_64.tbl
arch/xtensa/Kconfig
arch/xtensa/Kconfig.debug
arch/xtensa/Makefile
arch/xtensa/boot/Makefile
arch/xtensa/boot/boot-elf/Makefile
arch/xtensa/boot/boot-redboot/Makefile
arch/xtensa/boot/boot-uboot/Makefile [new file with mode: 0644]
arch/xtensa/boot/dts/lx60.dts [new file with mode: 0644]
arch/xtensa/boot/dts/ml605.dts [new file with mode: 0644]
arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi [new file with mode: 0644]
arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi [new file with mode: 0644]
arch/xtensa/boot/dts/xtfpga.dtsi [new file with mode: 0644]
arch/xtensa/include/asm/atomic.h
arch/xtensa/include/asm/barrier.h
arch/xtensa/include/asm/bitops.h
arch/xtensa/include/asm/bootparam.h
arch/xtensa/include/asm/cacheasm.h
arch/xtensa/include/asm/cacheflush.h
arch/xtensa/include/asm/checksum.h
arch/xtensa/include/asm/cmpxchg.h
arch/xtensa/include/asm/current.h
arch/xtensa/include/asm/delay.h
arch/xtensa/include/asm/dma-mapping.h
arch/xtensa/include/asm/elf.h
arch/xtensa/include/asm/highmem.h
arch/xtensa/include/asm/initialize_mmu.h [new file with mode: 0644]
arch/xtensa/include/asm/mmu_context.h
arch/xtensa/include/asm/nommu_context.h
arch/xtensa/include/asm/page.h
arch/xtensa/include/asm/pci-bridge.h
arch/xtensa/include/asm/pci.h
arch/xtensa/include/asm/pgalloc.h
arch/xtensa/include/asm/pgtable.h
arch/xtensa/include/asm/platform.h
arch/xtensa/include/asm/processor.h
arch/xtensa/include/asm/prom.h [new file with mode: 0644]
arch/xtensa/include/asm/ptrace.h
arch/xtensa/include/asm/regs.h
arch/xtensa/include/asm/spinlock.h
arch/xtensa/include/asm/syscall.h
arch/xtensa/include/asm/traps.h [new file with mode: 0644]
arch/xtensa/include/asm/uaccess.h
arch/xtensa/kernel/Makefile
arch/xtensa/kernel/align.S
arch/xtensa/kernel/asm-offsets.c
arch/xtensa/kernel/coprocessor.S
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/head.S
arch/xtensa/kernel/irq.c
arch/xtensa/kernel/module.c
arch/xtensa/kernel/platform.c
arch/xtensa/kernel/process.c
arch/xtensa/kernel/ptrace.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/signal.c
arch/xtensa/kernel/syscall.c
arch/xtensa/kernel/time.c
arch/xtensa/kernel/traps.c
arch/xtensa/kernel/vectors.S
arch/xtensa/lib/checksum.S
arch/xtensa/lib/memcopy.S
arch/xtensa/lib/pci-auto.c
arch/xtensa/lib/strncpy_user.S
arch/xtensa/lib/strnlen_user.S
arch/xtensa/lib/usercopy.S
arch/xtensa/mm/cache.c
arch/xtensa/mm/fault.c
arch/xtensa/mm/init.c
arch/xtensa/mm/misc.S
arch/xtensa/mm/mmu.c
arch/xtensa/mm/tlb.c
arch/xtensa/platforms/iss/include/platform/serial.h
arch/xtensa/platforms/iss/include/platform/simcall.h
arch/xtensa/platforms/xtfpga/Makefile [new file with mode: 0644]
arch/xtensa/platforms/xtfpga/include/platform/hardware.h [new file with mode: 0644]
arch/xtensa/platforms/xtfpga/include/platform/lcd.h [new file with mode: 0644]
arch/xtensa/platforms/xtfpga/include/platform/serial.h [new file with mode: 0644]
arch/xtensa/platforms/xtfpga/lcd.c [new file with mode: 0644]
arch/xtensa/platforms/xtfpga/setup.c [new file with mode: 0644]
arch/xtensa/variants/s6000/gpio.c
drivers/amba/tegra-ahb.c
drivers/atm/solos-pci.c
drivers/base/dma-buf.c
drivers/bcma/driver_chipcommon_pmu.c
drivers/char/random.c
drivers/clk/clk-nomadik.c
drivers/gpio/Kconfig
drivers/gpio/gpio-ich.c
drivers/gpio/gpio-mvebu.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/hwmon.c
drivers/hwmon/it87.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83627hf.c
drivers/input/serio/i8042-x86ia64io.h
drivers/isdn/mISDN/dsp_core.c
drivers/mfd/omap-usb-host.c
drivers/mtd/ar7part.c
drivers/mtd/bcm63xxpart.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/cmdlinepart.c
drivers/mtd/devices/bcm47xxsflash.c
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/docg3.c
drivers/mtd/devices/docprobe.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/spear_smi.c
drivers/mtd/devices/sst25l.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/amd76xrom.c
drivers/mtd/maps/autcpu12-nvram.c
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ck804xrom.c
drivers/mtd/maps/esb2rom.c
drivers/mtd/maps/fortunet.c [deleted file]
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/ichxrom.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/lantiq-flash.c
drivers/mtd/maps/latch-addr-flash.c
drivers/mtd/maps/pci.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/pismo.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/maps/scb2_flash.c
drivers/mtd/maps/sun_uflash.c
drivers/mtd/maps/vmu-flash.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdoops.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/ams-delta.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/bcm47xxnflash/Makefile [new file with mode: 0644]
drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h [new file with mode: 0644]
drivers/mtd/nand/bcm47xxnflash/main.c [new file with mode: 0644]
drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c [new file with mode: 0644]
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/denali.h
drivers/mtd/nand/denali_dt.c [new file with mode: 0644]
drivers/mtd/nand/denali_pci.c [new file with mode: 0644]
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/docg4.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/fsmc_nand.c
drivers/mtd/nand/gpio.c
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.h
drivers/mtd/nand/jz4740_nand.c
drivers/mtd/nand/lpc32xx_mlc.c
drivers/mtd/nand/lpc32xx_slc.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/nomadik_nand.c [deleted file]
drivers/mtd/nand/nuc900_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/plat_nand.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sh_flctl.c
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/socrates_nand.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/generic.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/samsung.c
drivers/mtd/tests/mtd_nandbiterrs.c
drivers/mtd/tests/mtd_nandecctest.c
drivers/mtd/tests/mtd_oobtest.c
drivers/mtd/tests/mtd_pagetest.c
drivers/mtd/tests/mtd_readtest.c
drivers/mtd/tests/mtd_speedtest.c
drivers/mtd/tests/mtd_stresstest.c
drivers/mtd/tests/mtd_subpagetest.c
drivers/mtd/tests/mtd_torturetest.c
drivers/net/bonding/bond_main.c
drivers/net/can/sja1000/sja1000_of_platform.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/micrel/ksz884x.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/cpts.c
drivers/net/tun.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/usbnet.c
drivers/net/wimax/i2400m/i2400m-usb.h
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/Makefile
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/of/base.c
drivers/power/charger-manager.c
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/core.c
drivers/pwm/pwm-imx.c
drivers/pwm/pwm-lpc32xx.c
drivers/pwm/pwm-samsung.c
drivers/pwm/pwm-spear.c [new file with mode: 0644]
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-tipwmss.c [new file with mode: 0644]
drivers/pwm/pwm-tipwmss.h [new file with mode: 0644]
drivers/pwm/pwm-twl-led.c [new file with mode: 0644]
drivers/pwm/pwm-twl.c [new file with mode: 0644]
drivers/pwm/pwm-twl6030.c [deleted file]
drivers/pwm/pwm-vt8500.c
drivers/spi/spi-atmel.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sh-hspi.c
drivers/spi/spi.c
drivers/tty/serial/omap-serial.c
fs/jffs2/nodemgmt.c
include/linux/asn1.h
include/linux/bcma/bcma.h
include/linux/blkdev.h
include/linux/compiler-gcc4.h
include/linux/compiler-intel.h
include/linux/compiler.h
include/linux/dma-buf.h
include/linux/ima.h
include/linux/moduleparam.h
include/linux/mtd/blktrans.h
include/linux/mtd/doc2000.h
include/linux/mtd/fsmc.h
include/linux/mtd/gpmi-nand.h [deleted file]
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/sh_flctl.h
include/linux/of_platform.h
include/linux/platform_data/mtd-nomadik-nand.h [deleted file]
include/linux/platform_data/serial-omap.h [moved from arch/arm/plat-omap/include/plat/omap-serial.h with 100% similarity]
include/linux/platform_data/usb-omap.h
include/linux/pwm.h
include/linux/security.h
include/linux/syscalls.h
include/linux/usb/usbnet.h
include/net/inet_connection_sock.h
include/net/ndisc.h
include/uapi/asm-generic/unistd.h
include/uapi/linux/if_bridge.h
include/uapi/linux/module.h [new file with mode: 0644]
include/uapi/linux/swab.h
include/video/omap-panel-tfp410.h
kernel/Makefile
kernel/modsign_certificate.S [new file with mode: 0644]
kernel/modsign_pubkey.c
kernel/module.c
kernel/posix-cpu-timers.c
kernel/sched/fair.c
kernel/sys_ni.c
kernel/watchdog.c
lib/asn1_decoder.c
mm/ksm.c
mm/vmscan.c
net/atm/atm_sysfs.c
net/bridge/br_mdb.c
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/ipv4/inet_connection_sock.c
net/ipv4/tcp_ipv4.c
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/ndisc.c
net/ipv6/tcp_ipv6.c
net/mac802154/ieee802154_dev.c
net/netlink/af_netlink.c
net/sctp/Kconfig
net/sctp/probe.c
net/sctp/protocol.c
scripts/Makefile.modsign [new file with mode: 0644]
security/capability.c
security/integrity/ima/ima.h
security/integrity/ima/ima_api.c
security/integrity/ima/ima_main.c
security/integrity/ima/ima_policy.c
security/security.c
security/selinux/nlmsgtab.c

index 9869466..ec0a38e 100644 (file)
@@ -23,7 +23,7 @@ Description:
                        lsm:    [[subj_user=] [subj_role=] [subj_type=]
                                 [obj_user=] [obj_role=] [obj_type=]]
 
-               base:   func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK]
+               base:   func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK][MODULE_CHECK]
                        mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
                        fsmagic:= hex value
                        uid:= decimal value
@@ -53,6 +53,7 @@ Description:
                        measure func=BPRM_CHECK
                        measure func=FILE_MMAP mask=MAY_EXEC
                        measure func=FILE_CHECK mask=MAY_READ uid=0
+                       measure func=MODULE_CHECK uid=0
                        appraise fowner=0
 
                The default policy measures all executables in bprm_check,
index 49fc7ad..3545ea7 100644 (file)
@@ -23,6 +23,9 @@ Recommended properties :
 - ti,davinci-nand-buswidth: buswidth 8 or 16
 - ti,davinci-nand-use-bbt: use flash based bad block table support.
 
+nand device bindings may contain additional sub-nodes describing
+partitions of the address space. See partition.txt for more detail.
+
 Example(da850 EVM ):
 nand_cs3@62000000 {
        compatible = "ti,davinci-nand";
@@ -35,4 +38,9 @@ nand_cs3@62000000 {
        ti,davinci-ecc-mode = "hw";
        ti,davinci-ecc-bits = <4>;
        ti,davinci-nand-use-bbt;
+
+       partition@180000 {
+               label = "ubifs";
+               reg = <0x180000 0x7e80000>;
+       };
 };
diff --git a/Documentation/devicetree/bindings/mtd/denali-nand.txt b/Documentation/devicetree/bindings/mtd/denali-nand.txt
new file mode 100644 (file)
index 0000000..b04d03a
--- /dev/null
@@ -0,0 +1,23 @@
+* Denali NAND controller
+
+Required properties:
+  - compatible : should be "denali,denali-nand-dt"
+  - reg : should contain registers location and length for data and reg.
+  - reg-names: Should contain the reg names "nand_data" and "denali_reg"
+  - interrupts : The interrupt number.
+  - dm-mask : DMA bit mask
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Examples:
+
+nand: nand@ff900000 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "denali,denali-nand-dt";
+       reg = <0xff900000 0x100000>, <0xffb80000 0x10000>;
+       reg-names = "nand_data", "denali_reg";
+       interrupts = <0 144 4>;
+       dma-mask = <0xffffffff>;
+};
diff --git a/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
new file mode 100644 (file)
index 0000000..427f46d
--- /dev/null
@@ -0,0 +1,49 @@
+FLCTL NAND controller
+
+Required properties:
+- compatible : "renesas,shmobile-flctl-sh7372"
+- reg : Address range of the FLCTL
+- interrupts : flste IRQ number
+- nand-bus-width : bus width to NAND chip
+
+Optional properties:
+- dmas: DMA specifier(s)
+- dma-names: name for each DMA specifier. Valid names are
+            "data_tx", "data_rx", "ecc_tx", "ecc_rx"
+
+The DMA fields are not used yet in the driver but are listed here for
+completing the bindings.
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+       flctl@e6a30000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "renesas,shmobile-flctl-sh7372";
+               reg = <0xe6a30000 0x100>;
+               interrupts = <0x0d80>;
+
+               nand-bus-width = <16>;
+
+               dmas = <&dmac 1 /* data_tx */
+                       &dmac 2;> /* data_rx */
+               dma-names = "data_tx", "data_rx";
+
+               system@0 {
+                       label = "system";
+                       reg = <0x0 0x8000000>;
+               };
+
+               userdata@8000000 {
+                       label = "userdata";
+                       reg = <0x8000000 0x10000000>;
+               };
+
+               cache@18000000 {
+                       label = "cache";
+                       reg = <0x18000000 0x8000000>;
+               };
+       };
index e2c663b..e3ea32e 100644 (file)
@@ -3,9 +3,7 @@
 Required properties:
 - compatible : "st,spear600-fsmc-nand"
 - reg : Address range of the mtd chip
-- reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
-- st,ale-off : Chip specific offset to ALE
-- st,cle-off : Chip specific offset to CLE
+- reg-names: Should contain the reg names "fsmc_regs", "nand_data", "nand_addr" and "nand_cmd"
 
 Optional properties:
 - bank-width : Width (in bytes) of the device.  If not present, the width
@@ -19,10 +17,10 @@ Example:
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0xd1800000 0x1000        /* FSMC Register */
-                      0xd2000000 0x4000>;      /* NAND Base */
-               reg-names = "fsmc_regs", "nand_data";
-               st,ale-off = <0x20000>;
-               st,cle-off = <0x10000>;
+                      0xd2000000 0x0010        /* NAND Base DATA */
+                      0xd2020000 0x0010        /* NAND Base ADDR */
+                      0xd2010000 0x0010>;      /* NAND Base CMD */
+               reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 
                bank-width = <1>;
                nand-skip-bbtscan;
diff --git a/Documentation/devicetree/bindings/mtd/m25p80.txt b/Documentation/devicetree/bindings/mtd/m25p80.txt
new file mode 100644 (file)
index 0000000..6d3d576
--- /dev/null
@@ -0,0 +1,29 @@
+* MTD SPI driver for ST M25Pxx (and similar) serial flash chips
+
+Required properties:
+- #address-cells, #size-cells : Must be present if the device has sub-nodes
+  representing partitions.
+- compatible : Should be the manufacturer and the name of the chip. Bear in mind
+               the DT binding is not Linux-only, but in case of Linux, see the
+               "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of
+               supported chips.
+- reg : Chip-Select number
+- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
+
+Optional properties:
+- m25p,fast-read : Use the "fast read" opcode to read data from the chip instead
+                   of the usual "read" opcode. This opcode is not supported by
+                   all chips and support for it can not be detected at runtime.
+                   Refer to your chips' datasheet to check if this is supported
+                   by your chip.
+
+Example:
+
+       flash: m25p80@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,m25p80";
+               reg = <0>;
+               spi-max-frequency = <40000000>;
+               m25p,fast-read;
+       };
index 94de19b..dab7847 100644 (file)
@@ -23,6 +23,9 @@ file systems on embedded devices.
    unaligned accesses as implemented in the JFFS2 code via memcpy().
    By defining "no-unaligned-direct-access", the flash will not be
    exposed directly to the MTD users (e.g. JFFS2) any more.
+ - linux,mtd-name: allow to specify the mtd name for retro capability with
+   physmap-flash drivers as boot loader pass the mtd partition via the old
+   device name physmap-flash.
 
 For JEDEC compatible devices, the following additional properties
 are defined:
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
new file mode 100644 (file)
index 0000000..131e8c1
--- /dev/null
@@ -0,0 +1,23 @@
+TI SOC ECAP based APWM controller
+
+Required properties:
+- compatible: Must be "ti,am33xx-ecap"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+  First cell specifies the per-chip index of the PWM to use, the second
+  cell is the period in nanoseconds and bit 0 in the third cell is used to
+  encode the polarity of PWM output. Set bit 0 of the third in PWM specifier
+  to 1 for inverse polarity & set to 0 for normal polarity.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the ECAP:
+  "ecap<x>", <x> being the 0-based instance number from the HW spec
+
+Example:
+
+ecap0: ecap@0 {
+       compatible = "ti,am33xx-ecap";
+       #pwm-cells = <3>;
+       reg = <0x48300100 0x80>;
+       ti,hwmods = "ecap0";
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
new file mode 100644 (file)
index 0000000..4fc7079
--- /dev/null
@@ -0,0 +1,23 @@
+TI SOC EHRPWM based PWM controller
+
+Required properties:
+- compatible : Must be "ti,am33xx-ehrpwm"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+  First cell specifies the per-chip index of the PWM to use, the second
+  cell is the period in nanoseconds and bit 0 in the third cell is used to
+  encode the polarity of PWM output. Set bit 0 of the third in PWM specifier
+  to 1 for inverse polarity & set to 0 for normal polarity.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the EHRPWM:
+  "ehrpwm<x>", <x> being the 0-based instance number from the HW spec
+
+Example:
+
+ehrpwm0: ehrpwm@0 {
+       compatible = "ti,am33xx-ehrpwm";
+       #pwm-cells = <3>;
+       reg = <0x48300200 0x100>;
+       ti,hwmods = "ehrpwm0";
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt
new file mode 100644 (file)
index 0000000..f7eae77
--- /dev/null
@@ -0,0 +1,31 @@
+TI SOC based PWM Subsystem
+
+Required properties:
+- compatible: Must be "ti,am33xx-pwmss";
+- reg: physical base address and size of the registers map.
+- address-cells: Specify the number of u32 entries needed in child nodes.
+                 Should set to 1.
+- size-cells: specify number of u32 entries needed to specify child nodes size
+               in reg property. Should set to 1.
+- ranges: describes the address mapping of a memory-mapped bus. Should set to
+          physical address map of child's base address, physical address within
+          parent's address  space and length of the address map. For am33xx,
+          3 set of child register maps present, ECAP register space, EQEP
+          register space, EHRPWM register space.
+
+Also child nodes should also populated under PWMSS DT node.
+
+Example:
+pwmss0: pwmss@48300000 {
+       compatible = "ti,am33xx-pwmss";
+       reg = <0x48300000 0x10>;
+       ti,hwmods = "epwmss0";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       status = "disabled";
+       ranges = <0x48300100 0x48300100 0x80   /* ECAP */
+                 0x48300180 0x48300180 0x80   /* EQEP */
+                 0x48300200 0x48300200 0x80>; /* EHRPWM */
+
+       /* child nodes go here */
+};
index 73ec962..06e6724 100644 (file)
@@ -37,10 +37,21 @@ device:
                pwm-names = "backlight";
        };
 
+Note that in the example above, specifying the "pwm-names" is redundant
+because the name "backlight" would be used as fallback anyway.
+
 pwm-specifier typically encodes the chip-relative PWM number and the PWM
-period in nanoseconds. Note that in the example above, specifying the
-"pwm-names" is redundant because the name "backlight" would be used as
-fallback anyway.
+period in nanoseconds.
+
+Optionally, the pwm-specifier can encode a number of flags in a third cell:
+- bit 0: PWM signal polarity (0: normal polarity, 1: inverse polarity)
+
+Example with optional PWM specifier for inverse polarity
+
+       bl: backlight {
+               pwms = <&pwm 0 5000000 1>;
+               pwm-names = "backlight";
+       };
 
 2) PWM controller nodes
 -----------------------
diff --git a/Documentation/devicetree/bindings/pwm/spear-pwm.txt b/Documentation/devicetree/bindings/pwm/spear-pwm.txt
new file mode 100644 (file)
index 0000000..3ac779d
--- /dev/null
@@ -0,0 +1,18 @@
+== ST SPEAr SoC PWM controller ==
+
+Required properties:
+- compatible: should be one of:
+  - "st,spear320-pwm"
+  - "st,spear1340-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: number of cells used to specify PWM which is fixed to 2 on
+  SPEAr. The first cell specifies the per-chip index of the PWM to use and
+  the second cell is the period in nanoseconds.
+
+Example:
+
+        pwm: pwm@a8000000 {
+            compatible ="st,spear320-pwm";
+            reg = <0xa8000000 0x1000>;
+            #pwm-cells = <2>;
+        };
diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt
new file mode 100644 (file)
index 0000000..2943ee5
--- /dev/null
@@ -0,0 +1,17 @@
+Texas Instruments TWL series PWM drivers
+
+Supported PWMs:
+On TWL4030 series: PWM1 and PWM2
+On TWL6030 series: PWM0 and PWM1
+
+Required properties:
+- compatible: "ti,twl4030-pwm" or "ti,twl6030-pwm"
+- #pwm-cells: should be 2.  The first cell specifies the per-chip index
+  of the PWM to use and the second cell is the period in nanoseconds.
+
+Example:
+
+twl_pwm: pwm {
+       compatible = "ti,twl6030-pwm";
+       #pwm-cells = <2>;
+};
diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt
new file mode 100644 (file)
index 0000000..cb64f3a
--- /dev/null
@@ -0,0 +1,17 @@
+Texas Instruments TWL series PWM drivers connected to LED terminals
+
+Supported PWMs:
+On TWL4030 series: PWMA and PWMB (connected to LEDA and LEDB terminals)
+On TWL6030 series: LED PWM (mainly used as charging indicator LED)
+
+Required properties:
+- compatible: "ti,twl4030-pwmled" or "ti,twl6030-pwmled"
+- #pwm-cells: should be 2.  The first cell specifies the per-chip index
+  of the PWM to use and the second cell is the period in nanoseconds.
+
+Example:
+
+twl_pwmled: pwmled {
+       compatible = "ti,twl6030-pwmled";
+       #pwm-cells = <2>;
+};
diff --git a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
new file mode 100644 (file)
index 0000000..bcc6367
--- /dev/null
@@ -0,0 +1,17 @@
+VIA/Wondermedia VT8500/WM8xxx series SoC PWM controller
+
+Required properties:
+- compatible: should be "via,vt8500-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: should be 2.  The first cell specifies the per-chip index
+  of the PWM to use and the second cell is the period in nanoseconds.
+- clocks: phandle to the PWM source clock
+
+Example:
+
+pwm1: pwm@d8220000 {
+       #pwm-cells = <2>;
+       compatible = "via,vt8500-pwm";
+       reg = <0xd8220000 0x1000>;
+       clocks = <&clkpwm>;
+};
index 8cf24f6..7b53da5 100644 (file)
@@ -13,7 +13,7 @@ Recommended properties:
 
 Example:
 
-spi@7000d600 {
+spi@7000c380 {
        compatible = "nvidia,tegra20-sflash";
        reg = <0x7000c380 0x80>;
        interrupts = <0 39 0x04>;
index f5b1ad1..eefe15e 100644 (file)
@@ -13,7 +13,7 @@ Recommended properties:
 
 Example:
 
-slink@7000d600 {
+spi@7000d600 {
        compatible = "nvidia,tegra20-slink";
        reg = <0x7000d600 0x200>;
        interrupts = <0 82 0x04>;
diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt
new file mode 100644 (file)
index 0000000..07e04cd
--- /dev/null
@@ -0,0 +1,26 @@
+Atmel SPI device
+
+Required properties:
+- compatible : should be "atmel,at91rm9200-spi".
+- reg: Address and length of the register set for the device
+- interrupts: Should contain spi interrupt
+- cs-gpios: chipselects
+
+Example:
+
+spi1: spi@fffcc000 {
+       compatible = "atmel,at91rm9200-spi";
+       reg = <0xfffcc000 0x4000>;
+       interrupts = <13 4 5>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       cs-gpios = <&pioB 3 0>;
+       status = "okay";
+
+       mmc-slot@0 {
+               compatible = "mmc-spi-slot";
+               reg = <0>;
+               gpios = <&pioC 4 0>;    /* CD */
+               spi-max-frequency = <25000000>;
+       };
+};
index 87850d8..8386aad 100644 (file)
@@ -209,3 +209,13 @@ doesn't use CPU cycles.
 Trip points must be set properly before switching to automatic fan speed
 control mode. The driver will perform basic integrity checks before
 actually switching to automatic control mode.
+
+
+Temperature offset attributes
+-----------------------------
+
+The driver supports temp[1-3]_offset sysfs attributes to adjust the reported
+temperature for thermal diodes or diode-connected thermal transistors.
+If a temperature sensor is configured for thermistors, the attribute values
+are ignored. If the thermal sensor type is Intel PECI, the temperature offset
+must be programmed to the critical CPU temperature.
index f15cb74..406d82d 100644 (file)
@@ -373,7 +373,7 @@ Protocol:   2.00+
        1  Loadlin
        2  bootsect-loader      (0x20, all other values reserved)
        3  Syslinux
-       4  Etherboot/gPXE
+       4  Etherboot/gPXE/iPXE
        5  ELILO
        7  GRUB
        8  U-Boot
@@ -381,6 +381,7 @@ Protocol:   2.00+
        A  Gujin
        B  Qemu
        C  Arcturus Networks uCbootloader
+       D  kexec-tools
        E  Extended             (see ext_loader_type)
        F  Special              (0xFF = undefined)
        10  Reserved
diff --git a/Documentation/xtensa/atomctl.txt b/Documentation/xtensa/atomctl.txt
new file mode 100644 (file)
index 0000000..10a8d1f
--- /dev/null
@@ -0,0 +1,44 @@
+We Have Atomic Operation Control (ATOMCTL) Register.
+This register determines the effect of using a S32C1I instruction
+with various combinations of:
+
+     1. With and without an Coherent Cache Controller which
+        can do Atomic Transactions to the memory internally.
+
+     2. With and without An Intelligent Memory Controller which
+        can do Atomic Transactions itself.
+
+The Core comes up with a default value of for the three types of cache ops:
+
+      0x28: (WB: Internal, WT: Internal, BY:Exception)
+
+On the FPGA Cards we typically simulate an Intelligent Memory controller
+which can implement  RCW transactions. For FPGA cards with an External
+Memory controller we let it to the atomic operations internally while
+doing a Cached (WB) transaction and use the Memory RCW for un-cached
+operations.
+
+For systems without an coherent cache controller, non-MX, we always
+use the memory controllers RCW, thought non-MX controlers likely
+support the Internal Operation.
+
+CUSTOMER-WARNING:
+   Virtually all customers buy their memory controllers from vendors that
+   don't support atomic RCW memory transactions and will likely want to
+   configure this register to not use RCW.
+
+Developers might find using RCW in Bypass mode convenient when testing
+with the cache being bypassed; for example studying cache alias problems.
+
+See Section 4.3.12.4 of ISA; Bits:
+
+                             WB     WT      BY
+                           5   4 | 3   2 | 1   0
+  2 Bit
+  Field
+  Values     WB - Write Back         WT - Write Thru         BY - Bypass
+---------    ---------------         -----------------     ----------------
+    0        Exception               Exception               Exception
+    1        RCW Transaction         RCW Transaction         RCW Transaction
+    2        Internal Operation      Exception               Reserved
+    3        Reserved                Reserved                Reserved
index 540f7b2..6f07f4a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -981,6 +981,12 @@ _modinst_post: _modinst_
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst
        $(call cmd,depmod)
 
+ifeq ($(CONFIG_MODULE_SIG), y)
+PHONY += modules_sign
+modules_sign:
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign
+endif
+
 else # CONFIG_MODULES
 
 # Modules not configured
index 54ffd0f..8e9e324 100644 (file)
@@ -113,6 +113,25 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS
          See Documentation/unaligned-memory-access.txt for more
          information on the topic of unaligned memory accesses.
 
+config ARCH_USE_BUILTIN_BSWAP
+       bool
+       help
+        Modern versions of GCC (since 4.4) have builtin functions
+        for handling byte-swapping. Using these, instead of the old
+        inline assembler that the architecture code provides in the
+        __arch_bswapXX() macros, allows the compiler to see what's
+        happening and offers more opportunity for optimisation. In
+        particular, the compiler will be able to combine the byteswap
+        with a nearby load or store and use load-and-swap or
+        store-and-swap instructions if the architecture has them. It
+        should almost *never* result in code which is worse than the
+        hand-coded assembler in <asm/swab.h>.  But just in case it
+        does, the use of the builtins is optional.
+
+        Any architecture with load-and-swap or store-and-swap
+        instructions should set this. And it shouldn't hurt to set it
+        on architectures that don't have such instructions.
+
 config HAVE_SYSCALL_WRAPPERS
        bool
 
index 0f44174..d077ef8 100644 (file)
@@ -107,6 +107,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        omap3-evm.dtb \
        omap3-tobi.dtb \
        omap4-panda.dtb \
+       omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
        omap4-var-som.dtb \
        omap4-sdp.dtb \
@@ -131,8 +132,8 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
        spear320-evb.dtb \
        spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
-dtb-$(CONFIG_ARCH_SUNXI) += sun4i-cubieboard.dtb \
-       sun5i-olinuxino.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun4i-a10-cubieboard.dtb \
+       sun5i-a13-olinuxino.dtb
 dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
        tegra20-medcom-wide.dtb \
        tegra20-paz00.dtb \
index b01c0d7..fa04c7b 100644 (file)
        };
 
        soc {
-               aipi@10000000 { /* aipi */
-
+               aipi@10000000 { /* aipi1 */
                        uart1: serial@1000a000 {
                                fsl,uart-has-rtscts;
                                status = "okay";
                        };
+               };
 
-                       fec@1002b000 {
+               aipi@10020000 { /* aipi2 */
+                       ethernet@1002b000 {
                                status = "okay";
                        };
                };
        };
-
 };
index af50469..53b0ec0 100644 (file)
@@ -21,8 +21,7 @@
        };
 
        soc {
-               aipi@10000000 { /* aipi */
-
+               aipi@10000000 { /* aipi1 */
                        serial@1000a000 {
                                fsl,uart-has-rtscts;
                                status = "okay";
                                status = "okay";
                        };
 
-                       ethernet@1002b000 {
-                               status = "okay";
-                       };
-
                        i2c@1001d000 {
                                clock-frequency = <400000>;
                                status = "okay";
                                };
                        };
                };
+
+               aipi@10020000 { /* aipi2 */
+                       ethernet@1002b000 {
+                               status = "okay";
+                       };
+               };
        };
 
        nor_flash@c0000000 {
index b8d3905..5a82cb5 100644 (file)
@@ -55,7 +55,7 @@
                        compatible = "fsl,aipi-bus", "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
-                       reg = <0x10000000 0x10000000>;
+                       reg = <0x10000000 0x20000>;
                        ranges;
 
                        wdog: wdog@10002000 {
                                status = "disabled";
                        };
 
+               };
+
+               aipi@10020000 { /* AIPI2 */
+                       compatible = "fsl,aipi-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x10020000 0x20000>;
+                       ranges;
+
                        fec: ethernet@1002b000 {
                                compatible = "fsl,imx27-fec";
                                reg = <0x1002b000 0x4000>;
index 77b84e1..9b0d077 100644 (file)
@@ -15,6 +15,6 @@
 
        memory {
                device_type = "memory";
-               reg = <0x80000000 0x84000000>; /* 64 MB */
+               reg = <0x80000000 0x4000000>; /* 64 MB */
        };
 };
index 009096d..b4ca60f 100644 (file)
@@ -73,7 +73,7 @@
                                400000
                                500000
                                600000 >;
-               status = "disable";
+               status = "disabled";
        };
 
        ahb {
                        compatible = "st,spear600-fsmc-nand";
                        #address-cells = <1>;
                        #size-cells = <1>;
-                       reg = <0xb0000000 0x1000        /* FSMC Register */
-                              0xb0800000 0x0010>;      /* NAND Base */
-                       reg-names = "fsmc_regs", "nand_data";
+                       reg = <0xb0000000 0x1000        /* FSMC Register*/
+                              0xb0800000 0x0010        /* NAND Base DATA */
+                              0xb0820000 0x0010        /* NAND Base ADDR */
+                              0xb0810000 0x0010>;      /* NAND Base CMD */
+                       reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                        interrupts = <0 20 0x4
                                      0 21 0x4
                                      0 22 0x4
                                      0 23 0x4>;
-                       st,ale-off = <0x20000>;
-                       st,cle-off = <0x10000>;
                        st,mode = <2>;
                        status = "disabled";
                };
                        compatible = "st,pcm-audio";
                        #address-cells = <0>;
                        #size-cells = <0>;
-                       status = "disable";
+                       status = "disabled";
                };
 
                smi: flash@ea000000 {
index 090adc6..f79b3df 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0x94000000 0x1000        /* FSMC Register */
-                              0x80000000 0x0010>;      /* NAND Base */
-                       reg-names = "fsmc_regs", "nand_data";
-                       st,ale-off = <0x20000>;
-                       st,cle-off = <0x10000>;
+                              0x80000000 0x0010        /* NAND Base DATA */
+                              0x80020000 0x0010        /* NAND Base ADDR */
+                              0x80010000 0x0010>;      /* NAND Base CMD */
+                       reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                        status = "disabled";
                };
 
index e814e5e..ab45b8c 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0x44000000 0x1000        /* FSMC Register */
-                              0x40000000 0x0010>;      /* NAND Base */
-                       reg-names = "fsmc_regs", "nand_data";
-                       st,ale-off = <0x10000>;
-                       st,cle-off = <0x20000>;
+                              0x40000000 0x0010        /* NAND Base DATA */
+                              0x40020000 0x0010        /* NAND Base ADDR */
+                              0x40010000 0x0010>;      /* NAND Base CMD */
+                       reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                        status = "disabled";
                };
 
index c056a84..caa5520 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0x4c000000 0x1000        /* FSMC Register */
-                              0x50000000 0x0010>;      /* NAND Base */
-                       reg-names = "fsmc_regs", "nand_data";
-                       st,ale-off = <0x20000>;
-                       st,cle-off = <0x10000>;
+                              0x50000000 0x0010        /* NAND Base DATA */
+                              0x50020000 0x0010        /* NAND Base ADDR */
+                              0x50010000 0x0010>;      /* NAND Base CMD */
+                       reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                        status = "disabled";
                };
 
index e051dde..19f99dc 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0xd1800000 0x1000        /* FSMC Register */
-                              0xd2000000 0x4000>;      /* NAND Base */
-                       reg-names = "fsmc_regs", "nand_data";
-                       st,ale-off = <0x20000>;
-                       st,cle-off = <0x10000>;
+                              0xd2000000 0x0010        /* NAND Base DATA */
+                              0xd2020000 0x0010        /* NAND Base ADDR */
+                              0xd2010000 0x0010>;      /* NAND Base CMD */
+                       reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                        status = "disabled";
                };
 
index f4ca126..5cab825 100644 (file)
  */
 
 /dts-v1/;
-/include/ "sun4i.dtsi"
+/include/ "sun4i-a10.dtsi"
 
 / {
        model = "Cubietech Cubieboard";
-       compatible = "cubietech,cubieboard", "allwinner,sun4i";
+       compatible = "cubietech,a10-cubieboard", "allwinner,sun4i-a10";
 
        aliases {
                serial0 = &uart0;
index d6ff889..498a091 100644 (file)
  */
 
 /dts-v1/;
-/include/ "sun5i.dtsi"
+/include/ "sun5i-a13.dtsi"
 
 / {
        model = "Olimex A13-Olinuxino";
-       compatible = "olimex,a13-olinuxino", "allwinner,sun5i";
+       compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13";
 
        chosen {
                bootargs = "earlyprintk console=ttyS0,115200";
index 240b25e..86cfd29 100644 (file)
@@ -57,7 +57,7 @@ CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC_SMC=y
-CONFIG_MTD_NAND_NOMADIK=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=y
index ac03bdb..4da7cde 100644 (file)
 #define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
                                        /* 378 for kcmp */
+#define __NR_finit_module              (__NR_SYSCALL_BASE+379)
 
 /*
  * This may need to be greater than __NR_last_syscall+1 in order to
index 5935b6a..a4fda4e 100644 (file)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
                CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
+               CALL(sys_finit_module)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index 7211772..0299915 100644 (file)
@@ -41,6 +41,7 @@
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <mach/mux.h>
+#include <mach/sram.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index 16026c2..d64274f 100644 (file)
@@ -47,13 +47,9 @@ static void __raw_writel(unsigned int value, unsigned int ptr)
 
 static inline void putc(int c)
 {
-       int i;
-
-       for (i = 0; i < 1000; i++) {
-               /* Transmit fifo not full?  */
-               if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
-                       break;
-       }
+       /* Transmit fifo not full?  */
+       while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)
+               ;
 
        __raw_writeb(c, PHYS_UART_DATA);
 }
index dac146d..04744f9 100644 (file)
@@ -25,7 +25,7 @@ void exynos_init_late(void);
 #ifdef CONFIG_PM_GENERIC_DOMAINS
 int exynos_pm_late_initcall(void);
 #else
-static int exynos_pm_late_initcall(void) { return 0; }
+static inline int exynos_pm_late_initcall(void) { return 0; }
 #endif
 
 #ifdef CONFIG_ARCH_EXYNOS4
index e8c0473..579023f 100644 (file)
@@ -319,6 +319,7 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
                        unsigned long rate_ckih1, unsigned long rate_ckih2)
 {
        int i;
+       u32 val;
        struct device_node *np;
 
        clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
@@ -390,6 +391,21 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        imx_print_silicon_rev("i.MX51", mx51_revision());
        clk_disable_unprepare(clk[iim_gate]);
 
+       /*
+        * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no
+        * longer supported. Set to one for better power saving.
+        *
+        * The effect of not setting these bits is that MIPI clocks can't be
+        * enabled without the IPU clock being enabled aswell.
+        */
+       val = readl(MXC_CCM_CCDR);
+       val |= 1 << 18;
+       writel(val, MXC_CCM_CCDR);
+
+       val = readl(MXC_CCM_CLPCR);
+       val |= 1 << 23;
+       writel(val, MXC_CCM_CLPCR);
+
        return 0;
 }
 
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_mx2_emmaprp_data_entry_single(soc)                         \
        {                                                               \
index 5ccdf53..98167a4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/i2c.h>
@@ -33,7 +34,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
-#include <mach/fsmc.h>
 #include <mach/irqs.h>
 
 #include "cpu-8815.h"
 #define SRC_CR_INIT_MASK       0x00007fff
 #define SRC_CR_INIT_VAL                0x2aaa8000
 
+#define ALE_OFF 0x1000000
+#define CLE_OFF 0x800000
+
 /* These addresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
        {
+               .name = "nand_data",
+               .start = 0x40000000,
+               .end = 0x40000000 + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       }, {
                .name = "nand_addr",
-               .start = NAND_IO_ADDR,
-               .end = NAND_IO_ADDR + 0xfff,
+               .start = 0x40000000 + ALE_OFF,
+               .end = 0x40000000 +ALE_OFF + SZ_16K - 1,
                .flags = IORESOURCE_MEM,
        }, {
                .name = "nand_cmd",
-               .start = NAND_IO_CMD,
-               .end = NAND_IO_CMD + 0xfff,
+               .start = 0x40000000 + CLE_OFF,
+               .end = 0x40000000 + CLE_OFF + SZ_16K - 1,
                .flags = IORESOURCE_MEM,
        }, {
-               .name = "nand_data",
-               .start = NAND_IO_DATA,
-               .end = NAND_IO_DATA + 0xfff,
+               .name  = "fsmc_regs",
+               .start = NOMADIK_FSMC_BASE,
+               .end   = NOMADIK_FSMC_BASE + SZ_4K - 1,
                .flags = IORESOURCE_MEM,
-       }
+       },
 };
 
-static int nhk8815_nand_init(void)
-{
-       /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */
-       writel(0x0000000E, FSMC_PCR(0));
-       writel(0x000D0A00, FSMC_PMEM(0));
-       writel(0x00100A00, FSMC_PATT(0));
-
-       /* enable access to the chip select area */
-       writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0));
-
-       return 0;
-}
-
 /*
  * These partitions are the same as those used in the 2.6.20 release
  * shipped by the vendor; the first two partitions are mandated
@@ -108,20 +103,28 @@ static struct mtd_partition nhk8815_partitions[] = {
        }
 };
 
-static struct nomadik_nand_platform_data nhk8815_nand_data = {
-       .parts          = nhk8815_partitions,
-       .nparts         = ARRAY_SIZE(nhk8815_partitions),
-       .options        = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING,
-       .init           = nhk8815_nand_init,
+static struct fsmc_nand_timings nhk8815_nand_timings = {
+       .thiz   = 0,
+       .thold  = 0x10,
+       .twait  = 0x0A,
+       .tset   = 0,
+};
+
+static struct fsmc_nand_platform_data nhk8815_nand_platform_data = {
+       .nand_timings = &nhk8815_nand_timings,
+       .partitions = nhk8815_partitions,
+       .nr_partitions = ARRAY_SIZE(nhk8815_partitions),
+       .width = FSMC_NAND_BW8,
 };
 
 static struct platform_device nhk8815_nand_device = {
-       .name           = "nomadik_nand",
-       .dev            = {
-               .platform_data = &nhk8815_nand_data,
+       .name = "fsmc-nand",
+       .id = -1,
+       .resource = nhk8815_nand_resources,
+       .num_resources = ARRAY_SIZE(nhk8815_nand_resources),
+       .dev = {
+               .platform_data = &nhk8815_nand_platform_data,
        },
-       .resource       = nhk8815_nand_resources,
-       .num_resources  = ARRAY_SIZE(nhk8815_nand_resources),
 };
 
 /* These are the partitions for the OneNand device, different from above */
@@ -176,6 +179,10 @@ static struct platform_device nhk8815_onenand_device = {
        .num_resources  = ARRAY_SIZE(nhk8815_onenand_resource),
 };
 
+/* bus control reg. and bus timing reg. for CS0..CS3 */
+#define FSMC_BCR(x)    (NOMADIK_FSMC_VA + (x << 3))
+#define FSMC_BTR(x)    (NOMADIK_FSMC_VA + (x << 3) + 0x04)
+
 static void __init nhk8815_onenand_init(void)
 {
 #ifdef CONFIG_MTD_ONENAND
diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h
deleted file mode 100644 (file)
index 8c2c051..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-/* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */
-
-#ifndef __ASM_ARCH_FSMC_H
-#define __ASM_ARCH_FSMC_H
-
-#include <mach/hardware.h>
-/*
- * Register list
- */
-
-/* bus control reg. and bus timing reg. for CS0..CS3 */
-#define FSMC_BCR(x)     (NOMADIK_FSMC_VA + (x << 3))
-#define FSMC_BTR(x)     (NOMADIK_FSMC_VA + (x << 3) + 0x04)
-
-/* PC-card and NAND:
- * PCR = control register
- * PMEM = memory timing
- * PATT = attribute timing
- * PIO = I/O timing
- * PECCR = ECC result
- */
-#define FSMC_PCR(x)     (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00)
-#define FSMC_PMEM(x)    (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08)
-#define FSMC_PATT(x)    (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c)
-#define FSMC_PIO(x)     (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10)
-#define FSMC_PECCR(x)   (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14)
-
-#endif /* __ASM_ARCH_FSMC_H */
index be0f62b..41b581f 100644 (file)
@@ -26,6 +26,8 @@ config SOC_HAS_OMAP2_SDRC
 
 config SOC_HAS_REALTIME_COUNTER
        bool "Real time free running counter"
+       depends on SOC_OMAP5
+       default y
 
 config ARCH_OMAP2
        bool "TI OMAP2"
@@ -79,7 +81,6 @@ config SOC_OMAP5
        select ARM_GIC
        select CPU_V7
        select HAVE_SMP
-       select SOC_HAS_REALTIME_COUNTER
        select COMMON_CLK
 
 comment "OMAP Core Type"
index 7b20154..bb73afc 100644 (file)
@@ -157,6 +157,7 @@ static struct omap_dss_device sdp3430_lcd_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = -1,
+       .i2c_bus_num            = -1,
 };
 
 static struct omap_dss_device sdp3430_dvi_device = {
index 4be58fd..f81a303 100644 (file)
@@ -208,6 +208,7 @@ static struct omap_dss_device am3517_evm_tv_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = -1,
+       .i2c_bus_num            = -1,
 };
 
 static struct omap_dss_device am3517_evm_dvi_device = {
index c8e37dc..b3102c2 100644 (file)
@@ -241,6 +241,7 @@ static struct omap_dss_device cm_t35_lcd_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = CM_T35_DVI_EN_GPIO,
+       .i2c_bus_num            = -1,
 };
 
 static struct omap_dss_device cm_t35_dvi_device = {
index 7667eb7..12865af 100644 (file)
@@ -141,6 +141,7 @@ static struct omap_dss_device devkit8000_lcd_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = -1,
+       .i2c_bus_num            = 1,
 };
 
 static struct omap_dss_device devkit8000_dvi_device = {
index 9a3878e..3be1311 100644 (file)
 #include <linux/io.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/mfd/menelaus.h>
+#include <linux/omap-dma.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <linux/omap-dma.h>
-#include <plat/debug-devices.h>
-
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
 
 #include "mux.h"
 #include "control.h"
 #include "gpmc.h"
+#include "gpmc-smc91x.h"
 
 #define H4_FLASH_CS    0
-#define H4_SMC91X_CS   1
-
-#define H4_ETHR_GPIO_IRQ               92
 
 #if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
 static const uint32_t board_matrix_keys[] = {
@@ -250,71 +246,31 @@ static u32 is_gpmc_muxed(void)
                return 0;
 }
 
-static inline void __init h4_init_debug(void)
-{
-       int eth_cs;
-       unsigned long cs_mem_base;
-       unsigned int muxed, rate;
-       struct clk *gpmc_fck;
-
-       eth_cs  = H4_SMC91X_CS;
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
 
-       gpmc_fck = clk_get(NULL, "gpmc_fck");   /* Always on ENABLE_ON_INIT */
-       if (IS_ERR(gpmc_fck)) {
-               WARN_ON(1);
-               return;
-       }
-
-       clk_prepare_enable(gpmc_fck);
-       rate = clk_get_rate(gpmc_fck);
-       clk_disable_unprepare(gpmc_fck);
-       clk_put(gpmc_fck);
+static struct omap_smc91x_platform_data board_smc91x_data = {
+       .cs             = 1,
+       .gpio_irq       = 92,
+       .flags          = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_LOWLEVEL,
+};
 
+static void __init board_smc91x_init(void)
+{
        if (is_gpmc_muxed())
-               muxed = 0x200;
-       else
-               muxed = 0;
-
-       /* Make sure CS1 timings are correct */
-       gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1,
-                         0x00011000 | muxed);
-
-       if (rate >= 160000000) {
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
-       } else if (rate >= 130000000) {
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
-       } else {/* rate = 100000000 */
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
-               gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
-       }
-
-       if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
-               printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
-               goto out;
-       }
+               board_smc91x_data.flags |= GPMC_MUX_ADD_DATA;
 
-       udelay(100);
+       omap_mux_init_gpio(board_smc91x_data.gpio_irq, OMAP_PIN_INPUT);
+       gpmc_smc91x_init(&board_smc91x_data);
+}
 
-       omap_mux_init_gpio(92, 0);
-       if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
-               gpmc_cs_free(eth_cs);
+#else
 
-out:
-       clk_disable_unprepare(gpmc_fck);
-       clk_put(gpmc_fck);
+static inline void board_smc91x_init(void)
+{
 }
 
+#endif
+
 static void __init h4_init_flash(void)
 {
        unsigned long base;
@@ -371,6 +327,7 @@ static void __init omap_h4_init(void)
        omap_serial_init();
        omap_sdrc_init(NULL, NULL);
        h4_init_flash();
+       board_smc91x_init();
 
        omap_display_init(&h4_dss_data);
 }
index 54647d6..3985f35 100644 (file)
@@ -240,6 +240,7 @@ static struct omap_dss_device omap3_evm_tv_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = OMAP3EVM_DVI_PANEL_EN_GPIO,
+       .i2c_bus_num            = -1,
 };
 
 static struct omap_dss_device omap3_evm_dvi_device = {
index d8638b3..53a6cbc 100644 (file)
@@ -118,6 +118,7 @@ static struct omap_dss_device omap3_stalker_tv_device = {
 
 static struct tfp410_platform_data dvi_panel = {
        .power_down_gpio        = DSS_ENABLE_GPIO,
+       .i2c_bus_num            = -1,
 };
 
 static struct omap_dss_device omap3_stalker_dvi_device = {
index 60529e0..cf07e28 100644 (file)
@@ -256,6 +256,11 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
        },
 };
 
+static struct platform_device rx51_battery_device = {
+       .name   = "rx51-battery",
+       .id     = -1,
+};
+
 static void rx51_charger_set_power(bool on)
 {
        gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on);
@@ -277,6 +282,7 @@ static void __init rx51_charger_init(void)
        WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO,
                GPIOF_OUT_INIT_HIGH, "isp1704_reset"));
 
+       platform_device_register(&rx51_battery_device);
        platform_device_register(&rx51_charger_device);
 }
 
index aa56c3e..5789a5e 100644 (file)
 #define OMAP4430_MODULEMODE_HWCTRL_SHIFT               0
 #define OMAP4430_MODULEMODE_SWCTRL_SHIFT               1
 
+/*
+ * OMAP4 ABE DPLL default frequency. In OMAP4460 TRM version V, section
+ * "3.6.3.2.3 CM1_ABE Clock Generator" states that the "DPLL_ABE_X2_CLK
+ * must be set to 196.608 MHz" and hence, the DPLL locked frequency is
+ * half of this value.
+ */
+#define OMAP4_DPLL_ABE_DEFFREQ                         98304000
+
 /* Root clocks */
 
 DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0);
@@ -124,6 +132,8 @@ static struct dpll_data dpll_abe_dd = {
        .enable_mask    = OMAP4430_DPLL_EN_MASK,
        .autoidle_mask  = OMAP4430_AUTO_DPLL_MODE_MASK,
        .idlest_mask    = OMAP4430_ST_DPLL_CLK_MASK,
+       .m4xen_mask     = OMAP4430_DPLL_REGM4XEN_MASK,
+       .lpmode_mask    = OMAP4430_DPLL_LPMODE_EN_MASK,
        .max_multiplier = 2047,
        .max_divider    = 128,
        .min_divider    = 1,
@@ -233,7 +243,7 @@ static struct dpll_data dpll_core_dd = {
 
 
 static const char *dpll_core_ck_parents[] = {
-       "sys_clkin_ck",
+       "sys_clkin_ck", "core_hsd_byp_clk_mux_ck"
 };
 
 static struct clk dpll_core_ck;
@@ -286,9 +296,9 @@ DEFINE_CLK_DIVIDER(div_core_ck, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, 0x0,
                   OMAP4430_CM_CLKSEL_CORE, OMAP4430_CLKSEL_CORE_SHIFT,
                   OMAP4430_CLKSEL_CORE_WIDTH, 0x0, NULL);
 
-DEFINE_CLK_OMAP_HSDIVIDER(div_iva_hs_clk, "dpll_core_m5x2_ck",
-                         &dpll_core_m5x2_ck, 0x0, OMAP4430_CM_BYPCLK_DPLL_IVA,
-                         OMAP4430_CLKSEL_0_1_MASK);
+DEFINE_CLK_DIVIDER(div_iva_hs_clk, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck,
+                  0x0, OMAP4430_CM_BYPCLK_DPLL_IVA, OMAP4430_CLKSEL_0_1_SHIFT,
+                  OMAP4430_CLKSEL_0_1_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
 
 DEFINE_CLK_DIVIDER(div_mpu_hs_clk, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck,
                   0x0, OMAP4430_CM_BYPCLK_DPLL_MPU, OMAP4430_CLKSEL_0_1_SHIFT,
@@ -363,8 +373,21 @@ static struct dpll_data dpll_iva_dd = {
        .min_divider    = 1,
 };
 
+static const char *dpll_iva_ck_parents[] = {
+       "sys_clkin_ck", "iva_hsd_byp_clk_mux_ck"
+};
+
 static struct clk dpll_iva_ck;
 
+static const struct clk_ops dpll_ck_ops = {
+       .enable         = &omap3_noncore_dpll_enable,
+       .disable        = &omap3_noncore_dpll_disable,
+       .recalc_rate    = &omap3_dpll_recalc,
+       .round_rate     = &omap2_dpll_round_rate,
+       .set_rate       = &omap3_noncore_dpll_set_rate,
+       .get_parent     = &omap2_init_dpll_parent,
+};
+
 static struct clk_hw_omap dpll_iva_ck_hw = {
        .hw = {
                .clk = &dpll_iva_ck,
@@ -373,7 +396,7 @@ static struct clk_hw_omap dpll_iva_ck_hw = {
        .ops            = &clkhwops_omap3_dpll,
 };
 
-DEFINE_STRUCT_CLK(dpll_iva_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+DEFINE_STRUCT_CLK(dpll_iva_ck, dpll_iva_ck_parents, dpll_ck_ops);
 
 static const char *dpll_iva_x2_ck_parents[] = {
        "dpll_iva_ck",
@@ -416,6 +439,10 @@ static struct dpll_data dpll_mpu_dd = {
        .min_divider    = 1,
 };
 
+static const char *dpll_mpu_ck_parents[] = {
+       "sys_clkin_ck", "div_mpu_hs_clk"
+};
+
 static struct clk dpll_mpu_ck;
 
 static struct clk_hw_omap dpll_mpu_ck_hw = {
@@ -426,7 +453,7 @@ static struct clk_hw_omap dpll_mpu_ck_hw = {
        .ops            = &clkhwops_omap3_dpll,
 };
 
-DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_mpu_ck_parents, dpll_ck_ops);
 
 DEFINE_CLK_FIXED_FACTOR(mpu_periphclk, "dpll_mpu_ck", &dpll_mpu_ck, 0x0, 1, 2);
 
@@ -464,6 +491,9 @@ static struct dpll_data dpll_per_dd = {
        .min_divider    = 1,
 };
 
+static const char *dpll_per_ck_parents[] = {
+       "sys_clkin_ck", "per_hsd_byp_clk_mux_ck"
+};
 
 static struct clk dpll_per_ck;
 
@@ -475,7 +505,7 @@ static struct clk_hw_omap dpll_per_ck_hw = {
        .ops            = &clkhwops_omap3_dpll,
 };
 
-DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+DEFINE_STRUCT_CLK(dpll_per_ck, dpll_per_ck_parents, dpll_ck_ops);
 
 DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
                   OMAP4430_CM_DIV_M2_DPLL_PER, OMAP4430_DPLL_CLKOUT_DIV_SHIFT,
@@ -559,6 +589,10 @@ static struct dpll_data dpll_usb_dd = {
        .min_divider    = 1,
 };
 
+static const char *dpll_usb_ck_parents[] = {
+       "sys_clkin_ck", "usb_hs_clk_div_ck"
+};
+
 static struct clk dpll_usb_ck;
 
 static struct clk_hw_omap dpll_usb_ck_hw = {
@@ -569,7 +603,7 @@ static struct clk_hw_omap dpll_usb_ck_hw = {
        .ops            = &clkhwops_omap3_dpll,
 };
 
-DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_usb_ck_parents, dpll_ck_ops);
 
 static const char *dpll_usb_clkdcoldo_ck_parents[] = {
        "dpll_usb_ck",
@@ -696,9 +730,13 @@ DEFINE_CLK_DIVIDER(syc_clk_div_ck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
                   OMAP4430_CM_ABE_DSS_SYS_CLKSEL, OMAP4430_CLKSEL_0_0_SHIFT,
                   OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL);
 
+static const char *dbgclk_mux_ck_parents[] = {
+       "sys_clkin_ck"
+};
+
 static struct clk dbgclk_mux_ck;
 DEFINE_STRUCT_CLK_HW_OMAP(dbgclk_mux_ck, NULL);
-DEFINE_STRUCT_CLK(dbgclk_mux_ck, dpll_core_ck_parents,
+DEFINE_STRUCT_CLK(dbgclk_mux_ck, dbgclk_mux_ck_parents,
                  dpll_usb_clkdcoldo_ck_ops);
 
 /* Leaf clocks controlled by modules */
@@ -1935,10 +1973,10 @@ static struct omap_clk omap44xx_clks[] = {
        CLK("4803e000.timer",   "timer_sys_ck", &sys_clkin_ck,  CK_443X),
        CLK("48086000.timer",   "timer_sys_ck", &sys_clkin_ck,  CK_443X),
        CLK("48088000.timer",   "timer_sys_ck", &sys_clkin_ck,  CK_443X),
-       CLK("49038000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
-       CLK("4903a000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
-       CLK("4903c000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
-       CLK("4903e000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
+       CLK("40138000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
+       CLK("4013a000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
+       CLK("4013c000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
+       CLK("4013e000.timer",   "timer_sys_ck", &syc_clk_div_ck,        CK_443X),
        CLK(NULL,       "cpufreq_ck",   &dpll_mpu_ck,   CK_443X),
 };
 
@@ -1955,6 +1993,7 @@ int __init omap4xxx_clk_init(void)
 {
        u32 cpu_clkflg;
        struct omap_clk *c;
+       int rc;
 
        if (cpu_is_omap443x()) {
                cpu_mask = RATE_IN_4430;
@@ -1983,5 +2022,18 @@ int __init omap4xxx_clk_init(void)
        omap2_clk_enable_init_clocks(enable_init_clks,
                                     ARRAY_SIZE(enable_init_clks));
 
+       /*
+        * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power
+        * state when turning the ABE clock domain. Workaround this by
+        * locking the ABE DPLL on boot.
+        */
+       if (cpu_is_omap446x()) {
+               rc = clk_set_parent(&abe_dpll_refclk_mux_ck, &sys_32k_ck);
+               if (!rc)
+                       rc = clk_set_rate(&dpll_abe_ck, OMAP4_DPLL_ABE_DEFFREQ);
+               if (rc)
+                       pr_err("%s: failed to configure ABE DPLL!\n", __func__);
+       }
+
        return 0;
 }
index 9917f79..b402048 100644 (file)
@@ -195,6 +195,10 @@ struct clksel {
  * @enable_mask: mask of the DPLL mode bitfield in @control_reg
  * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
  * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
+ * @last_rounded_m4xen: cache of the last M4X result of
+ *                     omap4_dpll_regm4xen_round_rate()
+ * @last_rounded_lpmode: cache of the last lpmode result of
+ *                      omap4_dpll_lpmode_recalc()
  * @max_multiplier: maximum valid non-bypass multiplier value (actual)
  * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
  * @min_divider: minimum valid non-bypass divider value (actual)
@@ -205,6 +209,8 @@ struct clksel {
  * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
  * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
  * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
+ * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg
+ * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg
  * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg
  * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs
  * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs
@@ -233,6 +239,8 @@ struct dpll_data {
        u32                     enable_mask;
        unsigned long           last_rounded_rate;
        u16                     last_rounded_m;
+       u8                      last_rounded_m4xen;
+       u8                      last_rounded_lpmode;
        u16                     max_multiplier;
        u8                      last_rounded_n;
        u8                      min_divider;
@@ -245,6 +253,8 @@ struct dpll_data {
        u32                     idlest_mask;
        u32                     dco_mask;
        u32                     sddiv_mask;
+       u32                     lpmode_mask;
+       u32                     m4xen_mask;
        u8                      auto_recal_bit;
        u8                      recal_en_bit;
        u8                      recal_st_bit;
index 3848735..7faf82d 100644 (file)
@@ -998,7 +998,8 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
        spin_lock_irqsave(&clkdm->lock, flags);
 
        /* corner case: disabling unused clocks */
-       if (__clk_get_enable_count(clk) == 0)
+       if ((__clk_get_enable_count(clk) == 0) &&
+           (atomic_read(&clkdm->usecount) == 0))
                goto ccd_exit;
 
        if (atomic_read(&clkdm->usecount) == 0) {
index 5c2fd48..2dabb9e 100644 (file)
@@ -16,8 +16,6 @@
 #include <linux/init.h>
 #include <linux/platform_data/dsp-omap.h>
 
-#include <plat/vram.h>
-
 #include "common.h"
 #include "omap-secure.h"
 
@@ -32,7 +30,6 @@ int __weak omap_secure_ram_reserve_memblock(void)
 
 void __init omap_reserve(void)
 {
-       omap_vram_reserve_sdram_memblock();
        omap_dsp_reserve_sdram_memblock();
        omap_secure_ram_reserve_memblock();
        omap_barrier_reserve_memblock();
index bca7a88..22590db 100644 (file)
@@ -40,6 +40,8 @@ struct omap3_idle_statedata {
        u32 core_state;
 };
 
+static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+
 static struct omap3_idle_statedata omap3_idle_data[] = {
        {
                .mpu_state = PWRDM_POWER_ON,
@@ -71,7 +73,7 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
        },
 };
 
-static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+/* Private functions */
 
 static int __omap3_enter_idle(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv,
@@ -260,11 +262,11 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
        return ret;
 }
 
-DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
+static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
 
-struct cpuidle_driver omap3_idle_driver = {
-       .name =         "omap3_idle",
-       .owner =        THIS_MODULE,
+static struct cpuidle_driver omap3_idle_driver = {
+       .name =         "omap3_idle",
+       .owner =        THIS_MODULE,
        .states = {
                {
                        .enter            = omap3_enter_idle_bm,
@@ -327,6 +329,8 @@ struct cpuidle_driver omap3_idle_driver = {
        .safe_state_index = 0,
 };
 
+/* Public functions */
+
 /**
  * omap3_idle_init - Init routine for OMAP3 idle
  *
index 288bee6..d639aef 100644 (file)
@@ -54,6 +54,8 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
 
+/* Private functions */
+
 /**
  * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
  * @dev: cpuidle device
@@ -161,9 +163,19 @@ fail:
        return index;
 }
 
-DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
+/*
+ * For each cpu, setup the broadcast timer because local timers
+ * stops for the states above C1.
+ */
+static void omap_setup_broadcast_timer(void *arg)
+{
+       int cpu = smp_processor_id();
+       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+}
+
+static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
 
-struct cpuidle_driver omap4_idle_driver = {
+static struct cpuidle_driver omap4_idle_driver = {
        .name                           = "omap4_idle",
        .owner                          = THIS_MODULE,
        .en_core_tk_irqen               = 1,
@@ -178,7 +190,7 @@ struct cpuidle_driver omap4_idle_driver = {
                        .desc = "MPUSS ON"
                },
                {
-                        /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
+                       /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
                        .exit_latency = 328 + 440,
                        .target_residency = 960,
                        .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
@@ -200,15 +212,7 @@ struct cpuidle_driver omap4_idle_driver = {
        .safe_state_index = 0,
 };
 
-/*
- * For each cpu, setup the broadcast timer because local timers
- * stops for the states above C1.
- */
-static void omap_setup_broadcast_timer(void *arg)
-{
-       int cpu = smp_processor_id();
-       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-}
+/* Public functions */
 
 /**
  * omap4_idle_init - Init routine for OMAP4 idle
index fafb28c..2bb1883 100644 (file)
@@ -291,16 +291,13 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
 
 /*
  * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
- * @clk: struct clk * of DPLL to set
- * @m: DPLL multiplier to set
- * @n: DPLL divider to set
- * @freqsel: FREQSEL value to set
+ * @clk:       struct clk * of DPLL to set
+ * @freqsel:   FREQSEL value to set
  *
- * Program the DPLL with the supplied M, N values, and wait for the DPLL to
- * lock..  Returns -EINVAL upon error, or 0 upon success.
+ * Program the DPLL with the last M, N values calculated, and wait for
+ * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success.
  */
-static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n,
-                                     u16 freqsel)
+static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)
 {
        struct dpll_data *dd = clk->dpll_data;
        u8 dco, sd_div;
@@ -323,23 +320,45 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n,
        /* Set DPLL multiplier, divider */
        v = __raw_readl(dd->mult_div1_reg);
        v &= ~(dd->mult_mask | dd->div1_mask);
-       v |= m << __ffs(dd->mult_mask);
-       v |= (n - 1) << __ffs(dd->div1_mask);
+       v |= dd->last_rounded_m << __ffs(dd->mult_mask);
+       v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask);
 
        /* Configure dco and sd_div for dplls that have these fields */
        if (dd->dco_mask) {
-               _lookup_dco(clk, &dco, m, n);
+               _lookup_dco(clk, &dco, dd->last_rounded_m, dd->last_rounded_n);
                v &= ~(dd->dco_mask);
                v |= dco << __ffs(dd->dco_mask);
        }
        if (dd->sddiv_mask) {
-               _lookup_sddiv(clk, &sd_div, m, n);
+               _lookup_sddiv(clk, &sd_div, dd->last_rounded_m,
+                             dd->last_rounded_n);
                v &= ~(dd->sddiv_mask);
                v |= sd_div << __ffs(dd->sddiv_mask);
        }
 
        __raw_writel(v, dd->mult_div1_reg);
 
+       /* Set 4X multiplier and low-power mode */
+       if (dd->m4xen_mask || dd->lpmode_mask) {
+               v = __raw_readl(dd->control_reg);
+
+               if (dd->m4xen_mask) {
+                       if (dd->last_rounded_m4xen)
+                               v |= dd->m4xen_mask;
+                       else
+                               v &= ~dd->m4xen_mask;
+               }
+
+               if (dd->lpmode_mask) {
+                       if (dd->last_rounded_lpmode)
+                               v |= dd->lpmode_mask;
+                       else
+                               v &= ~dd->lpmode_mask;
+               }
+
+               __raw_writel(v, dd->control_reg);
+       }
+
        /* We let the clock framework set the other output dividers later */
 
        /* REVISIT: Set ramp-up delay? */
@@ -492,8 +511,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
                pr_debug("%s: %s: set rate: locking rate to %lu.\n",
                         __func__, __clk_get_name(hw->clk), rate);
 
-               ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
-                                               dd->last_rounded_n, freqsel);
+               ret = omap3_noncore_dpll_program(clk, freqsel);
                if (!ret)
                        new_parent = dd->clk_ref;
        }
index d3326c4..d28b0f7 100644 (file)
 #include "clock44xx.h"
 #include "cm-regbits-44xx.h"
 
+/*
+ * Maximum DPLL input frequency (FINT) and output frequency (FOUT) that
+ * can supported when using the DPLL low-power mode. Frequencies are
+ * defined in OMAP4430/60 Public TRM section 3.6.3.3.2 "Enable Control,
+ * Status, and Low-Power Operation Mode".
+ */
+#define OMAP4_DPLL_LP_FINT_MAX 1000000
+#define OMAP4_DPLL_LP_FOUT_MAX 100000000
+
 /* Supported only on OMAP4 */
 int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
 {
@@ -82,6 +91,31 @@ const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
 };
 
 /**
+ * omap4_dpll_lpmode_recalc - compute DPLL low-power setting
+ * @dd: pointer to the dpll data structure
+ *
+ * Calculates if low-power mode can be enabled based upon the last
+ * multiplier and divider values calculated. If low-power mode can be
+ * enabled, then the bit to enable low-power mode is stored in the
+ * last_rounded_lpmode variable. This implementation is based upon the
+ * criteria for enabling low-power mode as described in the OMAP4430/60
+ * Public TRM section 3.6.3.3.2 "Enable Control, Status, and Low-Power
+ * Operation Mode".
+ */
+static void omap4_dpll_lpmode_recalc(struct dpll_data *dd)
+{
+       long fint, fout;
+
+       fint = __clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1);
+       fout = fint * dd->last_rounded_m;
+
+       if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX))
+               dd->last_rounded_lpmode = 1;
+       else
+               dd->last_rounded_lpmode = 0;
+}
+
+/**
  * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit
  * @clk: struct clk * of the DPLL to compute the rate for
  *
@@ -130,7 +164,6 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
                                    unsigned long *parent_rate)
 {
        struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-       u32 v;
        struct dpll_data *dd;
        long r;
 
@@ -139,18 +172,31 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
 
        dd = clk->dpll_data;
 
-       /* regm4xen adds a multiplier of 4 to DPLL calculations */
-       v = __raw_readl(dd->control_reg) & OMAP4430_DPLL_REGM4XEN_MASK;
-
-       if (v)
-               target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
+       dd->last_rounded_m4xen = 0;
 
+       /*
+        * First try to compute the DPLL configuration for
+        * target rate without using the 4X multiplier.
+        */
        r = omap2_dpll_round_rate(hw, target_rate, NULL);
+       if (r != ~0)
+               goto out;
+
+       /*
+        * If we did not find a valid DPLL configuration, try again, but
+        * this time see if using the 4X multiplier can help. Enabling the
+        * 4X multiplier is equivalent to dividing the target rate by 4.
+        */
+       r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT,
+                                 NULL);
        if (r == ~0)
                return r;
 
-       if (v)
-               clk->dpll_data->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
+       dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
+       dd->last_rounded_m4xen = 1;
+
+out:
+       omap4_dpll_lpmode_recalc(dd);
 
-       return clk->dpll_data->last_rounded_rate;
+       return dd->last_rounded_rate;
 }
index 2612634..6a217c9 100644 (file)
@@ -135,10 +135,7 @@ static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
 
        old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
        mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
-       if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
-               mux_mode |= OMAP_MUX_MODE3;
-       else
-               mux_mode |= OMAP_MUX_MODE4;
+       mux_mode |= partition->gpio;
        pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
                 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
        omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
@@ -800,7 +797,7 @@ int __init omap_mux_late_init(void)
                        struct omap_mux *m = &e->mux;
                        u16 mode = omap_mux_read(partition, m->reg_offset);
 
-                       if (OMAP_MODE_GPIO(mode))
+                       if (OMAP_MODE_GPIO(partition, mode))
                                continue;
 
 #ifndef CONFIG_DEBUG_FS
@@ -1065,7 +1062,7 @@ static void __init omap_mux_init_list(struct omap_mux_partition *partition,
                }
 #else
                /* Skip pins that are not muxed as GPIO by bootloader */
-               if (!OMAP_MODE_GPIO(omap_mux_read(partition,
+               if (!OMAP_MODE_GPIO(partition, omap_mux_read(partition,
                                    superset->reg_offset))) {
                        superset++;
                        continue;
@@ -1132,6 +1129,7 @@ int __init omap_mux_init(const char *name, u32 flags,
 
        partition->name = name;
        partition->flags = flags;
+       partition->gpio = flags & OMAP_MUX_MODE7;
        partition->size = mux_size;
        partition->phys = mux_pbase;
        partition->base = ioremap(mux_pbase, mux_size);
index 76f9b3c..fdb22f1 100644 (file)
@@ -58,7 +58,8 @@
 #define OMAP_PIN_OFF_INPUT_PULLDOWN    (OMAP_OFF_EN | OMAP_OFF_PULL_EN)
 #define OMAP_PIN_OFF_WAKEUPENABLE      OMAP_WAKEUP_EN
 
-#define OMAP_MODE_GPIO(x)      (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
+#define OMAP_MODE_GPIO(partition, x)   (((x) & OMAP_MUX_MODE7) == \
+                                         partition->gpio)
 #define OMAP_MODE_UART(x)      (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0)
 
 /* Flags for omapX_mux_init */
 /*
  * omap_mux_init flags definition:
  *
+ * OMAP_GPIO_MUX_MODE, bits 0-2: gpio muxing mode, same like pad control
+ *      register which includes values from 0-7.
  * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
  * The default value is 16 bits.
- * OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.
- * The default is mode4.
  */
-#define OMAP_MUX_REG_8BIT              (1 << 0)
-#define OMAP_MUX_GPIO_IN_MODE3         (1 << 1)
+#define OMAP_MUX_GPIO_IN_MODE0         OMAP_MUX_MODE0
+#define OMAP_MUX_GPIO_IN_MODE1         OMAP_MUX_MODE1
+#define OMAP_MUX_GPIO_IN_MODE2         OMAP_MUX_MODE2
+#define OMAP_MUX_GPIO_IN_MODE3         OMAP_MUX_MODE3
+#define OMAP_MUX_GPIO_IN_MODE4         OMAP_MUX_MODE4
+#define OMAP_MUX_GPIO_IN_MODE5         OMAP_MUX_MODE5
+#define OMAP_MUX_GPIO_IN_MODE6         OMAP_MUX_MODE6
+#define OMAP_MUX_GPIO_IN_MODE7         OMAP_MUX_MODE7
+#define OMAP_MUX_REG_8BIT              (1 << 3)
 
 /**
  * struct omap_board_data - board specific device data
@@ -105,6 +113,7 @@ struct omap_board_data {
  * struct mux_partition - contain partition related information
  * @name: name of the current partition
  * @flags: flags specific to this partition
+ * @gpio: gpio mux mode
  * @phys: physical address
  * @size: partition size
  * @base: virtual address after ioremap
@@ -114,6 +123,7 @@ struct omap_board_data {
 struct omap_mux_partition {
        const char              *name;
        u32                     flags;
+       u32                     gpio;
        u32                     phys;
        u32                     size;
        void __iomem            *base;
index c47140b..c53609f 100644 (file)
@@ -2053,7 +2053,7 @@ int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
                return -EINVAL;
        }
 
-       return omap_mux_init("core", 0,
+       return omap_mux_init("core", OMAP_MUX_GPIO_IN_MODE4,
                             OMAP3_CONTROL_PADCONF_MUX_PBASE,
                             OMAP3_CONTROL_PADCONF_MUX_SIZE,
                             omap3_muxmodes, package_subset, board_subset,
index 93d1025..04fdbc4 100644 (file)
@@ -27,8 +27,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/console.h>
 #include <linux/omap-dma.h>
-
-#include <plat/omap-serial.h>
+#include <linux/platform_data/serial-omap.h>
 
 #include "common.h"
 #include "omap_hwmod.h"
index 7016637..06e1415 100644 (file)
@@ -190,7 +190,7 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,
  * kernel registering these devices remove them dynamically from the device
  * tree on boot.
  */
-void __init omap_dmtimer_init(void)
+static void __init omap_dmtimer_init(void)
 {
        struct device_node *np;
 
@@ -210,7 +210,7 @@ void __init omap_dmtimer_init(void)
  *
  * Get the timer errata flags that are specific to the OMAP device being used.
  */
-u32 __init omap_dm_timer_get_errata(void)
+static u32 __init omap_dm_timer_get_errata(void)
 {
        if (cpu_is_omap24xx())
                return 0;
@@ -392,7 +392,7 @@ static struct of_device_id omap_counter_match[] __initdata = {
 };
 
 /* Setup free-running counter for clocksource */
-static int __init omap2_sync32k_clocksource_init(void)
+static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
 {
        int ret;
        struct device_node *np = NULL;
index d1dbe12..2e44e8a 100644 (file)
@@ -508,6 +508,10 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
        if (cpu_is_omap34xx()) {
                setup_ehci_io_mux(pdata->port_mode);
                setup_ohci_io_mux(pdata->port_mode);
+
+               if (omap_rev() <= OMAP3430_REV_ES2_1)
+                       usbhs_data.single_ulpi_bypass = true;
+
        } else if (cpu_is_omap44xx()) {
                setup_4430ehci_io_mux(pdata->port_mode);
                setup_4430ohci_io_mux(pdata->port_mode);
index 0816562..d54cfc5 100644 (file)
@@ -104,7 +104,7 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
 static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
        /* name         parent          rate            enabled */
        { "clk_m",      NULL,           0,              true },
-       { "pll_p",      "clk_m",        408000000,      true },
+       { "pll_p",      "pll_ref",      408000000,      true },
        { "pll_p_out1", "pll_p",        9600000,        true },
        { "pll_p_out4", "pll_p",        102000000,      true },
        { "sclk",       "pll_p_out4",   102000000,      true },
index efc000e..d714777 100644 (file)
@@ -2045,9 +2045,7 @@ struct clk_ops tegra30_periph_clk_ops = {
 static int tegra30_dsib_clk_set_parent(struct clk_hw *hw, u8 index)
 {
        struct clk *d = clk_get_sys(NULL, "pll_d");
-       /* The DSIB parent selection bit is in PLLD base
-          register - can not do direct r-m-w, must be
-          protected by PLLD lock */
+       /* The DSIB parent selection bit is in PLLD base register */
        tegra_clk_cfg_ex(
                d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, index);
 
index 12f3994..4ce77cd 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
 #include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_data/clk-u300.h>
@@ -250,6 +249,18 @@ static struct resource rtc_resources[] = {
  */
 static struct resource fsmc_resources[] = {
        {
+               .name  = "nand_addr",
+               .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
+               .end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name  = "nand_cmd",
+               .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
+               .end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
                .name  = "nand_data",
                .start = U300_NAND_CS0_PHYS_BASE,
                .end   = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
@@ -1492,8 +1503,6 @@ static struct fsmc_nand_platform_data nand_platform_data = {
        .nr_partitions = ARRAY_SIZE(u300_partitions),
        .options = NAND_SKIP_BBTSCAN,
        .width = FSMC_NAND_BW8,
-       .ale_off = PLAT_NAND_ALE,
-       .cle_off = PLAT_NAND_CLE,
 };
 
 static struct platform_device nand_device = {
@@ -1543,39 +1552,6 @@ static struct pinctrl_map __initdata u300_pinmux_map[] = {
                                    pin_highz_conf),
 };
 
-struct u300_mux_hog {
-       struct device *dev;
-       struct pinctrl *p;
-};
-
-static struct u300_mux_hog u300_mux_hogs[] = {
-       {
-               .dev = &uart0_device.dev,
-       },
-       {
-               .dev = &mmcsd_device.dev,
-       },
-};
-
-static int __init u300_pinctrl_fetch(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
-               struct pinctrl *p;
-
-               p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
-               if (IS_ERR(p)) {
-                       pr_err("u300: could not get pinmux hog for dev %s\n",
-                              dev_name(u300_mux_hogs[i].dev));
-                       continue;
-               }
-               u300_mux_hogs[i].p = p;
-       }
-       return 0;
-}
-subsys_initcall(u300_pinctrl_fetch);
-
 /*
  * Notice that AMBA devices are initialized before platform devices.
  *
index 4b24c99..a5e05f6 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef __DEVICES_DB8500_H
 #define __DEVICES_DB8500_H
 
+#include <linux/platform_data/usb-musb-ux500.h>
 #include <mach/irqs.h>
 #include "devices-common.h"
 
index 8d88584..9d9aa2f 100644 (file)
@@ -11,7 +11,6 @@ obj-  :=
 # omap_device support (OMAP2+ only at the moment)
 
 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
-obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
 obj-y += $(i2c-omap-m) $(i2c-omap-y)
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
deleted file mode 100644 (file)
index a609e21..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/debug-devices.c
- *
- * Copyright (C) 2005 Nokia Corporation
- * Modified from mach-omap2/board-h4.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/smc91x.h>
-
-#include <plat/debug-devices.h>
-
-/* Many OMAP development platforms reuse the same "debug board"; these
- * platforms include H2, H3, H4, and Perseus2.
- */
-
-static struct smc91x_platdata smc91x_info = {
-       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
-       .leda   = RPC_LED_100_10,
-       .ledb   = RPC_LED_TX_RX,
-};
-
-static struct resource smc91x_resources[] = {
-       [0] = {
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
-       },
-};
-
-static struct platform_device smc91x_device = {
-       .name           = "smc91x",
-       .id             = -1,
-       .dev            = {
-               .platform_data = &smc91x_info,
-       },
-       .num_resources  = ARRAY_SIZE(smc91x_resources),
-       .resource       = smc91x_resources,
-};
-
-static struct resource led_resources[] = {
-       [0] = {
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device led_device = {
-       .name           = "omap_dbg_led",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(led_resources),
-       .resource       = led_resources,
-};
-
-static struct platform_device *debug_devices[] __initdata = {
-       &smc91x_device,
-       &led_device,
-       /* ps2 kbd + mouse ports */
-       /* 4 extra uarts */
-       /* 6 input dip switches */
-       /* 8 output pins */
-};
-
-int __init debug_card_init(u32 addr, unsigned gpio)
-{
-       int     status;
-
-       smc91x_resources[0].start = addr + 0x300;
-       smc91x_resources[0].end   = addr + 0x30f;
-
-       smc91x_resources[1].start = gpio_to_irq(gpio);
-       smc91x_resources[1].end   = gpio_to_irq(gpio);
-
-       status = gpio_request(gpio, "SMC91x irq");
-       if (status < 0) {
-               printk(KERN_ERR "GPIO%d unavailable for smc91x IRQ\n", gpio);
-               return status;
-       }
-       gpio_direction_input(gpio);
-
-       led_resources[0].start = addr;
-       led_resources[0].end   = addr + SZ_4K - 1;
-
-       return platform_add_devices(debug_devices, ARRAY_SIZE(debug_devices));
-}
diff --git a/arch/arm/plat-omap/include/plat/debug-devices.h b/arch/arm/plat-omap/include/plat/debug-devices.h
deleted file mode 100644 (file)
index 8fc4287..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* for TI reference platforms sharing the same debug card */
-extern int debug_card_init(u32 addr, unsigned gpio);
index 7a192e1..1f0fc7a 100644 (file)
@@ -1,4 +1 @@
-header-y += user.h
-header-y += svinto.h
-header-y += sv_addr_ag.h
-header-y += sv_addr.agh
+# CRISv10 arch
index 35f2fc4..2fd65c7 100644 (file)
@@ -1,2 +1 @@
-header-y += user.h
-header-y += cryptocop.h
+# CRISv32 arch
index e1cd83d..716e434 100644 (file)
  * The device /dev/cryptocop is accessible using this driver using
  * CRYPTOCOP_MAJOR (254) and minor number 0.
  */
-
 #ifndef CRYPTOCOP_H
 #define CRYPTOCOP_H
 
-#include <linux/uio.h>
-
-
-#define CRYPTOCOP_SESSION_ID_NONE (0)
-
-typedef unsigned long long int cryptocop_session_id;
-
-/* cryptocop ioctls */
-#define ETRAXCRYPTOCOP_IOCTYPE         (250)
-
-#define CRYPTOCOP_IO_CREATE_SESSION    _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 1, struct strcop_session_op)
-#define CRYPTOCOP_IO_CLOSE_SESSION     _IOW(ETRAXCRYPTOCOP_IOCTYPE, 2, struct strcop_session_op)
-#define CRYPTOCOP_IO_PROCESS_OP        _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 3, struct strcop_crypto_op)
-#define CRYPTOCOP_IO_MAXNR             (3)
-
-typedef enum {
-       cryptocop_cipher_des = 0,
-       cryptocop_cipher_3des = 1,
-       cryptocop_cipher_aes = 2,
-       cryptocop_cipher_m2m = 3, /* mem2mem is essentially a NULL cipher with blocklength=1 */
-       cryptocop_cipher_none
-} cryptocop_cipher_type;
-
-typedef enum {
-       cryptocop_digest_sha1 = 0,
-       cryptocop_digest_md5 = 1,
-       cryptocop_digest_none
-} cryptocop_digest_type;
-
-typedef enum {
-       cryptocop_csum_le = 0,
-       cryptocop_csum_be = 1,
-       cryptocop_csum_none
-} cryptocop_csum_type;
-
-typedef enum {
-       cryptocop_cipher_mode_ecb = 0,
-       cryptocop_cipher_mode_cbc,
-       cryptocop_cipher_mode_none
-} cryptocop_cipher_mode;
-
-typedef enum {
-       cryptocop_3des_eee = 0,
-       cryptocop_3des_eed = 1,
-       cryptocop_3des_ede = 2,
-       cryptocop_3des_edd = 3,
-       cryptocop_3des_dee = 4,
-       cryptocop_3des_ded = 5,
-       cryptocop_3des_dde = 6,
-       cryptocop_3des_ddd = 7
-} cryptocop_3des_mode;
-
-/* Usermode accessible (ioctl) operations. */
-struct strcop_session_op{
-       cryptocop_session_id    ses_id;
-
-       cryptocop_cipher_type   cipher; /* AES, DES, 3DES, m2m, none */
-
-       cryptocop_cipher_mode   cmode; /* ECB, CBC, none */
-       cryptocop_3des_mode     des3_mode;
-
-       cryptocop_digest_type   digest; /* MD5, SHA1, none */
-
-       cryptocop_csum_type     csum;   /* BE, LE, none */
-
-       unsigned char           *key;
-       size_t                  keylen;
-};
-
-#define CRYPTOCOP_CSUM_LENGTH         (2)
-#define CRYPTOCOP_MAX_DIGEST_LENGTH   (20)  /* SHA-1 20, MD5 16 */
-#define CRYPTOCOP_MAX_IV_LENGTH       (16)  /* (3)DES==8, AES == 16 */
-#define CRYPTOCOP_MAX_KEY_LENGTH      (32)
-
-struct strcop_crypto_op{
-       cryptocop_session_id ses_id;
-
-       /* Indata. */
-       unsigned char            *indata;
-       size_t                   inlen; /* Total indata length. */
-
-       /* Cipher configuration. */
-       unsigned char            do_cipher:1;
-       unsigned char            decrypt:1; /* 1 == decrypt, 0 == encrypt */
-       unsigned char            cipher_explicit:1;
-       size_t                   cipher_start;
-       size_t                   cipher_len;
-       /* cipher_iv is used if do_cipher and cipher_explicit and the cipher
-          mode is CBC.  The length is controlled by the type of cipher,
-          e.g. DES/3DES 8 octets and AES 16 octets. */
-       unsigned char            cipher_iv[CRYPTOCOP_MAX_IV_LENGTH];
-       /* Outdata. */
-       unsigned char            *cipher_outdata;
-       size_t                   cipher_outlen;
-
-       /* digest configuration. */
-       unsigned char            do_digest:1;
-       size_t                   digest_start;
-       size_t                   digest_len;
-       /* Outdata.  The actual length is determined by the type of the digest. */
-       unsigned char            digest[CRYPTOCOP_MAX_DIGEST_LENGTH];
-
-       /* Checksum configuration. */
-       unsigned char            do_csum:1;
-       size_t                   csum_start;
-       size_t                   csum_len;
-       /* Outdata. */
-       unsigned char            csum[CRYPTOCOP_CSUM_LENGTH];
-};
+#include <uapi/arch-v32/arch/cryptocop.h>
 
 
-
-#ifdef __KERNEL__
-
 /********** The API to use from inside the kernel. ************/
 
 #include <arch/hwregs/dma.h>
@@ -267,6 +155,4 @@ int cryptocop_job_queue_insert_crypto(struct cryptocop_operation *operation);
 
 int cryptocop_job_queue_insert_user_job(struct cryptocop_operation *operation);
 
-#endif /* __KERNEL__ */
-
 #endif /* CRYPTOCOP_H */
index f171a66..f132755 100644 (file)
@@ -118,7 +118,7 @@ static  inline int arch_write_trylock(arch_rwlock_t *rw)
                ret = 1;
        }
        arch_spin_unlock(&rw->slock);
-       return 1;
+       return ret;
 }
 
 #define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock)
index 15a122c..f1e79ed 100644 (file)
@@ -1,12 +1,7 @@
-include include/asm-generic/Kbuild.asm
 
 header-y += arch-v10/
 header-y += arch-v32/
 
-header-y += ethernet.h
-header-y += etraxgpio.h
-header-y += rs485.h
-header-y += sync_serial.h
 
 generic-y += clkdev.h
 generic-y += exec.h
index 6618893..2de84d7 100644 (file)
@@ -1,9 +1,8 @@
 #ifndef _CRIS_PTRACE_H
 #define _CRIS_PTRACE_H
 
-#include <arch/ptrace.h>
+#include <uapi/asm/ptrace.h>
 
-#ifdef __KERNEL__
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 #define PTRACE_GETREGS            12
@@ -11,6 +10,4 @@
 
 #define profile_pc(regs) instruction_pointer(regs)
 
-#endif /* __KERNEL__ */
-
 #endif /* _CRIS_PTRACE_H */
index 72dbbf5..c0cb1fd 100644 (file)
@@ -1,12 +1,8 @@
 #ifndef _ASM_CRIS_SIGNAL_H
 #define _ASM_CRIS_SIGNAL_H
 
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
 
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-
-#ifdef __KERNEL__
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 
@@ -20,95 +16,6 @@ typedef struct {
        unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-#define NSIG           32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-#define SIGBUS          7
-#define SIGFPE          8
-#define SIGKILL                 9
-#define SIGUSR1                10
-#define SIGSEGV                11
-#define SIGUSR2                12
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGSTKFLT      16
-#define SIGCHLD                17
-#define SIGCONT                18
-#define SIGSTOP                19
-#define SIGTSTP                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGURG         23
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGIO          29
-#define SIGPOLL                SIGIO
-/*
-#define SIGLOST                29
-*/
-#define SIGPWR         30
-#define SIGSYS          31
-#define        SIGUNUSED       31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN        32
-#define SIGRTMAX        _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-
-#define SA_NOCLDSTOP   0x00000001u
-#define SA_NOCLDWAIT   0x00000002u
-#define SA_SIGINFO     0x00000004u
-#define SA_ONSTACK     0x08000000u
-#define SA_RESTART     0x10000000u
-#define SA_NODEFER     0x40000000u
-#define SA_RESETHAND   0x80000000u
-
-#define SA_NOMASK      SA_NODEFER
-#define SA_ONESHOT     SA_RESETHAND
-
-#define SA_RESTORER    0x04000000
-
-/* 
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    2048
-#define SIGSTKSZ       8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
 struct old_sigaction {
        __sighandler_t sa_handler;
        old_sigset_t sa_mask;
@@ -126,32 +33,6 @@ struct sigaction {
 struct k_sigaction {
        struct sigaction sa;
 };
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-struct sigaction {
-       union {
-         __sighandler_t _sa_handler;
-         void (*_sa_sigaction)(int, struct siginfo *, void *);
-       } _u;
-       sigset_t sa_mask;
-       unsigned long sa_flags;
-       void (*sa_restorer)(void);
-};
-
-#define sa_handler     _u._sa_handler
-#define sa_sigaction   _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
-       void *ss_sp;
-       int ss_flags;
-       size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
 #include <asm/sigcontext.h>
-#endif /* __KERNEL__ */
 
 #endif
index 80668e8..991b6ac 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _CRIS_SWAB_H
 #define _CRIS_SWAB_H
 
-#ifdef __KERNEL__
 #include <arch/swab.h>
-#endif /* __KERNEL__ */
+#include <uapi/asm/swab.h>
 
 #endif /* _CRIS_SWAB_H */
index 1265109..1991cd9 100644 (file)
@@ -1,47 +1,8 @@
 #ifndef _CRIS_TERMIOS_H
 #define _CRIS_TERMIOS_H
 
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-#include <asm/rs485.h>
-#include <linux/serial.h>
+#include <uapi/asm/termios.h>
 
-struct winsize {
-       unsigned short ws_row;
-       unsigned short ws_col;
-       unsigned short ws_xpixel;
-       unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-       unsigned short c_iflag;         /* input mode flags */
-       unsigned short c_oflag;         /* output mode flags */
-       unsigned short c_cflag;         /* control mode flags */
-       unsigned short c_lflag;         /* local mode flags */
-       unsigned char c_line;           /* line discipline */
-       unsigned char c_cc[NCC];        /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE       0x001
-#define TIOCM_DTR      0x002
-#define TIOCM_RTS      0x004
-#define TIOCM_ST       0x008
-#define TIOCM_SR       0x010
-#define TIOCM_CTS      0x020
-#define TIOCM_CAR      0x040
-#define TIOCM_RNG      0x080
-#define TIOCM_DSR      0x100
-#define TIOCM_CD       TIOCM_CAR
-#define TIOCM_RI       TIOCM_RNG
-#define TIOCM_OUT1     0x2000
-#define TIOCM_OUT2     0x4000
-#define TIOCM_LOOP     0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
 
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          vtime=\0        vmin=\1         sxtc=\0
@@ -87,6 +48,4 @@ struct termio {
 #define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
 #define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
 
-#endif /* __KERNEL__ */
-
 #endif /* _CRIS_TERMIOS_H */
index adaf827..a3cac77 100644 (file)
@@ -1,15 +1,12 @@
 #ifndef _ETRAX_TYPES_H
 #define _ETRAX_TYPES_H
 
-#include <asm-generic/int-ll64.h>
+#include <uapi/asm/types.h>
 
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
-#ifdef __KERNEL__
 
 #define BITS_PER_LONG 32
 
-#endif /* __KERNEL__ */
-
 #endif
index f27b542..89680f9 100644 (file)
@@ -1,347 +1,8 @@
 #ifndef _ASM_CRIS_UNISTD_H_
 #define _ASM_CRIS_UNISTD_H_
 
-/*
- * This file contains the system call numbers, and stub macros for libc.
- */
-
-#define __NR_restart_syscall      0
-#define __NR_exit                1
-#define __NR_fork                2
-#define __NR_read                3
-#define __NR_write               4
-#define __NR_open                5
-#define __NR_close               6
-#define __NR_waitpid             7
-#define __NR_creat               8
-#define __NR_link                9
-#define __NR_unlink             10
-#define __NR_execve             11
-#define __NR_chdir              12
-#define __NR_time               13
-#define __NR_mknod              14
-#define __NR_chmod              15
-#define __NR_lchown             16
-#define __NR_break              17
-#define __NR_oldstat            18
-#define __NR_lseek              19
-#define __NR_getpid             20
-#define __NR_mount              21
-#define __NR_umount             22
-#define __NR_setuid             23
-#define __NR_getuid             24
-#define __NR_stime              25
-#define __NR_ptrace             26
-#define __NR_alarm              27
-#define __NR_oldfstat           28
-#define __NR_pause              29
-#define __NR_utime              30
-#define __NR_stty               31
-#define __NR_gtty               32
-#define __NR_access             33
-#define __NR_nice               34
-#define __NR_ftime              35
-#define __NR_sync               36
-#define __NR_kill               37
-#define __NR_rename             38
-#define __NR_mkdir              39
-#define __NR_rmdir              40
-#define __NR_dup                41
-#define __NR_pipe               42
-#define __NR_times              43
-#define __NR_prof               44
-#define __NR_brk                45
-#define __NR_setgid             46
-#define __NR_getgid             47
-#define __NR_signal             48
-#define __NR_geteuid            49
-#define __NR_getegid            50
-#define __NR_acct               51
-#define __NR_umount2            52
-#define __NR_lock               53
-#define __NR_ioctl              54
-#define __NR_fcntl              55
-#define __NR_mpx                56
-#define __NR_setpgid            57
-#define __NR_ulimit             58
-#define __NR_oldolduname        59
-#define __NR_umask              60
-#define __NR_chroot             61
-#define __NR_ustat              62
-#define __NR_dup2               63
-#define __NR_getppid            64
-#define __NR_getpgrp            65
-#define __NR_setsid             66
-#define __NR_sigaction          67
-#define __NR_sgetmask           68
-#define __NR_ssetmask           69
-#define __NR_setreuid           70
-#define __NR_setregid           71
-#define __NR_sigsuspend                 72
-#define __NR_sigpending                 73
-#define __NR_sethostname        74
-#define __NR_setrlimit          75
-#define __NR_getrlimit          76
-#define __NR_getrusage          77
-#define __NR_gettimeofday       78
-#define __NR_settimeofday       79
-#define __NR_getgroups          80
-#define __NR_setgroups          81
-#define __NR_select             82
-#define __NR_symlink            83
-#define __NR_oldlstat           84
-#define __NR_readlink           85
-#define __NR_uselib             86
-#define __NR_swapon             87
-#define __NR_reboot             88
-#define __NR_readdir            89
-#define __NR_mmap               90
-#define __NR_munmap             91
-#define __NR_truncate           92
-#define __NR_ftruncate          93
-#define __NR_fchmod             94
-#define __NR_fchown             95
-#define __NR_getpriority        96
-#define __NR_setpriority        97
-#define __NR_profil             98
-#define __NR_statfs             99
-#define __NR_fstatfs           100
-#define __NR_ioperm            101
-#define __NR_socketcall                102
-#define __NR_syslog            103
-#define __NR_setitimer         104
-#define __NR_getitimer         105
-#define __NR_stat              106
-#define __NR_lstat             107
-#define __NR_fstat             108
-#define __NR_olduname          109
-#define __NR_iopl              110
-#define __NR_vhangup           111
-#define __NR_idle              112
-#define __NR_vm86              113
-#define __NR_wait4             114
-#define __NR_swapoff           115
-#define __NR_sysinfo           116
-#define __NR_ipc               117
-#define __NR_fsync             118
-#define __NR_sigreturn         119
-#define __NR_clone             120
-#define __NR_setdomainname     121
-#define __NR_uname             122
-#define __NR_modify_ldt                123
-#define __NR_adjtimex          124
-#define __NR_mprotect          125
-#define __NR_sigprocmask       126
-#define __NR_create_module     127
-#define __NR_init_module       128
-#define __NR_delete_module     129
-#define __NR_get_kernel_syms   130
-#define __NR_quotactl          131
-#define __NR_getpgid           132
-#define __NR_fchdir            133
-#define __NR_bdflush           134
-#define __NR_sysfs             135
-#define __NR_personality       136
-#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
-#define __NR_setfsuid          138
-#define __NR_setfsgid          139
-#define __NR__llseek           140
-#define __NR_getdents          141
-#define __NR__newselect                142
-#define __NR_flock             143
-#define __NR_msync             144
-#define __NR_readv             145
-#define __NR_writev            146
-#define __NR_getsid            147
-#define __NR_fdatasync         148
-#define __NR__sysctl           149
-#define __NR_mlock             150
-#define __NR_munlock           151
-#define __NR_mlockall          152
-#define __NR_munlockall                153
-#define __NR_sched_setparam            154
-#define __NR_sched_getparam            155
-#define __NR_sched_setscheduler                156
-#define __NR_sched_getscheduler                157
-#define __NR_sched_yield               158
-#define __NR_sched_get_priority_max    159
-#define __NR_sched_get_priority_min    160
-#define __NR_sched_rr_get_interval     161
-#define __NR_nanosleep         162
-#define __NR_mremap            163
-#define __NR_setresuid         164
-#define __NR_getresuid         165
-
-#define __NR_query_module      167
-#define __NR_poll              168
-#define __NR_nfsservctl                169
-#define __NR_setresgid         170
-#define __NR_getresgid         171
-#define __NR_prctl              172
-#define __NR_rt_sigreturn      173
-#define __NR_rt_sigaction      174
-#define __NR_rt_sigprocmask    175
-#define __NR_rt_sigpending     176
-#define __NR_rt_sigtimedwait   177
-#define __NR_rt_sigqueueinfo   178
-#define __NR_rt_sigsuspend     179
-#define __NR_pread64           180
-#define __NR_pwrite64          181
-#define __NR_chown             182
-#define __NR_getcwd            183
-#define __NR_capget            184
-#define __NR_capset            185
-#define __NR_sigaltstack       186
-#define __NR_sendfile          187
-#define __NR_getpmsg           188     /* some people actually want streams */
-#define __NR_putpmsg           189     /* some people actually want streams */
-#define __NR_vfork             190
-#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
-#define __NR_mmap2             192
-#define __NR_truncate64                193
-#define __NR_ftruncate64       194
-#define __NR_stat64            195
-#define __NR_lstat64           196
-#define __NR_fstat64           197
-#define __NR_lchown32          198
-#define __NR_getuid32          199
-#define __NR_getgid32          200
-#define __NR_geteuid32         201
-#define __NR_getegid32         202
-#define __NR_setreuid32                203
-#define __NR_setregid32                204
-#define __NR_getgroups32       205
-#define __NR_setgroups32       206
-#define __NR_fchown32          207
-#define __NR_setresuid32       208
-#define __NR_getresuid32       209
-#define __NR_setresgid32       210
-#define __NR_getresgid32       211
-#define __NR_chown32           212
-#define __NR_setuid32          213
-#define __NR_setgid32          214
-#define __NR_setfsuid32                215
-#define __NR_setfsgid32                216
-#define __NR_pivot_root                217
-#define __NR_mincore           218
-#define __NR_madvise           219
-#define __NR_getdents64                220
-#define __NR_fcntl64           221
-/* 223 is unused */
-#define __NR_gettid             224
-#define __NR_readahead          225
-#define __NR_setxattr          226
-#define __NR_lsetxattr         227
-#define __NR_fsetxattr         228
-#define __NR_getxattr          229
-#define __NR_lgetxattr         230
-#define __NR_fgetxattr         231
-#define __NR_listxattr         232
-#define __NR_llistxattr                233
-#define __NR_flistxattr                234
-#define __NR_removexattr       235
-#define __NR_lremovexattr      236
-#define __NR_fremovexattr      237
-#define __NR_tkill             238
-#define __NR_sendfile64                239
-#define __NR_futex             240
-#define __NR_sched_setaffinity 241
-#define __NR_sched_getaffinity 242
-#define __NR_set_thread_area   243
-#define __NR_get_thread_area   244
-#define __NR_io_setup          245
-#define __NR_io_destroy                246
-#define __NR_io_getevents      247
-#define __NR_io_submit         248
-#define __NR_io_cancel         249
-#define __NR_fadvise64         250
-/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
-#define __NR_exit_group                252
-#define __NR_lookup_dcookie    253
-#define __NR_epoll_create      254
-#define __NR_epoll_ctl         255
-#define __NR_epoll_wait                256
-#define __NR_remap_file_pages  257
-#define __NR_set_tid_address   258
-#define __NR_timer_create      259
-#define __NR_timer_settime     (__NR_timer_create+1)
-#define __NR_timer_gettime     (__NR_timer_create+2)
-#define __NR_timer_getoverrun  (__NR_timer_create+3)
-#define __NR_timer_delete      (__NR_timer_create+4)
-#define __NR_clock_settime     (__NR_timer_create+5)
-#define __NR_clock_gettime     (__NR_timer_create+6)
-#define __NR_clock_getres      (__NR_timer_create+7)
-#define __NR_clock_nanosleep   (__NR_timer_create+8)
-#define __NR_statfs64          268
-#define __NR_fstatfs64         269
-#define __NR_tgkill            270
-#define __NR_utimes            271
-#define __NR_fadvise64_64      272
-#define __NR_vserver           273
-#define __NR_mbind             274
-#define __NR_get_mempolicy     275
-#define __NR_set_mempolicy     276
-#define __NR_mq_open           277
-#define __NR_mq_unlink         (__NR_mq_open+1)
-#define __NR_mq_timedsend      (__NR_mq_open+2)
-#define __NR_mq_timedreceive   (__NR_mq_open+3)
-#define __NR_mq_notify         (__NR_mq_open+4)
-#define __NR_mq_getsetattr     (__NR_mq_open+5)
-#define __NR_kexec_load                283
-#define __NR_waitid            284
-/* #define __NR_sys_setaltroot 285 */
-#define __NR_add_key           286
-#define __NR_request_key       287
-#define __NR_keyctl            288
-#define __NR_ioprio_set                289
-#define __NR_ioprio_get                290
-#define __NR_inotify_init      291
-#define __NR_inotify_add_watch 292
-#define __NR_inotify_rm_watch  293
-#define __NR_migrate_pages     294
-#define __NR_openat            295
-#define __NR_mkdirat           296
-#define __NR_mknodat           297
-#define __NR_fchownat          298
-#define __NR_futimesat         299
-#define __NR_fstatat64         300
-#define __NR_unlinkat          301
-#define __NR_renameat          302
-#define __NR_linkat            303
-#define __NR_symlinkat         304
-#define __NR_readlinkat                305
-#define __NR_fchmodat          306
-#define __NR_faccessat         307
-#define __NR_pselect6          308
-#define __NR_ppoll             309
-#define __NR_unshare           310
-#define __NR_set_robust_list   311
-#define __NR_get_robust_list   312
-#define __NR_splice            313
-#define __NR_sync_file_range   314
-#define __NR_tee               315
-#define __NR_vmsplice          316
-#define __NR_move_pages                317
-#define __NR_getcpu            318
-#define __NR_epoll_pwait       319
-#define __NR_utimensat         320
-#define __NR_signalfd          321
-#define __NR_timerfd_create    322
-#define __NR_eventfd           323
-#define __NR_fallocate         324
-#define __NR_timerfd_settime   325
-#define __NR_timerfd_gettime   326
-#define __NR_signalfd4         327
-#define __NR_eventfd2          328
-#define __NR_epoll_create1     329
-#define __NR_dup3              330
-#define __NR_pipe2             331
-#define __NR_inotify_init1     332
-#define __NR_preadv            333
-#define __NR_pwritev           334
-#define __NR_setns             335
+#include <uapi/asm/unistd.h>
 
-#ifdef __KERNEL__
 
 #define NR_syscalls 336
 
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __KERNEL__ */
 #endif /* _ASM_CRIS_UNISTD_H_ */
index aafaa5a..9048c87 100644 (file)
@@ -1 +1,5 @@
 # UAPI Header export list
+header-y += sv_addr.agh
+header-y += sv_addr_ag.h
+header-y += svinto.h
+header-y += user.h
index aafaa5a..59efffd 100644 (file)
@@ -1 +1,3 @@
 # UAPI Header export list
+header-y += cryptocop.h
+header-y += user.h
diff --git a/arch/cris/include/uapi/arch-v32/arch/cryptocop.h b/arch/cris/include/uapi/arch-v32/arch/cryptocop.h
new file mode 100644 (file)
index 0000000..694fd13
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * The device /dev/cryptocop is accessible using this driver using
+ * CRYPTOCOP_MAJOR (254) and minor number 0.
+ */
+
+#ifndef _UAPICRYPTOCOP_H
+#define _UAPICRYPTOCOP_H
+
+#include <linux/uio.h>
+
+
+#define CRYPTOCOP_SESSION_ID_NONE (0)
+
+typedef unsigned long long int cryptocop_session_id;
+
+/* cryptocop ioctls */
+#define ETRAXCRYPTOCOP_IOCTYPE         (250)
+
+#define CRYPTOCOP_IO_CREATE_SESSION    _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 1, struct strcop_session_op)
+#define CRYPTOCOP_IO_CLOSE_SESSION     _IOW(ETRAXCRYPTOCOP_IOCTYPE, 2, struct strcop_session_op)
+#define CRYPTOCOP_IO_PROCESS_OP        _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 3, struct strcop_crypto_op)
+#define CRYPTOCOP_IO_MAXNR             (3)
+
+typedef enum {
+       cryptocop_cipher_des = 0,
+       cryptocop_cipher_3des = 1,
+       cryptocop_cipher_aes = 2,
+       cryptocop_cipher_m2m = 3, /* mem2mem is essentially a NULL cipher with blocklength=1 */
+       cryptocop_cipher_none
+} cryptocop_cipher_type;
+
+typedef enum {
+       cryptocop_digest_sha1 = 0,
+       cryptocop_digest_md5 = 1,
+       cryptocop_digest_none
+} cryptocop_digest_type;
+
+typedef enum {
+       cryptocop_csum_le = 0,
+       cryptocop_csum_be = 1,
+       cryptocop_csum_none
+} cryptocop_csum_type;
+
+typedef enum {
+       cryptocop_cipher_mode_ecb = 0,
+       cryptocop_cipher_mode_cbc,
+       cryptocop_cipher_mode_none
+} cryptocop_cipher_mode;
+
+typedef enum {
+       cryptocop_3des_eee = 0,
+       cryptocop_3des_eed = 1,
+       cryptocop_3des_ede = 2,
+       cryptocop_3des_edd = 3,
+       cryptocop_3des_dee = 4,
+       cryptocop_3des_ded = 5,
+       cryptocop_3des_dde = 6,
+       cryptocop_3des_ddd = 7
+} cryptocop_3des_mode;
+
+/* Usermode accessible (ioctl) operations. */
+struct strcop_session_op{
+       cryptocop_session_id    ses_id;
+
+       cryptocop_cipher_type   cipher; /* AES, DES, 3DES, m2m, none */
+
+       cryptocop_cipher_mode   cmode; /* ECB, CBC, none */
+       cryptocop_3des_mode     des3_mode;
+
+       cryptocop_digest_type   digest; /* MD5, SHA1, none */
+
+       cryptocop_csum_type     csum;   /* BE, LE, none */
+
+       unsigned char           *key;
+       size_t                  keylen;
+};
+
+#define CRYPTOCOP_CSUM_LENGTH         (2)
+#define CRYPTOCOP_MAX_DIGEST_LENGTH   (20)  /* SHA-1 20, MD5 16 */
+#define CRYPTOCOP_MAX_IV_LENGTH       (16)  /* (3)DES==8, AES == 16 */
+#define CRYPTOCOP_MAX_KEY_LENGTH      (32)
+
+struct strcop_crypto_op{
+       cryptocop_session_id ses_id;
+
+       /* Indata. */
+       unsigned char            *indata;
+       size_t                   inlen; /* Total indata length. */
+
+       /* Cipher configuration. */
+       unsigned char            do_cipher:1;
+       unsigned char            decrypt:1; /* 1 == decrypt, 0 == encrypt */
+       unsigned char            cipher_explicit:1;
+       size_t                   cipher_start;
+       size_t                   cipher_len;
+       /* cipher_iv is used if do_cipher and cipher_explicit and the cipher
+          mode is CBC.  The length is controlled by the type of cipher,
+          e.g. DES/3DES 8 octets and AES 16 octets. */
+       unsigned char            cipher_iv[CRYPTOCOP_MAX_IV_LENGTH];
+       /* Outdata. */
+       unsigned char            *cipher_outdata;
+       size_t                   cipher_outlen;
+
+       /* digest configuration. */
+       unsigned char            do_digest:1;
+       size_t                   digest_start;
+       size_t                   digest_len;
+       /* Outdata.  The actual length is determined by the type of the digest. */
+       unsigned char            digest[CRYPTOCOP_MAX_DIGEST_LENGTH];
+
+       /* Checksum configuration. */
+       unsigned char            do_csum:1;
+       size_t                   csum_start;
+       size_t                   csum_len;
+       /* Outdata. */
+       unsigned char            csum[CRYPTOCOP_CSUM_LENGTH];
+};
+
+
+
+
+#endif /* _UAPICRYPTOCOP_H */
index f50236a..7d47b36 100644 (file)
@@ -3,3 +3,37 @@ include include/uapi/asm-generic/Kbuild.asm
 
 header-y += arch-v10/
 header-y += arch-v32/
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += ethernet.h
+header-y += etraxgpio.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += rs485.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += sync_serial.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/cris/include/uapi/asm/ptrace.h b/arch/cris/include/uapi/asm/ptrace.h
new file mode 100644 (file)
index 0000000..c689c9b
--- /dev/null
@@ -0,0 +1 @@
+#include <arch/ptrace.h>
diff --git a/arch/cris/include/uapi/asm/signal.h b/arch/cris/include/uapi/asm/signal.h
new file mode 100644 (file)
index 0000000..2162494
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef _UAPI_ASM_CRIS_SIGNAL_H
+#define _UAPI_ASM_CRIS_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG           32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+#define SIGBUS          7
+#define SIGFPE          8
+#define SIGKILL                 9
+#define SIGUSR1                10
+#define SIGSEGV                11
+#define SIGUSR2                12
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGSTKFLT      16
+#define SIGCHLD                17
+#define SIGCONT                18
+#define SIGSTOP                19
+#define SIGTSTP                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGURG         23
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGIO          29
+#define SIGPOLL                SIGIO
+/*
+#define SIGLOST                29
+*/
+#define SIGPWR         30
+#define SIGSYS          31
+#define        SIGUNUSED       31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN        32
+#define SIGRTMAX        _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+
+#define SA_NOCLDSTOP   0x00000001u
+#define SA_NOCLDWAIT   0x00000002u
+#define SA_SIGINFO     0x00000004u
+#define SA_ONSTACK     0x08000000u
+#define SA_RESTART     0x10000000u
+#define SA_NODEFER     0x40000000u
+#define SA_RESETHAND   0x80000000u
+
+#define SA_NOMASK      SA_NODEFER
+#define SA_ONESHOT     SA_RESETHAND
+
+#define SA_RESTORER    0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+       union {
+         __sighandler_t _sa_handler;
+         void (*_sa_sigaction)(int, struct siginfo *, void *);
+       } _u;
+       sigset_t sa_mask;
+       unsigned long sa_flags;
+       void (*sa_restorer)(void);
+};
+
+#define sa_handler     _u._sa_handler
+#define sa_sigaction   _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+       void *ss_sp;
+       int ss_flags;
+       size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASM_CRIS_SIGNAL_H */
diff --git a/arch/cris/include/uapi/asm/swab.h b/arch/cris/include/uapi/asm/swab.h
new file mode 100644 (file)
index 0000000..4adf1e9
--- /dev/null
@@ -0,0 +1,3 @@
+/*
+ * CRIS byte swapping.
+ */
diff --git a/arch/cris/include/uapi/asm/termios.h b/arch/cris/include/uapi/asm/termios.h
new file mode 100644 (file)
index 0000000..0a0386a
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _UAPI_CRIS_TERMIOS_H
+#define _UAPI_CRIS_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+#include <asm/rs485.h>
+#include <linux/serial.h>
+
+struct winsize {
+       unsigned short ws_row;
+       unsigned short ws_col;
+       unsigned short ws_xpixel;
+       unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+       unsigned short c_iflag;         /* input mode flags */
+       unsigned short c_oflag;         /* output mode flags */
+       unsigned short c_cflag;         /* control mode flags */
+       unsigned short c_lflag;         /* local mode flags */
+       unsigned char c_line;           /* line discipline */
+       unsigned char c_cc[NCC];        /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE       0x001
+#define TIOCM_DTR      0x002
+#define TIOCM_RTS      0x004
+#define TIOCM_ST       0x008
+#define TIOCM_SR       0x010
+#define TIOCM_CTS      0x020
+#define TIOCM_CAR      0x040
+#define TIOCM_RNG      0x080
+#define TIOCM_DSR      0x100
+#define TIOCM_CD       TIOCM_CAR
+#define TIOCM_RI       TIOCM_RNG
+#define TIOCM_OUT1     0x2000
+#define TIOCM_OUT2     0x4000
+#define TIOCM_LOOP     0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_CRIS_TERMIOS_H */
diff --git a/arch/cris/include/uapi/asm/types.h b/arch/cris/include/uapi/asm/types.h
new file mode 100644 (file)
index 0000000..9ec9d4c
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/int-ll64.h>
diff --git a/arch/cris/include/uapi/asm/unistd.h b/arch/cris/include/uapi/asm/unistd.h
new file mode 100644 (file)
index 0000000..4884289
--- /dev/null
@@ -0,0 +1,344 @@
+#ifndef _UAPI_ASM_CRIS_UNISTD_H_
+#define _UAPI_ASM_CRIS_UNISTD_H_
+
+/*
+ * This file contains the system call numbers, and stub macros for libc.
+ */
+
+#define __NR_restart_syscall      0
+#define __NR_exit                1
+#define __NR_fork                2
+#define __NR_read                3
+#define __NR_write               4
+#define __NR_open                5
+#define __NR_close               6
+#define __NR_waitpid             7
+#define __NR_creat               8
+#define __NR_link                9
+#define __NR_unlink             10
+#define __NR_execve             11
+#define __NR_chdir              12
+#define __NR_time               13
+#define __NR_mknod              14
+#define __NR_chmod              15
+#define __NR_lchown             16
+#define __NR_break              17
+#define __NR_oldstat            18
+#define __NR_lseek              19
+#define __NR_getpid             20
+#define __NR_mount              21
+#define __NR_umount             22
+#define __NR_setuid             23
+#define __NR_getuid             24
+#define __NR_stime              25
+#define __NR_ptrace             26
+#define __NR_alarm              27
+#define __NR_oldfstat           28
+#define __NR_pause              29
+#define __NR_utime              30
+#define __NR_stty               31
+#define __NR_gtty               32
+#define __NR_access             33
+#define __NR_nice               34
+#define __NR_ftime              35
+#define __NR_sync               36
+#define __NR_kill               37
+#define __NR_rename             38
+#define __NR_mkdir              39
+#define __NR_rmdir              40
+#define __NR_dup                41
+#define __NR_pipe               42
+#define __NR_times              43
+#define __NR_prof               44
+#define __NR_brk                45
+#define __NR_setgid             46
+#define __NR_getgid             47
+#define __NR_signal             48
+#define __NR_geteuid            49
+#define __NR_getegid            50
+#define __NR_acct               51
+#define __NR_umount2            52
+#define __NR_lock               53
+#define __NR_ioctl              54
+#define __NR_fcntl              55
+#define __NR_mpx                56
+#define __NR_setpgid            57
+#define __NR_ulimit             58
+#define __NR_oldolduname        59
+#define __NR_umask              60
+#define __NR_chroot             61
+#define __NR_ustat              62
+#define __NR_dup2               63
+#define __NR_getppid            64
+#define __NR_getpgrp            65
+#define __NR_setsid             66
+#define __NR_sigaction          67
+#define __NR_sgetmask           68
+#define __NR_ssetmask           69
+#define __NR_setreuid           70
+#define __NR_setregid           71
+#define __NR_sigsuspend                 72
+#define __NR_sigpending                 73
+#define __NR_sethostname        74
+#define __NR_setrlimit          75
+#define __NR_getrlimit          76
+#define __NR_getrusage          77
+#define __NR_gettimeofday       78
+#define __NR_settimeofday       79
+#define __NR_getgroups          80
+#define __NR_setgroups          81
+#define __NR_select             82
+#define __NR_symlink            83
+#define __NR_oldlstat           84
+#define __NR_readlink           85
+#define __NR_uselib             86
+#define __NR_swapon             87
+#define __NR_reboot             88
+#define __NR_readdir            89
+#define __NR_mmap               90
+#define __NR_munmap             91
+#define __NR_truncate           92
+#define __NR_ftruncate          93
+#define __NR_fchmod             94
+#define __NR_fchown             95
+#define __NR_getpriority        96
+#define __NR_setpriority        97
+#define __NR_profil             98
+#define __NR_statfs             99
+#define __NR_fstatfs           100
+#define __NR_ioperm            101
+#define __NR_socketcall                102
+#define __NR_syslog            103
+#define __NR_setitimer         104
+#define __NR_getitimer         105
+#define __NR_stat              106
+#define __NR_lstat             107
+#define __NR_fstat             108
+#define __NR_olduname          109
+#define __NR_iopl              110
+#define __NR_vhangup           111
+#define __NR_idle              112
+#define __NR_vm86              113
+#define __NR_wait4             114
+#define __NR_swapoff           115
+#define __NR_sysinfo           116
+#define __NR_ipc               117
+#define __NR_fsync             118
+#define __NR_sigreturn         119
+#define __NR_clone             120
+#define __NR_setdomainname     121
+#define __NR_uname             122
+#define __NR_modify_ldt                123
+#define __NR_adjtimex          124
+#define __NR_mprotect          125
+#define __NR_sigprocmask       126
+#define __NR_create_module     127
+#define __NR_init_module       128
+#define __NR_delete_module     129
+#define __NR_get_kernel_syms   130
+#define __NR_quotactl          131
+#define __NR_getpgid           132
+#define __NR_fchdir            133
+#define __NR_bdflush           134
+#define __NR_sysfs             135
+#define __NR_personality       136
+#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
+#define __NR_setfsuid          138
+#define __NR_setfsgid          139
+#define __NR__llseek           140
+#define __NR_getdents          141
+#define __NR__newselect                142
+#define __NR_flock             143
+#define __NR_msync             144
+#define __NR_readv             145
+#define __NR_writev            146
+#define __NR_getsid            147
+#define __NR_fdatasync         148
+#define __NR__sysctl           149
+#define __NR_mlock             150
+#define __NR_munlock           151
+#define __NR_mlockall          152
+#define __NR_munlockall                153
+#define __NR_sched_setparam            154
+#define __NR_sched_getparam            155
+#define __NR_sched_setscheduler                156
+#define __NR_sched_getscheduler                157
+#define __NR_sched_yield               158
+#define __NR_sched_get_priority_max    159
+#define __NR_sched_get_priority_min    160
+#define __NR_sched_rr_get_interval     161
+#define __NR_nanosleep         162
+#define __NR_mremap            163
+#define __NR_setresuid         164
+#define __NR_getresuid         165
+
+#define __NR_query_module      167
+#define __NR_poll              168
+#define __NR_nfsservctl                169
+#define __NR_setresgid         170
+#define __NR_getresgid         171
+#define __NR_prctl              172
+#define __NR_rt_sigreturn      173
+#define __NR_rt_sigaction      174
+#define __NR_rt_sigprocmask    175
+#define __NR_rt_sigpending     176
+#define __NR_rt_sigtimedwait   177
+#define __NR_rt_sigqueueinfo   178
+#define __NR_rt_sigsuspend     179
+#define __NR_pread64           180
+#define __NR_pwrite64          181
+#define __NR_chown             182
+#define __NR_getcwd            183
+#define __NR_capget            184
+#define __NR_capset            185
+#define __NR_sigaltstack       186
+#define __NR_sendfile          187
+#define __NR_getpmsg           188     /* some people actually want streams */
+#define __NR_putpmsg           189     /* some people actually want streams */
+#define __NR_vfork             190
+#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
+#define __NR_mmap2             192
+#define __NR_truncate64                193
+#define __NR_ftruncate64       194
+#define __NR_stat64            195
+#define __NR_lstat64           196
+#define __NR_fstat64           197
+#define __NR_lchown32          198
+#define __NR_getuid32          199
+#define __NR_getgid32          200
+#define __NR_geteuid32         201
+#define __NR_getegid32         202
+#define __NR_setreuid32                203
+#define __NR_setregid32                204
+#define __NR_getgroups32       205
+#define __NR_setgroups32       206
+#define __NR_fchown32          207
+#define __NR_setresuid32       208
+#define __NR_getresuid32       209
+#define __NR_setresgid32       210
+#define __NR_getresgid32       211
+#define __NR_chown32           212
+#define __NR_setuid32          213
+#define __NR_setgid32          214
+#define __NR_setfsuid32                215
+#define __NR_setfsgid32                216
+#define __NR_pivot_root                217
+#define __NR_mincore           218
+#define __NR_madvise           219
+#define __NR_getdents64                220
+#define __NR_fcntl64           221
+/* 223 is unused */
+#define __NR_gettid             224
+#define __NR_readahead          225
+#define __NR_setxattr          226
+#define __NR_lsetxattr         227
+#define __NR_fsetxattr         228
+#define __NR_getxattr          229
+#define __NR_lgetxattr         230
+#define __NR_fgetxattr         231
+#define __NR_listxattr         232
+#define __NR_llistxattr                233
+#define __NR_flistxattr                234
+#define __NR_removexattr       235
+#define __NR_lremovexattr      236
+#define __NR_fremovexattr      237
+#define __NR_tkill             238
+#define __NR_sendfile64                239
+#define __NR_futex             240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area   243
+#define __NR_get_thread_area   244
+#define __NR_io_setup          245
+#define __NR_io_destroy                246
+#define __NR_io_getevents      247
+#define __NR_io_submit         248
+#define __NR_io_cancel         249
+#define __NR_fadvise64         250
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group                252
+#define __NR_lookup_dcookie    253
+#define __NR_epoll_create      254
+#define __NR_epoll_ctl         255
+#define __NR_epoll_wait                256
+#define __NR_remap_file_pages  257
+#define __NR_set_tid_address   258
+#define __NR_timer_create      259
+#define __NR_timer_settime     (__NR_timer_create+1)
+#define __NR_timer_gettime     (__NR_timer_create+2)
+#define __NR_timer_getoverrun  (__NR_timer_create+3)
+#define __NR_timer_delete      (__NR_timer_create+4)
+#define __NR_clock_settime     (__NR_timer_create+5)
+#define __NR_clock_gettime     (__NR_timer_create+6)
+#define __NR_clock_getres      (__NR_timer_create+7)
+#define __NR_clock_nanosleep   (__NR_timer_create+8)
+#define __NR_statfs64          268
+#define __NR_fstatfs64         269
+#define __NR_tgkill            270
+#define __NR_utimes            271
+#define __NR_fadvise64_64      272
+#define __NR_vserver           273
+#define __NR_mbind             274
+#define __NR_get_mempolicy     275
+#define __NR_set_mempolicy     276
+#define __NR_mq_open           277
+#define __NR_mq_unlink         (__NR_mq_open+1)
+#define __NR_mq_timedsend      (__NR_mq_open+2)
+#define __NR_mq_timedreceive   (__NR_mq_open+3)
+#define __NR_mq_notify         (__NR_mq_open+4)
+#define __NR_mq_getsetattr     (__NR_mq_open+5)
+#define __NR_kexec_load                283
+#define __NR_waitid            284
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key           286
+#define __NR_request_key       287
+#define __NR_keyctl            288
+#define __NR_ioprio_set                289
+#define __NR_ioprio_get                290
+#define __NR_inotify_init      291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch  293
+#define __NR_migrate_pages     294
+#define __NR_openat            295
+#define __NR_mkdirat           296
+#define __NR_mknodat           297
+#define __NR_fchownat          298
+#define __NR_futimesat         299
+#define __NR_fstatat64         300
+#define __NR_unlinkat          301
+#define __NR_renameat          302
+#define __NR_linkat            303
+#define __NR_symlinkat         304
+#define __NR_readlinkat                305
+#define __NR_fchmodat          306
+#define __NR_faccessat         307
+#define __NR_pselect6          308
+#define __NR_ppoll             309
+#define __NR_unshare           310
+#define __NR_set_robust_list   311
+#define __NR_get_robust_list   312
+#define __NR_splice            313
+#define __NR_sync_file_range   314
+#define __NR_tee               315
+#define __NR_vmsplice          316
+#define __NR_move_pages                317
+#define __NR_getcpu            318
+#define __NR_epoll_pwait       319
+#define __NR_utimensat         320
+#define __NR_signalfd          321
+#define __NR_timerfd_create    322
+#define __NR_eventfd           323
+#define __NR_fallocate         324
+#define __NR_timerfd_settime   325
+#define __NR_timerfd_gettime   326
+#define __NR_signalfd4         327
+#define __NR_eventfd2          328
+#define __NR_epoll_create1     329
+#define __NR_dup3              330
+#define __NR_pipe2             331
+#define __NR_inotify_init1     332
+#define __NR_preadv            333
+#define __NR_pwritev           334
+#define __NR_setns             335
+
+#endif /* _UAPI_ASM_CRIS_UNISTD_H_ */
index dd7b8e9..a5fd88d 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/kbuild.h>
 #include <linux/sched.h>
 #include <asm/thread_info.h>
 
@@ -7,11 +8,6 @@
  * and format the required data.
  */
 
-#define DEFINE(sym, val) \
-       asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-
-#define BLANK() asm volatile("\n->" : : )
-
 #if !defined(CONFIG_ETRAX_ARCH_V10) && !defined(CONFIG_ETRAX_ARCH_V32)
 #error One of ARCH v10 and ARCH v32 must be true!
 #endif
index 37400f5..51123f9 100644 (file)
@@ -32,8 +32,6 @@
 #ifdef CONFIG_ETRAX_KMALLOCED_MODULES
 void *module_alloc(unsigned long size)
 {
-       if (size == 0)
-               return NULL;
        return kmalloc(size, GFP_KERNEL);
 }
 
index 4bc8ae7..bebdc36 100644 (file)
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
 
 generic-y += clkdev.h
 generic-y += exec.h
index c4432f1..ba487c5 100644 (file)
@@ -1,6 +1,3 @@
-#ifndef _ASM_M32R_PTRACE_H
-#define _ASM_M32R_PTRACE_H
-
 /*
  * linux/include/asm-m32r/ptrace.h
  *
  * M32R version:
  *   Copyright (C) 2001-2002, 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
+#ifndef _ASM_M32R_PTRACE_H
+#define _ASM_M32R_PTRACE_H
 
-/* 0 - 13 are integer registers (general purpose registers).  */
-#define PT_R4          0
-#define PT_R5          1
-#define PT_R6          2
-#define PT_REGS        3
-#define PT_R0          4
-#define PT_R1          5
-#define PT_R2          6
-#define PT_R3          7
-#define PT_R7          8
-#define PT_R8          9
-#define PT_R9          10
-#define PT_R10         11
-#define PT_R11         12
-#define PT_R12         13
-#define PT_SYSCNR      14
-#define PT_R13         PT_FP
-#define PT_R14         PT_LR
-#define PT_R15         PT_SP
-
-/* processor status and miscellaneous context registers.  */
-#define PT_ACC0H       15
-#define PT_ACC0L       16
-#define PT_ACC1H       17      /* ISA_DSP_LEVEL2 only */
-#define PT_ACC1L       18      /* ISA_DSP_LEVEL2 only */
-#define PT_PSW         19
-#define PT_BPC         20
-#define PT_BBPSW       21
-#define PT_BBPC                22
-#define PT_SPU         23
-#define PT_FP          24
-#define PT_LR          25
-#define PT_SPI         26
-#define PT_ORIGR0      27
-
-/* virtual pt_reg entry for gdb */
-#define PT_PC          30
-#define PT_CBR         31
-#define PT_EVB         32
-
-
-/* Control registers.  */
-#define SPR_CR0 PT_PSW
-#define SPR_CR1 PT_CBR         /* read only */
-#define SPR_CR2 PT_SPI
-#define SPR_CR3 PT_SPU
-#define SPR_CR4
-#define SPR_CR5 PT_EVB         /* part of M32R/E, M32R/I core only */
-#define SPR_CR6 PT_BPC
-#define SPR_CR7
-#define SPR_CR8 PT_BBPSW
-#define SPR_CR9
-#define SPR_CR10
-#define SPR_CR11
-#define SPR_CR12
-#define SPR_CR13 PT_WR
-#define SPR_CR14 PT_BBPC
-#define SPR_CR15
-
-/* this struct defines the way the registers are stored on the
-   stack during a system call. */
-struct pt_regs {
-       /* Saved main processor registers. */
-       unsigned long r4;
-       unsigned long r5;
-       unsigned long r6;
-       struct pt_regs *pt_regs;
-       unsigned long r0;
-       unsigned long r1;
-       unsigned long r2;
-       unsigned long r3;
-       unsigned long r7;
-       unsigned long r8;
-       unsigned long r9;
-       unsigned long r10;
-       unsigned long r11;
-       unsigned long r12;
-       long syscall_nr;
-
-       /* Saved main processor status and miscellaneous context registers. */
-       unsigned long acc0h;
-       unsigned long acc0l;
-       unsigned long acc1h;    /* ISA_DSP_LEVEL2 only */
-       unsigned long acc1l;    /* ISA_DSP_LEVEL2 only */
-       unsigned long psw;
-       unsigned long bpc;              /* saved PC for TRAP syscalls */
-       unsigned long bbpsw;
-       unsigned long bbpc;
-       unsigned long spu;              /* saved user stack */
-       unsigned long fp;
-       unsigned long lr;               /* saved PC for JL syscalls */
-       unsigned long spi;              /* saved kernel stack */
-       unsigned long orig_r0;
-};
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS         12
-#define PTRACE_SETREGS         13
-
-#define PTRACE_OLDSETOPTIONS   21
-
-#ifdef __KERNEL__
 
 #include <asm/m32r.h>          /* M32R_PSW_BSM, M32R_PSW_BPM */
+#include <uapi/asm/ptrace.h>
 
 #define arch_has_single_step() (1)
 
@@ -142,6 +40,4 @@ extern void withdraw_debug_trap(struct pt_regs *regs);
 #define current_pt_regs() ((struct pt_regs *) \
        ((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
 
-#endif /* __KERNEL */
-
 #endif /* _ASM_M32R_PTRACE_H */
index c637ab9..bbe59a9 100644 (file)
@@ -1,13 +1,8 @@
 #ifndef _ASM_M32R_SETUP_H
 #define _ASM_M32R_SETUP_H
 
-/*
- * This is set up by the setup-routine at boot-time
- */
+#include <uapi/asm/setup.h>
 
-#define COMMAND_LINE_SIZE       512
-
-#ifdef __KERNEL__
 
 #define PARAM                  ((unsigned char *)empty_zero_page)
 
@@ -33,6 +28,4 @@
 extern unsigned long memory_start;
 extern unsigned long memory_end;
 
-#endif  /*  __KERNEL__  */
-
 #endif /* _ASM_M32R_SETUP_H */
index e4d2e2a..a5ba4a2 100644 (file)
@@ -1,14 +1,8 @@
 #ifndef _ASM_M32R_SIGNAL_H
 #define _ASM_M32R_SIGNAL_H
 
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/compiler.h>
+#include <uapi/asm/signal.h>
 
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-
-#ifdef __KERNEL__
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 
@@ -22,94 +16,6 @@ typedef struct {
        unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-#define NSIG           32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-#define SIGBUS          7
-#define SIGFPE          8
-#define SIGKILL                 9
-#define SIGUSR1                10
-#define SIGSEGV                11
-#define SIGUSR2                12
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGSTKFLT      16
-#define SIGCHLD                17
-#define SIGCONT                18
-#define SIGSTOP                19
-#define SIGTSTP                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGURG         23
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGIO          29
-#define SIGPOLL                SIGIO
-/*
-#define SIGLOST                29
-*/
-#define SIGPWR         30
-#define SIGSYS         31
-#define        SIGUNUSED       31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN       32
-#define SIGRTMAX       _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP   0x00000001u
-#define SA_NOCLDWAIT   0x00000002u
-#define SA_SIGINFO     0x00000004u
-#define SA_ONSTACK     0x08000000u
-#define SA_RESTART     0x10000000u
-#define SA_NODEFER     0x40000000u
-#define SA_RESETHAND   0x80000000u
-
-#define SA_NOMASK      SA_NODEFER
-#define SA_ONESHOT     SA_RESETHAND
-
-#define SA_RESTORER    0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    2048
-#define SIGSTKSZ       8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
 struct sigaction {
        __sighandler_t sa_handler;
        unsigned long sa_flags;
@@ -120,35 +26,8 @@ struct sigaction {
 struct k_sigaction {
        struct sigaction sa;
 };
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-struct sigaction {
-       union {
-         __sighandler_t _sa_handler;
-         void (*_sa_sigaction)(int, struct siginfo *, void *);
-       } _u;
-       sigset_t sa_mask;
-       unsigned long sa_flags;
-       void (*sa_restorer)(void);
-};
-
-#define sa_handler     _u._sa_handler
-#define sa_sigaction   _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
-       void __user *ss_sp;
-       int ss_flags;
-       size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
 #undef __HAVE_ARCH_SIG_BITOPS
 
-#endif /* __KERNEL__ */
-
 #endif  /* _ASM_M32R_SIGNAL_H */
index 93ce79f..680898f 100644 (file)
@@ -1,46 +1,8 @@
 #ifndef _M32R_TERMIOS_H
 #define _M32R_TERMIOS_H
 
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
-       unsigned short ws_row;
-       unsigned short ws_col;
-       unsigned short ws_xpixel;
-       unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-       unsigned short c_iflag;         /* input mode flags */
-       unsigned short c_oflag;         /* output mode flags */
-       unsigned short c_cflag;         /* control mode flags */
-       unsigned short c_lflag;         /* local mode flags */
-       unsigned char c_line;           /* line discipline */
-       unsigned char c_cc[NCC];        /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE       0x001
-#define TIOCM_DTR      0x002
-#define TIOCM_RTS      0x004
-#define TIOCM_ST       0x008
-#define TIOCM_SR       0x010
-#define TIOCM_CTS      0x020
-#define TIOCM_CAR      0x040
-#define TIOCM_RNG      0x080
-#define TIOCM_DSR      0x100
-#define TIOCM_CD       TIOCM_CAR
-#define TIOCM_RI       TIOCM_RNG
-#define TIOCM_OUT1     0x2000
-#define TIOCM_OUT2     0x4000
-#define TIOCM_LOOP     0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
 #include <linux/module.h>
+#include <uapi/asm/termios.h>
 
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          vtime=\0        vmin=\1         sxtc=\0
@@ -86,6 +48,4 @@ struct termio {
 #define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
 #define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
 
-#endif /* __KERNEL__ */
-
 #endif /* _M32R_TERMIOS_H */
index bb2eead..04a44c6 100644 (file)
@@ -1,15 +1,12 @@
 #ifndef _ASM_M32R_TYPES_H
 #define _ASM_M32R_TYPES_H
 
-#include <asm-generic/int-ll64.h>
+#include <uapi/asm/types.h>
 
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
-#ifdef __KERNEL__
 
 #define BITS_PER_LONG 32
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_M32R_TYPES_H */
index d9e7351..1eade32 100644 (file)
@@ -1,338 +1,8 @@
 #ifndef _ASM_M32R_UNISTD_H
 #define _ASM_M32R_UNISTD_H
 
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall     0
-#define __NR_exit                1
-#define __NR_fork                2
-#define __NR_read                3
-#define __NR_write               4
-#define __NR_open                5
-#define __NR_close               6
-#define __NR_waitpid             7
-#define __NR_creat               8
-#define __NR_link                9
-#define __NR_unlink             10
-#define __NR_execve             11
-#define __NR_chdir              12
-#define __NR_time               13
-#define __NR_mknod              14
-#define __NR_chmod              15
-/* 16 is unused */
-/* 17 is unused */
-/* 18 is unused */
-#define __NR_lseek              19
-#define __NR_getpid             20
-#define __NR_mount              21
-#define __NR_umount             22
-/* 23 is unused */
-/* 24 is unused */
-#define __NR_stime              25
-#define __NR_ptrace             26
-#define __NR_alarm              27
-/* 28 is unused */
-#define __NR_pause              29
-#define __NR_utime              30
-/* 31 is unused */
-#define __NR_cachectl           32 /* old #define __NR_gtty             32*/
-#define __NR_access             33
-/* 34 is unused */
-/* 35 is unused */
-#define __NR_sync               36
-#define __NR_kill               37
-#define __NR_rename             38
-#define __NR_mkdir              39
-#define __NR_rmdir              40
-#define __NR_dup                41
-#define __NR_pipe               42
-#define __NR_times              43
-/* 44 is unused */
-#define __NR_brk                45
-/* 46 is unused */
-/* 47 is unused (getgid16) */
-/* 48 is unused */
-/* 49 is unused */
-/* 50 is unused */
-#define __NR_acct               51
-#define __NR_umount2            52
-/* 53 is unused */
-#define __NR_ioctl              54
-/* 55 is unused (fcntl) */
-/* 56 is unused */
-#define __NR_setpgid            57
-/* 58 is unused */
-/* 59 is unused */
-#define __NR_umask              60
-#define __NR_chroot             61
-#define __NR_ustat              62
-#define __NR_dup2               63
-#define __NR_getppid            64
-#define __NR_getpgrp            65
-#define __NR_setsid             66
-/* 67 is unused */
-/* 68 is unused*/
-/* 69 is unused*/
-/* 70 is unused */
-/* 71 is unused */
-/* 72 is unused */
-/* 73 is unused */
-#define __NR_sethostname        74
-#define __NR_setrlimit          75
-/* 76 is unused (old getrlimit) */
-#define __NR_getrusage          77
-#define __NR_gettimeofday       78
-#define __NR_settimeofday       79
-/* 80 is unused */
-/* 81 is unused */
-/* 82 is unused */
-#define __NR_symlink            83
-/* 84 is unused */
-#define __NR_readlink           85
-#define __NR_uselib             86
-#define __NR_swapon             87
-#define __NR_reboot             88
-/* 89 is unused */
-/* 90 is unused */
-#define __NR_munmap             91
-#define __NR_truncate           92
-#define __NR_ftruncate          93
-#define __NR_fchmod             94
-/* 95 is unused */
-#define __NR_getpriority        96
-#define __NR_setpriority        97
-/* 98 is unused */
-#define __NR_statfs             99
-#define __NR_fstatfs           100
-/* 101 is unused */
-#define __NR_socketcall                102
-#define __NR_syslog            103
-#define __NR_setitimer         104
-#define __NR_getitimer         105
-#define __NR_stat              106
-#define __NR_lstat             107
-#define __NR_fstat             108
-/* 109 is unused */
-/* 110 is unused */
-#define __NR_vhangup           111
-/* 112 is unused */
-/* 113 is unused */
-#define __NR_wait4             114
-#define __NR_swapoff           115
-#define __NR_sysinfo           116
-#define __NR_ipc               117
-#define __NR_fsync             118
-/* 119 is unused */
-#define __NR_clone             120
-#define __NR_setdomainname     121
-#define __NR_uname             122
-/* 123 is unused */
-#define __NR_adjtimex          124
-#define __NR_mprotect          125
-/* 126 is unused */
-/* 127 is unused */
-#define __NR_init_module       128
-#define __NR_delete_module     129
-/* 130 is unused */
-#define __NR_quotactl          131
-#define __NR_getpgid           132
-#define __NR_fchdir            133
-#define __NR_bdflush           134
-#define __NR_sysfs             135
-#define __NR_personality       136
-/* 137 is unused */
-/* 138 is unused */
-/* 139 is unused */
-#define __NR__llseek           140
-#define __NR_getdents          141
-#define __NR__newselect                142
-#define __NR_flock             143
-#define __NR_msync             144
-#define __NR_readv             145
-#define __NR_writev            146
-#define __NR_getsid            147
-#define __NR_fdatasync         148
-#define __NR__sysctl           149
-#define __NR_mlock             150
-#define __NR_munlock           151
-#define __NR_mlockall          152
-#define __NR_munlockall                153
-#define __NR_sched_setparam            154
-#define __NR_sched_getparam            155
-#define __NR_sched_setscheduler                156
-#define __NR_sched_getscheduler                157
-#define __NR_sched_yield               158
-#define __NR_sched_get_priority_max    159
-#define __NR_sched_get_priority_min    160
-#define __NR_sched_rr_get_interval     161
-#define __NR_nanosleep         162
-#define __NR_mremap            163
-/* 164 is unused */
-/* 165 is unused */
-#define __NR_tas               166
-/* 167 is unused */
-#define __NR_poll              168
-#define __NR_nfsservctl                169
-/* 170 is unused */
-/* 171 is unused */
-#define __NR_prctl              172
-#define __NR_rt_sigreturn      173
-#define __NR_rt_sigaction      174
-#define __NR_rt_sigprocmask    175
-#define __NR_rt_sigpending     176
-#define __NR_rt_sigtimedwait   177
-#define __NR_rt_sigqueueinfo   178
-#define __NR_rt_sigsuspend     179
-#define __NR_pread64           180
-#define __NR_pwrite64          181
-/* 182 is unused */
-#define __NR_getcwd            183
-#define __NR_capget            184
-#define __NR_capset            185
-#define __NR_sigaltstack       186
-#define __NR_sendfile          187
-/* 188 is unused */
-/* 189 is unused */
-#define __NR_vfork             190
-#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
-#define __NR_mmap2             192
-#define __NR_truncate64                193
-#define __NR_ftruncate64       194
-#define __NR_stat64            195
-#define __NR_lstat64           196
-#define __NR_fstat64           197
-#define __NR_lchown32          198
-#define __NR_getuid32          199
-#define __NR_getgid32          200
-#define __NR_geteuid32         201
-#define __NR_getegid32         202
-#define __NR_setreuid32                203
-#define __NR_setregid32                204
-#define __NR_getgroups32       205
-#define __NR_setgroups32       206
-#define __NR_fchown32          207
-#define __NR_setresuid32       208
-#define __NR_getresuid32       209
-#define __NR_setresgid32       210
-#define __NR_getresgid32       211
-#define __NR_chown32           212
-#define __NR_setuid32          213
-#define __NR_setgid32          214
-#define __NR_setfsuid32                215
-#define __NR_setfsgid32                216
-#define __NR_pivot_root                217
-#define __NR_mincore           218
-#define __NR_madvise           219
-#define __NR_getdents64                220
-#define __NR_fcntl64           221
-/* 222 is unused */
-/* 223 is unused */
-#define __NR_gettid            224
-#define __NR_readahead         225
-#define __NR_setxattr          226
-#define __NR_lsetxattr         227
-#define __NR_fsetxattr         228
-#define __NR_getxattr          229
-#define __NR_lgetxattr         230
-#define __NR_fgetxattr         231
-#define __NR_listxattr         232
-#define __NR_llistxattr                233
-#define __NR_flistxattr                234
-#define __NR_removexattr       235
-#define __NR_lremovexattr      236
-#define __NR_fremovexattr      237
-#define __NR_tkill             238
-#define __NR_sendfile64                239
-#define __NR_futex             240
-#define __NR_sched_setaffinity 241
-#define __NR_sched_getaffinity 242
-#define __NR_set_thread_area   243
-#define __NR_get_thread_area   244
-#define __NR_io_setup          245
-#define __NR_io_destroy                246
-#define __NR_io_getevents      247
-#define __NR_io_submit         248
-#define __NR_io_cancel         249
-#define __NR_fadvise64         250
-/* 251 is unused */
-#define __NR_exit_group                252
-#define __NR_lookup_dcookie    253
-#define __NR_epoll_create      254
-#define __NR_epoll_ctl         255
-#define __NR_epoll_wait                256
-#define __NR_remap_file_pages  257
-#define __NR_set_tid_address   258
-#define __NR_timer_create      259
-#define __NR_timer_settime     (__NR_timer_create+1)
-#define __NR_timer_gettime     (__NR_timer_create+2)
-#define __NR_timer_getoverrun  (__NR_timer_create+3)
-#define __NR_timer_delete      (__NR_timer_create+4)
-#define __NR_clock_settime     (__NR_timer_create+5)
-#define __NR_clock_gettime     (__NR_timer_create+6)
-#define __NR_clock_getres      (__NR_timer_create+7)
-#define __NR_clock_nanosleep   (__NR_timer_create+8)
-#define __NR_statfs64          268
-#define __NR_fstatfs64         269
-#define __NR_tgkill            270
-#define __NR_utimes            271
-#define __NR_fadvise64_64      272
-#define __NR_vserver           273
-#define __NR_mbind             274
-#define __NR_get_mempolicy     275
-#define __NR_set_mempolicy     276
-#define __NR_mq_open           277
-#define __NR_mq_unlink         (__NR_mq_open+1)
-#define __NR_mq_timedsend      (__NR_mq_open+2)
-#define __NR_mq_timedreceive   (__NR_mq_open+3)
-#define __NR_mq_notify         (__NR_mq_open+4)
-#define __NR_mq_getsetattr     (__NR_mq_open+5)
-#define __NR_kexec_load                283
-#define __NR_waitid            284
-/* 285 is unused */
-#define __NR_add_key           286
-#define __NR_request_key       287
-#define __NR_keyctl            288
-#define __NR_ioprio_set                289
-#define __NR_ioprio_get                290
-#define __NR_inotify_init      291
-#define __NR_inotify_add_watch 292
-#define __NR_inotify_rm_watch  293
-#define __NR_migrate_pages     294
-#define __NR_openat            295
-#define __NR_mkdirat           296
-#define __NR_mknodat           297
-#define __NR_fchownat          298
-#define __NR_futimesat         299
-#define __NR_fstatat64         300
-#define __NR_unlinkat          301
-#define __NR_renameat          302
-#define __NR_linkat            303
-#define __NR_symlinkat         304
-#define __NR_readlinkat                305
-#define __NR_fchmodat          306
-#define __NR_faccessat         307
-#define __NR_pselect6          308
-#define __NR_ppoll             309
-#define __NR_unshare           310
-#define __NR_set_robust_list   311
-#define __NR_get_robust_list   312
-#define __NR_splice            313
-#define __NR_sync_file_range   314
-#define __NR_tee               315
-#define __NR_vmsplice          316
-#define __NR_move_pages                317
-#define __NR_getcpu            318
-#define __NR_epoll_pwait       319
-#define __NR_utimensat         320
-#define __NR_signalfd          321
-/* #define __NR_timerfd                322 removed */
-#define __NR_eventfd           323
-#define __NR_fallocate         324
-#define __NR_setns             325
+#include <uapi/asm/unistd.h>
 
-#ifdef __KERNEL__
 
 #define NR_syscalls 326
 
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* _ASM_M32R_UNISTD_H */
index baebb3d..43937a6 100644 (file)
@@ -1,3 +1,33 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/m32r/include/uapi/asm/ptrace.h b/arch/m32r/include/uapi/asm/ptrace.h
new file mode 100644 (file)
index 0000000..f6930a8
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * linux/include/asm-m32r/ptrace.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * M32R version:
+ *   Copyright (C) 2001-2002, 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+#ifndef _UAPI_ASM_M32R_PTRACE_H
+#define _UAPI_ASM_M32R_PTRACE_H
+
+
+/* 0 - 13 are integer registers (general purpose registers).  */
+#define PT_R4          0
+#define PT_R5          1
+#define PT_R6          2
+#define PT_REGS        3
+#define PT_R0          4
+#define PT_R1          5
+#define PT_R2          6
+#define PT_R3          7
+#define PT_R7          8
+#define PT_R8          9
+#define PT_R9          10
+#define PT_R10         11
+#define PT_R11         12
+#define PT_R12         13
+#define PT_SYSCNR      14
+#define PT_R13         PT_FP
+#define PT_R14         PT_LR
+#define PT_R15         PT_SP
+
+/* processor status and miscellaneous context registers.  */
+#define PT_ACC0H       15
+#define PT_ACC0L       16
+#define PT_ACC1H       17      /* ISA_DSP_LEVEL2 only */
+#define PT_ACC1L       18      /* ISA_DSP_LEVEL2 only */
+#define PT_PSW         19
+#define PT_BPC         20
+#define PT_BBPSW       21
+#define PT_BBPC                22
+#define PT_SPU         23
+#define PT_FP          24
+#define PT_LR          25
+#define PT_SPI         26
+#define PT_ORIGR0      27
+
+/* virtual pt_reg entry for gdb */
+#define PT_PC          30
+#define PT_CBR         31
+#define PT_EVB         32
+
+
+/* Control registers.  */
+#define SPR_CR0 PT_PSW
+#define SPR_CR1 PT_CBR         /* read only */
+#define SPR_CR2 PT_SPI
+#define SPR_CR3 PT_SPU
+#define SPR_CR4
+#define SPR_CR5 PT_EVB         /* part of M32R/E, M32R/I core only */
+#define SPR_CR6 PT_BPC
+#define SPR_CR7
+#define SPR_CR8 PT_BBPSW
+#define SPR_CR9
+#define SPR_CR10
+#define SPR_CR11
+#define SPR_CR12
+#define SPR_CR13 PT_WR
+#define SPR_CR14 PT_BBPC
+#define SPR_CR15
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+struct pt_regs {
+       /* Saved main processor registers. */
+       unsigned long r4;
+       unsigned long r5;
+       unsigned long r6;
+       struct pt_regs *pt_regs;
+       unsigned long r0;
+       unsigned long r1;
+       unsigned long r2;
+       unsigned long r3;
+       unsigned long r7;
+       unsigned long r8;
+       unsigned long r9;
+       unsigned long r10;
+       unsigned long r11;
+       unsigned long r12;
+       long syscall_nr;
+
+       /* Saved main processor status and miscellaneous context registers. */
+       unsigned long acc0h;
+       unsigned long acc0l;
+       unsigned long acc1h;    /* ISA_DSP_LEVEL2 only */
+       unsigned long acc1l;    /* ISA_DSP_LEVEL2 only */
+       unsigned long psw;
+       unsigned long bpc;              /* saved PC for TRAP syscalls */
+       unsigned long bbpsw;
+       unsigned long bbpc;
+       unsigned long spu;              /* saved user stack */
+       unsigned long fp;
+       unsigned long lr;               /* saved PC for JL syscalls */
+       unsigned long spi;              /* saved kernel stack */
+       unsigned long orig_r0;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS         12
+#define PTRACE_SETREGS         13
+
+#define PTRACE_OLDSETOPTIONS   21
+
+
+#endif /* _UAPI_ASM_M32R_PTRACE_H */
diff --git a/arch/m32r/include/uapi/asm/setup.h b/arch/m32r/include/uapi/asm/setup.h
new file mode 100644 (file)
index 0000000..96961a4
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _UAPI_ASM_M32R_SETUP_H
+#define _UAPI_ASM_M32R_SETUP_H
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+
+#define COMMAND_LINE_SIZE       512
+
+
+#endif /* _UAPI_ASM_M32R_SETUP_H */
diff --git a/arch/m32r/include/uapi/asm/signal.h b/arch/m32r/include/uapi/asm/signal.h
new file mode 100644 (file)
index 0000000..ef9788f
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef _UAPI_ASM_M32R_SIGNAL_H
+#define _UAPI_ASM_M32R_SIGNAL_H
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/compiler.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG           32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+#define SIGBUS          7
+#define SIGFPE          8
+#define SIGKILL                 9
+#define SIGUSR1                10
+#define SIGSEGV                11
+#define SIGUSR2                12
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGSTKFLT      16
+#define SIGCHLD                17
+#define SIGCONT                18
+#define SIGSTOP                19
+#define SIGTSTP                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGURG         23
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGIO          29
+#define SIGPOLL                SIGIO
+/*
+#define SIGLOST                29
+*/
+#define SIGPWR         30
+#define SIGSYS         31
+#define        SIGUNUSED       31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN       32
+#define SIGRTMAX       _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP   0x00000001u
+#define SA_NOCLDWAIT   0x00000002u
+#define SA_SIGINFO     0x00000004u
+#define SA_ONSTACK     0x08000000u
+#define SA_RESTART     0x10000000u
+#define SA_NODEFER     0x40000000u
+#define SA_RESETHAND   0x80000000u
+
+#define SA_NOMASK      SA_NODEFER
+#define SA_ONESHOT     SA_RESETHAND
+
+#define SA_RESTORER    0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+       union {
+         __sighandler_t _sa_handler;
+         void (*_sa_sigaction)(int, struct siginfo *, void *);
+       } _u;
+       sigset_t sa_mask;
+       unsigned long sa_flags;
+       void (*sa_restorer)(void);
+};
+
+#define sa_handler     _u._sa_handler
+#define sa_sigaction   _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+       void __user *ss_sp;
+       int ss_flags;
+       size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASM_M32R_SIGNAL_H */
diff --git a/arch/m32r/include/uapi/asm/termios.h b/arch/m32r/include/uapi/asm/termios.h
new file mode 100644 (file)
index 0000000..07ad27b
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef _UAPI_M32R_TERMIOS_H
+#define _UAPI_M32R_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+       unsigned short ws_row;
+       unsigned short ws_col;
+       unsigned short ws_xpixel;
+       unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+       unsigned short c_iflag;         /* input mode flags */
+       unsigned short c_oflag;         /* output mode flags */
+       unsigned short c_cflag;         /* control mode flags */
+       unsigned short c_lflag;         /* local mode flags */
+       unsigned char c_line;           /* line discipline */
+       unsigned char c_cc[NCC];        /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE       0x001
+#define TIOCM_DTR      0x002
+#define TIOCM_RTS      0x004
+#define TIOCM_ST       0x008
+#define TIOCM_SR       0x010
+#define TIOCM_CTS      0x020
+#define TIOCM_CAR      0x040
+#define TIOCM_RNG      0x080
+#define TIOCM_DSR      0x100
+#define TIOCM_CD       TIOCM_CAR
+#define TIOCM_RI       TIOCM_RNG
+#define TIOCM_OUT1     0x2000
+#define TIOCM_OUT2     0x4000
+#define TIOCM_LOOP     0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_M32R_TERMIOS_H */
diff --git a/arch/m32r/include/uapi/asm/types.h b/arch/m32r/include/uapi/asm/types.h
new file mode 100644 (file)
index 0000000..9ec9d4c
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/int-ll64.h>
diff --git a/arch/m32r/include/uapi/asm/unistd.h b/arch/m32r/include/uapi/asm/unistd.h
new file mode 100644 (file)
index 0000000..5a54f2a
--- /dev/null
@@ -0,0 +1,335 @@
+#ifndef _UAPI_ASM_M32R_UNISTD_H
+#define _UAPI_ASM_M32R_UNISTD_H
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall     0
+#define __NR_exit                1
+#define __NR_fork                2
+#define __NR_read                3
+#define __NR_write               4
+#define __NR_open                5
+#define __NR_close               6
+#define __NR_waitpid             7
+#define __NR_creat               8
+#define __NR_link                9
+#define __NR_unlink             10
+#define __NR_execve             11
+#define __NR_chdir              12
+#define __NR_time               13
+#define __NR_mknod              14
+#define __NR_chmod              15
+/* 16 is unused */
+/* 17 is unused */
+/* 18 is unused */
+#define __NR_lseek              19
+#define __NR_getpid             20
+#define __NR_mount              21
+#define __NR_umount             22
+/* 23 is unused */
+/* 24 is unused */
+#define __NR_stime              25
+#define __NR_ptrace             26
+#define __NR_alarm              27
+/* 28 is unused */
+#define __NR_pause              29
+#define __NR_utime              30
+/* 31 is unused */
+#define __NR_cachectl           32 /* old #define __NR_gtty             32*/
+#define __NR_access             33
+/* 34 is unused */
+/* 35 is unused */
+#define __NR_sync               36
+#define __NR_kill               37
+#define __NR_rename             38
+#define __NR_mkdir              39
+#define __NR_rmdir              40
+#define __NR_dup                41
+#define __NR_pipe               42
+#define __NR_times              43
+/* 44 is unused */
+#define __NR_brk                45
+/* 46 is unused */
+/* 47 is unused (getgid16) */
+/* 48 is unused */
+/* 49 is unused */
+/* 50 is unused */
+#define __NR_acct               51
+#define __NR_umount2            52
+/* 53 is unused */
+#define __NR_ioctl              54
+/* 55 is unused (fcntl) */
+/* 56 is unused */
+#define __NR_setpgid            57
+/* 58 is unused */
+/* 59 is unused */
+#define __NR_umask              60
+#define __NR_chroot             61
+#define __NR_ustat              62
+#define __NR_dup2               63
+#define __NR_getppid            64
+#define __NR_getpgrp            65
+#define __NR_setsid             66
+/* 67 is unused */
+/* 68 is unused*/
+/* 69 is unused*/
+/* 70 is unused */
+/* 71 is unused */
+/* 72 is unused */
+/* 73 is unused */
+#define __NR_sethostname        74
+#define __NR_setrlimit          75
+/* 76 is unused (old getrlimit) */
+#define __NR_getrusage          77
+#define __NR_gettimeofday       78
+#define __NR_settimeofday       79
+/* 80 is unused */
+/* 81 is unused */
+/* 82 is unused */
+#define __NR_symlink            83
+/* 84 is unused */
+#define __NR_readlink           85
+#define __NR_uselib             86
+#define __NR_swapon             87
+#define __NR_reboot             88
+/* 89 is unused */
+/* 90 is unused */
+#define __NR_munmap             91
+#define __NR_truncate           92
+#define __NR_ftruncate          93
+#define __NR_fchmod             94
+/* 95 is unused */
+#define __NR_getpriority        96
+#define __NR_setpriority        97
+/* 98 is unused */
+#define __NR_statfs             99
+#define __NR_fstatfs           100
+/* 101 is unused */
+#define __NR_socketcall                102
+#define __NR_syslog            103
+#define __NR_setitimer         104
+#define __NR_getitimer         105
+#define __NR_stat              106
+#define __NR_lstat             107
+#define __NR_fstat             108
+/* 109 is unused */
+/* 110 is unused */
+#define __NR_vhangup           111
+/* 112 is unused */
+/* 113 is unused */
+#define __NR_wait4             114
+#define __NR_swapoff           115
+#define __NR_sysinfo           116
+#define __NR_ipc               117
+#define __NR_fsync             118
+/* 119 is unused */
+#define __NR_clone             120
+#define __NR_setdomainname     121
+#define __NR_uname             122
+/* 123 is unused */
+#define __NR_adjtimex          124
+#define __NR_mprotect          125
+/* 126 is unused */
+/* 127 is unused */
+#define __NR_init_module       128
+#define __NR_delete_module     129
+/* 130 is unused */
+#define __NR_quotactl          131
+#define __NR_getpgid           132
+#define __NR_fchdir            133
+#define __NR_bdflush           134
+#define __NR_sysfs             135
+#define __NR_personality       136
+/* 137 is unused */
+/* 138 is unused */
+/* 139 is unused */
+#define __NR__llseek           140
+#define __NR_getdents          141
+#define __NR__newselect                142
+#define __NR_flock             143
+#define __NR_msync             144
+#define __NR_readv             145
+#define __NR_writev            146
+#define __NR_getsid            147
+#define __NR_fdatasync         148
+#define __NR__sysctl           149
+#define __NR_mlock             150
+#define __NR_munlock           151
+#define __NR_mlockall          152
+#define __NR_munlockall                153
+#define __NR_sched_setparam            154
+#define __NR_sched_getparam            155
+#define __NR_sched_setscheduler                156
+#define __NR_sched_getscheduler                157
+#define __NR_sched_yield               158
+#define __NR_sched_get_priority_max    159
+#define __NR_sched_get_priority_min    160
+#define __NR_sched_rr_get_interval     161
+#define __NR_nanosleep         162
+#define __NR_mremap            163
+/* 164 is unused */
+/* 165 is unused */
+#define __NR_tas               166
+/* 167 is unused */
+#define __NR_poll              168
+#define __NR_nfsservctl                169
+/* 170 is unused */
+/* 171 is unused */
+#define __NR_prctl              172
+#define __NR_rt_sigreturn      173
+#define __NR_rt_sigaction      174
+#define __NR_rt_sigprocmask    175
+#define __NR_rt_sigpending     176
+#define __NR_rt_sigtimedwait   177
+#define __NR_rt_sigqueueinfo   178
+#define __NR_rt_sigsuspend     179
+#define __NR_pread64           180
+#define __NR_pwrite64          181
+/* 182 is unused */
+#define __NR_getcwd            183
+#define __NR_capget            184
+#define __NR_capset            185
+#define __NR_sigaltstack       186
+#define __NR_sendfile          187
+/* 188 is unused */
+/* 189 is unused */
+#define __NR_vfork             190
+#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
+#define __NR_mmap2             192
+#define __NR_truncate64                193
+#define __NR_ftruncate64       194
+#define __NR_stat64            195
+#define __NR_lstat64           196
+#define __NR_fstat64           197
+#define __NR_lchown32          198
+#define __NR_getuid32          199
+#define __NR_getgid32          200
+#define __NR_geteuid32         201
+#define __NR_getegid32         202
+#define __NR_setreuid32                203
+#define __NR_setregid32                204
+#define __NR_getgroups32       205
+#define __NR_setgroups32       206
+#define __NR_fchown32          207
+#define __NR_setresuid32       208
+#define __NR_getresuid32       209
+#define __NR_setresgid32       210
+#define __NR_getresgid32       211
+#define __NR_chown32           212
+#define __NR_setuid32          213
+#define __NR_setgid32          214
+#define __NR_setfsuid32                215
+#define __NR_setfsgid32                216
+#define __NR_pivot_root                217
+#define __NR_mincore           218
+#define __NR_madvise           219
+#define __NR_getdents64                220
+#define __NR_fcntl64           221
+/* 222 is unused */
+/* 223 is unused */
+#define __NR_gettid            224
+#define __NR_readahead         225
+#define __NR_setxattr          226
+#define __NR_lsetxattr         227
+#define __NR_fsetxattr         228
+#define __NR_getxattr          229
+#define __NR_lgetxattr         230
+#define __NR_fgetxattr         231
+#define __NR_listxattr         232
+#define __NR_llistxattr                233
+#define __NR_flistxattr                234
+#define __NR_removexattr       235
+#define __NR_lremovexattr      236
+#define __NR_fremovexattr      237
+#define __NR_tkill             238
+#define __NR_sendfile64                239
+#define __NR_futex             240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area   243
+#define __NR_get_thread_area   244
+#define __NR_io_setup          245
+#define __NR_io_destroy                246
+#define __NR_io_getevents      247
+#define __NR_io_submit         248
+#define __NR_io_cancel         249
+#define __NR_fadvise64         250
+/* 251 is unused */
+#define __NR_exit_group                252
+#define __NR_lookup_dcookie    253
+#define __NR_epoll_create      254
+#define __NR_epoll_ctl         255
+#define __NR_epoll_wait                256
+#define __NR_remap_file_pages  257
+#define __NR_set_tid_address   258
+#define __NR_timer_create      259
+#define __NR_timer_settime     (__NR_timer_create+1)
+#define __NR_timer_gettime     (__NR_timer_create+2)
+#define __NR_timer_getoverrun  (__NR_timer_create+3)
+#define __NR_timer_delete      (__NR_timer_create+4)
+#define __NR_clock_settime     (__NR_timer_create+5)
+#define __NR_clock_gettime     (__NR_timer_create+6)
+#define __NR_clock_getres      (__NR_timer_create+7)
+#define __NR_clock_nanosleep   (__NR_timer_create+8)
+#define __NR_statfs64          268
+#define __NR_fstatfs64         269
+#define __NR_tgkill            270
+#define __NR_utimes            271
+#define __NR_fadvise64_64      272
+#define __NR_vserver           273
+#define __NR_mbind             274
+#define __NR_get_mempolicy     275
+#define __NR_set_mempolicy     276
+#define __NR_mq_open           277
+#define __NR_mq_unlink         (__NR_mq_open+1)
+#define __NR_mq_timedsend      (__NR_mq_open+2)
+#define __NR_mq_timedreceive   (__NR_mq_open+3)
+#define __NR_mq_notify         (__NR_mq_open+4)
+#define __NR_mq_getsetattr     (__NR_mq_open+5)
+#define __NR_kexec_load                283
+#define __NR_waitid            284
+/* 285 is unused */
+#define __NR_add_key           286
+#define __NR_request_key       287
+#define __NR_keyctl            288
+#define __NR_ioprio_set                289
+#define __NR_ioprio_get                290
+#define __NR_inotify_init      291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch  293
+#define __NR_migrate_pages     294
+#define __NR_openat            295
+#define __NR_mkdirat           296
+#define __NR_mknodat           297
+#define __NR_fchownat          298
+#define __NR_futimesat         299
+#define __NR_fstatat64         300
+#define __NR_unlinkat          301
+#define __NR_renameat          302
+#define __NR_linkat            303
+#define __NR_symlinkat         304
+#define __NR_readlinkat                305
+#define __NR_fchmodat          306
+#define __NR_faccessat         307
+#define __NR_pselect6          308
+#define __NR_ppoll             309
+#define __NR_unshare           310
+#define __NR_set_robust_list   311
+#define __NR_get_robust_list   312
+#define __NR_splice            313
+#define __NR_sync_file_range   314
+#define __NR_tee               315
+#define __NR_vmsplice          316
+#define __NR_move_pages                317
+#define __NR_getcpu            318
+#define __NR_epoll_pwait       319
+#define __NR_utimensat         320
+#define __NR_signalfd          321
+/* #define __NR_timerfd                322 removed */
+#define __NR_eventfd           323
+#define __NR_fallocate         324
+#define __NR_setns             325
+
+#endif /* _UAPI_ASM_M32R_UNISTD_H */
index 5e34ccf..2a625fb 100644 (file)
@@ -214,8 +214,6 @@ static inline int reassemble_22(int as22)
 
 void *module_alloc(unsigned long size)
 {
-       if (size == 0)
-               return NULL;
        /* using RWX means less protection for modules, but it's
         * easier than trying to map the text, data, init_text and
         * init_data correctly */
index cec8aae..97909d3 100644 (file)
@@ -356,3 +356,4 @@ COMPAT_SYS_SPU(sendmmsg)
 SYSCALL_SPU(setns)
 COMPAT_SYS(process_vm_readv)
 COMPAT_SYS(process_vm_writev)
+SYSCALL(finit_module)
index bcbbe41..29365e1 100644 (file)
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls          353
+#define __NR_syscalls          354
 
 #define __NR__exit __NR_exit
 #define NR_syscalls    __NR_syscalls
index 380b5d3..8c478c6 100644 (file)
 #define __NR_setns             350
 #define __NR_process_vm_readv  351
 #define __NR_process_vm_writev 352
+#define __NR_finit_module      353
 
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index 16e41fe..cebaff8 100644 (file)
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
 
 header-y +=
 
index e89dc9b..78fc538 100644 (file)
@@ -1,78 +1,8 @@
 #ifndef _ASM_SCORE_PTRACE_H
 #define _ASM_SCORE_PTRACE_H
 
-#define PTRACE_GETREGS         12
-#define PTRACE_SETREGS         13
+#include <uapi/asm/ptrace.h>
 
-#define PC             32
-#define CONDITION      33
-#define ECR            34
-#define EMA            35
-#define CEH            36
-#define CEL            37
-#define COUNTER                38
-#define LDCR           39
-#define STCR           40
-#define PSR            41
-
-#define SINGLESTEP16_INSN      0x7006
-#define SINGLESTEP32_INSN      0x840C8000
-#define BREAKPOINT16_INSN      0x7002          /* work on SPG300 */
-#define BREAKPOINT32_INSN      0x84048000      /* work on SPG300 */
-
-/* Define instruction mask */
-#define INSN32_MASK    0x80008000
-
-#define J32    0x88008000      /* 1_00010_0000000000_1_000000000000000 */
-#define J32M   0xFC008000      /* 1_11111_0000000000_1_000000000000000 */
-
-#define B32    0x90008000      /* 1_00100_0000000000_1_000000000000000 */
-#define B32M   0xFC008000
-#define BL32   0x90008001      /* 1_00100_0000000000_1_000000000000001 */
-#define BL32M  B32
-#define BR32   0x80008008      /* 1_00000_0000000000_1_00000000_000100_0 */
-#define BR32M  0xFFE0807E
-#define BRL32  0x80008009      /* 1_00000_0000000000_1_00000000_000100_1 */
-#define BRL32M BR32M
-
-#define B32_SET        (J32 | B32 | BL32 | BR32 | BRL32)
-
-#define J16    0x3000          /* 0_011_....... */
-#define J16M   0xF000
-#define B16    0x4000          /* 0_100_....... */
-#define B16M   0xF000
-#define BR16   0x0004          /* 0_000.......0100 */
-#define BR16M  0xF00F
-#define B16_SET (J16 | B16 | BR16)
-
-
-/*
- * This struct defines the way the registers are stored on the stack during a
- * system call/exception. As usual the registers k0/k1 aren't being saved.
- */
-struct pt_regs {
-       unsigned long pad0[6];  /* stack arguments */
-       unsigned long orig_r4;
-       unsigned long orig_r7;
-       long is_syscall;
-
-       unsigned long regs[32];
-
-       unsigned long cel;
-       unsigned long ceh;
-
-       unsigned long sr0;      /* cnt */
-       unsigned long sr1;      /* lcr */
-       unsigned long sr2;      /* scr */
-
-       unsigned long cp0_epc;
-       unsigned long cp0_ema;
-       unsigned long cp0_psr;
-       unsigned long cp0_ecr;
-       unsigned long cp0_condition;
-};
-
-#ifdef __KERNEL__
 
 struct task_struct;
 
@@ -91,6 +21,4 @@ extern int read_tsk_short(struct task_struct *, unsigned long,
 
 #define arch_has_single_step() (1)
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_SCORE_PTRACE_H */
index 3cb944d..1f3aa72 100644 (file)
@@ -1,11 +1,8 @@
 #ifndef _ASM_SCORE_SETUP_H
 #define _ASM_SCORE_SETUP_H
 
-#define COMMAND_LINE_SIZE      256
-#define MEMORY_START           0
-#define MEMORY_SIZE            0x2000000
+#include <uapi/asm/setup.h>
 
-#ifdef __KERNEL__
 
 extern void pagetable_init(void);
 extern void pgd_init(unsigned long page);
@@ -36,6 +33,4 @@ extern void debug_exception_vector(void);
 extern void general_exception_vector(void);
 extern void interrupt_exception_vector(void);
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_SCORE_SETUP_H */
index baebb3d..040178c 100644 (file)
@@ -1,3 +1,34 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/score/include/uapi/asm/ptrace.h b/arch/score/include/uapi/asm/ptrace.h
new file mode 100644 (file)
index 0000000..f59771a
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _UAPI_ASM_SCORE_PTRACE_H
+#define _UAPI_ASM_SCORE_PTRACE_H
+
+#define PTRACE_GETREGS         12
+#define PTRACE_SETREGS         13
+
+#define PC             32
+#define CONDITION      33
+#define ECR            34
+#define EMA            35
+#define CEH            36
+#define CEL            37
+#define COUNTER                38
+#define LDCR           39
+#define STCR           40
+#define PSR            41
+
+#define SINGLESTEP16_INSN      0x7006
+#define SINGLESTEP32_INSN      0x840C8000
+#define BREAKPOINT16_INSN      0x7002          /* work on SPG300 */
+#define BREAKPOINT32_INSN      0x84048000      /* work on SPG300 */
+
+/* Define instruction mask */
+#define INSN32_MASK    0x80008000
+
+#define J32    0x88008000      /* 1_00010_0000000000_1_000000000000000 */
+#define J32M   0xFC008000      /* 1_11111_0000000000_1_000000000000000 */
+
+#define B32    0x90008000      /* 1_00100_0000000000_1_000000000000000 */
+#define B32M   0xFC008000
+#define BL32   0x90008001      /* 1_00100_0000000000_1_000000000000001 */
+#define BL32M  B32
+#define BR32   0x80008008      /* 1_00000_0000000000_1_00000000_000100_0 */
+#define BR32M  0xFFE0807E
+#define BRL32  0x80008009      /* 1_00000_0000000000_1_00000000_000100_1 */
+#define BRL32M BR32M
+
+#define B32_SET        (J32 | B32 | BL32 | BR32 | BRL32)
+
+#define J16    0x3000          /* 0_011_....... */
+#define J16M   0xF000
+#define B16    0x4000          /* 0_100_....... */
+#define B16M   0xF000
+#define BR16   0x0004          /* 0_000.......0100 */
+#define BR16M  0xF00F
+#define B16_SET (J16 | B16 | BR16)
+
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+       unsigned long pad0[6];  /* stack arguments */
+       unsigned long orig_r4;
+       unsigned long orig_r7;
+       long is_syscall;
+
+       unsigned long regs[32];
+
+       unsigned long cel;
+       unsigned long ceh;
+
+       unsigned long sr0;      /* cnt */
+       unsigned long sr1;      /* lcr */
+       unsigned long sr2;      /* scr */
+
+       unsigned long cp0_epc;
+       unsigned long cp0_ema;
+       unsigned long cp0_psr;
+       unsigned long cp0_ecr;
+       unsigned long cp0_condition;
+};
+
+
+#endif /* _UAPI_ASM_SCORE_PTRACE_H */
diff --git a/arch/score/include/uapi/asm/setup.h b/arch/score/include/uapi/asm/setup.h
new file mode 100644 (file)
index 0000000..ab9dbdb
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _UAPI_ASM_SCORE_SETUP_H
+#define _UAPI_ASM_SCORE_SETUP_H
+
+#define COMMAND_LINE_SIZE      256
+#define MEMORY_START           0
+#define MEMORY_SIZE            0x2000000
+
+
+#endif /* _UAPI_ASM_SCORE_SETUP_H */
index 23f6cbb..1cda8aa 100644 (file)
@@ -1024,7 +1024,11 @@ ENTRY(aes_sparc64_ecb_encrypt_256)
         add            %o2, 0x20, %o2
        brlz,pt         %o3, 11f
         nop
-10:    ldx             [%o1 + 0x00], %g3
+10:    ldd             [%o0 + 0xd0], %f56
+       ldd             [%o0 + 0xd8], %f58
+       ldd             [%o0 + 0xe0], %f60
+       ldd             [%o0 + 0xe8], %f62
+       ldx             [%o1 + 0x00], %g3
        ldx             [%o1 + 0x08], %g7
        xor             %g1, %g3, %g3
        xor             %g2, %g7, %g7
@@ -1128,9 +1132,9 @@ ENTRY(aes_sparc64_ecb_decrypt_256)
        /* %o0=&key[key_len], %o1=input, %o2=output, %o3=len */
        ldx             [%o0 - 0x10], %g1
        subcc           %o3, 0x10, %o3
+       ldx             [%o0 - 0x08], %g2
        be              10f
-        ldx            [%o0 - 0x08], %g2
-       sub             %o0, 0xf0, %o0
+        sub            %o0, 0xf0, %o0
 1:     ldx             [%o1 + 0x00], %g3
        ldx             [%o1 + 0x08], %g7
        ldx             [%o1 + 0x10], %o4
@@ -1154,7 +1158,11 @@ ENTRY(aes_sparc64_ecb_decrypt_256)
         add            %o2, 0x20, %o2
        brlz,pt         %o3, 11f
         nop
-10:    ldx             [%o1 + 0x00], %g3
+10:    ldd             [%o0 + 0x18], %f56
+       ldd             [%o0 + 0x10], %f58
+       ldd             [%o0 + 0x08], %f60
+       ldd             [%o0 + 0x00], %f62
+       ldx             [%o1 + 0x00], %g3
        ldx             [%o1 + 0x08], %g7
        xor             %g1, %g3, %g3
        xor             %g2, %g7, %g7
@@ -1511,11 +1519,11 @@ ENTRY(aes_sparc64_ctr_crypt_256)
         add            %o2, 0x20, %o2
        brlz,pt         %o3, 11f
         nop
-       ldd             [%o0 + 0xd0], %f56
+10:    ldd             [%o0 + 0xd0], %f56
        ldd             [%o0 + 0xd8], %f58
        ldd             [%o0 + 0xe0], %f60
        ldd             [%o0 + 0xe8], %f62
-10:    xor             %g1, %g3, %o5
+       xor             %g1, %g3, %o5
        MOVXTOD_O5_F0
        xor             %g2, %g7, %o5
        MOVXTOD_O5_F2
index 3965d1d..503e6d9 100644 (file)
@@ -222,6 +222,7 @@ static int ecb_encrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        ctx->ops->load_encrypt_keys(&ctx->key[0]);
        while ((nbytes = walk.nbytes)) {
@@ -251,6 +252,7 @@ static int ecb_decrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        ctx->ops->load_decrypt_keys(&ctx->key[0]);
        key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
@@ -280,6 +282,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        ctx->ops->load_encrypt_keys(&ctx->key[0]);
        while ((nbytes = walk.nbytes)) {
@@ -309,6 +312,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        ctx->ops->load_decrypt_keys(&ctx->key[0]);
        key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
@@ -329,6 +333,22 @@ static int cbc_decrypt(struct blkcipher_desc *desc,
        return err;
 }
 
+static void ctr_crypt_final(struct crypto_sparc64_aes_ctx *ctx,
+                           struct blkcipher_walk *walk)
+{
+       u8 *ctrblk = walk->iv;
+       u64 keystream[AES_BLOCK_SIZE / sizeof(u64)];
+       u8 *src = walk->src.virt.addr;
+       u8 *dst = walk->dst.virt.addr;
+       unsigned int nbytes = walk->nbytes;
+
+       ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk,
+                             keystream, AES_BLOCK_SIZE);
+       crypto_xor((u8 *) keystream, src, nbytes);
+       memcpy(dst, keystream, nbytes);
+       crypto_inc(ctrblk, AES_BLOCK_SIZE);
+}
+
 static int ctr_crypt(struct blkcipher_desc *desc,
                     struct scatterlist *dst, struct scatterlist *src,
                     unsigned int nbytes)
@@ -338,10 +358,11 @@ static int ctr_crypt(struct blkcipher_desc *desc,
        int err;
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
-       err = blkcipher_walk_virt(desc, &walk);
+       err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        ctx->ops->load_encrypt_keys(&ctx->key[0]);
-       while ((nbytes = walk.nbytes)) {
+       while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
                unsigned int block_len = nbytes & AES_BLOCK_MASK;
 
                if (likely(block_len)) {
@@ -353,6 +374,10 @@ static int ctr_crypt(struct blkcipher_desc *desc,
                nbytes &= AES_BLOCK_SIZE - 1;
                err = blkcipher_walk_done(desc, &walk, nbytes);
        }
+       if (walk.nbytes) {
+               ctr_crypt_final(ctx, &walk);
+               err = blkcipher_walk_done(desc, &walk, 0);
+       }
        fprs_write(0);
        return err;
 }
@@ -418,7 +443,7 @@ static struct crypto_alg algs[] = { {
        .cra_driver_name        = "ctr-aes-sparc64",
        .cra_priority           = SPARC_CR_OPCODE_PRIORITY,
        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER,
-       .cra_blocksize          = AES_BLOCK_SIZE,
+       .cra_blocksize          = 1,
        .cra_ctxsize            = sizeof(struct crypto_sparc64_aes_ctx),
        .cra_alignmask          = 7,
        .cra_type               = &crypto_blkcipher_type,
index 62c89af..888f626 100644 (file)
@@ -98,6 +98,7 @@ static int __ecb_crypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        if (encrypt)
                key = &ctx->encrypt_key[0];
@@ -160,6 +161,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        key = &ctx->encrypt_key[0];
        camellia_sparc64_load_keys(key, ctx->key_len);
@@ -198,6 +200,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        key = &ctx->decrypt_key[0];
        camellia_sparc64_load_keys(key, ctx->key_len);
index 30b6e90..b5c8fc2 100644 (file)
@@ -376,6 +376,7 @@ ENTRY(des3_ede_sparc64_ecb_crypt)
 1:     ldd     [%o1 + 0x00], %f60
        DES3_LOOP_BODY(60)
        std     %f60, [%o2 + 0x00]
+       add     %o1, 0x08, %o1
        subcc   %o3, 0x08, %o3
        bne,pt  %icc, 1b
         add    %o2, 0x08, %o2
index 41524ce..3065bc6 100644 (file)
@@ -100,6 +100,7 @@ static int __ecb_crypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        if (encrypt)
                des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
@@ -147,6 +148,7 @@ static int cbc_encrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
        while ((nbytes = walk.nbytes)) {
@@ -177,6 +179,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
        while ((nbytes = walk.nbytes)) {
@@ -266,6 +269,7 @@ static int __ecb3_crypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        if (encrypt)
                K = &ctx->encrypt_expkey[0];
@@ -317,6 +321,7 @@ static int cbc3_encrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        K = &ctx->encrypt_expkey[0];
        des3_ede_sparc64_load_keys(K);
@@ -352,6 +357,7 @@ static int cbc3_decrypt(struct blkcipher_desc *desc,
 
        blkcipher_walk_init(&walk, dst, src, nbytes);
        err = blkcipher_walk_virt(desc, &walk);
+       desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 
        K = &ctx->decrypt_expkey[0];
        des3_ede_sparc64_load_keys(K);
index 8c5eed6..9661e9b 100644 (file)
@@ -61,14 +61,20 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
 static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
                                           unsigned long addr, pte_t *ptep)
 {
-       ptep_set_wrprotect(mm, addr, ptep);
+       pte_t old_pte = *ptep;
+       set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
 }
 
 static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
                                             unsigned long addr, pte_t *ptep,
                                             pte_t pte, int dirty)
 {
-       return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+       int changed = !pte_same(*ptep, pte);
+       if (changed) {
+               set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+               flush_tlb_page(vma, addr);
+       }
+       return changed;
 }
 
 static inline pte_t huge_ptep_get(pte_t *ptep)
index 95515f1..7870be0 100644 (file)
@@ -617,6 +617,12 @@ static inline unsigned long pte_present(pte_t pte)
        return val;
 }
 
+#define pte_accessible pte_accessible
+static inline unsigned long pte_accessible(pte_t a)
+{
+       return pte_val(a) & _PAGE_VALID;
+}
+
 static inline unsigned long pte_special(pte_t pte)
 {
        return pte_val(pte) & _PAGE_SPECIAL;
@@ -802,7 +808,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
         * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
         *             and SUN4V pte layout, so this inline test is fine.
         */
-       if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
+       if (likely(mm != &init_mm) && pte_accessible(orig))
                tlb_batch_add(mm, addr, ptep, orig, fullmm);
 }
 
index f1ddc0d..4435488 100644 (file)
@@ -43,10 +43,6 @@ void *module_alloc(unsigned long size)
 {
        void *ret;
 
-       /* We handle the zero case fine, unlike vmalloc */
-       if (size == 0)
-               return NULL;
-
        ret = module_map(size);
        if (ret)
                memset(ret, 0, size);
index 243ffeb..4918d91 100644 (file)
@@ -42,8 +42,6 @@ void *module_alloc(unsigned long size)
        int i = 0;
        int npages;
 
-       if (size == 0)
-               return NULL;
        npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
        pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
        if (pages == NULL)
index 8fbe857..16bd149 100644 (file)
@@ -27,9 +27,6 @@ void *module_alloc(unsigned long size)
        struct vm_struct *area;
 
        size = PAGE_ALIGN(size);
-       if (!size)
-               return NULL;
-
        area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
        if (!area)
                return NULL;
index fbd8955..3286a92 100644 (file)
@@ -26,11 +26,6 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
 #ifdef CONFIG_X86_32
 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 {
-       /*
-        * We use exception 16 if we have hardware math and we've either seen
-        * it or the CPU claims it is internal
-        */
-       int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
        seq_printf(m,
                   "fdiv_bug\t: %s\n"
                   "hlt_bug\t\t: %s\n"
@@ -45,7 +40,7 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
                   c->f00f_bug ? "yes" : "no",
                   c->coma_bug ? "yes" : "no",
                   c->hard_math ? "yes" : "no",
-                  fpu_exception ? "yes" : "no",
+                  c->hard_math ? "yes" : "no",
                   c->cpuid_level,
                   c->wp_works_ok ? "yes" : "no");
 }
index 6e03b0d..7dc4e45 100644 (file)
  * (these are usually mapped into the 0x30-0xff vector range)
  */
 
-#ifdef CONFIG_X86_32
-/*
- * Note that on a 486, we don't want to do a SIGFPE on an irq13
- * as the irq is unreliable, and exception 16 works correctly
- * (ie as explained in the intel literature). On a 386, you
- * can't use exception 16 due to bad IBM design, so we have to
- * rely on the less exact irq13.
- *
- * Careful.. Not only is IRQ13 unreliable, but it is also
- * leads to races. IBM designers who came up with it should
- * be shot.
- */
-
-static irqreturn_t math_error_irq(int cpl, void *dev_id)
-{
-       outb(0, 0xF0);
-       if (ignore_fpu_irq || !boot_cpu_data.hard_math)
-               return IRQ_NONE;
-       math_error(get_irq_regs(), 0, X86_TRAP_MF);
-       return IRQ_HANDLED;
-}
-
-/*
- * New motherboards sometimes make IRQ 13 be a PCI interrupt,
- * so allow interrupt sharing.
- */
-static struct irqaction fpu_irq = {
-       .handler = math_error_irq,
-       .name = "fpu",
-       .flags = IRQF_NO_THREAD,
-};
-#endif
-
 /*
  * IRQ2 is cascade interrupt to second interrupt controller
  */
@@ -242,13 +209,6 @@ void __init native_init_IRQ(void)
                setup_irq(2, &irq2);
 
 #ifdef CONFIG_X86_32
-       /*
-        * External FPU? Set up irq13 if so, for
-        * original braindamaged IBM FERR coupling.
-        */
-       if (boot_cpu_data.hard_math && !cpu_has_fpu)
-               setup_irq(FPU_IRQ, &fpu_irq);
-
        irq_ctx_init(smp_processor_id());
 #endif
 }
index eb85866..ecffca1 100644 (file)
@@ -69,9 +69,6 @@
 
 asmlinkage int system_call(void);
 
-/* Do we ignore FPU interrupts ? */
-char ignore_fpu_irq;
-
 /*
  * The IDT has to be page-aligned to simplify the Pentium
  * F0 0F bug workaround.
@@ -564,9 +561,6 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr)
 
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-#ifdef CONFIG_X86_32
-       ignore_fpu_irq = 1;
-#endif
        exception_enter(regs);
        math_error(regs, error_code, X86_TRAP_MF);
        exception_exit(regs);
index ee3c220..05f404f 100644 (file)
 347    i386    process_vm_readv        sys_process_vm_readv            compat_sys_process_vm_readv
 348    i386    process_vm_writev       sys_process_vm_writev           compat_sys_process_vm_writev
 349    i386    kcmp                    sys_kcmp
+350    i386    finit_module            sys_finit_module
index a582bfe..7c58c84 100644 (file)
 310    64      process_vm_readv        sys_process_vm_readv
 311    64      process_vm_writev       sys_process_vm_writev
 312    common  kcmp                    sys_kcmp
+313    common  finit_module            sys_finit_module
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
index 2481f26..73d34e7 100644 (file)
@@ -17,6 +17,7 @@ config XTENSA
        select GENERIC_KERNEL_EXECVE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select CLONE_BACKWARDS
+       select IRQ_DOMAIN
        help
          Xtensa processors are 32-bit RISC machines designed by Tensilica
          primarily for embedded systems.  These processors are both
@@ -150,6 +151,15 @@ config XTENSA_PLATFORM_S6105
        select SERIAL_CONSOLE
        select NO_IOPORT
 
+config XTENSA_PLATFORM_XTFPGA
+       bool "XTFPGA"
+       select SERIAL_CONSOLE
+       select ETHOC
+       select XTENSA_CALIBRATE_CCOUNT
+       help
+         XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605).
+         This hardware is capable of running a full Linux distribution.
+
 endchoice
 
 
@@ -177,6 +187,17 @@ config CMDLINE
          time by entering them here. As a minimum, you should specify the
          memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
+config USE_OF
+       bool "Flattened Device Tree support"
+       select OF
+       select OF_EARLY_FLATTREE
+       help
+         Include support for flattened device tree machine descriptions.
+
+config BUILTIN_DTB
+       string "DTB to build into the kernel image"
+       depends on OF
+
 source "mm/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
index 11c5852..a34010e 100644 (file)
@@ -2,6 +2,26 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-endmenu
+config LD_NO_RELAX
+       bool "Disable linker relaxation"
+       default n
+       help
+         Enable this function to disable link-time optimizations.
+         The default linker behavior is to combine identical literal
+         values to reduce code size and remove unnecessary overhead from
+         assembler-generated 'longcall' sequences.
+         Enabling this option improves the link time but increases the
+         code size, and possibly execution time.
+
+config S32C1I_SELFTEST
+       bool "Perform S32C1I instruction self-test at boot"
+       default y
+       help
+         Enable this option to test S32C1I instruction behavior at boot.
+         Correct operation of this instruction requires some cooperation from hardware
+         external to the processor (such as bus bridge, bus fabric, or memory controller).
+         It is easy to make wrong hardware configuration, this test should catch it early.
 
+         Say 'N' on stable hardware.
 
+endmenu
index bb5ba61..0aa7270 100644 (file)
@@ -38,6 +38,7 @@ endif
 platform-$(CONFIG_XTENSA_PLATFORM_XT2000)      := xt2000
 platform-$(CONFIG_XTENSA_PLATFORM_ISS)         := iss
 platform-$(CONFIG_XTENSA_PLATFORM_S6105)       := s6105
+platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA)      := xtfpga
 
 PLATFORM = $(platform-y)
 export PLATFORM
@@ -49,6 +50,17 @@ KBUILD_CFLAGS += -pipe -mlongcalls
 
 KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,)
 
+ifneq ($(CONFIG_LD_NO_RELAX),)
+LDFLAGS := --no-relax
+endif
+
+ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1)
+CHECKFLAGS += -D__XTENSA_EB__
+endif
+ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1)
+CHECKFLAGS += -D__XTENSA_EL__
+endif
+
 vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y))
 plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y))
 
@@ -75,6 +87,10 @@ core-y               += $(buildvar) $(buildplf)
 
 libs-y         += arch/xtensa/lib/ $(LIBGCC)
 
+ifneq ($(CONFIG_BUILTIN_DTB),"")
+core-$(CONFIG_OF) += arch/xtensa/boot/
+endif
+
 boot           := arch/xtensa/boot
 
 all: zImage
@@ -84,7 +100,9 @@ bzImage : zImage
 zImage: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $@
 
+%.dtb:
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
 define archhelp
   @echo '* zImage      - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
 endef
-
index 4018f89..818647e 100644 (file)
@@ -22,12 +22,35 @@ subdir-y    := lib
 # Subdirs for the boot loader(s)
 
 bootdir-$(CONFIG_XTENSA_PLATFORM_ISS)   += boot-elf
-bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
+bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot
+bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot
 
 
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o
+ifneq ($(CONFIG_BUILTIN_DTB),"")
+obj-$(CONFIG_OF) += $(BUILTIN_DTB)
+endif
+
+# Rule to build device tree blobs
+$(obj)/%.dtb: $(src)/dts/%.dts FORCE
+       $(call if_changed_dep,dtc)
+
+clean-files := *.dtb.S
+
 zImage Image: $(bootdir-y)
 
 $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
              $(addprefix $(obj)/,$(host-progs))
        $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
 
+OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary
+
+vmlinux.bin: vmlinux FORCE
+       $(call if_changed,objcopy)
+
+vmlinux.bin.gz: vmlinux.bin FORCE
+       $(call if_changed,gzip)
+
+boot-elf: vmlinux.bin
+boot-redboot: vmlinux.bin.gz
+boot-uboot: vmlinux.bin.gz
index f10992b..1fe01b7 100644 (file)
@@ -4,9 +4,6 @@
 # for more details.
 #
 
-GZIP = gzip
-GZIP_FLAGS = -v9fc
-
 ifeq ($(BIG_ENDIAN),1)
 OBJCOPY_ARGS    := -O elf32-xtensa-be
 else
@@ -20,18 +17,17 @@ boot-y              := bootstrap.o
 
 OBJS           := $(addprefix $(obj)/,$(boot-y))
 
-vmlinux.tmp: vmlinux
-       $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
-               $^ $@
-
-Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
-       $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-               --add-section image=vmlinux.tmp \
+$(obj)/Image.o: vmlinux.bin $(OBJS)
+       $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+               --add-section image=vmlinux.bin \
                --set-section-flags image=contents,alloc,load,load,data \
-               $(OBJS) $@.tmp
-       $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
-               -T arch/$(ARCH)/boot/boot-elf/boot.lds \
-               -o arch/$(ARCH)/boot/$@.elf $@.tmp
+               $(OBJS) $@
 
-zImage:        Image
+$(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds
+       $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
+               -T $(obj)/boot.lds \
+               --build-id=none \
+               -o $@ $(obj)/Image.o
+       $(Q)$(kecho) '  Kernel: $@ is ready'
 
+zImage:        $(obj)/../Image.elf
index 25a78c6..8be8b94 100644 (file)
@@ -4,8 +4,6 @@
 # for more details.
 #
 
-GZIP = gzip
-GZIP_FLAGS = -v9fc
 ifeq ($(BIG_ENDIAN),1)
 OBJCOPY_ARGS   := -O elf32-xtensa-be
 else
@@ -21,17 +19,17 @@ LIBS        := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-vmlinux.tmp: vmlinux
-       $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
-               $^ $@
+$(obj)/zImage.o: vmlinux.bin.gz $(OBJS)
+       $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+               --add-section image=vmlinux.bin.gz \
+               --set-section-flags image=contents,alloc,load,load,data \
+               $(OBJS) $@
 
-vmlinux.tmp.gz: vmlinux.tmp
-       $(GZIP) $(GZIP_FLAGS) $^ > $@
+$(obj)/zImage.elf: $(obj)/zImage.o $(LIBS)
+       $(Q)$(LD) $(LD_ARGS) -o $@ $^ -L/xtensa-elf/lib $(LIBGCC)
 
-zImage: vmlinux.tmp.gz $(OBJS) $(LIBS)
-       $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-               --add-section image=vmlinux.tmp.gz \
-               --set-section-flags image=contents,alloc,load,load,data \
-               $(OBJS) $@.tmp
-       $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
-       $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
+$(obj)/../zImage.redboot: $(obj)/zImage.elf
+       $(Q)$(OBJCOPY) -S -O binary $< $@
+       $(Q)$(kecho) '  Kernel: $@ is ready'
+
+zImage: $(obj)/../zImage.redboot
diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile
new file mode 100644 (file)
index 0000000..bfbf8af
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+UIMAGE_LOADADDR = 0xd0001000
+UIMAGE_COMPRESSION = gzip
+
+$(obj)/../uImage: vmlinux.bin.gz FORCE
+       $(call if_changed,uimage)
+       $(Q)$(kecho) '  Kernel: $@ is ready'
+
+zImage: $(obj)/../uImage
diff --git a/arch/xtensa/boot/dts/lx60.dts b/arch/xtensa/boot/dts/lx60.dts
new file mode 100644 (file)
index 0000000..2eab365
--- /dev/null
@@ -0,0 +1,11 @@
+/dts-v1/;
+/include/ "xtfpga.dtsi"
+/include/ "xtfpga-flash-4m.dtsi"
+
+/ {
+       compatible = "xtensa,lx60";
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x04000000>;
+       };
+};
diff --git a/arch/xtensa/boot/dts/ml605.dts b/arch/xtensa/boot/dts/ml605.dts
new file mode 100644 (file)
index 0000000..6ed51d6
--- /dev/null
@@ -0,0 +1,11 @@
+/dts-v1/;
+/include/ "xtfpga.dtsi"
+/include/ "xtfpga-flash-16m.dtsi"
+
+/ {
+       compatible = "xtensa,ml605";
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x08000000>;
+       };
+};
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi
new file mode 100644 (file)
index 0000000..e5703c7
--- /dev/null
@@ -0,0 +1,26 @@
+/ {
+       flash: flash@f8000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "cfi-flash";
+               reg = <0xf8000000 0x01000000>;
+               bank-width = <2>;
+               device-width = <2>;
+               partition@0x0 {
+                       label = "boot loader area";
+                       reg = <0x00000000 0x00400000>;
+               };
+               partition@0x400000 {
+                       label = "kernel image";
+                       reg = <0x00400000 0x00600000>;
+               };
+               partition@0xa00000 {
+                       label = "data";
+                       reg = <0x00a00000 0x005e0000>;
+               };
+               partition@0xfe0000 {
+                       label = "boot environment";
+                       reg = <0x00fe0000 0x00020000>;
+               };
+        };
+};
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi
new file mode 100644 (file)
index 0000000..6f9c10d
--- /dev/null
@@ -0,0 +1,18 @@
+/ {
+       flash: flash@f8000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "cfi-flash";
+               reg = <0xf8000000 0x00400000>;
+               bank-width = <2>;
+               device-width = <2>;
+               partition@0x0 {
+                       label = "boot loader area";
+                       reg = <0x00000000 0x003f0000>;
+               };
+               partition@0x3f0000 {
+                       label = "boot environment";
+                       reg = <0x003f0000 0x00010000>;
+               };
+        };
+};
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi
new file mode 100644 (file)
index 0000000..7eda6ec
--- /dev/null
@@ -0,0 +1,56 @@
+/ {
+       compatible = "xtensa,xtfpga";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&pic>;
+
+       chosen {
+               bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x06000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       compatible = "xtensa,cpu";
+                       reg = <0>;
+                       /* Filled in by platform_setup from FPGA register
+                        * clock-frequency = <100000000>;
+                        */
+               };
+       };
+
+       pic: pic {
+               compatible = "xtensa,pic";
+               /* one cell: internal irq number,
+                * two cells: second cell == 0: internal irq number
+                *            second cell == 1: external irq number
+                */
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       serial0: serial@fd050020 {
+               device_type = "serial";
+               compatible = "ns16550a";
+               no-loopback-test;
+               reg = <0xfd050020 0x20>;
+               reg-shift = <2>;
+               interrupts = <0 1>; /* external irq 0 */
+               /* Filled in by platform_setup from FPGA register
+                * clock-frequency = <100000000>;
+                */
+       };
+
+       enet0: ethoc@fd030000 {
+               compatible = "opencores,ethoc";
+               reg = <0xfd030000 0x4000 0xfd800000 0x4000>;
+               interrupts = <1 1>; /* external irq 1 */
+               local-mac-address = [00 50 c2 13 6f 00];
+       };
+};
index 24f50ca..c3f2891 100644 (file)
  */
 static inline void atomic_add(int i, atomic_t * v)
 {
-    unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0              \n\t"
-       "add     %0, %0, %1             \n\t"
-       "s32i    %0, %2, 0              \n\t"
-       "wsr     a15, ps                \n\t"
-       "rsync                          \n"
-       : "=&a" (vval)
-       : "a" (i), "a" (v)
-       : "a15", "memory"
-       );
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       add     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (i), "a" (v)
+                       : "memory"
+                       );
+#else
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15, "__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       add     %0, %0, %1\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval)
+                       : "a" (i), "a" (v)
+                       : "a15", "memory"
+                       );
+#endif
 }
 
 /**
@@ -90,19 +106,35 @@ static inline void atomic_add(int i, atomic_t * v)
  */
 static inline void atomic_sub(int i, atomic_t *v)
 {
-    unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0              \n\t"
-       "sub     %0, %0, %1             \n\t"
-       "s32i    %0, %2, 0              \n\t"
-       "wsr     a15, ps                \n\t"
-       "rsync                          \n"
-       : "=&a" (vval)
-       : "a" (i), "a" (v)
-       : "a15", "memory"
-       );
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       sub     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (i), "a" (v)
+                       : "memory"
+                       );
+#else
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15, "__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       sub     %0, %0, %1\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval)
+                       : "a" (i), "a" (v)
+                       : "a15", "memory"
+                       );
+#endif
 }
 
 /*
@@ -111,40 +143,78 @@ static inline void atomic_sub(int i, atomic_t *v)
 
 static inline int atomic_add_return(int i, atomic_t * v)
 {
-     unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0             \n\t"
-       "add     %0, %0, %1            \n\t"
-       "s32i    %0, %2, 0             \n\t"
-       "wsr     a15, ps               \n\t"
-       "rsync                         \n"
-       : "=&a" (vval)
-       : "a" (i), "a" (v)
-       : "a15", "memory"
-       );
-
-    return vval;
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       add     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       "       add     %0, %0, %2\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (i), "a" (v)
+                       : "memory"
+                       );
+
+       return result;
+#else
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15,"__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       add     %0, %0, %1\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval)
+                       : "a" (i), "a" (v)
+                       : "a15", "memory"
+                       );
+
+       return vval;
+#endif
 }
 
 static inline int atomic_sub_return(int i, atomic_t * v)
 {
-    unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0             \n\t"
-       "sub     %0, %0, %1            \n\t"
-       "s32i    %0, %2, 0             \n\t"
-       "wsr     a15, ps               \n\t"
-       "rsync                         \n"
-       : "=&a" (vval)
-       : "a" (i), "a" (v)
-       : "a15", "memory"
-       );
-
-    return vval;
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       sub     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       "       sub     %0, %0, %2\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (i), "a" (v)
+                       : "memory"
+                       );
+
+       return result;
+#else
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15,"__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       sub     %0, %0, %1\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval)
+                       : "a" (i), "a" (v)
+                       : "a15", "memory"
+                       );
+
+       return vval;
+#endif
 }
 
 /**
@@ -251,38 +321,70 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
 
 static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
-    unsigned int all_f = -1;
-    unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0             \n\t"
-       "xor     %1, %4, %3            \n\t"
-       "and     %0, %0, %4            \n\t"
-       "s32i    %0, %2, 0             \n\t"
-       "wsr     a15, ps               \n\t"
-       "rsync                         \n"
-       : "=&a" (vval), "=a" (mask)
-       : "a" (v), "a" (all_f), "1" (mask)
-       : "a15", "memory"
-       );
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       and     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (~mask), "a" (v)
+                       : "memory"
+                       );
+#else
+       unsigned int all_f = -1;
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15,"__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       xor     %1, %4, %3\n"
+                       "       and     %0, %0, %4\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval), "=a" (mask)
+                       : "a" (v), "a" (all_f), "1" (mask)
+                       : "a15", "memory"
+                       );
+#endif
 }
 
 static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 {
-    unsigned int vval;
-
-    __asm__ __volatile__(
-       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
-       "l32i    %0, %2, 0             \n\t"
-       "or      %0, %0, %1            \n\t"
-       "s32i    %0, %2, 0             \n\t"
-       "wsr     a15, ps               \n\t"
-       "rsync                         \n"
-       : "=&a" (vval)
-       : "a" (mask), "a" (v)
-       : "a15", "memory"
-       );
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       or      %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (mask), "a" (v)
+                       : "memory"
+                       );
+#else
+       unsigned int vval;
+
+       __asm__ __volatile__(
+                       "       rsil    a15,"__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %2, 0\n"
+                       "       or      %0, %0, %1\n"
+                       "       s32i    %0, %2, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (vval)
+                       : "a" (mask), "a" (v)
+                       : "a15", "memory"
+                       );
+#endif
 }
 
 /* Atomic operations are already serializing */
@@ -294,4 +396,3 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 #endif /* __KERNEL__ */
 
 #endif /* _XTENSA_ATOMIC_H */
-
index 55707a8..ef02167 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2012 Tensilica Inc.
  */
 
 #ifndef _XTENSA_SYSTEM_H
@@ -12,8 +12,8 @@
 #define smp_read_barrier_depends() do { } while(0)
 #define read_barrier_depends() do { } while(0)
 
-#define mb()  barrier()
-#define rmb() mb()
+#define mb()  ({ __asm__ __volatile__("memw" : : : "memory"); })
+#define rmb() barrier()
 #define wmb() mb()
 
 #ifdef CONFIG_SMP
index 5270197..84afe58 100644 (file)
@@ -29,7 +29,6 @@
 #define smp_mb__before_clear_bit()     barrier()
 #define smp_mb__after_clear_bit()      barrier()
 
-#include <asm-generic/bitops/atomic.h>
 #include <asm-generic/bitops/non-atomic.h>
 
 #if XCHAL_HAVE_NSA
@@ -104,6 +103,132 @@ static inline unsigned long __fls(unsigned long word)
 #endif
 
 #include <asm-generic/bitops/fls64.h>
+
+#if XCHAL_HAVE_S32C1I
+
+static inline void set_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       or      %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (mask), "a" (p)
+                       : "memory");
+}
+
+static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       and     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (~mask), "a" (p)
+                       : "memory");
+}
+
+static inline void change_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       xor     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (mask), "a" (p)
+                       : "memory");
+}
+
+static inline int
+test_and_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       or      %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (mask), "a" (p)
+                       : "memory");
+
+       return tmp & mask;
+}
+
+static inline int
+test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       and     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (~mask), "a" (p)
+                       : "memory");
+
+       return tmp & mask;
+}
+
+static inline int
+test_and_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+       unsigned long tmp, value;
+       unsigned long mask = 1UL << (bit & 31);
+
+       p += bit >> 5;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %3, 0\n"
+                       "       wsr     %1, scompare1\n"
+                       "       xor     %0, %1, %2\n"
+                       "       s32c1i  %0, %3, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp), "=&a" (value)
+                       : "a" (mask), "a" (p)
+                       : "memory");
+
+       return tmp & mask;
+}
+
+#else
+
+#include <asm-generic/bitops/atomic.h>
+
+#endif /* XCHAL_HAVE_S32C1I */
+
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/le.h>
 
index 9983f2c..0c25799 100644 (file)
@@ -22,6 +22,7 @@
 #define BP_TAG_MEMORY          0x1003  /* memory addr and size (bp_meminfo) */
 #define BP_TAG_SERIAL_BAUSRATE 0x1004  /* baud rate of current console. */
 #define BP_TAG_SERIAL_PORT     0x1005  /* serial device of current console */
+#define BP_TAG_FDT             0x1006  /* flat device tree addr */
 
 #define BP_TAG_FIRST           0x7B0B  /* first tag with a version number */
 #define BP_TAG_LAST            0x7E0B  /* last tag */
 /* All records are aligned to 4 bytes */
 
 typedef struct bp_tag {
-  unsigned short id;           /* tag id */
-  unsigned short size;         /* size of this record excluding the structure*/
-  unsigned long data[0];       /* data */
+       unsigned short id;      /* tag id */
+       unsigned short size;    /* size of this record excluding the structure*/
+       unsigned long data[0];  /* data */
 } bp_tag_t;
 
 typedef struct meminfo {
-  unsigned long type;
-  unsigned long start;
-  unsigned long end;
+       unsigned long type;
+       unsigned long start;
+       unsigned long end;
 } meminfo_t;
 
 #define SYSMEM_BANKS_MAX 5
@@ -48,14 +49,11 @@ typedef struct meminfo {
 #define MEMORY_TYPE_NONE               0x2000
 
 typedef struct sysmem_info {
-  int nr_banks;
-  meminfo_t bank[SYSMEM_BANKS_MAX];
+       int nr_banks;
+       meminfo_t bank[SYSMEM_BANKS_MAX];
 } sysmem_info_t;
 
 extern sysmem_info_t sysmem;
 
 #endif
 #endif
-
-
-
index 2c20a58..60e1877 100644 (file)
        __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
 
        .endm
-
index 569fec4..127cd48 100644 (file)
@@ -104,7 +104,8 @@ static inline void __invalidate_icache_page_alias(unsigned long virt,
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page*);
 extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
-extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long);
+extern void flush_cache_page(struct vm_area_struct*,
+                            unsigned long, unsigned long);
 
 #else
 
index e4d831a..aed7ad6 100644 (file)
@@ -36,8 +36,9 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum);
  * better 64-bit) boundary
  */
 
-asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum,
-                                                  int *src_err_ptr, int *dst_err_ptr);
+asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
+                                           int len, __wsum sum,
+                                           int *src_err_ptr, int *dst_err_ptr);
 
 /*
  *     Note: when you get a NULL pointer exception here this means someone
@@ -54,7 +55,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst,
 
 static inline
 __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
-                                               int len, __wsum sum, int *err_ptr)
+                                  int len, __wsum sum, int *err_ptr)
 {
        return csum_partial_copy_generic((__force const void *)src, dst,
                                        len, sum, err_ptr, NULL);
@@ -112,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
        /* Since the input registers which are loaded with iph and ihl
           are modified, we must also specify them as outputs, or gcc
           will assume they contain their original values. */
-               : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
+               : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp),
+                 "=&r" (endaddr)
                : "1" (iph), "2" (ihl)
                : "memory");
 
@@ -168,7 +170,7 @@ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
 
 static __inline__ __sum16 ip_compute_csum(const void *buff, int len)
 {
-    return csum_fold (csum_partial(buff, len, 0));
+       return csum_fold (csum_partial(buff, len, 0));
 }
 
 #define _HAVE_ARCH_IPV6_CSUM
@@ -238,11 +240,12 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ __wsum csum_and_copy_to_user(const void *src, void __user *dst,
-                                   int len, __wsum sum, int *err_ptr)
+static __inline__ __wsum csum_and_copy_to_user(const void *src,
+                                              void __user *dst, int len,
+                                              __wsum sum, int *err_ptr)
 {
        if (access_ok(VERIFY_WRITE, dst, len))
-               return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
+               return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr);
 
        if (len)
                *err_ptr = -EFAULT;
index 64dad04..d9ab131 100644 (file)
 static inline unsigned long
 __cmpxchg_u32(volatile int *p, int old, int new)
 {
-  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
-                      "l32i    %0, %1, 0              \n\t"
-                      "bne     %0, %2, 1f             \n\t"
-                      "s32i    %3, %1, 0              \n\t"
-                      "1:                             \n\t"
-                      "wsr     a15, ps                \n\t"
-                      "rsync                          \n\t"
-                      : "=&a" (old)
-                      : "a" (p), "a" (old), "r" (new)
-                      : "a15", "memory");
-  return old;
+#if XCHAL_HAVE_S32C1I
+       __asm__ __volatile__(
+                       "       wsr     %2, scompare1\n"
+                       "       s32c1i  %0, %1, 0\n"
+                       : "+a" (new)
+                       : "a" (p), "a" (old)
+                       : "memory"
+                       );
+
+       return new;
+#else
+       __asm__ __volatile__(
+                       "       rsil    a15, "__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %1, 0\n"
+                       "       bne     %0, %2, 1f\n"
+                       "       s32i    %3, %1, 0\n"
+                       "1:\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (old)
+                       : "a" (p), "a" (old), "r" (new)
+                       : "a15", "memory");
+       return old;
+#endif
 }
 /* This function doesn't exist, so you'll get a linker error
  * if something tries to do an invalid cmpxchg(). */
@@ -93,19 +106,36 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
 
 static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
 {
-  unsigned long tmp;
-  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
-                      "l32i    %0, %1, 0              \n\t"
-                      "s32i    %2, %1, 0              \n\t"
-                      "wsr     a15, ps                \n\t"
-                      "rsync                          \n\t"
-                      : "=&a" (tmp)
-                      : "a" (m), "a" (val)
-                      : "a15", "memory");
-  return tmp;
+#if XCHAL_HAVE_S32C1I
+       unsigned long tmp, result;
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %2, 0\n"
+                       "       mov     %0, %3\n"
+                       "       wsr     %1, scompare1\n"
+                       "       s32c1i  %0, %2, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (m), "a" (val)
+                       : "memory"
+                       );
+       return result;
+#else
+       unsigned long tmp;
+       __asm__ __volatile__(
+                       "       rsil    a15, "__stringify(LOCKLEVEL)"\n"
+                       "       l32i    %0, %1, 0\n"
+                       "       s32i    %2, %1, 0\n"
+                       "       wsr     a15, ps\n"
+                       "       rsync\n"
+                       : "=&a" (tmp)
+                       : "a" (m), "a" (val)
+                       : "a15", "memory");
+       return tmp;
+#endif
 }
 
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define xchg(ptr,x) \
+       ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
 /*
  * This only works if the compiler isn't horribly bad at optimizing.
index 8d1eb5d..47e46dc 100644 (file)
@@ -30,7 +30,7 @@ static inline struct task_struct *get_current(void)
 
 #define GET_CURRENT(reg,sp)            \
        GET_THREAD_INFO(reg,sp);        \
-       l32i reg, reg, TI_TASK          \
+       l32i reg, reg, TI_TASK          \
 
 #endif
 
index 58c0a4f..61fc5fa 100644 (file)
@@ -19,9 +19,9 @@ extern unsigned long loops_per_jiffy;
 
 static inline void __delay(unsigned long loops)
 {
-  /* 2 cycles per loop. */
-  __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
-                       : "=r" (loops) : "0" (loops));
+       /* 2 cycles per loop. */
+       __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
+                             : "=r" (loops) : "0" (loops));
 }
 
 static __inline__ u32 xtensa_get_ccount(void)
@@ -46,4 +46,3 @@ static __inline__ void udelay (unsigned long usecs)
 }
 
 #endif
-
index 492c957..4acb5fe 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 
+#define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
+
 /*
  * DMA-consistent mapping functions.
  */
@@ -98,8 +100,8 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
 }
 
 static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-               enum dma_data_direction direction)
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+                          size_t size, enum dma_data_direction direction)
 {
        consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
 }
index 5293312..264d5fa 100644 (file)
@@ -168,11 +168,11 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
  */
 
 #define ELF_PLAT_INIT(_r, load_addr) \
-  do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0;  _r->areg[3]=0;  \
-       _r->areg[4]=0;  _r->areg[5]=0;    _r->areg[6]=0;  _r->areg[7]=0;  \
-       _r->areg[8]=0;  _r->areg[9]=0;    _r->areg[10]=0; _r->areg[11]=0; \
-       _r->areg[12]=0; _r->areg[13]=0;   _r->areg[14]=0; _r->areg[15]=0; \
-  } while (0)
+       do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0;  _r->areg[3]=0;  \
+            _r->areg[4]=0;  _r->areg[5]=0;    _r->areg[6]=0;  _r->areg[7]=0;  \
+            _r->areg[8]=0;  _r->areg[9]=0;    _r->areg[10]=0; _r->areg[11]=0; \
+            _r->areg[12]=0; _r->areg[13]=0;   _r->areg[14]=0; _r->areg[15]=0; \
+       } while (0)
 
 typedef struct {
        xtregs_opt_t    opt;
index 0a046ca..80be151 100644 (file)
@@ -14,4 +14,3 @@
 extern void flush_cache_kmaps(void);
 
 #endif
-
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h
new file mode 100644 (file)
index 0000000..e1f8ba4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * arch/xtensa/include/asm/initialize_mmu.h
+ *
+ * Initializes MMU:
+ *
+ *      For the new V3 MMU we remap the TLB from virtual == physical
+ *      to the standard Linux mapping used in earlier MMU's.
+ *
+ *      The the MMU we also support a new configuration register that
+ *      specifies how the S32C1I instruction operates with the cache
+ *      controller.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2008 - 2012 Tensilica, Inc.
+ *
+ *   Marc Gauthier <marc@tensilica.com>
+ *   Pete Delaney <piet@tensilica.com>
+ */
+
+#ifndef _XTENSA_INITIALIZE_MMU_H
+#define _XTENSA_INITIALIZE_MMU_H
+
+#ifdef __ASSEMBLY__
+
+#define XTENSA_HWVERSION_RC_2009_0 230000
+
+       .macro  initialize_mmu
+
+#if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)
+/*
+ * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it.
+ * For details see Documentation/xtensa/atomctl.txt
+ */
+#if XCHAL_DCACHE_IS_COHERENT
+       movi    a3, 0x25        /* For SMP/MX -- internal for writeback,
+                                * RCW otherwise
+                                */
+#else
+       movi    a3, 0x29        /* non-MX -- Most cores use Std Memory
+                                * Controlers which usually can't use RCW
+                                */
+#endif
+       wsr     a3, atomctl
+#endif  /* XCHAL_HAVE_S32C1I &&
+        * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)
+        */
+
+       .endm
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* _XTENSA_INITIALIZE_MMU_H */
index feb10af..d43525a 100644 (file)
@@ -107,7 +107,7 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
 
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
-                             struct task_struct *tsk)
+                            struct task_struct *tsk)
 {
        unsigned long asid = asid_cache;
 
index 599e7a2..3407cf7 100644 (file)
@@ -2,7 +2,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
 }
 
-static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+static inline int init_new_context(struct task_struct *tsk,struct mm_struct *mm)
 {
        return 0;
 }
index 7a5591a..47f5823 100644 (file)
  * PAGE_SHIFT determines the page size
  */
 
-#define PAGE_SHIFT             12
-#define PAGE_SIZE              (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
-#define PAGE_MASK              (~(PAGE_SIZE-1))
+#define PAGE_SHIFT     12
+#define PAGE_SIZE      (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
+#define PAGE_MASK      (~(PAGE_SIZE-1))
 
 #ifdef CONFIG_MMU
-#define PAGE_OFFSET            XCHAL_KSEG_CACHED_VADDR
-#define MAX_MEM_PFN            XCHAL_KSEG_SIZE
+#define PAGE_OFFSET    XCHAL_KSEG_CACHED_VADDR
+#define MAX_MEM_PFN    XCHAL_KSEG_SIZE
 #else
-#define PAGE_OFFSET            0
-#define MAX_MEM_PFN            (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#define PAGE_OFFSET    0
+#define MAX_MEM_PFN    (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
 #endif
 
-#define PGTABLE_START          0x80000000
+#define PGTABLE_START  0x80000000
 
 /*
  * Cache aliasing:
@@ -161,7 +161,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
 
 #define __pa(x)                        ((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
-#define pfn_valid(pfn)         ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
+#define pfn_valid(pfn) \
+       ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
+
 #ifdef CONFIG_DISCONTIGMEM
 # error CONFIG_DISCONTIGMEM not supported
 #endif
index 00fcbd7..0b68c76 100644 (file)
@@ -35,7 +35,7 @@ struct pci_space {
 struct pci_controller {
        int index;                      /* used for pci_controller_num */
        struct pci_controller *next;
-        struct pci_bus *bus;
+       struct pci_bus *bus;
        void *arch_data;
 
        int first_busno;
index 05244f0..614be03 100644 (file)
@@ -53,7 +53,7 @@ struct pci_dev;
 
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
-                        enum pci_mmap_state mmap_state, int write_combine);
+                       enum pci_mmap_state mmap_state, int write_combine);
 
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP  1
index 40cf9bc..cf914c8 100644 (file)
@@ -42,7 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 extern struct kmem_cache *pgtable_cache;
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
                                         unsigned long address)
 {
        return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT);
index b03c043..c90ea5b 100644 (file)
@@ -284,7 +284,7 @@ struct vm_area_struct;
 
 static inline int
 ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
-                         pte_t *ptep)
+                         pte_t *ptep)
 {
        pte_t pte = *ptep;
        if (!pte_young(pte))
@@ -304,8 +304,8 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 static inline void
 ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
-       pte_t pte = *ptep;
-       update_pte(ptep, pte_wrprotect(pte));
+       pte_t pte = *ptep;
+       update_pte(ptep, pte_wrprotect(pte));
 }
 
 /* to find an entry in a kernel page-table-directory */
@@ -399,7 +399,7 @@ extern  void update_mmu_cache(struct vm_area_struct * vma,
  */
 
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
-                remap_pfn_range(vma, from, pfn, size, prot)
+       remap_pfn_range(vma, from, pfn, size, prot)
 
 typedef pte_t *pte_addr_t;
 
index 7d936e5..ec098b6 100644 (file)
@@ -75,4 +75,3 @@ extern int platform_pcibios_fixup (void);
 extern void platform_calibrate_ccount (void);
 
 #endif /* _XTENSA_PLATFORM_H */
-
index 2d630e7..e5fb6b0 100644 (file)
@@ -89,7 +89,7 @@
 #define MAKE_PC_FROM_RA(ra,sp)    (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
 
 typedef struct {
-    unsigned long seg;
+       unsigned long seg;
 } mm_segment_t;
 
 struct thread_struct {
@@ -145,10 +145,10 @@ struct thread_struct {
  *       set_thread_state in signal.c depends on it.
  */
 #define USER_PS_VALUE ((1 << PS_WOE_BIT) |                             \
-                       (1 << PS_CALLINC_SHIFT) |                       \
-                       (USER_RING << PS_RING_SHIFT) |                  \
-                       (1 << PS_UM_BIT) |                              \
-                       (1 << PS_EXCM_BIT))
+                      (1 << PS_CALLINC_SHIFT) |                        \
+                      (USER_RING << PS_RING_SHIFT) |                   \
+                      (1 << PS_UM_BIT) |                               \
+                      (1 << PS_EXCM_BIT))
 
 /* Clearing a0 terminates the backtrace. */
 #define start_thread(regs, new_pc, new_sp) \
diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h
new file mode 100644 (file)
index 0000000..f3d7cd2
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _XTENSA_ASM_PROM_H
+#define _XTENSA_ASM_PROM_H
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+#endif /* _XTENSA_ASM_PROM_H */
index da21c17..58bf6fd 100644 (file)
@@ -37,7 +37,7 @@ struct pt_regs {
        unsigned long windowstart;      /*  52 */
        unsigned long syscall;          /*  56 */
        unsigned long icountlevel;      /*  60 */
-       int reserved[1];                /*  64 */
+       unsigned long scompare1;        /*  64 */
 
        /* Additional configurable registers that are used by the compiler. */
        xtregs_opt_t xtregs_opt;
@@ -55,7 +55,7 @@ struct pt_regs {
 
 # define arch_has_single_step()        (1)
 # define task_pt_regs(tsk) ((struct pt_regs*) \
-  (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
+       (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
 # define instruction_pointer(regs) ((regs)->pc)
 
index 8a8aa61..76096a4 100644 (file)
 #define EXCCAUSE_SPECULATION                   7
 #define EXCCAUSE_PRIVILEGED                    8
 #define EXCCAUSE_UNALIGNED                     9
+#define EXCCAUSE_INSTR_DATA_ERROR              12
+#define EXCCAUSE_LOAD_STORE_DATA_ERROR         13
+#define EXCCAUSE_INSTR_ADDR_ERROR              14
+#define EXCCAUSE_LOAD_STORE_ADDR_ERROR         15
 #define EXCCAUSE_ITLB_MISS                     16
 #define EXCCAUSE_ITLB_MULTIHIT                 17
 #define EXCCAUSE_ITLB_PRIVILEGE                        18
 #define DEBUGCAUSE_ICOUNT_BIT          0       /* ICOUNT would incr. to zero */
 
 #endif /* _XTENSA_SPECREG_H */
-
index 8ff2364..0397590 100644 (file)
 #ifndef _XTENSA_SPINLOCK_H
 #define _XTENSA_SPINLOCK_H
 
-#include <linux/spinlock.h>
+/*
+ * spinlock
+ *
+ * There is at most one owner of a spinlock.  There are not different
+ * types of spinlock owners like there are for rwlocks (see below).
+ *
+ * When trying to obtain a spinlock, the function "spins" forever, or busy-
+ * waits, until the lock is obtained.  When spinning, presumably some other
+ * owner will soon give up the spinlock making it available to others.  Use
+ * the trylock functions to avoid spinning forever.
+ *
+ * possible values:
+ *
+ *    0         nobody owns the spinlock
+ *    1         somebody owns the spinlock
+ */
+
+#define __raw_spin_is_locked(x) ((x)->slock != 0)
+#define __raw_spin_unlock_wait(lock) \
+       do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       wsr     %0, scompare1\n"
+                       "1:     movi    %0, 1\n"
+                       "       s32c1i  %0, %1, 0\n"
+                       "       bnez    %0, 1b\n"
+                       : "=&a" (tmp)
+                       : "a" (&lock->slock)
+                       : "memory");
+}
+
+/* Returns 1 if the lock is obtained, 0 otherwise. */
+
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       wsr     %0, scompare1\n"
+                       "       movi    %0, 1\n"
+                       "       s32c1i  %0, %1, 0\n"
+                       : "=&a" (tmp)
+                       : "a" (&lock->slock)
+                       : "memory");
+
+       return tmp == 0 ? 1 : 0;
+}
+
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       s32ri   %0, %1, 0\n"
+                       : "=&a" (tmp)
+                       : "a" (&lock->slock)
+                       : "memory");
+}
+
+/*
+ * rwlock
+ *
+ * Read-write locks are really a more flexible spinlock.  They allow
+ * multiple readers but only one writer.  Write ownership is exclusive
+ * (i.e., all other readers and writers are blocked from ownership while
+ * there is a write owner).  These rwlocks are unfair to writers.  Writers
+ * can be starved for an indefinite time by readers.
+ *
+ * possible values:
+ *
+ *   0          nobody owns the rwlock
+ *  >0          one or more readers own the rwlock
+ *                (the positive value is the actual number of readers)
+ *  0x80000000  one writer owns the rwlock, no other writers, no readers
+ */
+
+#define __raw_write_can_lock(x)  ((x)->lock == 0)
+
+static inline void __raw_write_lock(raw_rwlock_t *rw)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       wsr     %0, scompare1\n"
+                       "1:     movi    %0, 1\n"
+                       "       slli    %0, %0, 31\n"
+                       "       s32c1i  %0, %1, 0\n"
+                       "       bnez    %0, 1b\n"
+                       : "=&a" (tmp)
+                       : "a" (&rw->lock)
+                       : "memory");
+}
+
+/* Returns 1 if the lock is obtained, 0 otherwise. */
+
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       wsr     %0, scompare1\n"
+                       "       movi    %0, 1\n"
+                       "       slli    %0, %0, 31\n"
+                       "       s32c1i  %0, %1, 0\n"
+                       : "=&a" (tmp)
+                       : "a" (&rw->lock)
+                       : "memory");
+
+       return tmp == 0 ? 1 : 0;
+}
+
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %0, 0\n"
+                       "       s32ri   %0, %1, 0\n"
+                       : "=&a" (tmp)
+                       : "a" (&rw->lock)
+                       : "memory");
+}
+
+static inline void __raw_read_lock(raw_rwlock_t *rw)
+{
+       unsigned long tmp;
+       unsigned long result;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %2, 0\n"
+                       "       bltz    %1, 1b\n"
+                       "       wsr     %1, scompare1\n"
+                       "       addi    %0, %1, 1\n"
+                       "       s32c1i  %0, %2, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (&rw->lock)
+                       : "memory");
+}
+
+/* Returns 1 if the lock is obtained, 0 otherwise. */
+
+static inline int __raw_read_trylock(raw_rwlock_t *rw)
+{
+       unsigned long result;
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                       "       l32i    %1, %2, 0\n"
+                       "       addi    %0, %1, 1\n"
+                       "       bltz    %0, 1f\n"
+                       "       wsr     %1, scompare1\n"
+                       "       s32c1i  %0, %2, 0\n"
+                       "       sub     %0, %0, %1\n"
+                       "1:\n"
+                       : "=&a" (result), "=&a" (tmp)
+                       : "a" (&rw->lock)
+                       : "memory");
+
+       return result == 0;
+}
+
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__(
+                       "1:     l32i    %1, %2, 0\n"
+                       "       addi    %0, %1, -1\n"
+                       "       wsr     %1, scompare1\n"
+                       "       s32c1i  %0, %2, 0\n"
+                       "       bne     %0, %1, 1b\n"
+                       : "=&a" (tmp1), "=&a" (tmp2)
+                       : "a" (&rw->lock)
+                       : "memory");
+}
 
 #endif /* _XTENSA_SPINLOCK_H */
index b00c928..8d5e47f 100644 (file)
@@ -25,9 +25,10 @@ asmlinkage long xtensa_fadvise64_64(int, int,
 /* Should probably move to linux/syscalls.h */
 struct pollfd;
 asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp,
-       fd_set __user *exp, struct timespec __user *tsp, void __user *sig);
+                            fd_set __user *exp, struct timespec __user *tsp,
+                            void __user *sig);
 asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
-       struct timespec __user *tsp, const sigset_t __user *sigmask,
-       size_t sigsetsize);
-asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset,
-               size_t sigsetsize);
+                         struct timespec __user *tsp,
+                         const sigset_t __user *sigmask,
+                         size_t sigsetsize);
+asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h
new file mode 100644 (file)
index 0000000..54f7044
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * arch/xtensa/include/asm/traps.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Tensilica Inc.
+ */
+#ifndef _XTENSA_TRAPS_H
+#define _XTENSA_TRAPS_H
+
+#include <asm/ptrace.h>
+
+/*
+ * handler must be either of the following:
+ *  void (*)(struct pt_regs *regs);
+ *  void (*)(struct pt_regs *regs, unsigned long exccause);
+ */
+extern void * __init trap_set_handler(int cause, void *handler);
+extern void do_unhandled(struct pt_regs *regs, unsigned long exccause);
+
+#endif /* _XTENSA_TRAPS_H */
index 6e4bb3b..fd686dc 100644 (file)
 #define segment_eq(a,b)        ((a).seg == (b).seg)
 
 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
-#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
+#define __user_ok(addr,size) \
+               (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
 #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
 #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
 
@@ -234,10 +235,10 @@ do {                                                                      \
        int __cb;                                                       \
        retval = 0;                                                     \
        switch (size) {                                                 \
-        case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb);  break;     \
-        case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break;     \
-        case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break;     \
-        case 8: {                                                      \
+       case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb);  break;      \
+       case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break;      \
+       case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break;      \
+       case 8: {                                                       \
                     __typeof__(*ptr) __v64 = x;                        \
                     retval = __copy_to_user(ptr,&__v64,8);             \
                     break;                                             \
@@ -291,7 +292,7 @@ do {                                                                        \
  * __check_align_* macros still work.
  */
 #define __put_user_asm(x, addr, err, align, insn, cb)  \
-   __asm__ __volatile__(                               \
+__asm__ __volatile__(                                  \
        __check_align_##align                           \
        "1: "insn"  %2, %3, 0           \n"             \
        "2:                             \n"             \
@@ -301,8 +302,8 @@ do {                                                                        \
        "   .long  2b                   \n"             \
        "5:                             \n"             \
        "   l32r   %1, 4b               \n"             \
-        "   movi   %0, %4              \n"             \
-        "   jx     %1                  \n"             \
+       "   movi   %0, %4               \n"             \
+       "   jx     %1                   \n"             \
        "   .previous                   \n"             \
        "   .section  __ex_table,\"a\"  \n"             \
        "   .long       1b, 5b          \n"             \
@@ -334,13 +335,13 @@ extern long __get_user_bad(void);
 do {                                                                   \
        int __cb;                                                       \
        retval = 0;                                                     \
-        switch (size) {                                                        \
-          case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb);  break;  \
-          case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break;  \
-          case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb);  break;  \
-          case 8: retval = __copy_from_user(&x,ptr,8);    break;       \
-          default: (x) = __get_user_bad();                             \
-        }                                                              \
+       switch (size) {                                                 \
+       case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb);  break;     \
+       case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break;     \
+       case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb);  break;     \
+       case 8: retval = __copy_from_user(&x,ptr,8);    break;  \
+       default: (x) = __get_user_bad();                                \
+                                                                     \
 } while (0)
 
 
@@ -349,7 +350,7 @@ do {                                                                        \
  * __check_align_* macros still work.
  */
 #define __get_user_asm(x, addr, err, align, insn, cb) \
-   __asm__ __volatile__(                       \
+__asm__ __volatile__(                  \
        __check_align_##align                   \
        "1: "insn"  %2, %3, 0           \n"     \
        "2:                             \n"     \
@@ -360,8 +361,8 @@ do {                                                                        \
        "5:                             \n"     \
        "   l32r   %1, 4b               \n"     \
        "   movi   %2, 0                \n"     \
-        "   movi   %0, %4              \n"     \
-        "   jx     %1                  \n"     \
+       "   movi   %0, %4               \n"     \
+       "   jx     %1                   \n"     \
        "   .previous                   \n"     \
        "   .section  __ex_table,\"a\"  \n"     \
        "   .long       1b, 5b          \n"     \
@@ -421,8 +422,10 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n)
 
 #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n))
 #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n))
-#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n))
-#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
+#define __copy_to_user(to,from,n) \
+       __generic_copy_to_user_nocheck((to),(from),(n))
+#define __copy_from_user(to,from,n) \
+       __generic_copy_from_user_nocheck((to),(from),(n))
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
index f36cef5..c3a59d9 100644 (file)
@@ -23,13 +23,13 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 #
 # Replicate rules in scripts/Makefile.build
 
-sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g'    \
-       -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \
+sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \
+       -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g'       \
        -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
 
 quiet_cmd__cpp_lds_S = LDS     $@
-      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \
-                       | sed $(sed-y) >$@
+cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $<    \
+                 | sed $(sed-y) >$@
 
 $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
        $(call if_changed_dep,_cpp_lds_S)
index 934ae58..aa2e87b 100644 (file)
@@ -442,7 +442,7 @@ ENTRY(fast_unaligned)
        mov     a1, a2
 
        rsr     a0, ps
-        bbsi.l  a2, PS_UM_BIT, 1f     # jump if user mode
+       bbsi.l  a2, PS_UM_BIT, 1f     # jump if user mode
 
        movi    a0, _kernel_exception
        jx      a0
@@ -450,6 +450,6 @@ ENTRY(fast_unaligned)
 1:     movi    a0, _user_exception
        jx      a0
 
+ENDPROC(fast_unaligned)
 
 #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */
-
index 7dc3f91..0701fad 100644 (file)
@@ -41,6 +41,7 @@ int main(void)
        DEFINE(PT_SAR, offsetof (struct pt_regs, sar));
        DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel));
        DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
+       DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1));
        DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
        DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
        DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1]));
@@ -91,7 +92,8 @@ int main(void)
 #endif
        DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
        DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
-       DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
+       DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \
+              thread.current_ds));
 
        /* struct mm_struct */
        DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
@@ -108,4 +110,3 @@ int main(void)
 
        return 0;
 }
-
index 54c3be3..6476574 100644 (file)
 /* IO protection is currently unsupported. */
 
 ENTRY(fast_io_protect)
+
        wsr     a0, excsave1
        movi    a0, unrecoverable_exception
        callx0  a0
 
+ENDPROC(fast_io_protect)
+
 #if XTENSA_HAVE_COPROCESSORS
 
 /*
@@ -139,6 +142,7 @@ ENTRY(fast_io_protect)
  */
 
 ENTRY(coprocessor_save)
+
        entry   a1, 32
        s32i    a0, a1, 0
        movi    a0, .Lsave_cp_regs_jump_table
@@ -150,7 +154,10 @@ ENTRY(coprocessor_save)
 1:     l32i    a0, a1, 0
        retw
 
+ENDPROC(coprocessor_save)
+
 ENTRY(coprocessor_load)
+
        entry   a1, 32
        s32i    a0, a1, 0
        movi    a0, .Lload_cp_regs_jump_table
@@ -162,8 +169,10 @@ ENTRY(coprocessor_load)
 1:     l32i    a0, a1, 0
        retw
 
+ENDPROC(coprocessor_load)
+
 /*
- * coprocessor_flush(struct task_info*, index) 
+ * coprocessor_flush(struct task_info*, index)
  *                             a2        a3
  * coprocessor_restore(struct task_info*, index)
  *                              a2         a3
@@ -178,6 +187,7 @@ ENTRY(coprocessor_load)
 
 
 ENTRY(coprocessor_flush)
+
        entry   a1, 32
        s32i    a0, a1, 0
        movi    a0, .Lsave_cp_regs_jump_table
@@ -191,6 +201,8 @@ ENTRY(coprocessor_flush)
 1:     l32i    a0, a1, 0
        retw
 
+ENDPROC(coprocessor_flush)
+
 ENTRY(coprocessor_restore)
        entry   a1, 32
        s32i    a0, a1, 0
@@ -205,6 +217,8 @@ ENTRY(coprocessor_restore)
 1:     l32i    a0, a1, 0
        retw
 
+ENDPROC(coprocessor_restore)
+
 /*
  * Entry condition:
  *
@@ -220,10 +234,12 @@ ENTRY(coprocessor_restore)
  */
 
 ENTRY(fast_coprocessor_double)
+
        wsr     a0, excsave1
        movi    a0, unrecoverable_exception
        callx0  a0
 
+ENDPROC(fast_coprocessor_double)
 
 ENTRY(fast_coprocessor)
 
@@ -327,9 +343,14 @@ ENTRY(fast_coprocessor)
 
        rfe
 
+ENDPROC(fast_coprocessor)
+
        .data
+
 ENTRY(coprocessor_owner)
+
        .fill XCHAL_CP_MAX, 4, 0
 
-#endif /* XTENSA_HAVE_COPROCESSORS */
+END(coprocessor_owner)
 
+#endif /* XTENSA_HAVE_COPROCESSORS */
index 90bfc1d..3777fec 100644 (file)
@@ -219,6 +219,7 @@ _user_exception:
 
        j       common_exception
 
+ENDPROC(user_exception)
 
 /*
  * First-level exit handler for kernel exceptions
@@ -371,6 +372,13 @@ common_exception:
        s32i    a2, a1, PT_LBEG
        s32i    a3, a1, PT_LEND
 
+       /* Save SCOMPARE1 */
+
+#if XCHAL_HAVE_S32C1I
+       rsr     a2, scompare1
+       s32i    a2, a1, PT_SCOMPARE1
+#endif
+
        /* Save optional registers. */
 
        save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
@@ -432,6 +440,12 @@ common_exception_return:
 
        load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
 
+       /* Restore SCOMPARE1 */
+
+#if XCHAL_HAVE_S32C1I
+       l32i    a2, a1, PT_SCOMPARE1
+       wsr     a2, scompare1
+#endif
        wsr     a3, ps          /* disable interrupts */
 
        _bbci.l a3, PS_UM_BIT, kernel_exception_exit
@@ -641,6 +655,8 @@ common_exception_exit:
        l32i    a1, a1, PT_AREG1
        rfde
 
+ENDPROC(kernel_exception)
+
 /*
  * Debug exception handler.
  *
@@ -701,6 +717,7 @@ ENTRY(debug_exception)
        /* Debug exception while in exception mode. */
 1:     j       1b      // FIXME!!
 
+ENDPROC(debug_exception)
 
 /*
  * We get here in case of an unrecoverable exception.
@@ -751,6 +768,7 @@ ENTRY(unrecoverable_exception)
 
 1:     j       1b
 
+ENDPROC(unrecoverable_exception)
 
 /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
 
@@ -856,7 +874,7 @@ ENTRY(fast_alloca)
 
        _bnei   a0, 1, 1f               # no 'movsp a1, ax': jump
 
-        /* Move the save area. This implies the use of the L32E
+       /* Move the save area. This implies the use of the L32E
         * and S32E instructions, because this move must be done with
         * the user's PS.RING privilege levels, not with ring 0
         * (kernel's) privileges currently active with PS.EXCM
@@ -929,6 +947,7 @@ ENTRY(fast_alloca)
        l32i    a2, a2, PT_AREG2
        rfe
 
+ENDPROC(fast_alloca)
 
 /*
  * fast system calls.
@@ -966,6 +985,8 @@ ENTRY(fast_syscall_kernel)
 
        j       kernel_exception
 
+ENDPROC(fast_syscall_kernel)
+
 ENTRY(fast_syscall_user)
 
        /* Skip syscall. */
@@ -983,19 +1004,21 @@ ENTRY(fast_syscall_user)
 
        j       user_exception
 
-ENTRY(fast_syscall_unrecoverable)
+ENDPROC(fast_syscall_user)
 
-        /* Restore all states. */
+ENTRY(fast_syscall_unrecoverable)
 
-        l32i    a0, a2, PT_AREG0        # restore a0
-        xsr     a2, depc                # restore a2, depc
-        rsr     a3, excsave1
+       /* Restore all states. */
 
-        wsr     a0, excsave1
-        movi    a0, unrecoverable_exception
-        callx0  a0
+       l32i    a0, a2, PT_AREG0        # restore a0
+       xsr     a2, depc                # restore a2, depc
+       rsr     a3, excsave1
 
+       wsr     a0, excsave1
+       movi    a0, unrecoverable_exception
+       callx0  a0
 
+ENDPROC(fast_syscall_unrecoverable)
 
 /*
  * sysxtensa syscall handler
@@ -1101,7 +1124,7 @@ CATCH
        movi    a2, -EINVAL
        rfe
 
-
+ENDPROC(fast_syscall_xtensa)
 
 
 /* fast_syscall_spill_registers.
@@ -1160,6 +1183,8 @@ ENTRY(fast_syscall_spill_registers)
        movi    a2, 0
        rfe
 
+ENDPROC(fast_syscall_spill_registers)
+
 /* Fixup handler.
  *
  * We get here if the spill routine causes an exception, e.g. tlb miss.
@@ -1228,9 +1253,9 @@ fast_syscall_spill_registers_fixup:
 
        movi    a3, exc_table
        rsr     a0, exccause
-        addx4  a0, a0, a3                      # find entry in table
-        l32i   a0, a0, EXC_TABLE_FAST_USER     # load handler
-        jx     a0
+       addx4   a0, a0, a3                      # find entry in table
+       l32i    a0, a0, EXC_TABLE_FAST_USER     # load handler
+       jx      a0
 
 fast_syscall_spill_registers_fixup_return:
 
@@ -1432,7 +1457,7 @@ ENTRY(_spill_registers)
        rsr     a0, ps
        _bbci.l a0, PS_UM_BIT, 1f
 
-       /* User space: Setup a dummy frame and kill application.
+       /* User space: Setup a dummy frame and kill application.
         * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer.
         */
 
@@ -1464,6 +1489,8 @@ ENTRY(_spill_registers)
        callx0  a0              # should not return
 1:     j       1b
 
+ENDPROC(_spill_registers)
+
 #ifdef CONFIG_MMU
 /*
  * We should never get here. Bail out!
@@ -1475,6 +1502,8 @@ ENTRY(fast_second_level_miss_double_kernel)
        callx0  a0              # should not return
 1:     j       1b
 
+ENDPROC(fast_second_level_miss_double_kernel)
+
 /* First-level entry handler for user, kernel, and double 2nd-level
  * TLB miss exceptions.  Note that for now, user and kernel miss
  * exceptions share the same entry point and are handled identically.
@@ -1682,6 +1711,7 @@ ENTRY(fast_second_level_miss)
        j       _kernel_exception
 1:     j       _user_exception
 
+ENDPROC(fast_second_level_miss)
 
 /*
  * StoreProhibitedException
@@ -1777,6 +1807,9 @@ ENTRY(fast_store_prohibited)
        bbsi.l  a2, PS_UM_BIT, 1f
        j       _kernel_exception
 1:     j       _user_exception
+
+ENDPROC(fast_store_prohibited)
+
 #endif /* CONFIG_MMU */
 
 /*
@@ -1787,6 +1820,7 @@ ENTRY(fast_store_prohibited)
  */
 
 ENTRY(system_call)
+
        entry   a1, 32
 
        /* regs->syscall = regs->areg[2] */
@@ -1831,6 +1865,8 @@ ENTRY(system_call)
        callx4  a4
        retw
 
+ENDPROC(system_call)
+
 
 /*
  * Task switch.
@@ -1899,6 +1935,7 @@ ENTRY(_switch_to)
 
        retw
 
+ENDPROC(_switch_to)
 
 ENTRY(ret_from_fork)
 
@@ -1914,6 +1951,8 @@ ENTRY(ret_from_fork)
 
        j       common_exception_return
 
+ENDPROC(ret_from_fork)
+
 /*
  * Kernel thread creation helper
  * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg
index bdc5078..91d9095 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/cacheasm.h>
+#include <asm/initialize_mmu.h>
 
 #include <linux/init.h>
 #include <linux/linkage.h>
         */
 
        __HEAD
-       .globl _start
-_start:        _j      2f
+ENTRY(_start)
+
+       _j      2f
        .align  4
 1:     .word   _startup
 2:     l32r    a0, 1b
        jx      a0
 
+ENDPROC(_start)
+
        .section .init.text, "ax"
-       .align 4
-_startup:
+
+ENTRY(_startup)
 
        /* Disable interrupts and exceptions. */
 
@@ -107,7 +111,7 @@ _startup:
        /* Disable all timers. */
 
        .set    _index, 0
-       .rept   XCHAL_NUM_TIMERS - 1
+       .rept   XCHAL_NUM_TIMERS
        wsr     a0, SREG_CCOMPARE + _index
        .set    _index, _index + 1
        .endr
@@ -120,7 +124,7 @@ _startup:
 
        /* Disable coprocessors. */
 
-#if XCHAL_CP_NUM > 0
+#if XCHAL_HAVE_CP
        wsr     a0, cpenable
 #endif
 
@@ -152,6 +156,8 @@ _startup:
 
        isync
 
+       initialize_mmu
+
        /* Unpack data sections
         *
         * The linker script used to build the Linux kernel image
@@ -230,6 +236,7 @@ _startup:
 should_never_return:
        j       should_never_return
 
+ENDPROC(_startup)
 
 /*
  * BSS section
@@ -239,6 +246,8 @@ __PAGE_ALIGNED_BSS
 #ifdef CONFIG_MMU
 ENTRY(swapper_pg_dir)
        .fill   PAGE_SIZE, 1, 0
+END(swapper_pg_dir)
 #endif
 ENTRY(empty_zero_page)
        .fill   PAGE_SIZE, 1, 0
+END(empty_zero_page)
index a6ce3e5..6f4f974 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kernel_stat.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
 
 #include <asm/uaccess.h>
 #include <asm/platform.h>
@@ -26,19 +28,22 @@ static unsigned int cached_irq_mask;
 
 atomic_t irq_err_count;
 
+static struct irq_domain *root_domain;
+
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
 
-asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
+       int irq = irq_find_mapping(root_domain, hwirq);
 
-       if (irq >= NR_IRQS) {
+       if (hwirq >= NR_IRQS) {
                printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                               __func__, irq);
+                               __func__, hwirq);
        }
 
        irq_enter();
@@ -71,40 +76,39 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 
 static void xtensa_irq_mask(struct irq_data *d)
 {
-       cached_irq_mask &= ~(1 << d->irq);
+       cached_irq_mask &= ~(1 << d->hwirq);
        set_sr (cached_irq_mask, intenable);
 }
 
 static void xtensa_irq_unmask(struct irq_data *d)
 {
-       cached_irq_mask |= 1 << d->irq;
+       cached_irq_mask |= 1 << d->hwirq;
        set_sr (cached_irq_mask, intenable);
 }
 
 static void xtensa_irq_enable(struct irq_data *d)
 {
-       variant_irq_enable(d->irq);
+       variant_irq_enable(d->hwirq);
        xtensa_irq_unmask(d);
 }
 
 static void xtensa_irq_disable(struct irq_data *d)
 {
        xtensa_irq_mask(d);
-       variant_irq_disable(d->irq);
+       variant_irq_disable(d->hwirq);
 }
 
 static void xtensa_irq_ack(struct irq_data *d)
 {
-       set_sr(1 << d->irq, intclear);
+       set_sr(1 << d->hwirq, intclear);
 }
 
 static int xtensa_irq_retrigger(struct irq_data *d)
 {
-       set_sr (1 << d->irq, INTSET);
+       set_sr(1 << d->hwirq, intset);
        return 1;
 }
 
-
 static struct irq_chip xtensa_irq_chip = {
        .name           = "xtensa",
        .irq_enable     = xtensa_irq_enable,
@@ -115,37 +119,99 @@ static struct irq_chip xtensa_irq_chip = {
        .irq_retrigger  = xtensa_irq_retrigger,
 };
 
-void __init init_IRQ(void)
+static int xtensa_irq_map(struct irq_domain *d, unsigned int irq,
+               irq_hw_number_t hw)
 {
-       int index;
-
-       for (index = 0; index < XTENSA_NR_IRQS; index++) {
-               int mask = 1 << index;
-
-               if (mask & XCHAL_INTTYPE_MASK_SOFTWARE)
-                       irq_set_chip_and_handler(index, &xtensa_irq_chip,
-                                                handle_simple_irq);
+       u32 mask = 1 << hw;
+
+       if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) {
+               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+                               handle_simple_irq, "level");
+               irq_set_status_flags(irq, IRQ_LEVEL);
+       } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) {
+               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+                               handle_edge_irq, "edge");
+               irq_clear_status_flags(irq, IRQ_LEVEL);
+       } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) {
+               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+                               handle_level_irq, "level");
+               irq_set_status_flags(irq, IRQ_LEVEL);
+       } else if (mask & XCHAL_INTTYPE_MASK_TIMER) {
+               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+                               handle_edge_irq, "edge");
+               irq_clear_status_flags(irq, IRQ_LEVEL);
+       } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */
+               /* XCHAL_INTTYPE_MASK_NMI */
+
+               irq_set_chip_and_handler_name(irq, &xtensa_irq_chip,
+                               handle_level_irq, "level");
+               irq_set_status_flags(irq, IRQ_LEVEL);
+       }
+       return 0;
+}
 
-               else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE)
-                       irq_set_chip_and_handler(index, &xtensa_irq_chip,
-                                                handle_edge_irq);
+static unsigned map_ext_irq(unsigned ext_irq)
+{
+       unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE |
+               XCHAL_INTTYPE_MASK_EXTERN_LEVEL;
+       unsigned i;
 
-               else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL)
-                       irq_set_chip_and_handler(index, &xtensa_irq_chip,
-                                                handle_level_irq);
+       for (i = 0; mask; ++i, mask >>= 1) {
+               if ((mask & 1) && ext_irq-- == 0)
+                       return i;
+       }
+       return XCHAL_NUM_INTERRUPTS;
+}
 
-               else if (mask & XCHAL_INTTYPE_MASK_TIMER)
-                       irq_set_chip_and_handler(index, &xtensa_irq_chip,
-                                                handle_edge_irq);
+/*
+ * Device Tree IRQ specifier translation function which works with one or
+ * two cell bindings. First cell value maps directly to the hwirq number.
+ * Second cell if present specifies whether hwirq number is external (1) or
+ * internal (0).
+ */
+int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
+               const u32 *intspec, unsigned int intsize,
+               unsigned long *out_hwirq, unsigned int *out_type)
+{
+       if (WARN_ON(intsize < 1 || intsize > 2))
+               return -EINVAL;
+       if (intsize == 2 && intspec[1] == 1) {
+               unsigned int_irq = map_ext_irq(intspec[0]);
+               if (int_irq < XCHAL_NUM_INTERRUPTS)
+                       *out_hwirq = int_irq;
+               else
+                       return -EINVAL;
+       } else {
+               *out_hwirq = intspec[0];
+       }
+       *out_type = IRQ_TYPE_NONE;
+       return 0;
+}
 
-               else    /* XCHAL_INTTYPE_MASK_WRITE_ERROR */
-                       /* XCHAL_INTTYPE_MASK_NMI */
+static const struct irq_domain_ops xtensa_irq_domain_ops = {
+       .xlate = xtensa_irq_domain_xlate,
+       .map = xtensa_irq_map,
+};
 
-                       irq_set_chip_and_handler(index, &xtensa_irq_chip,
-                                                handle_level_irq);
-       }
+void __init init_IRQ(void)
+{
+       struct device_node *intc = NULL;
 
        cached_irq_mask = 0;
+       set_sr(~0, intclear);
+
+#ifdef CONFIG_OF
+       /* The interrupt controller device node is mandatory */
+       intc = of_find_compatible_node(NULL, NULL, "xtensa,pic");
+       BUG_ON(!intc);
+
+       root_domain = irq_domain_add_linear(intc, NR_IRQS,
+                       &xtensa_irq_domain_ops, NULL);
+#else
+       root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
+                       &xtensa_irq_domain_ops, NULL);
+#endif
+       irq_set_default_host(root_domain);
 
        variant_init_irq();
 }
index 451dda9..b715237 100644 (file)
@@ -53,7 +53,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
                       struct module *mod)
 {
        unsigned int i;
-        Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+       Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
        Elf32_Sym *sym;
        unsigned char *location;
        uint32_t value;
index 97230e4..44bf21c 100644 (file)
@@ -44,4 +44,3 @@ _F(void, calibrate_ccount, (void),
        ccount_per_jiffy = 10 * (1000000UL/HZ);
 });
 #endif
-
index 1accf28..0dd5784 100644 (file)
@@ -108,7 +108,7 @@ void coprocessor_flush_all(struct thread_info *ti)
 
 void cpu_idle(void)
 {
-       local_irq_enable();
+       local_irq_enable();
 
        /* endless idle loop with no priority at all */
        while (1) {
index 33eea4c..61fb2e9 100644 (file)
@@ -154,7 +154,7 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs)
        coprocessor_flush_all(ti);
        coprocessor_release_all(ti);
 
-       ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, 
+       ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0,
                                sizeof(xtregs_coprocessor_t));
 #endif
        ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
@@ -343,4 +343,3 @@ void do_syscall_trace_leave(struct pt_regs *regs)
                        && (current->ptrace & PT_PTRACED))
                do_syscall_trace();
 }
-
index b237988..24c1a57 100644 (file)
 #include <linux/bootmem.h>
 #include <linux/kernel.h>
 
+#ifdef CONFIG_OF
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#endif
+
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 # include <linux/console.h>
 #endif
@@ -42,6 +47,7 @@
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <asm/param.h>
+#include <asm/traps.h>
 
 #include <platform/hardware.h>
 
@@ -64,6 +70,11 @@ int initrd_is_mapped = 0;
 extern int initrd_below_start_ok;
 #endif
 
+#ifdef CONFIG_OF
+extern u32 __dtb_start[];
+void *dtb_start = __dtb_start;
+#endif
+
 unsigned char aux_device_present;
 extern unsigned long loops_per_jiffy;
 
@@ -83,6 +94,8 @@ extern void init_mmu(void);
 static inline void init_mmu(void) { }
 #endif
 
+extern int mem_reserve(unsigned long, unsigned long, int);
+extern void bootmem_init(void);
 extern void zones_init(void);
 
 /*
@@ -104,28 +117,33 @@ typedef struct tagtable {
 
 /* parse current tag */
 
-static int __init parse_tag_mem(const bp_tag_t *tag)
+static int __init add_sysmem_bank(unsigned long type, unsigned long start,
+               unsigned long end)
 {
-       meminfo_t *mi = (meminfo_t*)(tag->data);
-
-       if (mi->type != MEMORY_TYPE_CONVENTIONAL)
-               return -1;
-
        if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) {
                printk(KERN_WARNING
-                      "Ignoring memory bank 0x%08lx size %ldKB\n",
-                      (unsigned long)mi->start,
-                      (unsigned long)mi->end - (unsigned long)mi->start);
+                               "Ignoring memory bank 0x%08lx size %ldKB\n",
+                               start, end - start);
                return -EINVAL;
        }
-       sysmem.bank[sysmem.nr_banks].type  = mi->type;
-       sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start);
-       sysmem.bank[sysmem.nr_banks].end   = mi->end & PAGE_MASK;
+       sysmem.bank[sysmem.nr_banks].type  = type;
+       sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start);
+       sysmem.bank[sysmem.nr_banks].end   = end & PAGE_MASK;
        sysmem.nr_banks++;
 
        return 0;
 }
 
+static int __init parse_tag_mem(const bp_tag_t *tag)
+{
+       meminfo_t *mi = (meminfo_t *)(tag->data);
+
+       if (mi->type != MEMORY_TYPE_CONVENTIONAL)
+               return -1;
+
+       return add_sysmem_bank(mi->type, mi->start, mi->end);
+}
+
 __tagtable(BP_TAG_MEMORY, parse_tag_mem);
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -142,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
 
 __tagtable(BP_TAG_INITRD, parse_tag_initrd);
 
+#ifdef CONFIG_OF
+
+static int __init parse_tag_fdt(const bp_tag_t *tag)
+{
+       dtb_start = (void *)(tag->data[0]);
+       return 0;
+}
+
+__tagtable(BP_TAG_FDT, parse_tag_fdt);
+
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+               unsigned long end)
+{
+       initrd_start = (void *)__va(start);
+       initrd_end = (void *)__va(end);
+       initrd_below_start_ok = 1;
+}
+
+#endif /* CONFIG_OF */
+
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 static int __init parse_tag_cmdline(const bp_tag_t* tag)
 {
-       strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE);
-       command_line[COMMAND_LINE_SIZE - 1] = '\0';
+       strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
        return 0;
 }
 
@@ -185,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag)
        return 0;
 }
 
+#ifdef CONFIG_OF
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+       size &= PAGE_MASK;
+       add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+       return __alloc_bootmem(size, align, 0);
+}
+
+void __init early_init_devtree(void *params)
+{
+       /* Setup flat device-tree pointer */
+       initial_boot_params = params;
+
+       /* Retrieve various informations from the /chosen node of the
+        * device-tree, including the platform type, initrd location and
+        * size, TCE reserve, and more ...
+        */
+       if (!command_line[0])
+               of_scan_flat_dt(early_init_dt_scan_chosen, command_line);
+
+       /* Scan memory nodes and rebuild MEMBLOCKs */
+       of_scan_flat_dt(early_init_dt_scan_root, NULL);
+       if (sysmem.nr_banks == 0)
+               of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+}
+
+static void __init copy_devtree(void)
+{
+       void *alloc = early_init_dt_alloc_memory_arch(
+                       be32_to_cpu(initial_boot_params->totalsize), 0);
+       if (alloc) {
+               memcpy(alloc, initial_boot_params,
+                               be32_to_cpu(initial_boot_params->totalsize));
+               initial_boot_params = alloc;
+       }
+}
+
+static int __init xtensa_device_probe(void)
+{
+       of_platform_populate(NULL, NULL, NULL, NULL);
+       return 0;
+}
+
+device_initcall(xtensa_device_probe);
+
+#endif /* CONFIG_OF */
+
 /*
  * Initialize architecture. (Early stage)
  */
@@ -193,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start)
 {
        sysmem.nr_banks = 0;
 
-#ifdef CONFIG_CMDLINE_BOOL
-       strcpy(command_line, default_command_line);
-#endif
-
        /* Parse boot parameters */
 
-        if (bp_start)
-         parse_bootparam(bp_start);
+       if (bp_start)
+               parse_bootparam(bp_start);
+
+#ifdef CONFIG_OF
+       early_init_devtree(dtb_start);
+#endif
 
        if (sysmem.nr_banks == 0) {
                sysmem.nr_banks = 1;
@@ -209,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start)
                                     + PLATFORM_DEFAULT_MEM_SIZE;
        }
 
+#ifdef CONFIG_CMDLINE_BOOL
+       if (!command_line[0])
+               strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE);
+#endif
+
        /* Early hook for platforms */
 
        platform_init(bp_start);
@@ -235,15 +329,130 @@ extern char _UserExceptionVector_text_end;
 extern char _DoubleExceptionVector_literal_start;
 extern char _DoubleExceptionVector_text_end;
 
-void __init setup_arch(char **cmdline_p)
+
+#ifdef CONFIG_S32C1I_SELFTEST
+#if XCHAL_HAVE_S32C1I
+
+static int __initdata rcw_word, rcw_probe_pc, rcw_exc;
+
+/*
+ * Basic atomic compare-and-swap, that records PC of S32C1I for probing.
+ *
+ * If *v == cmp, set *v = set.  Return previous *v.
+ */
+static inline int probed_compare_swap(int *v, int cmp, int set)
+{
+       int tmp;
+
+       __asm__ __volatile__(
+                       "       movi    %1, 1f\n"
+                       "       s32i    %1, %4, 0\n"
+                       "       wsr     %2, scompare1\n"
+                       "1:     s32c1i  %0, %3, 0\n"
+                       : "=a" (set), "=&a" (tmp)
+                       : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set)
+                       : "memory"
+                       );
+       return set;
+}
+
+/* Handle probed exception */
+
+void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause)
+{
+       if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */
+               regs->pc += 3;          /* skip the s32c1i instruction */
+               rcw_exc = exccause;
+       } else {
+               do_unhandled(regs, exccause);
+       }
+}
+
+/* Simple test of S32C1I (soc bringup assist) */
+
+void __init check_s32c1i(void)
+{
+       int n, cause1, cause2;
+       void *handbus, *handdata, *handaddr; /* temporarily saved handlers */
+
+       rcw_probe_pc = 0;
+       handbus  = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR,
+                       do_probed_exception);
+       handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR,
+                       do_probed_exception);
+       handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR,
+                       do_probed_exception);
+
+       /* First try an S32C1I that does not store: */
+       rcw_exc = 0;
+       rcw_word = 1;
+       n = probed_compare_swap(&rcw_word, 0, 2);
+       cause1 = rcw_exc;
+
+       /* took exception? */
+       if (cause1 != 0) {
+               /* unclean exception? */
+               if (n != 2 || rcw_word != 1)
+                       panic("S32C1I exception error");
+       } else if (rcw_word != 1 || n != 1) {
+               panic("S32C1I compare error");
+       }
+
+       /* Then an S32C1I that stores: */
+       rcw_exc = 0;
+       rcw_word = 0x1234567;
+       n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde);
+       cause2 = rcw_exc;
+
+       if (cause2 != 0) {
+               /* unclean exception? */
+               if (n != 0xabcde || rcw_word != 0x1234567)
+                       panic("S32C1I exception error (b)");
+       } else if (rcw_word != 0xabcde || n != 0x1234567) {
+               panic("S32C1I store error");
+       }
+
+       /* Verify consistency of exceptions: */
+       if (cause1 || cause2) {
+               pr_warn("S32C1I took exception %d, %d\n", cause1, cause2);
+               /* If emulation of S32C1I upon bus error gets implemented,
+                  we can get rid of this panic for single core (not SMP) */
+               panic("S32C1I exceptions not currently supported");
+       }
+       if (cause1 != cause2)
+               panic("inconsistent S32C1I exceptions");
+
+       trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus);
+       trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata);
+       trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr);
+}
+
+#else /* XCHAL_HAVE_S32C1I */
+
+/* This condition should not occur with a commercially deployed processor.
+   Display reminder for early engr test or demo chips / FPGA bitstreams */
+void __init check_s32c1i(void)
+{
+       pr_warn("Processor configuration lacks atomic compare-and-swap support!\n");
+}
+
+#endif /* XCHAL_HAVE_S32C1I */
+#else /* CONFIG_S32C1I_SELFTEST */
+
+void __init check_s32c1i(void)
 {
-       extern int mem_reserve(unsigned long, unsigned long, int);
-       extern void bootmem_init(void);
+}
+
+#endif /* CONFIG_S32C1I_SELFTEST */
 
-       memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
-       boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
+
+void __init setup_arch(char **cmdline_p)
+{
+       strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
 
+       check_s32c1i();
+
        /* Reserve some memory regions */
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -251,7 +460,7 @@ void __init setup_arch(char **cmdline_p)
                initrd_is_mapped = mem_reserve(__pa(initrd_start),
                                               __pa(initrd_end), 0);
                initrd_below_start_ok = 1;
-       } else {
+       } else {
                initrd_start = 0;
        }
 #endif
@@ -275,8 +484,12 @@ void __init setup_arch(char **cmdline_p)
 
        bootmem_init();
 
-       platform_setup(cmdline_p);
+#ifdef CONFIG_OF
+       copy_devtree();
+       unflatten_device_tree();
+#endif
 
+       platform_setup(cmdline_p);
 
        paging_init();
        zones_init();
@@ -326,7 +539,7 @@ c_show(struct seq_file *f, void *slot)
                     "core ID\t\t: " XCHAL_CORE_ID "\n"
                     "build ID\t: 0x%x\n"
                     "byte order\t: %s\n"
-                    "cpu MHz\t\t: %lu.%02lu\n"
+                    "cpu MHz\t\t: %lu.%02lu\n"
                     "bogomips\t: %lu.%02lu\n",
                     XCHAL_BUILD_UNIQUE_ID,
                     XCHAL_HAVE_BE ?  "big" : "little",
@@ -381,6 +594,9 @@ c_show(struct seq_file *f, void *slot)
 #if XCHAL_HAVE_FP
                     "fpu "
 #endif
+#if XCHAL_HAVE_S32C1I
+                    "s32c1i "
+#endif
                     "\n");
 
        /* Registers. */
@@ -412,7 +628,7 @@ c_show(struct seq_file *f, void *slot)
                     "icache size\t: %d\n"
                     "icache flags\t: "
 #if XCHAL_ICACHE_LINE_LOCKABLE
-                    "lock"
+                    "lock "
 #endif
                     "\n"
                     "dcache line size: %d\n"
@@ -420,10 +636,10 @@ c_show(struct seq_file *f, void *slot)
                     "dcache size\t: %d\n"
                     "dcache flags\t: "
 #if XCHAL_DCACHE_IS_WRITEBACK
-                    "writeback"
+                    "writeback "
 #endif
 #if XCHAL_DCACHE_LINE_LOCKABLE
-                    "lock"
+                    "lock "
 #endif
                     "\n",
                     XCHAL_ICACHE_LINESIZE,
@@ -465,4 +681,3 @@ const struct seq_operations cpuinfo_op =
 };
 
 #endif /* CONFIG_PROC_FS */
-
index 63c566f..de34d6b 100644 (file)
@@ -212,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
        if (err)
                return err;
 
-       /* The signal handler may have used coprocessors in which
+       /* The signal handler may have used coprocessors in which
         * case they are still enabled.  We disable them to force a
         * reloading of the original task's CP state by the lazy
         * context-switching mechanisms of CP exception handling.
@@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         */
 
        /* Set up registers for signal handler */
-       start_thread(regs, (unsigned long) ka->sa.sa_handler, 
+       start_thread(regs, (unsigned long) ka->sa.sa_handler,
                     (unsigned long) frame);
 
        /* Set up a stack frame for a call4
@@ -424,9 +424,9 @@ give_sigsegv:
        return -EFAULT;
 }
 
-asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, 
+asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,
                                   stack_t __user *uoss,
-                                  long a2, long a3, long a4, long a5,
+                                  long a2, long a3, long a4, long a5,
                                   struct pt_regs *regs)
 {
        return do_sigaltstack(uss, uoss, regs->areg[1]);
index 5702065..54fa842 100644 (file)
@@ -52,4 +52,3 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice,
 {
        return sys_fadvise64_64(fd, offset, len, advice);
 }
-
index ac62f9c..ffb4741 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/delay.h>
+#include <linux/irqdomain.h>
 
 #include <asm/timex.h>
 #include <asm/platform.h>
@@ -31,7 +32,7 @@ unsigned long ccount_per_jiffy;               /* per 1/HZ */
 unsigned long nsec_per_ccount;         /* nsec per ccount increment */
 #endif
 
-static cycle_t ccount_read(void)
+static cycle_t ccount_read(struct clocksource *cs)
 {
        return (cycle_t)get_ccount();
 }
@@ -52,6 +53,7 @@ static struct irqaction timer_irqaction = {
 
 void __init time_init(void)
 {
+       unsigned int irq;
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
        printk("Calibrating CPU frequency ");
        platform_calibrate_ccount();
@@ -62,7 +64,8 @@ void __init time_init(void)
 
        /* Initialize the linux timer interrupt. */
 
-       setup_irq(LINUX_TIMER_INT, &timer_irqaction);
+       irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
+       setup_irq(irq, &timer_irqaction);
        set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
 }
 
index 5caf2b6..01e0111 100644 (file)
@@ -293,6 +293,17 @@ do_debug(struct pt_regs *regs)
 }
 
 
+/* Set exception C handler - for temporary use when probing exceptions */
+
+void * __init trap_set_handler(int cause, void *handler)
+{
+       unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause];
+       void *previous = (void *)*entry;
+       *entry = (unsigned long)handler;
+       return previous;
+}
+
+
 /*
  * Initialize dispatch tables.
  *
@@ -397,7 +408,8 @@ static inline void spill_registers(void)
                "wsr    a13, sar\n\t"
                "wsr    a14, ps\n\t"
                :: "a" (&a0), "a" (&ps)
-               : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
+               : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15",
+                 "memory");
 }
 
 void show_trace(struct task_struct *task, unsigned long *sp)
@@ -452,7 +464,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
 
        if (!sp)
                sp = stack_pointer(task);
-       stack = sp;
+       stack = sp;
 
        printk("\nStack: ");
 
@@ -523,5 +535,3 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        do_exit(err);
 }
-
-
index 4462c1e..68df35f 100644 (file)
@@ -79,6 +79,8 @@ ENTRY(_UserExceptionVector)
        l32i    a0, a0, EXC_TABLE_FAST_USER     # load handler
        jx      a0
 
+ENDPROC(_UserExceptionVector)
+
 /*
  * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0)
  *
@@ -103,6 +105,7 @@ ENTRY(_KernelExceptionVector)
        l32i    a0, a0, EXC_TABLE_FAST_KERNEL   # load handler address
        jx      a0
 
+ENDPROC(_KernelExceptionVector)
 
 /*
  * Double exception vector (Exceptions with PS.EXCM == 1)
@@ -225,7 +228,13 @@ ENTRY(_DoubleExceptionVector)
        /* Window overflow/underflow exception. Get stack pointer. */
 
        mov     a3, a2
-       movi    a2, exc_table
+       /* This explicit literal and the following references to it are made
+        * in order to fit DoubleExceptionVector.literals into the available
+        * 16-byte gap before DoubleExceptionVector.text in the absence of
+        * link time relaxation. See kernel/vmlinux.lds.S
+        */
+       .literal .Lexc_table, exc_table
+       l32r    a2, .Lexc_table
        l32i    a2, a2, EXC_TABLE_KSTK
 
        /* Check for overflow/underflow exception, jump if overflow. */
@@ -255,7 +264,7 @@ ENTRY(_DoubleExceptionVector)
        s32i    a0, a2, PT_AREG0
 
        wsr     a3, excsave1            # save a3
-       movi    a3, exc_table
+       l32r    a3, .Lexc_table
 
        rsr     a0, exccause
        s32i    a0, a2, PT_DEPC         # mark it as a regular exception
@@ -267,7 +276,7 @@ ENTRY(_DoubleExceptionVector)
 
        /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */
 
-       movi    a3, exc_table
+       l32r    a3, .Lexc_table
        s32i    a2, a3, EXC_TABLE_DOUBLE_SAVE   # temporary variable
 
        /* Enter critical section. */
@@ -296,7 +305,7 @@ ENTRY(_DoubleExceptionVector)
 
        /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */
 
-       movi    a3, exc_table
+       l32r    a3, .Lexc_table
        rsr     a0, exccause
        addx4   a0, a0, a3
        l32i    a0, a0, EXC_TABLE_FAST_USER
@@ -338,6 +347,7 @@ ENTRY(_DoubleExceptionVector)
 
        .end literal_prefix
 
+ENDPROC(_DoubleExceptionVector)
 
 /*
  * Debug interrupt vector
@@ -349,9 +359,11 @@ ENTRY(_DoubleExceptionVector)
        .section .DebugInterruptVector.text, "ax"
 
 ENTRY(_DebugInterruptVector)
+
        xsr     a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
        jx      a0
 
+ENDPROC(_DebugInterruptVector)
 
 
 /* Window overflow and underflow handlers.
@@ -363,38 +375,43 @@ ENTRY(_DebugInterruptVector)
  *      we try to access any page that would cause a page fault early.
  */
 
+#define ENTRY_ALIGN64(name)    \
+       .globl name;            \
+       .align 64;              \
+       name:
+
        .section                .WindowVectors.text, "ax"
 
 
 /* 4-Register Window Overflow Vector (Handler) */
 
-       .align 64
-.global _WindowOverflow4
-_WindowOverflow4:
+ENTRY_ALIGN64(_WindowOverflow4)
+
        s32e    a0, a5, -16
        s32e    a1, a5, -12
        s32e    a2, a5,  -8
        s32e    a3, a5,  -4
        rfwo
 
+ENDPROC(_WindowOverflow4)
+
 
 /* 4-Register Window Underflow Vector (Handler) */
 
-       .align 64
-.global _WindowUnderflow4
-_WindowUnderflow4:
+ENTRY_ALIGN64(_WindowUnderflow4)
+
        l32e    a0, a5, -16
        l32e    a1, a5, -12
        l32e    a2, a5,  -8
        l32e    a3, a5,  -4
        rfwu
 
+ENDPROC(_WindowUnderflow4)
 
 /* 8-Register Window Overflow Vector (Handler) */
 
-       .align 64
-.global _WindowOverflow8
-_WindowOverflow8:
+ENTRY_ALIGN64(_WindowOverflow8)
+
        s32e    a0, a9, -16
        l32e    a0, a1, -12
        s32e    a2, a9,  -8
@@ -406,11 +423,12 @@ _WindowOverflow8:
        s32e    a7, a0, -20
        rfwo
 
+ENDPROC(_WindowOverflow8)
+
 /* 8-Register Window Underflow Vector (Handler) */
 
-       .align 64
-.global _WindowUnderflow8
-_WindowUnderflow8:
+ENTRY_ALIGN64(_WindowUnderflow8)
+
        l32e    a1, a9, -12
        l32e    a0, a9, -16
        l32e    a7, a1, -12
@@ -422,12 +440,12 @@ _WindowUnderflow8:
        l32e    a7, a7, -20
        rfwu
 
+ENDPROC(_WindowUnderflow8)
 
 /* 12-Register Window Overflow Vector (Handler) */
 
-       .align 64
-.global _WindowOverflow12
-_WindowOverflow12:
+ENTRY_ALIGN64(_WindowOverflow12)
+
        s32e    a0,  a13, -16
        l32e    a0,  a1,  -12
        s32e    a1,  a13, -12
@@ -443,11 +461,12 @@ _WindowOverflow12:
        s32e    a11, a0,  -20
        rfwo
 
+ENDPROC(_WindowOverflow12)
+
 /* 12-Register Window Underflow Vector (Handler) */
 
-       .align 64
-.global _WindowUnderflow12
-_WindowUnderflow12:
+ENTRY_ALIGN64(_WindowUnderflow12)
+
        l32e    a1,  a13, -12
        l32e    a0,  a13, -16
        l32e    a11, a1,  -12
@@ -463,6 +482,6 @@ _WindowUnderflow12:
        l32e    a11, a11, -20
        rfwu
 
-       .text
-
+ENDPROC(_WindowUnderflow12)
 
+       .text
index df397f9..4eb573d 100644 (file)
 
 .text
 ENTRY(csum_partial)
-         /*
-          * Experiments with Ethernet and SLIP connections show that buf
-          * is aligned on either a 2-byte or 4-byte boundary.
-          */
+
+       /*
+        * Experiments with Ethernet and SLIP connections show that buf
+        * is aligned on either a 2-byte or 4-byte boundary.
+        */
        entry   sp, 32
        extui   a5, a2, 0, 2
        bnez    a5, 8f          /* branch if 2-byte aligned */
@@ -170,7 +171,7 @@ ENTRY(csum_partial)
 3:
        j       5b              /* branch to handle the remaining byte */
 
-
+ENDPROC(csum_partial)
 
 /*
  * Copy from ds while checksumming, otherwise like csum_partial
@@ -211,6 +212,7 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
  */
 
 ENTRY(csum_partial_copy_generic)
+
        entry   sp, 32
        mov     a12, a3
        mov     a11, a4
@@ -367,6 +369,8 @@ DST(        s8i     a8, a3, 1       )
 6:
        j       4b              /* process the possible trailing odd byte */
 
+ENDPROC(csum_partial_copy_generic)
+
 
 # Exception handler:
 .section .fixup, "ax"
@@ -406,4 +410,3 @@ DST(        s8i     a8, a3, 1       )
        retw
 
 .previous
-
index c48b80a..b1c219a 100644 (file)
@@ -210,8 +210,10 @@ memcpy:
        _beqz   a4, .Ldone      # avoid loading anything for zero-length copies
        # copy 16 bytes per iteration for word-aligned dst and unaligned src
        ssa8    a3              # set shift amount from byte offset
-#define SIM_CHECKS_ALIGNMENT   1       /* set to 1 when running on ISS (simulator) with the
-                                          lint or ferret client, or 0 to save a few cycles */
+
+/* set to 1 when running on ISS (simulator) with the
+   lint or ferret client, or 0 to save a few cycles */
+#define SIM_CHECKS_ALIGNMENT   1
 #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT
        and     a11, a3, a8     # save unalignment offset for below
        sub     a3, a3, a11     # align a3
index a71733a..34d05ab 100644 (file)
@@ -241,8 +241,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
        unsigned char header_type;
        struct pci_dev *dev = &pciauto_dev;
 
-        pciauto_dev.bus = &pciauto_bus;
-        pciauto_dev.sysdata = pci_ctrl;
+       pciauto_dev.bus = &pciauto_bus;
+       pciauto_dev.sysdata = pci_ctrl;
        pciauto_bus.ops = pci_ctrl->ops;
 
        /*
@@ -345,8 +345,3 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
        }
        return sub_bus;
 }
-
-
-
-
-
index 9f603cd..1ad0ecf 100644 (file)
@@ -166,7 +166,7 @@ __strncpy_user:
        retw
 .Lz1:  # byte 1 is zero
 #ifdef __XTENSA_EB__
-        extui   a9, a9, 16, 16
+       extui   a9, a9, 16, 16
 #endif /* __XTENSA_EB__ */
        EX(s16i, a9, a11, 0, fixup_s)
        addi    a11, a11, 1             # advance dst pointer
@@ -174,7 +174,7 @@ __strncpy_user:
        retw
 .Lz2:  # byte 2 is zero
 #ifdef __XTENSA_EB__
-        extui   a9, a9, 16, 16
+       extui   a9, a9, 16, 16
 #endif /* __XTENSA_EB__ */
        EX(s16i, a9, a11, 0, fixup_s)
        movi    a9, 0
index 23f2a89..4c03b1e 100644 (file)
@@ -145,4 +145,3 @@ __strnlen_user:
 lenfixup:
        movi    a2, 0
        retw
-
index 46d6031..ace1892 100644 (file)
@@ -318,4 +318,3 @@ l_fixup:
        /* Ignore memset return value in a6. */
        /* a2 still contains bytes not copied. */
        retw
-
index 85df465..81edeab 100644 (file)
@@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page)
  * For now, flush the whole cache. FIXME??
  */
 
-void flush_cache_range(struct vm_area_struct* vma, 
+void flush_cache_range(struct vm_area_struct* vma,
                       unsigned long start, unsigned long end)
 {
        __flush_invalidate_dcache_all();
@@ -133,7 +133,7 @@ void flush_cache_range(struct vm_area_struct* vma,
  */
 
 void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
-                     unsigned long pfn)
+                     unsigned long pfn)
 {
        /* Note that we have to use the 'alias' address to avoid multi-hit */
 
@@ -166,14 +166,14 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
 
        if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
 
-               unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
                unsigned long paddr = (unsigned long) page_address(page);
                unsigned long phys = page_to_phys(page);
+               unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
 
                __flush_invalidate_dcache_page(paddr);
 
-               __flush_invalidate_dcache_page_alias(vaddr, phys);
-               __invalidate_icache_page_alias(vaddr, phys);
+               __flush_invalidate_dcache_page_alias(tmp, phys);
+               __invalidate_icache_page_alias(tmp, phys);
 
                clear_bit(PG_arch_1, &page->flags);
        }
@@ -195,7 +195,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
 
 #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
 
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page, 
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
                unsigned long vaddr, void *dst, const void *src,
                unsigned long len)
 {
@@ -205,8 +205,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
        /* Flush and invalidate user page if aliased. */
 
        if (alias) {
-               unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
-               __flush_invalidate_dcache_page_alias(temp, phys);
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
+               __flush_invalidate_dcache_page_alias(t, phys);
        }
 
        /* Copy data */
@@ -219,12 +219,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
         */
 
        if (alias) {
-               unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
 
                __flush_invalidate_dcache_range((unsigned long) dst, len);
-               if ((vma->vm_flags & VM_EXEC) != 0) {
-                       __invalidate_icache_page_alias(temp, phys);
-               }
+               if ((vma->vm_flags & VM_EXEC) != 0)
+                       __invalidate_icache_page_alias(t, phys);
 
        } else if ((vma->vm_flags & VM_EXEC) != 0) {
                __flush_dcache_range((unsigned long)dst,len);
@@ -245,8 +244,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
         */
 
        if (alias) {
-               unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
-               __flush_invalidate_dcache_page_alias(temp, phys);
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
+               __flush_invalidate_dcache_page_alias(t, phys);
        }
 
        memcpy(dst, src, len);
index 245b08f..4b7bc8d 100644 (file)
@@ -254,4 +254,3 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
        die("Oops", regs, sig);
        do_exit(sig);
 }
-
index db95517..7a5156f 100644 (file)
@@ -75,15 +75,15 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
                        sysmem.nr_banks++;
                }
                sysmem.bank[i].end = start;
+
+       } else if (end < sysmem.bank[i].end) {
+               sysmem.bank[i].start = end;
+
        } else {
-               if (end < sysmem.bank[i].end)
-                       sysmem.bank[i].start = end;
-               else {
-                       /* remove entry */
-                       sysmem.nr_banks--;
-                       sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
-                       sysmem.bank[i].end   = sysmem.bank[sysmem.nr_banks].end;
-               }
+               /* remove entry */
+               sysmem.nr_banks--;
+               sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
+               sysmem.bank[i].end   = sysmem.bank[sysmem.nr_banks].end;
        }
        return -1;
 }
index b048406..d97ed1b 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 ENTRY(clear_page)
+
        entry   a1, 16
 
        movi    a3, 0
@@ -45,6 +46,8 @@ ENTRY(clear_page)
 
        retw
 
+ENDPROC(clear_page)
+
 /*
  * copy_page and copy_user_page are the same for non-cache-aliased configs.
  *
@@ -53,6 +56,7 @@ ENTRY(clear_page)
  */
 
 ENTRY(copy_page)
+
        entry   a1, 16
 
        __loopi a2, a4, PAGE_SIZE, 32
@@ -84,6 +88,8 @@ ENTRY(copy_page)
 
        retw
 
+ENDPROC(copy_page)
+
 #ifdef CONFIG_MMU
 /*
  * If we have to deal with cache aliasing, we use temporary memory mappings
@@ -109,6 +115,7 @@ ENTRY(__tlbtemp_mapping_start)
  */
 
 ENTRY(clear_user_page)
+
        entry   a1, 32
 
        /* Mark page dirty and determine alias. */
@@ -164,6 +171,8 @@ ENTRY(clear_user_page)
 
        retw
 
+ENDPROC(clear_user_page)
+
 /*
  * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page)
  *                    a2          a3           a4                  a5
@@ -171,7 +180,7 @@ ENTRY(clear_user_page)
 
 ENTRY(copy_user_page)
 
-       entry   a1, 32 
+       entry   a1, 32
 
        /* Mark page dirty and determine alias for destination. */
 
@@ -262,6 +271,8 @@ ENTRY(copy_user_page)
 
        retw
 
+ENDPROC(copy_user_page)
+
 #endif
 
 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
@@ -272,6 +283,7 @@ ENTRY(copy_user_page)
  */
 
 ENTRY(__flush_invalidate_dcache_page_alias)
+
        entry   sp, 16
 
        movi    a7, 0                   # required for exception handler
@@ -287,6 +299,7 @@ ENTRY(__flush_invalidate_dcache_page_alias)
 
        retw
 
+ENDPROC(__flush_invalidate_dcache_page_alias)
 #endif
 
 ENTRY(__tlbtemp_mapping_itlb)
@@ -294,6 +307,7 @@ ENTRY(__tlbtemp_mapping_itlb)
 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
        
 ENTRY(__invalidate_icache_page_alias)
+
        entry   sp, 16
 
        addi    a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
@@ -307,11 +321,14 @@ ENTRY(__invalidate_icache_page_alias)
        isync
        retw
 
+ENDPROC(__invalidate_icache_page_alias)
+
 #endif
 
 /* End of special treatment in tlb miss exception */
 
 ENTRY(__tlbtemp_mapping_end)
+
 #endif /* CONFIG_MMU
 
 /*
@@ -319,6 +336,7 @@ ENTRY(__tlbtemp_mapping_end)
  */
 
 ENTRY(__invalidate_icache_page)
+
        entry   sp, 16
 
        ___invalidate_icache_page a2 a3
@@ -326,11 +344,14 @@ ENTRY(__invalidate_icache_page)
 
        retw
 
+ENDPROC(__invalidate_icache_page)
+
 /*
  * void __invalidate_dcache_page(ulong start)
  */
 
 ENTRY(__invalidate_dcache_page)
+
        entry   sp, 16
 
        ___invalidate_dcache_page a2 a3
@@ -338,11 +359,14 @@ ENTRY(__invalidate_dcache_page)
 
        retw
 
+ENDPROC(__invalidate_dcache_page)
+
 /*
  * void __flush_invalidate_dcache_page(ulong start)
  */
 
 ENTRY(__flush_invalidate_dcache_page)
+
        entry   sp, 16
 
        ___flush_invalidate_dcache_page a2 a3
@@ -350,11 +374,14 @@ ENTRY(__flush_invalidate_dcache_page)
        dsync
        retw
 
+ENDPROC(__flush_invalidate_dcache_page)
+
 /*
  * void __flush_dcache_page(ulong start)
  */
 
 ENTRY(__flush_dcache_page)
+
        entry   sp, 16
 
        ___flush_dcache_page a2 a3
@@ -362,11 +389,14 @@ ENTRY(__flush_dcache_page)
        dsync
        retw
 
+ENDPROC(__flush_dcache_page)
+
 /*
  * void __invalidate_icache_range(ulong start, ulong size)
  */
 
 ENTRY(__invalidate_icache_range)
+
        entry   sp, 16
 
        ___invalidate_icache_range a2 a3 a4
@@ -374,11 +404,14 @@ ENTRY(__invalidate_icache_range)
 
        retw
 
+ENDPROC(__invalidate_icache_range)
+
 /*
  * void __flush_invalidate_dcache_range(ulong start, ulong size)
  */
 
 ENTRY(__flush_invalidate_dcache_range)
+
        entry   sp, 16
 
        ___flush_invalidate_dcache_range a2 a3 a4
@@ -386,11 +419,14 @@ ENTRY(__flush_invalidate_dcache_range)
 
        retw
 
+ENDPROC(__flush_invalidate_dcache_range)
+
 /*
  * void _flush_dcache_range(ulong start, ulong size)
  */
 
 ENTRY(__flush_dcache_range)
+
        entry   sp, 16
 
        ___flush_dcache_range a2 a3 a4
@@ -398,22 +434,28 @@ ENTRY(__flush_dcache_range)
 
        retw
 
+ENDPROC(__flush_dcache_range)
+
 /*
  * void _invalidate_dcache_range(ulong start, ulong size)
  */
 
 ENTRY(__invalidate_dcache_range)
+
        entry   sp, 16
 
        ___invalidate_dcache_range a2 a3 a4
 
        retw
 
+ENDPROC(__invalidate_dcache_range)
+
 /*
  * void _invalidate_icache_all(void)
  */
 
 ENTRY(__invalidate_icache_all)
+
        entry   sp, 16
 
        ___invalidate_icache_all a2 a3
@@ -421,11 +463,14 @@ ENTRY(__invalidate_icache_all)
 
        retw
 
+ENDPROC(__invalidate_icache_all)
+
 /*
  * void _flush_invalidate_dcache_all(void)
  */
 
 ENTRY(__flush_invalidate_dcache_all)
+
        entry   sp, 16
 
        ___flush_invalidate_dcache_all a2 a3
@@ -433,11 +478,14 @@ ENTRY(__flush_invalidate_dcache_all)
 
        retw
 
+ENDPROC(__flush_invalidate_dcache_all)
+
 /*
  * void _invalidate_dcache_all(void)
  */
 
 ENTRY(__invalidate_dcache_all)
+
        entry   sp, 16
 
        ___invalidate_dcache_all a2 a3
@@ -445,3 +493,4 @@ ENTRY(__invalidate_dcache_all)
 
        retw
 
+ENDPROC(__invalidate_dcache_all)
index ca81654..0f77f9d 100644 (file)
@@ -37,7 +37,7 @@ void __init init_mmu(void)
 
        /* Set rasid register to a known value. */
 
-       set_rasid_register(ASID_USER_FIRST);
+       set_rasid_register(ASID_INSERT(ASID_USER_FIRST));
 
        /* Set PTEVADDR special register to the start of the page
         * table, which is in kernel mappable space (ie. not
index e2700b2..5411aa6 100644 (file)
@@ -63,7 +63,7 @@ void flush_tlb_all (void)
 void flush_tlb_mm(struct mm_struct *mm)
 {
        if (mm == current->active_mm) {
-               int flags;
+               unsigned long flags;
                local_save_flags(flags);
                __get_new_mmu_context(mm);
                __load_mmu_context(mm);
@@ -82,7 +82,7 @@ void flush_tlb_mm(struct mm_struct *mm)
 #endif
 
 void flush_tlb_range (struct vm_area_struct *vma,
-                     unsigned long start, unsigned long end)
+                     unsigned long start, unsigned long end)
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long flags;
@@ -100,7 +100,7 @@ void flush_tlb_range (struct vm_area_struct *vma,
                int oldpid = get_rasid_register();
                set_rasid_register (ASID_INSERT(mm->context));
                start &= PAGE_MASK;
-               if (vma->vm_flags & VM_EXEC)
+               if (vma->vm_flags & VM_EXEC)
                        while(start < end) {
                                invalidate_itlb_mapping(start);
                                invalidate_dtlb_mapping(start);
@@ -130,7 +130,7 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
 
        local_save_flags(flags);
 
-               oldpid = get_rasid_register();
+       oldpid = get_rasid_register();
 
        if (vma->vm_flags & VM_EXEC)
                invalidate_itlb_mapping(page);
@@ -140,4 +140,3 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
 
        local_irq_restore(flags);
 }
-
index e69de29..16aec54 100644 (file)
@@ -0,0 +1,15 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Tensilica Inc.
+ */
+
+#ifndef __ASM_XTENSA_ISS_SERIAL_H
+#define __ASM_XTENSA_ISS_SERIAL_H
+
+/* Have no meaning on ISS, but needed for 8250_early.c */
+#define BASE_BAUD 0
+
+#endif /* __ASM_XTENSA_ISS_SERIAL_H */
index bd78192..b5a4edf 100644 (file)
@@ -74,13 +74,12 @@ static inline int __simc(int a, int b, int c, int d, int e, int f)
                        "mov %1, a3\n"
                        : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1)
                        : "r"(c1), "r"(d1), "r"(e1), "r"(f1)
-                       : );
+                       : "memory");
        return ret;
 }
 
 static inline int simc_open(const char *file, int flags, int mode)
 {
-       wmb();
        return __simc(SYS_open, (int) file, flags, mode, 0, 0);
 }
 
@@ -91,19 +90,16 @@ static inline int simc_close(int fd)
 
 static inline int simc_ioctl(int fd, int request, void *arg)
 {
-       wmb();
        return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
 }
 
 static inline int simc_read(int fd, void *buf, size_t count)
 {
-       rmb();
        return __simc(SYS_read, fd, (int) buf, count, 0, 0);
 }
 
 static inline int simc_write(int fd, const void *buf, size_t count)
 {
-       wmb();
        return __simc(SYS_write, fd, (int) buf, count, 0, 0);
 }
 
@@ -111,7 +107,6 @@ static inline int simc_poll(int fd)
 {
        struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
 
-       wmb();
        return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,
                        0, 0);
 }
diff --git a/arch/xtensa/platforms/xtfpga/Makefile b/arch/xtensa/platforms/xtfpga/Makefile
new file mode 100644 (file)
index 0000000..b9ae206
--- /dev/null
@@ -0,0 +1,9 @@
+# Makefile for the Tensilica xtavnet Emulation Board
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are in the main makefile...
+
+obj-y                  = setup.o lcd.o
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h
new file mode 100644 (file)
index 0000000..4416773
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * arch/xtensa/platform/xtavnet/include/platform/hardware.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Tensilica Inc.
+ */
+
+/*
+ * This file contains the hardware configuration of the XTAVNET boards.
+ */
+
+#ifndef __XTENSA_XTAVNET_HARDWARE_H
+#define __XTENSA_XTAVNET_HARDWARE_H
+
+/* By default NO_IRQ is defined to 0 in Linux, but we use the
+   interrupt 0 for UART... */
+#define NO_IRQ                 -1
+
+/* Memory configuration. */
+
+#define PLATFORM_DEFAULT_MEM_START 0x00000000
+#define PLATFORM_DEFAULT_MEM_SIZE  0x04000000
+
+/* Interrupt configuration. */
+
+#define PLATFORM_NR_IRQS       10
+
+/* Default assignment of LX60 devices to external interrupts. */
+
+#ifdef CONFIG_ARCH_HAS_SMP
+#define DUART16552_INTNUM      XCHAL_EXTINT3_NUM
+#define OETH_IRQ               XCHAL_EXTINT4_NUM
+#else
+#define DUART16552_INTNUM      XCHAL_EXTINT0_NUM
+#define OETH_IRQ               XCHAL_EXTINT1_NUM
+#endif
+
+/*
+ *  Device addresses and parameters.
+ */
+
+/* UART */
+#define DUART16552_PADDR       (XCHAL_KIO_PADDR + 0x0D050020)
+/* LCD instruction and data addresses. */
+#define LCD_INSTR_ADDR         ((char *)IOADDR(0x0D040000))
+#define LCD_DATA_ADDR          ((char *)IOADDR(0x0D040004))
+
+/* Misc. */
+#define XTFPGA_FPGAREGS_VADDR  IOADDR(0x0D020000)
+/* Clock frequency in Hz (read-only):  */
+#define XTFPGA_CLKFRQ_VADDR    (XTFPGA_FPGAREGS_VADDR + 0x04)
+/* Setting of 8 DIP switches:  */
+#define DIP_SWITCHES_VADDR     (XTFPGA_FPGAREGS_VADDR + 0x0C)
+/* Software reset (write 0xdead):  */
+#define XTFPGA_SWRST_VADDR     (XTFPGA_FPGAREGS_VADDR + 0x10)
+
+/*  OpenCores Ethernet controller:  */
+                               /* regs + RX/TX descriptors */
+#define OETH_REGS_PADDR                (XCHAL_KIO_PADDR + 0x0D030000)
+#define OETH_REGS_SIZE         0x1000
+#define OETH_SRAMBUFF_PADDR    (XCHAL_KIO_PADDR + 0x0D800000)
+
+                               /* 5*rx buffs + 5*tx buffs */
+#define OETH_SRAMBUFF_SIZE     (5 * 0x600 + 5 * 0x600)
+
+#endif /* __XTENSA_XTAVNET_HARDWARE_H */
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h
new file mode 100644 (file)
index 0000000..0e43564
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * arch/xtensa/platform/xtavnet/include/platform/lcd.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2006 Tensilica Inc.
+ */
+
+#ifndef __XTENSA_XTAVNET_LCD_H
+#define __XTENSA_XTAVNET_LCD_H
+
+/* Display string STR at position POS on the LCD. */
+void lcd_disp_at_pos(char *str, unsigned char pos);
+
+/* Shift the contents of the LCD display left or right. */
+void lcd_shiftleft(void);
+void lcd_shiftright(void);
+#endif
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/arch/xtensa/platforms/xtfpga/include/platform/serial.h
new file mode 100644 (file)
index 0000000..14d8f7b
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * arch/xtensa/platform/xtavnet/include/platform/serial.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2006 Tensilica Inc.
+ */
+
+#ifndef __ASM_XTENSA_XTAVNET_SERIAL_H
+#define __ASM_XTENSA_XTAVNET_SERIAL_H
+
+#include <platform/hardware.h>
+
+#define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16)
+
+#endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */
diff --git a/arch/xtensa/platforms/xtfpga/lcd.c b/arch/xtensa/platforms/xtfpga/lcd.c
new file mode 100644 (file)
index 0000000..2872301
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Driver for the LCD display on the Tensilica LX60 Board.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2006 Tensilica Inc.
+ */
+
+/*
+ *
+ * FIXME: this code is from the examples from the LX60 user guide.
+ *
+ * The lcd_pause function does busy waiting, which is probably not
+ * great. Maybe the code could be changed to use kernel timers, or
+ * change the hardware to not need to wait.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <platform/hardware.h>
+#include <platform/lcd.h>
+#include <linux/delay.h>
+
+#define LCD_PAUSE_ITERATIONS   4000
+#define LCD_CLEAR              0x1
+#define LCD_DISPLAY_ON         0xc
+
+/* 8bit and 2 lines display */
+#define LCD_DISPLAY_MODE8BIT   0x38
+#define LCD_DISPLAY_POS                0x80
+#define LCD_SHIFT_LEFT         0x18
+#define LCD_SHIFT_RIGHT                0x1c
+
+static int __init lcd_init(void)
+{
+       *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+       mdelay(5);
+       *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+       udelay(200);
+       *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+       udelay(50);
+       *LCD_INSTR_ADDR = LCD_DISPLAY_ON;
+       udelay(50);
+       *LCD_INSTR_ADDR = LCD_CLEAR;
+       mdelay(10);
+       lcd_disp_at_pos("XTENSA LINUX", 0);
+       return 0;
+}
+
+void lcd_disp_at_pos(char *str, unsigned char pos)
+{
+       *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos;
+       udelay(100);
+       while (*str != 0) {
+               *LCD_DATA_ADDR = *str;
+               udelay(200);
+               str++;
+       }
+}
+
+void lcd_shiftleft(void)
+{
+       *LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
+       udelay(50);
+}
+
+void lcd_shiftright(void)
+{
+       *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
+       udelay(50);
+}
+
+arch_initcall(lcd_init);
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
new file mode 100644 (file)
index 0000000..4b9951a
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ *
+ * arch/xtensa/platform/xtavnet/setup.c
+ *
+ * ...
+ *
+ * Authors:    Chris Zankel <chris@zankel.net>
+ *             Joe Taylor <joe@tensilica.com>
+ *
+ * Copyright 2001 - 2006 Tensilica Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#include <asm/timex.h>
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/bootparam.h>
+#include <platform/lcd.h>
+#include <platform/hardware.h>
+
+void platform_halt(void)
+{
+       lcd_disp_at_pos(" HALT ", 0);
+       local_irq_disable();
+       while (1)
+               cpu_relax();
+}
+
+void platform_power_off(void)
+{
+       lcd_disp_at_pos("POWEROFF", 0);
+       local_irq_disable();
+       while (1)
+               cpu_relax();
+}
+
+void platform_restart(void)
+{
+       /* Flush and reset the mmu, simulate a processor reset, and
+        * jump to the reset vector. */
+
+
+       __asm__ __volatile__ ("movi     a2, 15\n\t"
+                             "wsr      a2, icountlevel\n\t"
+                             "movi     a2, 0\n\t"
+                             "wsr      a2, icount\n\t"
+                             "wsr      a2, ibreakenable\n\t"
+                             "wsr      a2, lcount\n\t"
+                             "movi     a2, 0x1f\n\t"
+                             "wsr      a2, ps\n\t"
+                             "isync\n\t"
+                             "jx       %0\n\t"
+                             :
+                             : "a" (XCHAL_RESET_VECTOR_VADDR)
+                             : "a2"
+                             );
+
+       /* control never gets here */
+}
+
+void __init platform_setup(char **cmdline)
+{
+}
+
+#ifdef CONFIG_OF
+
+static void __init update_clock_frequency(struct device_node *node)
+{
+       struct property *newfreq;
+       u32 freq;
+
+       if (!of_property_read_u32(node, "clock-frequency", &freq) && freq != 0)
+               return;
+
+       newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL);
+       if (!newfreq)
+               return;
+       newfreq->value = newfreq + 1;
+       newfreq->length = sizeof(freq);
+       newfreq->name = kstrdup("clock-frequency", GFP_KERNEL);
+       if (!newfreq->name) {
+               kfree(newfreq);
+               return;
+       }
+
+       *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR);
+       prom_update_property(node, newfreq);
+}
+
+#define MAC_LEN 6
+static void __init update_local_mac(struct device_node *node)
+{
+       struct property *newmac;
+       const u8* macaddr;
+       int prop_len;
+
+       macaddr = of_get_property(node, "local-mac-address", &prop_len);
+       if (macaddr == NULL || prop_len != MAC_LEN)
+               return;
+
+       newmac = kzalloc(sizeof(*newmac) + MAC_LEN, GFP_KERNEL);
+       if (newmac == NULL)
+               return;
+
+       newmac->value = newmac + 1;
+       newmac->length = MAC_LEN;
+       newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+       if (newmac->name == NULL) {
+               kfree(newmac);
+               return;
+       }
+
+       memcpy(newmac->value, macaddr, MAC_LEN);
+       ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f;
+       prom_update_property(node, newmac);
+}
+
+static int __init machine_setup(void)
+{
+       struct device_node *serial;
+       struct device_node *eth = NULL;
+
+       for_each_compatible_node(serial, NULL, "ns16550a")
+               update_clock_frequency(serial);
+
+       if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc")))
+               update_local_mac(eth);
+       return 0;
+}
+arch_initcall(machine_setup);
+
+#endif
+
+/* early initialization */
+
+void __init platform_init(bp_tag_t *first)
+{
+}
+
+/* Heartbeat. */
+
+void platform_heartbeat(void)
+{
+}
+
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
+
+void platform_calibrate_ccount(void)
+{
+       long clk_freq = 0;
+#ifdef CONFIG_OF
+       struct device_node *cpu =
+               of_find_compatible_node(NULL, NULL, "xtensa,cpu");
+       if (cpu) {
+               u32 freq;
+               update_clock_frequency(cpu);
+               if (!of_property_read_u32(cpu, "clock-frequency", &freq))
+                       clk_freq = freq;
+       }
+#endif
+       if (!clk_freq)
+               clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR;
+
+       ccount_per_jiffy = clk_freq / HZ;
+       nsec_per_ccount = 1000000000UL / clk_freq;
+}
+
+#endif
+
+#ifndef CONFIG_OF
+
+#include <linux/serial_8250.h>
+#include <linux/if.h>
+#include <net/ethoc.h>
+
+/*----------------------------------------------------------------------------
+ *  Ethernet -- OpenCores Ethernet MAC (ethoc driver)
+ */
+
+static struct resource ethoc_res[] __initdata = {
+       [0] = { /* register space */
+               .start = OETH_REGS_PADDR,
+               .end   = OETH_REGS_PADDR + OETH_REGS_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = { /* buffer space */
+               .start = OETH_SRAMBUFF_PADDR,
+               .end   = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [2] = { /* IRQ number */
+               .start = OETH_IRQ,
+               .end   = OETH_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct ethoc_platform_data ethoc_pdata __initdata = {
+       /*
+        * The MAC address for these boards is 00:50:c2:13:6f:xx.
+        * The last byte (here as zero) is read from the DIP switches on the
+        * board.
+        */
+       .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 },
+       .phy_id = -1,
+};
+
+static struct platform_device ethoc_device __initdata = {
+       .name = "ethoc",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(ethoc_res),
+       .resource = ethoc_res,
+       .dev = {
+               .platform_data = &ethoc_pdata,
+       },
+};
+
+/*----------------------------------------------------------------------------
+ *  UART
+ */
+
+static struct resource serial_resource __initdata = {
+       .start  = DUART16552_PADDR,
+       .end    = DUART16552_PADDR + 0x1f,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port serial_platform_data[] __initdata = {
+       [0] = {
+               .mapbase        = DUART16552_PADDR,
+               .irq            = DUART16552_INTNUM,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM32,
+               .regshift       = 2,
+               .uartclk        = 0,    /* set in xtavnet_init() */
+       },
+       { },
+};
+
+static struct platform_device xtavnet_uart __initdata = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data  = serial_platform_data,
+       },
+       .num_resources  = 1,
+       .resource       = &serial_resource,
+};
+
+/* platform devices */
+static struct platform_device *platform_devices[] __initdata = {
+       &ethoc_device,
+       &xtavnet_uart,
+};
+
+
+static int __init xtavnet_init(void)
+{
+       /* Ethernet MAC address.  */
+       ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR;
+
+       /* Clock rate varies among FPGA bitstreams; board specific FPGA register
+        * reports the actual clock rate.
+        */
+       serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR;
+
+
+       /* register platform devices */
+       platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+       /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user
+        * knows whether they set it correctly on the DIP switches.
+        */
+       pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr);
+
+       return 0;
+}
+
+/*
+ * Register to be done during do_initcalls().
+ */
+arch_initcall(xtavnet_init);
+
+#endif /* CONFIG_OF */
index b89541b..da9e85c 100644 (file)
@@ -164,7 +164,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
        int cirq;
 
        chip->irq_mask(&desc->irq_data);
-       chip->irq_ack(&desc->irq_data));
+       chip->irq_ack(&desc->irq_data);
        pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask;
        cirq = IRQ_BASE - 1;
        while (pending) {
@@ -173,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
                pending >>= n;
                generic_handle_irq(cirq);
        }
-       chip->irq_unmask(&desc->irq_data));
+       chip->irq_unmask(&desc->irq_data);
 }
 
 extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS];
index bd5de08..0576a7d 100644 (file)
@@ -157,6 +157,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn)
 EXPORT_SYMBOL(tegra_ahb_enable_smmu);
 #endif
 
+#ifdef CONFIG_PM_SLEEP
 static int tegra_ahb_suspend(struct device *dev)
 {
        int i;
@@ -176,6 +177,7 @@ static int tegra_ahb_resume(struct device *dev)
                gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
        return 0;
 }
+#endif
 
 static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
                            tegra_ahb_suspend,
index c909b7b..d70abe7 100644 (file)
@@ -42,7 +42,8 @@
 #include <linux/swab.h>
 #include <linux/slab.h>
 
-#define VERSION "0.07"
+#define VERSION "1.04"
+#define DRIVER_VERSION 0x01
 #define PTAG "solos-pci"
 
 #define CONFIG_RAM_SIZE        128
 #define FLASH_BUSY     0x60
 #define FPGA_MODE      0x5C
 #define FLASH_MODE     0x58
+#define GPIO_STATUS    0x54
+#define DRIVER_VER     0x50
 #define TX_DMA_ADDR(port)      (0x40 + (4 * (port)))
 #define RX_DMA_ADDR(port)      (0x30 + (4 * (port)))
 
 #define DATA_RAM_SIZE  32768
 #define BUF_SIZE       2048
 #define OLD_BUF_SIZE   4096 /* For FPGA versions <= 2*/
-#define FPGA_PAGE      528 /* FPGA flash page size*/
-#define SOLOS_PAGE     512 /* Solos flash page size*/
-#define FPGA_BLOCK     (FPGA_PAGE * 8) /* FPGA flash block size*/
-#define SOLOS_BLOCK    (SOLOS_PAGE * 8) /* Solos flash block size*/
+/* Old boards use ATMEL AD45DB161D flash */
+#define ATMEL_FPGA_PAGE        528 /* FPGA flash page size*/
+#define ATMEL_SOLOS_PAGE       512 /* Solos flash page size*/
+#define ATMEL_FPGA_BLOCK       (ATMEL_FPGA_PAGE * 8) /* FPGA block size*/
+#define ATMEL_SOLOS_BLOCK      (ATMEL_SOLOS_PAGE * 8) /* Solos block size*/
+/* Current boards use M25P/M25PE SPI flash */
+#define SPI_FLASH_BLOCK        (256 * 64)
 
 #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2)
 #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size))
@@ -122,11 +128,14 @@ struct solos_card {
        struct sk_buff_head cli_queue[4];
        struct sk_buff *tx_skb[4];
        struct sk_buff *rx_skb[4];
+       unsigned char *dma_bounce;
        wait_queue_head_t param_wq;
        wait_queue_head_t fw_wq;
        int using_dma;
+       int dma_alignment;
        int fpga_version;
        int buffer_size;
+       int atmel_flash;
 };
 
 
@@ -451,7 +460,6 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr,
 
        len = skb->len;
        memcpy(buf, skb->data, len);
-       dev_dbg(&card->dev->dev, "len: %d\n", len);
 
        kfree_skb(skb);
        return len;
@@ -498,6 +506,78 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr,
        return err?:count;
 }
 
+struct geos_gpio_attr {
+       struct device_attribute attr;
+       int offset;
+};
+
+#define SOLOS_GPIO_ATTR(_name, _mode, _show, _store, _offset)  \
+       struct geos_gpio_attr gpio_attr_##_name = {             \
+               .attr = __ATTR(_name, _mode, _show, _store),    \
+               .offset = _offset }
+
+static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr,
+                              const char *buf, size_t count)
+{
+       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
+       struct solos_card *card = pci_get_drvdata(pdev);
+       uint32_t data32;
+
+       if (count != 1 && (count != 2 || buf[1] != '\n'))
+               return -EINVAL;
+
+       spin_lock_irq(&card->param_queue_lock);
+       data32 = ioread32(card->config_regs + GPIO_STATUS);
+       if (buf[0] == '1') {
+               data32 |= 1 << gattr->offset;
+               iowrite32(data32, card->config_regs + GPIO_STATUS);
+       } else if (buf[0] == '0') {
+               data32 &= ~(1 << gattr->offset);
+               iowrite32(data32, card->config_regs + GPIO_STATUS);
+       } else {
+               count = -EINVAL;
+       }
+       spin_lock_irq(&card->param_queue_lock);
+       return count;
+}
+
+static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
+       struct solos_card *card = pci_get_drvdata(pdev);
+       uint32_t data32;
+
+       data32 = ioread32(card->config_regs + GPIO_STATUS);
+       data32 = (data32 >> gattr->offset) & 1;
+
+       return sprintf(buf, "%d\n", data32);
+}
+
+static ssize_t hardware_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
+       struct solos_card *card = pci_get_drvdata(pdev);
+       uint32_t data32;
+
+       data32 = ioread32(card->config_regs + GPIO_STATUS);
+       switch (gattr->offset) {
+       case 0:
+               /* HardwareVersion */
+               data32 = data32 & 0x1F;
+               break;
+       case 1:
+               /* HardwareVariant */
+               data32 = (data32 >> 5) & 0x0F;
+               break;
+       }
+       return sprintf(buf, "%d\n", data32);
+}
+
 static DEVICE_ATTR(console, 0644, console_show, console_store);
 
 
@@ -506,6 +586,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store);
 
 #include "solos-attrlist.c"
 
+static SOLOS_GPIO_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store, 9);
+static SOLOS_GPIO_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store, 10);
+static SOLOS_GPIO_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store, 11);
+static SOLOS_GPIO_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store, 12);
+static SOLOS_GPIO_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store, 13);
+static SOLOS_GPIO_ATTR(PushButton, 0444, geos_gpio_show, NULL, 14);
+static SOLOS_GPIO_ATTR(HardwareVersion, 0444, hardware_show, NULL, 0);
+static SOLOS_GPIO_ATTR(HardwareVariant, 0444, hardware_show, NULL, 1);
 #undef SOLOS_ATTR_RO
 #undef SOLOS_ATTR_RW
 
@@ -522,6 +610,23 @@ static struct attribute_group solos_attr_group = {
        .name = "parameters",
 };
 
+static struct attribute *gpio_attrs[] = {
+       &gpio_attr_GPIO1.attr.attr,
+       &gpio_attr_GPIO2.attr.attr,
+       &gpio_attr_GPIO3.attr.attr,
+       &gpio_attr_GPIO4.attr.attr,
+       &gpio_attr_GPIO5.attr.attr,
+       &gpio_attr_PushButton.attr.attr,
+       &gpio_attr_HardwareVersion.attr.attr,
+       &gpio_attr_HardwareVariant.attr.attr,
+       NULL
+};
+
+static struct attribute_group gpio_attr_group = {
+       .attrs = gpio_attrs,
+       .name = "gpio",
+};
+
 static int flash_upgrade(struct solos_card *card, int chip)
 {
        const struct firmware *fw;
@@ -533,16 +638,25 @@ static int flash_upgrade(struct solos_card *card, int chip)
        switch (chip) {
        case 0:
                fw_name = "solos-FPGA.bin";
-               blocksize = FPGA_BLOCK;
+               if (card->atmel_flash)
+                       blocksize = ATMEL_FPGA_BLOCK;
+               else
+                       blocksize = SPI_FLASH_BLOCK;
                break;
        case 1:
                fw_name = "solos-Firmware.bin";
-               blocksize = SOLOS_BLOCK;
+               if (card->atmel_flash)
+                       blocksize = ATMEL_SOLOS_BLOCK;
+               else
+                       blocksize = SPI_FLASH_BLOCK;
                break;
        case 2:
                if (card->fpga_version > LEGACY_BUFFERS){
                        fw_name = "solos-db-FPGA.bin";
-                       blocksize = FPGA_BLOCK;
+                       if (card->atmel_flash)
+                               blocksize = ATMEL_FPGA_BLOCK;
+                       else
+                               blocksize = SPI_FLASH_BLOCK;
                } else {
                        dev_info(&card->dev->dev, "FPGA version doesn't support"
                                        " daughter board upgrades\n");
@@ -552,7 +666,10 @@ static int flash_upgrade(struct solos_card *card, int chip)
        case 3:
                if (card->fpga_version > LEGACY_BUFFERS){
                        fw_name = "solos-Firmware.bin";
-                       blocksize = SOLOS_BLOCK;
+                       if (card->atmel_flash)
+                               blocksize = ATMEL_SOLOS_BLOCK;
+                       else
+                               blocksize = SPI_FLASH_BLOCK;
                } else {
                        dev_info(&card->dev->dev, "FPGA version doesn't support"
                                        " daughter board upgrades\n");
@@ -568,6 +685,9 @@ static int flash_upgrade(struct solos_card *card, int chip)
 
        dev_info(&card->dev->dev, "Flash upgrade starting\n");
 
+       /* New FPGAs require driver version before permitting flash upgrades */
+       iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER);
+
        numblocks = fw->size / blocksize;
        dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
        dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
@@ -597,9 +717,13 @@ static int flash_upgrade(struct solos_card *card, int chip)
                /* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
                iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
 
-               /* Copy block to buffer, swapping each 16 bits */
+               /* Copy block to buffer, swapping each 16 bits for Atmel flash */
                for(i = 0; i < blocksize; i += 4) {
-                       uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
+                       uint32_t word;
+                       if (card->atmel_flash)
+                               word = swahb32p((uint32_t *)(fw->data + offset + i));
+                       else
+                               word = *(uint32_t *)(fw->data + offset + i);
                        if(card->fpga_version > LEGACY_BUFFERS)
                                iowrite32(word, FLASH_BUF + i);
                        else
@@ -961,7 +1085,12 @@ static uint32_t fpga_tx(struct solos_card *card)
                                tx_started |= 1 << port;
                                oldskb = skb; /* We're done with this skb already */
                        } else if (skb && card->using_dma) {
-                               SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
+                               unsigned char *data = skb->data;
+                               if ((unsigned long)data & card->dma_alignment) {
+                                       data = card->dma_bounce + (BUF_SIZE * port);
+                                       memcpy(data, skb->data, skb->len);
+                               }
+                               SKB_CB(skb)->dma_addr = pci_map_single(card->dev, data,
                                                                       skb->len, PCI_DMA_TODEVICE);
                                card->tx_skb[port] = skb;
                                iowrite32(SKB_CB(skb)->dma_addr,
@@ -1133,18 +1262,33 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
                db_fpga_upgrade = db_firmware_upgrade = 0;
        }
 
+       /* Stopped using Atmel flash after 0.03-38 */
+       if (fpga_ver < 39)
+               card->atmel_flash = 1;
+       else
+               card->atmel_flash = 0;
+
+       data32 = ioread32(card->config_regs + PORTS);
+       card->nr_ports = (data32 & 0x000000FF);
+
        if (card->fpga_version >= DMA_SUPPORTED) {
                pci_set_master(dev);
                card->using_dma = 1;
+               if (1) { /* All known FPGA versions so far */
+                       card->dma_alignment = 3;
+                       card->dma_bounce = kmalloc(card->nr_ports * BUF_SIZE, GFP_KERNEL);
+                       if (!card->dma_bounce) {
+                               dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
+                               /* Fallback to MMIO doesn't work */
+                               goto out_unmap_both;
+                       }
+               }
        } else {
                card->using_dma = 0;
                /* Set RX empty flag for all ports */
                iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
        }
 
-       data32 = ioread32(card->config_regs + PORTS);
-       card->nr_ports = (data32 & 0x000000FF);
-
        pci_set_drvdata(dev, card);
 
        tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
@@ -1179,6 +1323,10 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (err)
                goto out_free_irq;
 
+       if (card->fpga_version >= DMA_SUPPORTED &&
+           sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
+               dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
+
        return 0;
 
  out_free_irq:
@@ -1187,6 +1335,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        tasklet_kill(&card->tlet);
        
  out_unmap_both:
+       kfree(card->dma_bounce);
        pci_set_drvdata(dev, NULL);
        pci_iounmap(dev, card->buffers);
  out_unmap_config:
@@ -1289,11 +1438,16 @@ static void fpga_remove(struct pci_dev *dev)
        iowrite32(1, card->config_regs + FPGA_MODE);
        (void)ioread32(card->config_regs + FPGA_MODE); 
 
+       if (card->fpga_version >= DMA_SUPPORTED)
+               sysfs_remove_group(&card->dev->dev.kobj, &gpio_attr_group);
+
        atm_remove(card);
 
        free_irq(dev->irq, card);
        tasklet_kill(&card->tlet);
 
+       kfree(card->dma_bounce);
+
        /* Release device from reset */
        iowrite32(0, card->config_regs + FPGA_MODE);
        (void)ioread32(card->config_regs + FPGA_MODE); 
index 460e22d..a3f79c4 100644 (file)
@@ -298,6 +298,8 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
                                struct sg_table *sg_table,
                                enum dma_data_direction direction)
 {
+       might_sleep();
+
        if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
                return;
 
index e162999..c62c788 100644 (file)
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
-static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
+u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
 {
        bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
        bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
        return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
 }
+EXPORT_SYMBOL_GPL(bcma_chipco_pll_read);
 
 void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
 {
index b86eae9..85e81ec 100644 (file)
@@ -399,7 +399,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
 static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
 static struct fasync_struct *fasync;
 
-#if 0
 static bool debug;
 module_param(debug, bool, 0644);
 #define DEBUG_ENT(fmt, arg...) do { \
@@ -410,9 +409,6 @@ module_param(debug, bool, 0644);
                blocking_pool.entropy_count,\
                nonblocking_pool.entropy_count,\
                ## arg); } while (0)
-#else
-#define DEBUG_ENT(fmt, arg...) do {} while (0)
-#endif
 
 /**********************************************************************
  *
@@ -437,6 +433,7 @@ struct entropy_store {
        int entropy_count;
        int entropy_total;
        unsigned int initialized:1;
+       bool last_data_init;
        __u8 last_data[EXTRACT_SIZE];
 };
 
@@ -829,7 +826,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
                bytes = min_t(int, bytes, sizeof(tmp));
 
                DEBUG_ENT("going to reseed %s with %d bits "
-                         "(%d of %d requested)\n",
+                         "(%zu of %d requested)\n",
                          r->name, bytes * 8, nbytes * 8, r->entropy_count);
 
                bytes = extract_entropy(r->pull, tmp, bytes,
@@ -860,7 +857,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
        spin_lock_irqsave(&r->lock, flags);
 
        BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
-       DEBUG_ENT("trying to extract %d bits from %s\n",
+       DEBUG_ENT("trying to extract %zu bits from %s\n",
                  nbytes * 8, r->name);
 
        /* Can we pull enough? */
@@ -882,7 +879,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                }
        }
 
-       DEBUG_ENT("debiting %d entropy credits from %s%s\n",
+       DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
                  nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
 
        spin_unlock_irqrestore(&r->lock, flags);
@@ -957,6 +954,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
        ssize_t ret = 0, i;
        __u8 tmp[EXTRACT_SIZE];
 
+       /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
+       if (fips_enabled && !r->last_data_init)
+               nbytes += EXTRACT_SIZE;
+
        trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
        xfer_secondary_pool(r, nbytes);
        nbytes = account(r, nbytes, min, reserved);
@@ -967,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
                if (fips_enabled) {
                        unsigned long flags;
 
+
+                       /* prime last_data value if need be, per fips 140-2 */
+                       if (!r->last_data_init) {
+                               spin_lock_irqsave(&r->lock, flags);
+                               memcpy(r->last_data, tmp, EXTRACT_SIZE);
+                               r->last_data_init = true;
+                               nbytes -= EXTRACT_SIZE;
+                               spin_unlock_irqrestore(&r->lock, flags);
+                               extract_buf(r, tmp);
+                       }
+
                        spin_lock_irqsave(&r->lock, flags);
                        if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
                                panic("Hardware RNG duplicated output!\n");
@@ -1086,6 +1098,7 @@ static void init_std_data(struct entropy_store *r)
 
        r->entropy_count = 0;
        r->entropy_total = 0;
+       r->last_data_init = false;
        mix_pool_bytes(r, &now, sizeof(now), NULL);
        for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
                if (!arch_get_random_long(&rv))
@@ -1142,11 +1155,16 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
                if (n > SEC_XFER_SIZE)
                        n = SEC_XFER_SIZE;
 
-               DEBUG_ENT("reading %d bits\n", n*8);
+               DEBUG_ENT("reading %zu bits\n", n*8);
 
                n = extract_entropy_user(&blocking_pool, buf, n);
 
-               DEBUG_ENT("read got %d bits (%d still needed)\n",
+               if (n < 0) {
+                       retval = n;
+                       break;
+               }
+
+               DEBUG_ENT("read got %zd bits (%zd still needed)\n",
                          n*8, (nbytes-n)*8);
 
                if (n == 0) {
@@ -1171,10 +1189,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
                        continue;
                }
 
-               if (n < 0) {
-                       retval = n;
-                       break;
-               }
                count += n;
                buf += n;
                nbytes -= n;
index 517a8ff..6b4c70f 100644 (file)
@@ -20,6 +20,7 @@ void __init nomadik_clk_init(void)
        clk_register_clkdev(clk, NULL, "gpio.2");
        clk_register_clkdev(clk, NULL, "gpio.3");
        clk_register_clkdev(clk, NULL, "rng");
+       clk_register_clkdev(clk, NULL, "fsmc-nand");
 
        /*
         * The 2.4 MHz TIMCLK reference clock is active at boot time, this is
index 8ae1f5b..682de75 100644 (file)
@@ -172,6 +172,7 @@ config GPIO_MSM_V2
 config GPIO_MVEBU
        def_bool y
        depends on PLAT_ORION
+       depends on OF
        select GPIO_GENERIC
        select GENERIC_IRQ_CHIP
 
index 6cc87ac..6f2306d 100644 (file)
@@ -390,6 +390,7 @@ static int ichx_gpio_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       spin_lock_init(&ichx_priv.lock);
        res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
        ichx_priv.use_gpio = ich_info->use_gpio;
        err = ichx_gpio_request_regions(res_base, pdev->name,
index d767b53..7d9bd94 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/io.h>
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
-#include <linux/platform_device.h>
 #include <linux/pinctrl/consumer.h>
 
 /*
@@ -469,19 +468,6 @@ static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        }
 }
 
-static struct platform_device_id mvebu_gpio_ids[] = {
-       {
-               .name = "orion-gpio",
-       }, {
-               .name = "mv78200-gpio",
-       }, {
-               .name = "armadaxp-gpio",
-       }, {
-               /* sentinel */
-       },
-};
-MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids);
-
 static struct of_device_id mvebu_gpio_of_match[] = {
        {
                .compatible = "marvell,orion-gpio",
@@ -555,9 +541,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK;
        mvchip->chip.ngpio = ngpios;
        mvchip->chip.can_sleep = 0;
-#ifdef CONFIG_OF
        mvchip->chip.of_node = np;
-#endif
 
        spin_lock_init(&mvchip->lock);
        mvchip->membase = devm_request_and_ioremap(&pdev->dev, res);
@@ -698,7 +682,6 @@ static struct platform_driver mvebu_gpio_driver = {
                .of_match_table = mvebu_gpio_of_match,
        },
        .probe          = mvebu_gpio_probe,
-       .id_table       = mvebu_gpio_ids,
 };
 
 static int __init mvebu_gpio_init(void)
index a915133..33d20be 100644 (file)
@@ -579,7 +579,7 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
                 * at this point the buffer should be dead, so
                 * no new sync objects can be attached.
                 */
-               sync_obj = driver->sync_obj_ref(&bo->sync_obj);
+               sync_obj = driver->sync_obj_ref(bo->sync_obj);
                spin_unlock(&bdev->fence_lock);
 
                atomic_set(&bo->reserved, 0);
index 9f26400..89cfd64 100644 (file)
@@ -115,6 +115,12 @@ int vid_from_reg(int val, u8 vrm)
                return (val < 32) ? 1550 - 25 * val
                        : 775 - (25 * (val - 31)) / 2;
 
+       case 26:                /* AMD family 10h to 15h, serial VID */
+               val &= 0x7f;
+               if (val >= 0x7c)
+                       return 0;
+               return DIV_ROUND_CLOSEST(15500 - 125 * val, 10);
+
        case 91:                /* VRM 9.1 */
        case 90:                /* VRM 9.0 */
                val &= 0x1f;
@@ -195,6 +201,10 @@ static struct vrm_model vrm_models[] = {
        {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24},     /* NPT family 0Fh */
        {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25},      /* future fam. 0Fh */
        {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25},      /* NPT family 10h */
+       {X86_VENDOR_AMD, 0x11, 0x0, ANY, ANY, 26},      /* family 11h */
+       {X86_VENDOR_AMD, 0x12, 0x0, ANY, ANY, 26},      /* family 12h */
+       {X86_VENDOR_AMD, 0x14, 0x0, ANY, ANY, 26},      /* family 14h */
+       {X86_VENDOR_AMD, 0x15, 0x0, ANY, ANY, 26},      /* family 15h */
 
        {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82},     /* Pentium Pro,
                                                         * Pentium II, Xeon,
index c3c471c..646314f 100644 (file)
@@ -84,19 +84,21 @@ static void __init hwmon_pci_quirks(void)
 
        /* Open access to 0x295-0x296 on MSI MS-7031 */
        sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL);
-       if (sb &&
-           (sb->subsystem_vendor == 0x1462 &&  /* MSI */
-            sb->subsystem_device == 0x0031)) { /* MS-7031 */
-
-               pci_read_config_byte(sb, 0x48, &enable);
-               pci_read_config_word(sb, 0x64, &base);
-
-               if (base == 0 && !(enable & BIT(2))) {
-                       dev_info(&sb->dev,
-                                "Opening wide generic port at 0x295\n");
-                       pci_write_config_word(sb, 0x64, 0x295);
-                       pci_write_config_byte(sb, 0x48, enable | BIT(2));
+       if (sb) {
+               if (sb->subsystem_vendor == 0x1462 &&   /* MSI */
+                   sb->subsystem_device == 0x0031) {   /* MS-7031 */
+                       pci_read_config_byte(sb, 0x48, &enable);
+                       pci_read_config_word(sb, 0x64, &base);
+
+                       if (base == 0 && !(enable & BIT(2))) {
+                               dev_info(&sb->dev,
+                                        "Opening wide generic port at 0x295\n");
+                               pci_write_config_word(sb, 0x64, 0x295);
+                               pci_write_config_byte(sb, 0x48,
+                                                     enable | BIT(2));
+                       }
                }
+               pci_dev_put(sb);
        }
 #endif
 }
index d32aa35..117d66f 100644 (file)
@@ -203,6 +203,8 @@ static const u8 IT87_REG_FAN[]              = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
 static const u8 IT87_REG_FAN_MIN[]     = { 0x10, 0x11, 0x12, 0x84, 0x86 };
 static const u8 IT87_REG_FANX[]                = { 0x18, 0x19, 0x1a, 0x81, 0x83 };
 static const u8 IT87_REG_FANX_MIN[]    = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
+static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
+
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
@@ -226,6 +228,83 @@ static const u8 IT87_REG_FANX_MIN[]        = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
 #define IT87_REG_AUTO_PWM(nr, i)  (0x65 + (nr) * 8 + (i))
 
+struct it87_devices {
+       const char *name;
+       u16 features;
+       u8 peci_mask;
+       u8 old_peci_mask;
+};
+
+#define FEAT_12MV_ADC          (1 << 0)
+#define FEAT_NEWER_AUTOPWM     (1 << 1)
+#define FEAT_OLD_AUTOPWM       (1 << 2)
+#define FEAT_16BIT_FANS                (1 << 3)
+#define FEAT_TEMP_OFFSET       (1 << 4)
+#define FEAT_TEMP_PECI         (1 << 5)
+#define FEAT_TEMP_OLD_PECI     (1 << 6)
+
+static const struct it87_devices it87_devices[] = {
+       [it87] = {
+               .name = "it87",
+               .features = FEAT_OLD_AUTOPWM,   /* may need to overwrite */
+       },
+       [it8712] = {
+               .name = "it8712",
+               .features = FEAT_OLD_AUTOPWM,   /* may need to overwrite */
+       },
+       [it8716] = {
+               .name = "it8716",
+               .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET,
+       },
+       [it8718] = {
+               .name = "it8718",
+               .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+                 | FEAT_TEMP_OLD_PECI,
+               .old_peci_mask = 0x4,
+       },
+       [it8720] = {
+               .name = "it8720",
+               .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+                 | FEAT_TEMP_OLD_PECI,
+               .old_peci_mask = 0x4,
+       },
+       [it8721] = {
+               .name = "it8721",
+               .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+                 | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI,
+               .peci_mask = 0x05,
+               .old_peci_mask = 0x02,  /* Actually reports PCH */
+       },
+       [it8728] = {
+               .name = "it8728",
+               .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+                 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
+               .peci_mask = 0x07,
+       },
+       [it8782] = {
+               .name = "it8782",
+               .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+                 | FEAT_TEMP_OLD_PECI,
+               .old_peci_mask = 0x4,
+       },
+       [it8783] = {
+               .name = "it8783",
+               .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+                 | FEAT_TEMP_OLD_PECI,
+               .old_peci_mask = 0x4,
+       },
+};
+
+#define has_16bit_fans(data)   ((data)->features & FEAT_16BIT_FANS)
+#define has_12mv_adc(data)     ((data)->features & FEAT_12MV_ADC)
+#define has_newer_autopwm(data)        ((data)->features & FEAT_NEWER_AUTOPWM)
+#define has_old_autopwm(data)  ((data)->features & FEAT_OLD_AUTOPWM)
+#define has_temp_offset(data)  ((data)->features & FEAT_TEMP_OFFSET)
+#define has_temp_peci(data, nr)        (((data)->features & FEAT_TEMP_PECI) && \
+                                ((data)->peci_mask & (1 << nr)))
+#define has_temp_old_peci(data, nr) \
+                               (((data)->features & FEAT_TEMP_OLD_PECI) && \
+                                ((data)->old_peci_mask & (1 << nr)))
 
 struct it87_sio_data {
        enum chips type;
@@ -249,7 +328,9 @@ struct it87_sio_data {
 struct it87_data {
        struct device *hwmon_dev;
        enum chips type;
-       u8 revision;
+       u16 features;
+       u8 peci_mask;
+       u8 old_peci_mask;
 
        unsigned short addr;
        const char *name;
@@ -258,17 +339,13 @@ struct it87_data {
        unsigned long last_updated;     /* In jiffies */
 
        u16 in_scaled;          /* Internal voltage sensors are scaled */
-       u8 in[9];               /* Register value */
-       u8 in_max[8];           /* Register value */
-       u8 in_min[8];           /* Register value */
+       u8 in[9][3];            /* [nr][0]=in, [1]=min, [2]=max */
        u8 has_fan;             /* Bitfield, fans enabled */
-       u16 fan[5];             /* Register values, possibly combined */
-       u16 fan_min[5];         /* Register values, possibly combined */
+       u16 fan[5][2];          /* Register values, [nr][0]=fan, [1]=min */
        u8 has_temp;            /* Bitfield, temp sensors enabled */
-       s8 temp[3];             /* Register value */
-       s8 temp_high[3];        /* Register value */
-       s8 temp_low[3];         /* Register value */
-       u8 sensor;              /* Register value */
+       s8 temp[3][4];          /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
+       u8 sensor;              /* Register value (IT87_REG_TEMP_ENABLE) */
+       u8 extra;               /* Register value (IT87_REG_TEMP_EXTRA) */
        u8 fan_div[3];          /* Register encoding, shifted right */
        u8 vid;                 /* Register encoding, combined */
        u8 vrm;
@@ -296,26 +373,6 @@ struct it87_data {
        s8 auto_temp[3][5];     /* [nr][0] is point1_temp_hyst */
 };
 
-static inline int has_12mv_adc(const struct it87_data *data)
-{
-       /*
-        * IT8721F and later have a 12 mV ADC, also with internal scaling
-        * on selected inputs.
-        */
-       return data->type == it8721
-           || data->type == it8728;
-}
-
-static inline int has_newer_autopwm(const struct it87_data *data)
-{
-       /*
-        * IT8721F and later have separate registers for the temperature
-        * mapping and the manual duty cycle.
-        */
-       return data->type == it8721
-           || data->type == it8728;
-}
-
 static int adc_lsb(const struct it87_data *data, int nr)
 {
        int lsb = has_12mv_adc(data) ? 12 : 16;
@@ -398,35 +455,6 @@ static const unsigned int pwm_freq[8] = {
        750000 / 128,
 };
 
-static inline int has_16bit_fans(const struct it87_data *data)
-{
-       /*
-        * IT8705F Datasheet 0.4.1, 3h == Version G.
-        * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
-        * These are the first revisions with 16-bit tachometer support.
-        */
-       return (data->type == it87 && data->revision >= 0x03)
-           || (data->type == it8712 && data->revision >= 0x08)
-           || data->type == it8716
-           || data->type == it8718
-           || data->type == it8720
-           || data->type == it8721
-           || data->type == it8728
-           || data->type == it8782
-           || data->type == it8783;
-}
-
-static inline int has_old_autopwm(const struct it87_data *data)
-{
-       /*
-        * The old automatic fan speed control interface is implemented
-        * by IT8705F chips up to revision F and IT8712F chips up to
-        * revision G.
-        */
-       return (data->type == it87 && data->revision < 0x03)
-           || (data->type == it8712 && data->revision < 0x08);
-}
-
 static int it87_probe(struct platform_device *pdev);
 static int it87_remove(struct platform_device *pdev);
 
@@ -447,59 +475,22 @@ static struct platform_driver it87_driver = {
 };
 
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr]));
-}
-
-static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
-               char *buf)
+                      char *buf)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
 
        struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_min[nr]));
+       return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr][index]));
 }
 
-static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_max[nr]));
-}
-
-static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
-       struct it87_data *data = dev_get_drvdata(dev);
-       unsigned long val;
-
-       if (kstrtoul(buf, 10, &val) < 0)
-               return -EINVAL;
-
-       mutex_lock(&data->update_lock);
-       data->in_min[nr] = in_to_reg(data, nr, val);
-       it87_write_value(data, IT87_REG_VIN_MIN(nr),
-                       data->in_min[nr]);
-       mutex_unlock(&data->update_lock);
-       return count;
-}
-static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
+static ssize_t set_in(struct device *dev, struct device_attribute *attr,
+                     const char *buf, size_t count)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
 
        struct it87_data *data = dev_get_drvdata(dev);
        unsigned long val;
@@ -508,140 +499,167 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       data->in_max[nr] = in_to_reg(data, nr, val);
-       it87_write_value(data, IT87_REG_VIN_MAX(nr),
-                       data->in_max[nr]);
+       data->in[nr][index] = in_to_reg(data, nr, val);
+       it87_write_value(data,
+                        index == 1 ? IT87_REG_VIN_MIN(nr)
+                                   : IT87_REG_VIN_MAX(nr),
+                        data->in[nr][index]);
        mutex_unlock(&data->update_lock);
        return count;
 }
 
-#define show_in_offset(offset)                                 \
-static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,         \
-               show_in, NULL, offset);
-
-#define limit_in_offset(offset)                                        \
-static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
-               show_in_min, set_in_min, offset);               \
-static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
-               show_in_max, set_in_max, offset);
-
-show_in_offset(0);
-limit_in_offset(0);
-show_in_offset(1);
-limit_in_offset(1);
-show_in_offset(2);
-limit_in_offset(2);
-show_in_offset(3);
-limit_in_offset(3);
-show_in_offset(4);
-limit_in_offset(4);
-show_in_offset(5);
-limit_in_offset(5);
-show_in_offset(6);
-limit_in_offset(6);
-show_in_offset(7);
-limit_in_offset(7);
-show_in_offset(8);
+static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           0, 1);
+static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           0, 2);
+
+static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           1, 1);
+static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           1, 2);
+
+static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           2, 1);
+static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           2, 2);
+
+static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           3, 1);
+static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           3, 2);
+
+static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           4, 1);
+static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           4, 2);
+
+static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           5, 1);
+static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           5, 2);
+
+static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 6, 0);
+static SENSOR_DEVICE_ATTR_2(in6_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           6, 1);
+static SENSOR_DEVICE_ATTR_2(in6_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           6, 2);
+
+static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 7, 0);
+static SENSOR_DEVICE_ATTR_2(in7_min, S_IRUGO | S_IWUSR, show_in, set_in,
+                           7, 1);
+static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
+                           7, 2);
+
+static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
 
 /* 3 temperatures */
 static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
-               char *buf)
+                        char *buf)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
        struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
-}
-static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
 
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr]));
+       return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index]));
 }
-static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
 
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr]));
-}
-static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
+static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
+       u8 reg, regval;
 
        if (kstrtol(buf, 10, &val) < 0)
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       data->temp_high[nr] = TEMP_TO_REG(val);
-       it87_write_value(data, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
-       mutex_unlock(&data->update_lock);
-       return count;
-}
-static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
 
-       struct it87_data *data = dev_get_drvdata(dev);
-       long val;
-
-       if (kstrtol(buf, 10, &val) < 0)
-               return -EINVAL;
+       switch (index) {
+       default:
+       case 1:
+               reg = IT87_REG_TEMP_LOW(nr);
+               break;
+       case 2:
+               reg = IT87_REG_TEMP_HIGH(nr);
+               break;
+       case 3:
+               regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+               if (!(regval & 0x80)) {
+                       regval |= 0x80;
+                       it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
+               }
+               data->valid = 0;
+               reg = IT87_REG_TEMP_OFFSET[nr];
+               break;
+       }
 
-       mutex_lock(&data->update_lock);
-       data->temp_low[nr] = TEMP_TO_REG(val);
-       it87_write_value(data, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
+       data->temp[nr][index] = TEMP_TO_REG(val);
+       it87_write_value(data, reg, data->temp[nr][index]);
        mutex_unlock(&data->update_lock);
        return count;
 }
-#define show_temp_offset(offset)                                       \
-static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,               \
-               show_temp, NULL, offset - 1);                           \
-static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,       \
-               show_temp_max, set_temp_max, offset - 1);               \
-static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,       \
-               show_temp_min, set_temp_min, offset - 1);
-
-show_temp_offset(1);
-show_temp_offset(2);
-show_temp_offset(3);
-
-static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
-               char *buf)
+
+static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           0, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           0, 2);
+static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
+                           set_temp, 0, 3);
+static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           1, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           1, 2);
+static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
+                           set_temp, 1, 3);
+static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           2, 1);
+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+                           2, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
+                           set_temp, 2, 3);
+
+static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
+                             char *buf)
 {
        struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
        int nr = sensor_attr->index;
        struct it87_data *data = it87_update_device(dev);
        u8 reg = data->sensor;      /* In case value is updated while used */
+       u8 extra = data->extra;
 
+       if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1))
+           || (has_temp_old_peci(data, nr) && (extra & 0x80)))
+               return sprintf(buf, "6\n");  /* Intel PECI */
        if (reg & (1 << nr))
                return sprintf(buf, "3\n");  /* thermal diode */
        if (reg & (8 << nr))
                return sprintf(buf, "4\n");  /* thermistor */
        return sprintf(buf, "0\n");      /* disabled */
 }
-static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
+
+static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t count)
 {
        struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
        int nr = sensor_attr->index;
 
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
-       u8 reg;
+       u8 reg, extra;
 
        if (kstrtol(buf, 10, &val) < 0)
                return -EINVAL;
@@ -649,33 +667,45 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
        reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
        reg &= ~(1 << nr);
        reg &= ~(8 << nr);
+       if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6))
+               reg &= 0x3f;
+       extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
+       if (has_temp_old_peci(data, nr) && ((extra & 0x80) || val == 6))
+               extra &= 0x7f;
        if (val == 2) { /* backwards compatibility */
-               dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
-                        "instead\n");
+               dev_warn(dev,
+                        "Sensor type 2 is deprecated, please use 4 instead\n");
                val = 4;
        }
-       /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
+       /* 3 = thermal diode; 4 = thermistor; 6 = Intel PECI; 0 = disabled */
        if (val == 3)
                reg |= 1 << nr;
        else if (val == 4)
                reg |= 8 << nr;
+       else if (has_temp_peci(data, nr) && val == 6)
+               reg |= (nr + 1) << 6;
+       else if (has_temp_old_peci(data, nr) && val == 6)
+               extra |= 0x80;
        else if (val != 0)
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
        data->sensor = reg;
+       data->extra = extra;
        it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+       if (has_temp_old_peci(data, nr))
+               it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
        data->valid = 0;        /* Force cache refresh */
        mutex_unlock(&data->update_lock);
        return count;
 }
-#define show_sensor_offset(offset)                                     \
-static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR,      \
-               show_sensor, set_sensor, offset - 1);
 
-show_sensor_offset(1);
-show_sensor_offset(2);
-show_sensor_offset(3);
+static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
+                         set_temp_type, 0);
+static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
+                         set_temp_type, 1);
+static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
+                         set_temp_type, 2);
 
 /* 3 Fans */
 
@@ -692,25 +722,21 @@ static int pwm_mode(const struct it87_data *data, int nr)
 }
 
 static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
-               char *buf)
+                       char *buf)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
+       int speed;
        struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-                               DIV_FROM_REG(data->fan_div[nr])));
-}
-static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
 
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
-                               DIV_FROM_REG(data->fan_div[nr])));
+       speed = has_16bit_fans(data) ?
+               FAN16_FROM_REG(data->fan[nr][index]) :
+               FAN_FROM_REG(data->fan[nr][index],
+                            DIV_FROM_REG(data->fan_div[nr]));
+       return sprintf(buf, "%d\n", speed);
 }
+
 static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
                char *buf)
 {
@@ -747,11 +773,13 @@ static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%u\n", pwm_freq[index]);
 }
-static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
+
+static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t count)
 {
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       int nr = sattr->nr;
+       int index = sattr->index;
 
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
@@ -761,24 +789,36 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       reg = it87_read_value(data, IT87_REG_FAN_DIV);
-       switch (nr) {
-       case 0:
-               data->fan_div[nr] = reg & 0x07;
-               break;
-       case 1:
-               data->fan_div[nr] = (reg >> 3) & 0x07;
-               break;
-       case 2:
-               data->fan_div[nr] = (reg & 0x40) ? 3 : 1;
-               break;
+
+       if (has_16bit_fans(data)) {
+               data->fan[nr][index] = FAN16_TO_REG(val);
+               it87_write_value(data, IT87_REG_FAN_MIN[nr],
+                                data->fan[nr][index] & 0xff);
+               it87_write_value(data, IT87_REG_FANX_MIN[nr],
+                                data->fan[nr][index] >> 8);
+       } else {
+               reg = it87_read_value(data, IT87_REG_FAN_DIV);
+               switch (nr) {
+               case 0:
+                       data->fan_div[nr] = reg & 0x07;
+                       break;
+               case 1:
+                       data->fan_div[nr] = (reg >> 3) & 0x07;
+                       break;
+               case 2:
+                       data->fan_div[nr] = (reg & 0x40) ? 3 : 1;
+                       break;
+               }
+               data->fan[nr][index] =
+                 FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+               it87_write_value(data, IT87_REG_FAN_MIN[nr],
+                                data->fan[nr][index]);
        }
 
-       data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-       it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]);
        mutex_unlock(&data->update_lock);
        return count;
 }
+
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
                const char *buf, size_t count)
 {
@@ -797,7 +837,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        old = it87_read_value(data, IT87_REG_FAN_DIV);
 
        /* Save fan min limit */
-       min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
+       min = FAN_FROM_REG(data->fan[nr][1], DIV_FROM_REG(data->fan_div[nr]));
 
        switch (nr) {
        case 0:
@@ -818,8 +858,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        it87_write_value(data, IT87_REG_FAN_DIV, val);
 
        /* Restore fan min limit */
-       data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-       it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]);
+       data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+       it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan[nr][1]);
 
        mutex_unlock(&data->update_lock);
        return count;
@@ -843,8 +883,8 @@ static int check_trip_points(struct device *dev, int nr)
        }
 
        if (err) {
-               dev_err(dev, "Inconsistent trip points, not switching to "
-                       "automatic mode\n");
+               dev_err(dev,
+                       "Inconsistent trip points, not switching to automatic mode\n");
                dev_err(dev, "Adjust the trip points and try again\n");
        }
        return err;
@@ -1092,118 +1132,106 @@ static ssize_t set_auto_temp(struct device *dev,
        return count;
 }
 
-#define show_fan_offset(offset)                                        \
-static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                \
-               show_fan, NULL, offset - 1);                    \
-static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
-               show_fan_min, set_fan_min, offset - 1);         \
-static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
-               show_fan_div, set_fan_div, offset - 1);
-
-show_fan_offset(1);
-show_fan_offset(2);
-show_fan_offset(3);
-
-#define show_pwm_offset(offset)                                                \
-static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,     \
-               show_pwm_enable, set_pwm_enable, offset - 1);           \
-static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,              \
-               show_pwm, set_pwm, offset - 1);                         \
-static DEVICE_ATTR(pwm##offset##_freq,                                 \
-               (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO),            \
-               show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL));    \
-static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp,            \
-               S_IRUGO | S_IWUSR, show_pwm_temp_map, set_pwm_temp_map, \
-               offset - 1);                                            \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_pwm,             \
-               S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,         \
-               offset - 1, 0);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_pwm,             \
-               S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,         \
-               offset - 1, 1);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_pwm,             \
-               S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,         \
-               offset - 1, 2);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_pwm,             \
-               S_IRUGO, show_auto_pwm, NULL, offset - 1, 3);           \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp,            \
-               S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,       \
-               offset - 1, 1);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp_hyst,       \
-               S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,       \
-               offset - 1, 0);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_temp,            \
-               S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,       \
-               offset - 1, 2);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_temp,            \
-               S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,       \
-               offset - 1, 3);                                         \
-static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_temp,            \
-               S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,       \
-               offset - 1, 4);
-
-show_pwm_offset(1);
-show_pwm_offset(2);
-show_pwm_offset(3);
-
-/* A different set of callbacks for 16-bit fans */
-static ssize_t show_fan16(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan[nr]));
-}
-
-static ssize_t show_fan16_min(struct device *dev, struct device_attribute *attr,
-               char *buf)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-       struct it87_data *data = it87_update_device(dev);
-       return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan_min[nr]));
-}
-
-static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-       int nr = sensor_attr->index;
-       struct it87_data *data = dev_get_drvdata(dev);
-       long val;
-
-       if (kstrtol(buf, 10, &val) < 0)
-               return -EINVAL;
-
-       mutex_lock(&data->update_lock);
-       data->fan_min[nr] = FAN16_TO_REG(val);
-       it87_write_value(data, IT87_REG_FAN_MIN[nr],
-                        data->fan_min[nr] & 0xff);
-       it87_write_value(data, IT87_REG_FANX_MIN[nr],
-                        data->fan_min[nr] >> 8);
-       mutex_unlock(&data->update_lock);
-       return count;
-}
-
-/*
- * We want to use the same sysfs file names as 8-bit fans, but we need
- * different variable names, so we have to use SENSOR_ATTR instead of
- * SENSOR_DEVICE_ATTR.
- */
-#define show_fan16_offset(offset) \
-static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \
-       = SENSOR_ATTR(fan##offset##_input, S_IRUGO,             \
-               show_fan16, NULL, offset - 1);                  \
-static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \
-       = SENSOR_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,     \
-               show_fan16_min, set_fan16_min, offset - 1)
-
-show_fan16_offset(1);
-show_fan16_offset(2);
-show_fan16_offset(3);
-show_fan16_offset(4);
-show_fan16_offset(5);
+static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+                           0, 1);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div,
+                         set_fan_div, 0);
+
+static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+                           1, 1);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, show_fan_div,
+                         set_fan_div, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+                           2, 1);
+static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, show_fan_div,
+                         set_fan_div, 2);
+
+static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+                           3, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+                           4, 1);
+
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
+static DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq);
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR,
+                         show_pwm_temp_map, set_pwm_temp_map, 0);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 0, 0);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 0, 1);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 0, 2);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO,
+                           show_auto_pwm, NULL, 0, 3);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 0, 1);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 0, 0);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 0, 2);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 0, 3);
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 0, 4);
+
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
+static DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, NULL);
+static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR,
+                         show_pwm_temp_map, set_pwm_temp_map, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 1, 0);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 1, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 1, 2);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO,
+                           show_auto_pwm, NULL, 1, 3);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 1, 0);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 1, 2);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 1, 3);
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 1, 4);
+
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 2);
+static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
+static DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL);
+static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR,
+                         show_pwm_temp_map, set_pwm_temp_map, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 2, 0);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 2, 1);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR,
+                           show_auto_pwm, set_auto_pwm, 2, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO,
+                           show_auto_pwm, NULL, 2, 3);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 2, 0);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 2, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 2, 3);
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
+                           show_auto_temp, set_auto_temp, 2, 4);
 
 /* Alarms */
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
@@ -1471,6 +1499,12 @@ static const struct attribute_group it87_group_temp[3] = {
        { .attrs = it87_attributes_temp[2] },
 };
 
+static struct attribute *it87_attributes_temp_offset[] = {
+       &sensor_dev_attr_temp1_offset.dev_attr.attr,
+       &sensor_dev_attr_temp2_offset.dev_attr.attr,
+       &sensor_dev_attr_temp3_offset.dev_attr.attr,
+};
+
 static struct attribute *it87_attributes[] = {
        &dev_attr_alarms.attr,
        &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
@@ -1500,73 +1534,47 @@ static struct attribute *it87_attributes_temp_beep[] = {
        &sensor_dev_attr_temp3_beep.dev_attr.attr,
 };
 
-static struct attribute *it87_attributes_fan16[5][3+1] = { {
-       &sensor_dev_attr_fan1_input16.dev_attr.attr,
-       &sensor_dev_attr_fan1_min16.dev_attr.attr,
+static struct attribute *it87_attributes_fan[5][3+1] = { {
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
        NULL
 }, {
-       &sensor_dev_attr_fan2_input16.dev_attr.attr,
-       &sensor_dev_attr_fan2_min16.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
        NULL
 }, {
-       &sensor_dev_attr_fan3_input16.dev_attr.attr,
-       &sensor_dev_attr_fan3_min16.dev_attr.attr,
+       &sensor_dev_attr_fan3_input.dev_attr.attr,
+       &sensor_dev_attr_fan3_min.dev_attr.attr,
        &sensor_dev_attr_fan3_alarm.dev_attr.attr,
        NULL
 }, {
-       &sensor_dev_attr_fan4_input16.dev_attr.attr,
-       &sensor_dev_attr_fan4_min16.dev_attr.attr,
+       &sensor_dev_attr_fan4_input.dev_attr.attr,
+       &sensor_dev_attr_fan4_min.dev_attr.attr,
        &sensor_dev_attr_fan4_alarm.dev_attr.attr,
        NULL
 }, {
-       &sensor_dev_attr_fan5_input16.dev_attr.attr,
-       &sensor_dev_attr_fan5_min16.dev_attr.attr,
+       &sensor_dev_attr_fan5_input.dev_attr.attr,
+       &sensor_dev_attr_fan5_min.dev_attr.attr,
        &sensor_dev_attr_fan5_alarm.dev_attr.attr,
        NULL
 } };
 
-static const struct attribute_group it87_group_fan16[5] = {
-       { .attrs = it87_attributes_fan16[0] },
-       { .attrs = it87_attributes_fan16[1] },
-       { .attrs = it87_attributes_fan16[2] },
-       { .attrs = it87_attributes_fan16[3] },
-       { .attrs = it87_attributes_fan16[4] },
+static const struct attribute_group it87_group_fan[5] = {
+       { .attrs = it87_attributes_fan[0] },
+       { .attrs = it87_attributes_fan[1] },
+       { .attrs = it87_attributes_fan[2] },
+       { .attrs = it87_attributes_fan[3] },
+       { .attrs = it87_attributes_fan[4] },
 };
 
-static struct attribute *it87_attributes_fan[3][4+1] = { {
-       &sensor_dev_attr_fan1_input.dev_attr.attr,
-       &sensor_dev_attr_fan1_min.dev_attr.attr,
+static const struct attribute *it87_attributes_fan_div[] = {
        &sensor_dev_attr_fan1_div.dev_attr.attr,
-       &sensor_dev_attr_fan1_alarm.dev_attr.attr,
-       NULL
-}, {
-       &sensor_dev_attr_fan2_input.dev_attr.attr,
-       &sensor_dev_attr_fan2_min.dev_attr.attr,
        &sensor_dev_attr_fan2_div.dev_attr.attr,
-       &sensor_dev_attr_fan2_alarm.dev_attr.attr,
-       NULL
-}, {
-       &sensor_dev_attr_fan3_input.dev_attr.attr,
-       &sensor_dev_attr_fan3_min.dev_attr.attr,
        &sensor_dev_attr_fan3_div.dev_attr.attr,
-       &sensor_dev_attr_fan3_alarm.dev_attr.attr,
-       NULL
-} };
-
-static const struct attribute_group it87_group_fan[3] = {
-       { .attrs = it87_attributes_fan[0] },
-       { .attrs = it87_attributes_fan[1] },
-       { .attrs = it87_attributes_fan[2] },
 };
 
-static const struct attribute_group *
-it87_get_fan_group(const struct it87_data *data)
-{
-       return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan;
-}
-
 static struct attribute *it87_attributes_pwm[3][4+1] = { {
        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
        &sensor_dev_attr_pwm1.dev_attr.attr,
@@ -1925,7 +1933,6 @@ static void it87_remove_files(struct device *dev)
 {
        struct it87_data *data = platform_get_drvdata(pdev);
        struct it87_sio_data *sio_data = dev->platform_data;
-       const struct attribute_group *fan_group = it87_get_fan_group(data);
        int i;
 
        sysfs_remove_group(&dev->kobj, &it87_group);
@@ -1941,6 +1948,9 @@ static void it87_remove_files(struct device *dev)
                if (!(data->has_temp & (1 << i)))
                        continue;
                sysfs_remove_group(&dev->kobj, &it87_group_temp[i]);
+               if (has_temp_offset(data))
+                       sysfs_remove_file(&dev->kobj,
+                                         it87_attributes_temp_offset[i]);
                if (sio_data->beep_pin)
                        sysfs_remove_file(&dev->kobj,
                                          it87_attributes_temp_beep[i]);
@@ -1948,10 +1958,13 @@ static void it87_remove_files(struct device *dev)
        for (i = 0; i < 5; i++) {
                if (!(data->has_fan & (1 << i)))
                        continue;
-               sysfs_remove_group(&dev->kobj, &fan_group[i]);
+               sysfs_remove_group(&dev->kobj, &it87_group_fan[i]);
                if (sio_data->beep_pin)
                        sysfs_remove_file(&dev->kobj,
                                          it87_attributes_fan_beep[i]);
+               if (i < 3 && !has_16bit_fans(data))
+                       sysfs_remove_file(&dev->kobj,
+                                         it87_attributes_fan_div[i]);
        }
        for (i = 0; i < 3; i++) {
                if (sio_data->skip_pwm & (1 << 0))
@@ -1972,21 +1985,9 @@ static int it87_probe(struct platform_device *pdev)
        struct resource *res;
        struct device *dev = &pdev->dev;
        struct it87_sio_data *sio_data = dev->platform_data;
-       const struct attribute_group *fan_group;
        int err = 0, i;
        int enable_pwm_interface;
        int fan_beep_need_rw;
-       static const char * const names[] = {
-               "it87",
-               "it8712",
-               "it8716",
-               "it8718",
-               "it8720",
-               "it8721",
-               "it8728",
-               "it8782",
-               "it8783",
-       };
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
        if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT,
@@ -2003,8 +2004,31 @@ static int it87_probe(struct platform_device *pdev)
 
        data->addr = res->start;
        data->type = sio_data->type;
-       data->revision = sio_data->revision;
-       data->name = names[sio_data->type];
+       data->features = it87_devices[sio_data->type].features;
+       data->peci_mask = it87_devices[sio_data->type].peci_mask;
+       data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
+       data->name = it87_devices[sio_data->type].name;
+       /*
+        * IT8705F Datasheet 0.4.1, 3h == Version G.
+        * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
+        * These are the first revisions with 16-bit tachometer support.
+        */
+       switch (data->type) {
+       case it87:
+               if (sio_data->revision >= 0x03) {
+                       data->features &= ~FEAT_OLD_AUTOPWM;
+                       data->features |= FEAT_16BIT_FANS;
+               }
+               break;
+       case it8712:
+               if (sio_data->revision >= 0x08) {
+                       data->features &= ~FEAT_OLD_AUTOPWM;
+                       data->features |= FEAT_16BIT_FANS;
+               }
+               break;
+       default:
+               break;
+       }
 
        /* Now, we do the remaining detection. */
        if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80)
@@ -2068,6 +2092,12 @@ static int it87_probe(struct platform_device *pdev)
                err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]);
                if (err)
                        goto error;
+               if (has_temp_offset(data)) {
+                       err = sysfs_create_file(&dev->kobj,
+                                               it87_attributes_temp_offset[i]);
+                       if (err)
+                               goto error;
+               }
                if (sio_data->beep_pin) {
                        err = sysfs_create_file(&dev->kobj,
                                                it87_attributes_temp_beep[i]);
@@ -2077,15 +2107,21 @@ static int it87_probe(struct platform_device *pdev)
        }
 
        /* Do not create fan files for disabled fans */
-       fan_group = it87_get_fan_group(data);
        fan_beep_need_rw = 1;
        for (i = 0; i < 5; i++) {
                if (!(data->has_fan & (1 << i)))
                        continue;
-               err = sysfs_create_group(&dev->kobj, &fan_group[i]);
+               err = sysfs_create_group(&dev->kobj, &it87_group_fan[i]);
                if (err)
                        goto error;
 
+               if (i < 3 && !has_16bit_fans(data)) {
+                       err = sysfs_create_file(&dev->kobj,
+                                               it87_attributes_fan_div[i]);
+                       if (err)
+                               goto error;
+               }
+
                if (sio_data->beep_pin) {
                        err = sysfs_create_file(&dev->kobj,
                                                it87_attributes_fan_beep[i]);
@@ -2221,8 +2257,8 @@ static int it87_check_pwm(struct device *dev)
                         * PWM interface).
                         */
                        if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
-                               dev_info(dev, "Reconfiguring PWM to "
-                                        "active high polarity\n");
+                               dev_info(dev,
+                                        "Reconfiguring PWM to active high polarity\n");
                                it87_write_value(data, IT87_REG_FAN_CTL,
                                                 tmp | 0x87);
                                for (i = 0; i < 3; i++)
@@ -2232,16 +2268,16 @@ static int it87_check_pwm(struct device *dev)
                                return 1;
                        }
 
-                       dev_info(dev, "PWM configuration is "
-                                "too broken to be fixed\n");
+                       dev_info(dev,
+                                "PWM configuration is too broken to be fixed\n");
                }
 
-               dev_info(dev, "Detected broken BIOS "
-                        "defaults, disabling PWM interface\n");
+               dev_info(dev,
+                        "Detected broken BIOS defaults, disabling PWM interface\n");
                return 0;
        } else if (fix_pwm_polarity) {
-               dev_info(dev, "PWM configuration looks "
-                        "sane, won't touch\n");
+               dev_info(dev,
+                        "PWM configuration looks sane, won't touch\n");
        }
 
        return 1;
@@ -2389,42 +2425,46 @@ static struct it87_data *it87_update_device(struct device *dev)
                                it87_read_value(data, IT87_REG_CONFIG) | 0x40);
                }
                for (i = 0; i <= 7; i++) {
-                       data->in[i] =
+                       data->in[i][0] =
                                it87_read_value(data, IT87_REG_VIN(i));
-                       data->in_min[i] =
+                       data->in[i][1] =
                                it87_read_value(data, IT87_REG_VIN_MIN(i));
-                       data->in_max[i] =
+                       data->in[i][2] =
                                it87_read_value(data, IT87_REG_VIN_MAX(i));
                }
                /* in8 (battery) has no limit registers */
-               data->in[8] = it87_read_value(data, IT87_REG_VIN(8));
+               data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8));
 
                for (i = 0; i < 5; i++) {
                        /* Skip disabled fans */
                        if (!(data->has_fan & (1 << i)))
                                continue;
 
-                       data->fan_min[i] =
+                       data->fan[i][1] =
                                it87_read_value(data, IT87_REG_FAN_MIN[i]);
-                       data->fan[i] = it87_read_value(data,
+                       data->fan[i][0] = it87_read_value(data,
                                       IT87_REG_FAN[i]);
                        /* Add high byte if in 16-bit mode */
                        if (has_16bit_fans(data)) {
-                               data->fan[i] |= it87_read_value(data,
+                               data->fan[i][0] |= it87_read_value(data,
                                                IT87_REG_FANX[i]) << 8;
-                               data->fan_min[i] |= it87_read_value(data,
+                               data->fan[i][1] |= it87_read_value(data,
                                                IT87_REG_FANX_MIN[i]) << 8;
                        }
                }
                for (i = 0; i < 3; i++) {
                        if (!(data->has_temp & (1 << i)))
                                continue;
-                       data->temp[i] =
+                       data->temp[i][0] =
                                it87_read_value(data, IT87_REG_TEMP(i));
-                       data->temp_high[i] =
-                               it87_read_value(data, IT87_REG_TEMP_HIGH(i));
-                       data->temp_low[i] =
+                       data->temp[i][1] =
                                it87_read_value(data, IT87_REG_TEMP_LOW(i));
+                       data->temp[i][2] =
+                               it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+                       if (has_temp_offset(data))
+                               data->temp[i][3] =
+                                 it87_read_value(data,
+                                                 IT87_REG_TEMP_OFFSET[i]);
                }
 
                /* Newer chips don't have clock dividers */
@@ -2448,6 +2488,7 @@ static struct it87_data *it87_update_device(struct device *dev)
                        it87_update_pwm_ctrl(data, i);
 
                data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+               data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
                /*
                 * The IT8705F does not have VID capability.
                 * The IT8718F and later don't use IT87_REG_VID for the
@@ -2549,8 +2590,7 @@ static void __exit sm_it87_exit(void)
 }
 
 
-MODULE_AUTHOR("Chris Gauthron, "
-             "Jean Delvare <khali@linux-fr.org>");
+MODULE_AUTHOR("Chris Gauthron, Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
 module_param(update_vbat, bool, 0);
 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
index 55ac41c..0e8ffd6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  w83627ehf - Driver for the hardware monitoring functionality of
  *             the Winbond W83627EHF Super-I/O chip
- *  Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
+ *  Copyright (C) 2005-2012  Jean Delvare <khali@linux-fr.org>
  *  Copyright (C) 2006  Yuan Mu (Winbond),
  *                     Rudolf Marek <r.marek@assembler.cz>
  *                     David Hubbard <david.c.hubbard@gmail.com>
@@ -502,6 +502,13 @@ struct w83627ehf_data {
        u16 have_temp_offset;
        u8 in6_skip:1;
        u8 temp3_val_only:1;
+
+#ifdef CONFIG_PM
+       /* Remember extra register values over suspend/resume */
+       u8 vbat;
+       u8 fandiv1;
+       u8 fandiv2;
+#endif
 };
 
 struct w83627ehf_sio_data {
@@ -898,6 +905,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
                                data->temp_max_hyst[i]
                                  = w83627ehf_read_temp(data,
                                                data->reg_temp_hyst[i]);
+                       if (i > 2)
+                               continue;
                        if (data->have_temp_offset & (1 << i))
                                data->temp_offset[i]
                                  = w83627ehf_read_value(data,
@@ -2608,10 +2617,98 @@ static int w83627ehf_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int w83627ehf_suspend(struct device *dev)
+{
+       struct w83627ehf_data *data = w83627ehf_update_device(dev);
+       struct w83627ehf_sio_data *sio_data = dev->platform_data;
+
+       mutex_lock(&data->update_lock);
+       data->vbat = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
+       if (sio_data->kind == nct6775) {
+               data->fandiv1 = w83627ehf_read_value(data, NCT6775_REG_FANDIV1);
+               data->fandiv2 = w83627ehf_read_value(data, NCT6775_REG_FANDIV2);
+       }
+       mutex_unlock(&data->update_lock);
+
+       return 0;
+}
+
+static int w83627ehf_resume(struct device *dev)
+{
+       struct w83627ehf_data *data = dev_get_drvdata(dev);
+       struct w83627ehf_sio_data *sio_data = dev->platform_data;
+       int i;
+
+       mutex_lock(&data->update_lock);
+       data->bank = 0xff;              /* Force initial bank selection */
+
+       /* Restore limits */
+       for (i = 0; i < data->in_num; i++) {
+               if ((i == 6) && data->in6_skip)
+                       continue;
+
+               w83627ehf_write_value(data, W83627EHF_REG_IN_MIN(i),
+                                     data->in_min[i]);
+               w83627ehf_write_value(data, W83627EHF_REG_IN_MAX(i),
+                                     data->in_max[i]);
+       }
+
+       for (i = 0; i < 5; i++) {
+               if (!(data->has_fan_min & (1 << i)))
+                       continue;
+
+               w83627ehf_write_value(data, data->REG_FAN_MIN[i],
+                                     data->fan_min[i]);
+       }
+
+       for (i = 0; i < NUM_REG_TEMP; i++) {
+               if (!(data->have_temp & (1 << i)))
+                       continue;
+
+               if (data->reg_temp_over[i])
+                       w83627ehf_write_temp(data, data->reg_temp_over[i],
+                                            data->temp_max[i]);
+               if (data->reg_temp_hyst[i])
+                       w83627ehf_write_temp(data, data->reg_temp_hyst[i],
+                                            data->temp_max_hyst[i]);
+               if (i > 2)
+                       continue;
+               if (data->have_temp_offset & (1 << i))
+                       w83627ehf_write_value(data,
+                                             W83627EHF_REG_TEMP_OFFSET[i],
+                                             data->temp_offset[i]);
+       }
+
+       /* Restore other settings */
+       w83627ehf_write_value(data, W83627EHF_REG_VBAT, data->vbat);
+       if (sio_data->kind == nct6775) {
+               w83627ehf_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
+               w83627ehf_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
+       }
+
+       /* Force re-reading all values */
+       data->valid = 0;
+       mutex_unlock(&data->update_lock);
+
+       return 0;
+}
+
+static const struct dev_pm_ops w83627ehf_dev_pm_ops = {
+       .suspend = w83627ehf_suspend,
+       .resume = w83627ehf_resume,
+};
+
+#define W83627EHF_DEV_PM_OPS   (&w83627ehf_dev_pm_ops)
+#else
+#define W83627EHF_DEV_PM_OPS   NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver w83627ehf_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = DRVNAME,
+               .pm     = W83627EHF_DEV_PM_OPS,
        },
        .probe          = w83627ehf_probe,
        .remove         = w83627ehf_remove,
index 7f68b83..81f4865 100644 (file)
@@ -5,7 +5,7 @@
  *                           Philip Edelbrock <phil@netroedge.com>,
  *                           and Mark Studebaker <mdsxyz123@yahoo.com>
  * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
- * Copyright (c) 2007  Jean Delvare <khali@linux-fr.org>
+ * Copyright (c) 2007 - 1012  Jean Delvare <khali@linux-fr.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -389,6 +389,12 @@ struct w83627hf_data {
                                 */
        u8 vrm;
        u8 vrm_ovt;             /* Register value, 627THF/637HF/687THF only */
+
+#ifdef CONFIG_PM
+       /* Remember extra register values over suspend/resume */
+       u8 scfg1;
+       u8 scfg2;
+#endif
 };
 
 
@@ -401,10 +407,77 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data);
 static struct w83627hf_data *w83627hf_update_device(struct device *dev);
 static void w83627hf_init_device(struct platform_device *pdev);
 
+#ifdef CONFIG_PM
+static int w83627hf_suspend(struct device *dev)
+{
+       struct w83627hf_data *data = w83627hf_update_device(dev);
+
+       mutex_lock(&data->update_lock);
+       data->scfg1 = w83627hf_read_value(data, W83781D_REG_SCFG1);
+       data->scfg2 = w83627hf_read_value(data, W83781D_REG_SCFG2);
+       mutex_unlock(&data->update_lock);
+
+       return 0;
+}
+
+static int w83627hf_resume(struct device *dev)
+{
+       struct w83627hf_data *data = dev_get_drvdata(dev);
+       int i, num_temps = (data->type == w83697hf) ? 2 : 3;
+
+       /* Restore limits */
+       mutex_lock(&data->update_lock);
+       for (i = 0; i <= 8; i++) {
+               /* skip missing sensors */
+               if (((data->type == w83697hf) && (i == 1)) ||
+                   ((data->type != w83627hf && data->type != w83697hf)
+                   && (i == 5 || i == 6)))
+                       continue;
+               w83627hf_write_value(data, W83781D_REG_IN_MAX(i),
+                                    data->in_max[i]);
+               w83627hf_write_value(data, W83781D_REG_IN_MIN(i),
+                                    data->in_min[i]);
+       }
+       for (i = 0; i <= 2; i++)
+               w83627hf_write_value(data, W83627HF_REG_FAN_MIN(i),
+                                    data->fan_min[i]);
+       for (i = 0; i < num_temps; i++) {
+               w83627hf_write_value(data, w83627hf_reg_temp_over[i],
+                                    data->temp_max[i]);
+               w83627hf_write_value(data, w83627hf_reg_temp_hyst[i],
+                                    data->temp_max_hyst[i]);
+       }
+
+       /* Fixup BIOS bugs */
+       if (data->type == w83627thf || data->type == w83637hf ||
+           data->type == w83687thf)
+               w83627hf_write_value(data, W83627THF_REG_VRM_OVT_CFG,
+                                    data->vrm_ovt);
+       w83627hf_write_value(data, W83781D_REG_SCFG1, data->scfg1);
+       w83627hf_write_value(data, W83781D_REG_SCFG2, data->scfg2);
+
+       /* Force re-reading all values */
+       data->valid = 0;
+       mutex_unlock(&data->update_lock);
+
+       return 0;
+}
+
+static const struct dev_pm_ops w83627hf_dev_pm_ops = {
+       .suspend = w83627hf_suspend,
+       .resume = w83627hf_resume,
+};
+
+#define W83627HF_DEV_PM_OPS    (&w83627hf_dev_pm_ops)
+#else
+#define W83627HF_DEV_PM_OPS    NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver w83627hf_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = DRVNAME,
+               .pm     = W83627HF_DEV_PM_OPS,
        },
        .probe          = w83627hf_probe,
        .remove         = w83627hf_remove,
@@ -1659,8 +1732,10 @@ static void w83627hf_init_device(struct platform_device *pdev)
        /* Minimize conflicts with other winbond i2c-only clients...  */
        /* disable i2c subclients... how to disable main i2c client?? */
        /* force i2c address to relatively uncommon address */
-       w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89);
-       w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c);
+       if (type == w83627hf) {
+               w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89);
+               w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c);
+       }
 
        /* Read VID only once */
        if (type == w83627hf || type == w83637hf) {
index d6cc77a..5f306f7 100644 (file)
@@ -921,6 +921,7 @@ static int __init i8042_platform_init(void)
        int retval;
 
 #ifdef CONFIG_X86
+       u8 a20_on = 0xdf;
        /* Just return if pre-detection shows no i8042 controller exist */
        if (!x86_platform.i8042_detect())
                return -ENODEV;
@@ -960,6 +961,14 @@ static int __init i8042_platform_init(void)
 
        if (dmi_check_system(i8042_dmi_dritek_table))
                i8042_dritek = true;
+
+       /*
+        * A20 was already enabled during early kernel init. But some buggy
+        * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
+        * resume from S3. So we do it here and hope that nothing breaks.
+        */
+       i8042_command(&a20_on, 0x10d1);
+       i8042_command(NULL, 0x00ff);    /* Null command for SMM firmware */
 #endif /* CONFIG_X86 */
 
        return retval;
index 28c99c6..22b720e 100644 (file)
@@ -1217,8 +1217,7 @@ static void __exit dsp_cleanup(void)
 {
        mISDN_unregister_Bprotocol(&DSP);
 
-       if (timer_pending(&dsp_spl_tl))
-               del_timer(&dsp_spl_tl);
+       del_timer_sync(&dsp_spl_tl);
 
        if (!list_empty(&dsp_ilist)) {
                printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
index 770a0d0..05164d7 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/gpio.h>
-#include <plat/cpu.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-omap.h>
 #include <linux/pm_runtime.h>
@@ -384,7 +383,7 @@ static void omap_usbhs_init(struct device *dev)
                        reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
 
                /* Bypass the TLL module for PHY mode operation */
-               if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) {
+               if (pdata->single_ulpi_bypass) {
                        dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
                        if (is_ehci_phy_mode(pdata->port_mode[0]) ||
                                is_ehci_phy_mode(pdata->port_mode[1]) ||
index 9453931..7c057a0 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/bootmem.h>
-#include <linux/magic.h>
 #include <linux/module.h>
 
+#include <uapi/linux/magic.h>
+
 #define AR7_PARTS      4
 #define ROOT_OFFSET    0xe0000
 
 #define LOADER_MAGIC1  le32_to_cpu(0xfeedfa42)
 #define LOADER_MAGIC2  le32_to_cpu(0xfeed1281)
 
-#ifndef SQUASHFS_MAGIC
-#define SQUASHFS_MAGIC 0x73717368
-#endif
-
 struct ar7_bin_rec {
        unsigned int checksum;
        unsigned int length;
index 63d2a64..6eeb84c 100644 (file)
@@ -37,8 +37,7 @@
 
 #define BCM63XX_EXTENDED_SIZE  0xBFC00000      /* Extended flash address */
 
-#define BCM63XX_MIN_CFE_SIZE   0x10000         /* always at least 64KiB */
-#define BCM63XX_MIN_NVRAM_SIZE 0x10000         /* always at least 64KiB */
+#define BCM63XX_CFE_BLOCK_SIZE 0x10000         /* always at least 64KiB */
 
 #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
 
@@ -79,7 +78,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
        unsigned int rootfsaddr, kerneladdr, spareaddr;
        unsigned int rootfslen, kernellen, sparelen, totallen;
        unsigned int cfelen, nvramlen;
-       int namelen = 0;
+       unsigned int cfe_erasesize;
        int i;
        u32 computed_crc;
        bool rootfs_first = false;
@@ -87,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
        if (bcm63xx_detect_cfe(master))
                return -EINVAL;
 
-       cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE);
-       nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE);
+       cfe_erasesize = max_t(uint32_t, master->erasesize,
+                             BCM63XX_CFE_BLOCK_SIZE);
+
+       cfelen = cfe_erasesize;
+       nvramlen = cfe_erasesize;
 
        /* Allocate memory for buffer */
        buf = vmalloc(sizeof(struct bcm_tag));
@@ -121,7 +123,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
                kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
                rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
                spareaddr = roundup(totallen, master->erasesize) + cfelen;
-               sparelen = master->size - spareaddr - nvramlen;
 
                if (rootfsaddr < kerneladdr) {
                        /* default Broadcom layout */
@@ -139,19 +140,15 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
                rootfslen = 0;
                rootfsaddr = 0;
                spareaddr = cfelen;
-               sparelen = master->size - cfelen - nvramlen;
        }
+       sparelen = master->size - spareaddr - nvramlen;
 
        /* Determine number of partitions */
-       namelen = 8;
-       if (rootfslen > 0) {
+       if (rootfslen > 0)
                nrparts++;
-               namelen += 6;
-       }
-       if (kernellen > 0) {
+
+       if (kernellen > 0)
                nrparts++;
-               namelen += 6;
-       }
 
        /* Ask kernel for more memory */
        parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
@@ -193,17 +190,16 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
        parts[curpart].name = "nvram";
        parts[curpart].offset = master->size - nvramlen;
        parts[curpart].size = nvramlen;
+       curpart++;
 
        /* Global partition "linux" to make easy firmware upgrade */
-       curpart++;
        parts[curpart].name = "linux";
        parts[curpart].offset = cfelen;
        parts[curpart].size = master->size - cfelen - nvramlen;
 
        for (i = 0; i < nrparts; i++)
-               pr_info("Partition %d is %s offset %lx and length %lx\n", i,
-                       parts[i].name, (long unsigned int)(parts[i].offset),
-                       (long unsigned int)(parts[i].size));
+               pr_info("Partition %d is %s offset %llx and length %llx\n", i,
+                       parts[i].name, parts[i].offset, parts[i].size);
 
        pr_info("Spare partition is offset %x and length %x\n", spareaddr,
                sparelen);
index 5ff5c4a..b861972 100644 (file)
@@ -1536,8 +1536,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                UDELAY(map, chip, adr, 1);
        }
 
-       /* reset on all failures. */
-       map_write( map, CMD(0xF0), chip->start );
+       /*
+        * Recovery from write-buffer programming failures requires
+        * the write-to-buffer-reset sequence.  Since the last part
+        * of the sequence also works as a normal reset, we can run
+        * the same commands regardless of why we are here.
+        * See e.g.
+        * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf
+        */
+       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
+                        cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,
+                        cfi->device_type, NULL);
+       cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi,
+                        cfi->device_type, NULL);
        xip_enable(map, chip, adr);
        /* FIXME - should have reset delay before continuing */
 
index aed1b8a..c533f27 100644 (file)
@@ -56,8 +56,8 @@
 
 
 /* special size referring to all the remaining space in a partition */
-#define SIZE_REMAINING UINT_MAX
-#define OFFSET_CONTINUOUS UINT_MAX
+#define SIZE_REMAINING ULLONG_MAX
+#define OFFSET_CONTINUOUS ULLONG_MAX
 
 struct cmdline_mtd_partition {
        struct cmdline_mtd_partition *next;
@@ -89,7 +89,7 @@ static struct mtd_partition * newpart(char *s,
                                      int extra_mem_size)
 {
        struct mtd_partition *parts;
-       unsigned long size, offset = OFFSET_CONTINUOUS;
+       unsigned long long size, offset = OFFSET_CONTINUOUS;
        char *name;
        int name_len;
        unsigned char *extra_mem;
@@ -104,7 +104,8 @@ static struct mtd_partition * newpart(char *s,
        } else {
                size = memparse(s, &s);
                if (size < PAGE_SIZE) {
-                       printk(KERN_ERR ERRP "partition size too small (%lx)\n", size);
+                       printk(KERN_ERR ERRP "partition size too small (%llx)\n",
+                              size);
                        return ERR_PTR(-EINVAL);
                }
        }
@@ -296,7 +297,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
                                    struct mtd_partition **pparts,
                                    struct mtd_part_parser_data *data)
 {
-       unsigned long offset;
+       unsigned long long offset;
        int i, err;
        struct cmdline_mtd_partition *part;
        const char *mtd_id = master->name;
@@ -308,48 +309,52 @@ static int parse_cmdline_partitions(struct mtd_info *master,
                        return err;
        }
 
+       /*
+        * Search for the partition definition matching master->name.
+        * If master->name is not set, stop at first partition definition.
+        */
        for (part = partitions; part; part = part->next) {
-               if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) {
-                       for (i = 0, offset = 0; i < part->num_parts; i++) {
-                               if (part->parts[i].offset == OFFSET_CONTINUOUS)
-                                       part->parts[i].offset = offset;
-                               else
-                                       offset = part->parts[i].offset;
-
-                               if (part->parts[i].size == SIZE_REMAINING)
-                                       part->parts[i].size = master->size - offset;
-
-                               if (part->parts[i].size == 0) {
-                                       printk(KERN_WARNING ERRP
-                                              "%s: skipping zero sized partition\n",
-                                              part->mtd_id);
-                                       part->num_parts--;
-                                       memmove(&part->parts[i],
-                                               &part->parts[i + 1],
-                                               sizeof(*part->parts) * (part->num_parts - i));
-                                       continue;
-                               }
-
-                               if (offset + part->parts[i].size > master->size) {
-                                       printk(KERN_WARNING ERRP
-                                              "%s: partitioning exceeds flash size, truncating\n",
-                                              part->mtd_id);
-                                       part->parts[i].size = master->size - offset;
-                               }
-                               offset += part->parts[i].size;
-                       }
-
-                       *pparts = kmemdup(part->parts,
-                                       sizeof(*part->parts) * part->num_parts,
-                                       GFP_KERNEL);
-                       if (!*pparts)
-                               return -ENOMEM;
-
-                       return part->num_parts;
+               if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
+                       break;
+       }
+
+       if (!part)
+               return 0;
+
+       for (i = 0, offset = 0; i < part->num_parts; i++) {
+               if (part->parts[i].offset == OFFSET_CONTINUOUS)
+                       part->parts[i].offset = offset;
+               else
+                       offset = part->parts[i].offset;
+
+               if (part->parts[i].size == SIZE_REMAINING)
+                       part->parts[i].size = master->size - offset;
+
+               if (part->parts[i].size == 0) {
+                       printk(KERN_WARNING ERRP
+                              "%s: skipping zero sized partition\n",
+                              part->mtd_id);
+                       part->num_parts--;
+                       memmove(&part->parts[i], &part->parts[i + 1],
+                               sizeof(*part->parts) * (part->num_parts - i));
+                       continue;
                }
+
+               if (offset + part->parts[i].size > master->size) {
+                       printk(KERN_WARNING ERRP
+                              "%s: partitioning exceeds flash size, truncating\n",
+                              part->mtd_id);
+                       part->parts[i].size = master->size - offset;
+               }
+               offset += part->parts[i].size;
        }
 
-       return 0;
+       *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
+                         GFP_KERNEL);
+       if (!*pparts)
+               return -ENOMEM;
+
+       return part->num_parts;
 }
 
 
index 2dc5a6f..4714584 100644 (file)
@@ -66,7 +66,7 @@ out:
        return err;
 }
 
-static int __devexit bcm47xxsflash_remove(struct platform_device *pdev)
+static int bcm47xxsflash_remove(struct platform_device *pdev)
 {
        struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
 
@@ -77,7 +77,7 @@ static int __devexit bcm47xxsflash_remove(struct platform_device *pdev)
 }
 
 static struct platform_driver bcma_sflash_driver = {
-       .remove = __devexit_p(bcm47xxsflash_remove),
+       .remove = bcm47xxsflash_remove,
        .driver = {
                .name = "bcma_sflash",
                .owner = THIS_MODULE,
index 681e2ee..e081bfe 100644 (file)
@@ -62,6 +62,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
                                memset(page_address(page), 0xff, PAGE_SIZE);
                                set_page_dirty(page);
                                unlock_page(page);
+                               balance_dirty_pages_ratelimited(mapping);
                                break;
                        }
 
@@ -152,6 +153,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
                        memcpy(page_address(page) + offset, buf, cpylen);
                        set_page_dirty(page);
                        unlock_page(page);
+                       balance_dirty_pages_ratelimited(mapping);
                }
                page_cache_release(page);
 
@@ -433,7 +435,7 @@ static int __init block2mtd_init(void)
 }
 
 
-static void __devexit block2mtd_exit(void)
+static void block2mtd_exit(void)
 {
        struct list_head *pos, *next;
 
index d34d83b..8510ccb 100644 (file)
@@ -1440,7 +1440,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
                oobdelta = mtd->ecclayout->oobavail;
                break;
        default:
-               oobdelta = 0;
+               return -EINVAL;
        }
        if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) ||
            (ofs % DOC_LAYOUT_PAGE_SIZE))
index 706b847..88b3fd3 100644 (file)
@@ -70,8 +70,6 @@ static unsigned long __initdata doc_locations[] = {
        0xe0000, 0xe2000, 0xe4000, 0xe6000,
        0xe8000, 0xea000, 0xec000, 0xee000,
 #endif /*  CONFIG_MTD_DOCPROBE_HIGH */
-#else
-#warning Unknown architecture for DiskOnChip. No default probe locations defined
 #endif
        0xffffffff };
 
index 03838ba..4eeeb2d 100644 (file)
 #define        MAX_READY_WAIT_JIFFIES  (40 * HZ)       /* M25P16 specs 40s max chip erase */
 #define        MAX_CMD_SIZE            5
 
-#ifdef CONFIG_M25PXX_USE_FAST_READ
-#define OPCODE_READ    OPCODE_FAST_READ
-#define FAST_READ_DUMMY_BYTE 1
-#else
-#define OPCODE_READ    OPCODE_NORM_READ
-#define FAST_READ_DUMMY_BYTE 0
-#endif
-
 #define JEDEC_MFR(_jedec_id)   ((_jedec_id) >> 16)
 
 /****************************************************************************/
@@ -93,6 +85,7 @@ struct m25p {
        u16                     addr_width;
        u8                      erase_opcode;
        u8                      *command;
+       bool                    fast_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -168,6 +161,7 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)
 {
        switch (JEDEC_MFR(jedec_id)) {
        case CFI_MFR_MACRONIX:
+       case 0xEF /* winbond */:
                flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
                return spi_write(flash->spi, flash->command, 1);
        default:
@@ -342,6 +336,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        struct m25p *flash = mtd_to_m25p(mtd);
        struct spi_transfer t[2];
        struct spi_message m;
+       uint8_t opcode;
 
        pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
                        __func__, (u32)from, len);
@@ -354,7 +349,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
         * Should add 1 byte DUMMY_BYTE.
         */
        t[0].tx_buf = flash->command;
-       t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
+       t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
        spi_message_add_tail(&t[0], &m);
 
        t[1].rx_buf = buf;
@@ -376,12 +371,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
         */
 
        /* Set up the write data buffer. */
-       flash->command[0] = OPCODE_READ;
+       opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
+       flash->command[0] = opcode;
        m25p_addr2cmd(flash, from, flash->command);
 
        spi_sync(flash->spi, &m);
 
-       *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE;
+       *retlen = m.actual_length - m25p_cmdsz(flash) -
+                       (flash->fast_read ? 1 : 0);
 
        mutex_unlock(&flash->lock);
 
@@ -664,7 +661,8 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
 
        /* Micron */
-       { "n25q128",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
+       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
        { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
 
        /* Spansion -- single (large) sector size only, at least
@@ -745,6 +743,8 @@ static const struct spi_device_id m25p_ids[] = {
        { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
        { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
        { "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
+       { "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
+       { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
 
        /* Catalyst / On Semiconductor -- non-JEDEC */
        { "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
@@ -756,7 +756,7 @@ static const struct spi_device_id m25p_ids[] = {
 };
 MODULE_DEVICE_TABLE(spi, m25p_ids);
 
-static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
+static const struct spi_device_id *jedec_probe(struct spi_device *spi)
 {
        int                     tmp;
        u8                      code = OPCODE_RDID;
@@ -801,7 +801,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
  * matches what the READ command supports, at least until this driver
  * understands FAST_READ (for clocks over 25 MHz).
  */
-static int __devinit m25p_probe(struct spi_device *spi)
+static int m25p_probe(struct spi_device *spi)
 {
        const struct spi_device_id      *id = spi_get_device_id(spi);
        struct flash_platform_data      *data;
@@ -809,9 +809,10 @@ static int __devinit m25p_probe(struct spi_device *spi)
        struct flash_info               *info;
        unsigned                        i;
        struct mtd_part_parser_data     ppdata;
+       struct device_node __maybe_unused *np = spi->dev.of_node;
 
 #ifdef CONFIG_MTD_OF_PARTS
-       if (!of_device_is_available(spi->dev.of_node))
+       if (!of_device_is_available(np))
                return -ENODEV;
 #endif
 
@@ -863,7 +864,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
        flash = kzalloc(sizeof *flash, GFP_KERNEL);
        if (!flash)
                return -ENOMEM;
-       flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
+       flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
+                                       GFP_KERNEL);
        if (!flash->command) {
                kfree(flash);
                return -ENOMEM;
@@ -920,6 +922,16 @@ static int __devinit m25p_probe(struct spi_device *spi)
        flash->page_size = info->page_size;
        flash->mtd.writebufsize = flash->page_size;
 
+       flash->fast_read = false;
+#ifdef CONFIG_OF
+       if (np && of_property_read_bool(np, "m25p,fast-read"))
+               flash->fast_read = true;
+#endif
+
+#ifdef CONFIG_M25PXX_USE_FAST_READ
+       flash->fast_read = true;
+#endif
+
        if (info->addr_width)
                flash->addr_width = info->addr_width;
        else {
@@ -961,7 +973,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
 }
 
 
-static int __devexit m25p_remove(struct spi_device *spi)
+static int m25p_remove(struct spi_device *spi)
 {
        struct m25p     *flash = dev_get_drvdata(&spi->dev);
        int             status;
@@ -983,7 +995,7 @@ static struct spi_driver m25p80_driver = {
        },
        .id_table       = m25p_ids,
        .probe  = m25p_probe,
-       .remove = __devexit_p(m25p_remove),
+       .remove = m25p_remove,
 
        /* REVISIT: many of these chips have deep power-down modes, which
         * should clearly be entered on suspend() to minimize power use.
index 928fb0e..ea7ea7b 100644 (file)
@@ -618,7 +618,7 @@ static char *otp_setup(struct mtd_info *device, char revision)
 /*
  * Register DataFlash device with MTD subsystem.
  */
-static int __devinit
+static int
 add_dataflash_otp(struct spi_device *spi, char *name,
                int nr_pages, int pagesize, int pageoffset, char revision)
 {
@@ -679,7 +679,7 @@ add_dataflash_otp(struct spi_device *spi, char *name,
        return err;
 }
 
-static inline int __devinit
+static inline int
 add_dataflash(struct spi_device *spi, char *name,
                int nr_pages, int pagesize, int pageoffset)
 {
@@ -705,7 +705,7 @@ struct flash_info {
 #define IS_POW2PS      0x0001          /* uses 2^N byte pages */
 };
 
-static struct flash_info __devinitdata dataflash_data [] = {
+static struct flash_info dataflash_data[] = {
 
        /*
         * NOTE:  chips with SUP_POW2PS (rev D and up) need two entries,
@@ -740,7 +740,7 @@ static struct flash_info __devinitdata dataflash_data [] = {
        { "at45db642d",  0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
 };
 
-static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
+static struct flash_info *jedec_probe(struct spi_device *spi)
 {
        int                     tmp;
        uint8_t                 code = OP_READ_ID;
@@ -823,7 +823,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
  *   AT45DB0642  64Mbit  (8M)    xx111xxx (0x3c)   8192   1056     11
  *   AT45DB1282  128Mbit (16M)   xx0100xx (0x10)  16384   1056     11
  */
-static int __devinit dataflash_probe(struct spi_device *spi)
+static int dataflash_probe(struct spi_device *spi)
 {
        int status;
        struct flash_info       *info;
@@ -897,7 +897,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)
        return status;
 }
 
-static int __devexit dataflash_remove(struct spi_device *spi)
+static int dataflash_remove(struct spi_device *spi)
 {
        struct dataflash        *flash = dev_get_drvdata(&spi->dev);
        int                     status;
@@ -920,7 +920,7 @@ static struct spi_driver dataflash_driver = {
        },
 
        .probe          = dataflash_probe,
-       .remove         = __devexit_p(dataflash_remove),
+       .remove         = dataflash_remove,
 
        /* FIXME:  investigate suspend and resume... */
 };
index dcc3c95..2d2c2a5 100644 (file)
@@ -756,7 +756,7 @@ err_probe:
 
 
 #ifdef CONFIG_OF
-static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
+static int spear_smi_probe_config_dt(struct platform_device *pdev,
                                               struct device_node *np)
 {
        struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev);
@@ -799,7 +799,7 @@ static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
        return 0;
 }
 #else
-static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
+static int spear_smi_probe_config_dt(struct platform_device *pdev,
                                               struct device_node *np)
 {
        return -ENOSYS;
@@ -901,7 +901,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev,
  * and do proper init for any found one.
  * Returns 0 on success, non zero otherwise
  */
-static int __devinit spear_smi_probe(struct platform_device *pdev)
+static int spear_smi_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct spear_smi_plat_data *pdata = NULL;
@@ -1016,7 +1016,7 @@ err:
  *
  * free all allocations and delete the partitions.
  */
-static int __devexit spear_smi_remove(struct platform_device *pdev)
+static int spear_smi_remove(struct platform_device *pdev)
 {
        struct spear_smi *dev;
        struct spear_snor_flash *flash;
@@ -1092,20 +1092,9 @@ static struct platform_driver spear_smi_driver = {
 #endif
        },
        .probe = spear_smi_probe,
-       .remove = __devexit_p(spear_smi_remove),
+       .remove = spear_smi_remove,
 };
-
-static int spear_smi_init(void)
-{
-       return platform_driver_register(&spear_smi_driver);
-}
-module_init(spear_smi_init);
-
-static void spear_smi_exit(void)
-{
-       platform_driver_unregister(&spear_smi_driver);
-}
-module_exit(spear_smi_exit);
+module_platform_driver(spear_smi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
index ab8a2f4..8091b01 100644 (file)
@@ -64,7 +64,7 @@ struct flash_info {
 
 #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd)
 
-static struct flash_info __devinitdata sst25l_flash_info[] = {
+static struct flash_info sst25l_flash_info[] = {
        {"sst25lf020a", 0xbf43, 256, 1024, 4096},
        {"sst25lf040a", 0xbf44, 256, 2048, 4096},
 };
@@ -313,7 +313,7 @@ out:
        return ret;
 }
 
-static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi)
+static struct flash_info *sst25l_match_device(struct spi_device *spi)
 {
        struct flash_info *flash_info = NULL;
        struct spi_message m;
@@ -353,7 +353,7 @@ static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi)
        return flash_info;
 }
 
-static int __devinit sst25l_probe(struct spi_device *spi)
+static int sst25l_probe(struct spi_device *spi)
 {
        struct flash_info *flash_info;
        struct sst25l_flash *flash;
@@ -411,7 +411,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)
        return 0;
 }
 
-static int __devexit sst25l_remove(struct spi_device *spi)
+static int sst25l_remove(struct spi_device *spi)
 {
        struct sst25l_flash *flash = dev_get_drvdata(&spi->dev);
        int ret;
@@ -428,7 +428,7 @@ static struct spi_driver sst25l_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = sst25l_probe,
-       .remove         = __devexit_p(sst25l_remove),
+       .remove         = sst25l_remove,
 };
 
 module_spi_driver(sst25l_driver);
index df30486..62ba82c 100644 (file)
@@ -358,13 +358,6 @@ config MTD_IXP2000
          IXP2000 based board and would like to use the flash chips on it,
          say 'Y'.
 
-config MTD_FORTUNET
-       tristate "CFI Flash device mapped on the FortuNet board"
-       depends on MTD_CFI && SA1100_FORTUNET
-       help
-         This enables access to the Flash on the FortuNet board.  If you
-         have such a board, say 'Y'.
-
 config MTD_AUTCPU12
        bool "NV-RAM mapping AUTCPU12 board"
        depends on ARCH_AUTCPU12
index a0240ed..4ded287 100644 (file)
@@ -39,7 +39,6 @@ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)          += pci.o
 obj-$(CONFIG_MTD_AUTCPU12)     += autcpu12-nvram.o
 obj-$(CONFIG_MTD_IMPA7)                += impa7.o
-obj-$(CONFIG_MTD_FORTUNET)     += fortunet.o
 obj-$(CONFIG_MTD_UCLINUX)      += uclinux.o
 obj-$(CONFIG_MTD_NETtel)       += nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)   += scb2_flash.o
index e2875d6..f7207b0 100644 (file)
@@ -100,8 +100,8 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
 }
 
 
-static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
-       const struct pci_device_id *ent)
+static int amd76xrom_init_one(struct pci_dev *pdev,
+                             const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
        u8 byte;
@@ -289,7 +289,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
 }
 
 
-static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
+static void amd76xrom_remove_one(struct pci_dev *pdev)
 {
        struct amd76xrom_window *window = &amd76xrom_window;
 
@@ -347,4 +347,3 @@ module_exit(cleanup_amd76xrom);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
 MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge");
-
index 76fb594..a2dc2ae 100644 (file)
@@ -33,7 +33,7 @@ struct autcpu12_nvram_priv {
        struct map_info map;
 };
 
-static int __devinit autcpu12_nvram_probe(struct platform_device *pdev)
+static int autcpu12_nvram_probe(struct platform_device *pdev)
 {
        map_word tmp, save0, save1;
        struct resource *res;
@@ -105,7 +105,7 @@ static int __devinit autcpu12_nvram_probe(struct platform_device *pdev)
        return -ENOMEM;
 }
 
-static int __devexit autcpu12_nvram_remove(struct platform_device *pdev)
+static int autcpu12_nvram_remove(struct platform_device *pdev)
 {
        struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev);
 
@@ -121,7 +121,7 @@ static struct platform_driver autcpu12_nvram_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = autcpu12_nvram_probe,
-       .remove         = __devexit_p(autcpu12_nvram_remove),
+       .remove         = autcpu12_nvram_remove,
 };
 module_platform_driver(autcpu12_nvram_driver);
 
index ef5cde8..f833edf 100644 (file)
@@ -30,7 +30,8 @@
 #include <linux/io.h>
 #include <asm/unaligned.h>
 
-#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
+#define pr_devinit(fmt, args...) \
+               ({ static const char __fmt[] = fmt; printk(__fmt, ## args); })
 
 #define DRIVER_NAME "bfin-async-flash"
 
@@ -123,7 +124,7 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi
 
 static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
 
-static int __devinit bfin_flash_probe(struct platform_device *pdev)
+static int bfin_flash_probe(struct platform_device *pdev)
 {
        int ret;
        struct physmap_flash_data *pdata = pdev->dev.platform_data;
@@ -172,7 +173,7 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __devexit bfin_flash_remove(struct platform_device *pdev)
+static int bfin_flash_remove(struct platform_device *pdev)
 {
        struct async_state *state = platform_get_drvdata(pdev);
        gpio_free(state->enet_flash_pin);
@@ -184,7 +185,7 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)
 
 static struct platform_driver bfin_flash_driver = {
        .probe          = bfin_flash_probe,
-       .remove         = __devexit_p(bfin_flash_remove),
+       .remove         = bfin_flash_remove,
        .driver         = {
                .name   = DRIVER_NAME,
        },
index 3d0e762..586a1c7 100644 (file)
@@ -112,8 +112,8 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window)
 }
 
 
-static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
-                                        const struct pci_device_id *ent)
+static int ck804xrom_init_one(struct pci_dev *pdev,
+                             const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
        u8 byte;
@@ -320,7 +320,7 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
 }
 
 
-static void __devexit ck804xrom_remove_one (struct pci_dev *pdev)
+static void ck804xrom_remove_one(struct pci_dev *pdev)
 {
        struct ck804xrom_window *window = &ck804xrom_window;
 
index 08322b1..ff8681a 100644 (file)
@@ -144,7 +144,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window)
        pci_dev_put(window->pdev);
 }
 
-static int __devinit esb2rom_init_one(struct pci_dev *pdev,
+static int esb2rom_init_one(struct pci_dev *pdev,
                                      const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
@@ -378,13 +378,13 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
        return 0;
 }
 
-static void __devexit esb2rom_remove_one (struct pci_dev *pdev)
+static void esb2rom_remove_one(struct pci_dev *pdev)
 {
        struct esb2rom_window *window = &esb2rom_window;
        esb2rom_cleanup(window);
 }
 
-static struct pci_device_id esb2rom_pci_tbl[] __devinitdata = {
+static struct pci_device_id esb2rom_pci_tbl[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
          PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
deleted file mode 100644 (file)
index 956e2e4..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/* fortunet.c memory map
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#define MAX_NUM_REGIONS                4
-#define MAX_NUM_PARTITIONS     8
-
-#define DEF_WINDOW_ADDR_PHY    0x00000000
-#define DEF_WINDOW_SIZE                0x00800000              // 8 Mega Bytes
-
-#define MTD_FORTUNET_PK                "MTD FortuNet: "
-
-#define MAX_NAME_SIZE          128
-
-struct map_region
-{
-       int                     window_addr_physical;
-       int                     altbankwidth;
-       struct map_info         map_info;
-       struct mtd_info         *mymtd;
-       struct mtd_partition    parts[MAX_NUM_PARTITIONS];
-       char                    map_name[MAX_NAME_SIZE];
-       char                    parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
-};
-
-static struct map_region       map_regions[MAX_NUM_REGIONS];
-static int                     map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
-static int                     map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
-
-
-
-struct map_info default_map = {
-       .size = DEF_WINDOW_SIZE,
-       .bankwidth = 4,
-};
-
-static char * __init get_string_option(char *dest,int dest_size,char *sor)
-{
-       if(!dest_size)
-               return sor;
-       dest_size--;
-       while(*sor)
-       {
-               if(*sor==',')
-               {
-                       sor++;
-                       break;
-               }
-               else if(*sor=='\"')
-               {
-                       sor++;
-                       while(*sor)
-                       {
-                               if(*sor=='\"')
-                               {
-                                       sor++;
-                                       break;
-                               }
-                               *dest = *sor;
-                               dest++;
-                               sor++;
-                               dest_size--;
-                               if(!dest_size)
-                               {
-                                       *dest = 0;
-                                       return sor;
-                               }
-                       }
-               }
-               else
-               {
-                       *dest = *sor;
-                       dest++;
-                       sor++;
-                       dest_size--;
-                       if(!dest_size)
-                       {
-                               *dest = 0;
-                               return sor;
-                       }
-               }
-       }
-       *dest = 0;
-       return sor;
-}
-
-static int __init MTD_New_Region(char *line)
-{
-       char    string[MAX_NAME_SIZE];
-       int     params[6];
-       get_options (get_string_option(string,sizeof(string),line),6,params);
-       if(params[0]<1)
-       {
-               printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
-                       " name,region-number[,base,size,bankwidth,altbankwidth]\n");
-               return 1;
-       }
-       if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
-       {
-               printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
-                       params[1],MAX_NUM_REGIONS-1);
-               return 1;
-       }
-       memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
-       memcpy(&map_regions[params[1]].map_info,
-               &default_map,sizeof(map_regions[params[1]].map_info));
-        map_regions_set[params[1]] = 1;
-        map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
-        map_regions[params[1]].altbankwidth = 2;
-        map_regions[params[1]].mymtd = NULL;
-       map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
-       strcpy(map_regions[params[1]].map_info.name,string);
-       if(params[0]>1)
-       {
-               map_regions[params[1]].window_addr_physical = params[2];
-       }
-       if(params[0]>2)
-       {
-               map_regions[params[1]].map_info.size = params[3];
-       }
-       if(params[0]>3)
-       {
-               map_regions[params[1]].map_info.bankwidth = params[4];
-       }
-       if(params[0]>4)
-       {
-               map_regions[params[1]].altbankwidth = params[5];
-       }
-       return 1;
-}
-
-static int __init MTD_New_Partition(char *line)
-{
-       char    string[MAX_NAME_SIZE];
-       int     params[4];
-       get_options (get_string_option(string,sizeof(string),line),4,params);
-       if(params[0]<3)
-       {
-               printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
-                       " name,region-number,size,offset\n");
-               return 1;
-       }
-       if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
-       {
-               printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
-                       params[1],MAX_NUM_REGIONS-1);
-               return 1;
-       }
-       if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
-       {
-               printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
-               return 1;
-       }
-       map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
-               map_regions[params[1]]. parts_name[map_regions_parts[params[1]]];
-       strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
-       map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
-               params[2];
-       map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
-               params[3];
-       map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
-       map_regions_parts[params[1]]++;
-       return 1;
-}
-
-__setup("MTD_Region=", MTD_New_Region);
-__setup("MTD_Partition=", MTD_New_Partition);
-
-/* Backwards-spelling-compatibility */
-__setup("MTD_Partion=", MTD_New_Partition);
-
-static int __init init_fortunet(void)
-{
-       int     ix,iy;
-       for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
-       {
-               if(map_regions_parts[ix]&&(!map_regions_set[ix]))
-               {
-                       printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
-                               ix);
-                       memset(&map_regions[ix],0,sizeof(map_regions[ix]));
-                       memcpy(&map_regions[ix].map_info,&default_map,
-                               sizeof(map_regions[ix].map_info));
-                       map_regions_set[ix] = 1;
-                       map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
-                       map_regions[ix].altbankwidth = 2;
-                       map_regions[ix].mymtd = NULL;
-                       map_regions[ix].map_info.name = map_regions[ix].map_name;
-                       strcpy(map_regions[ix].map_info.name,"FORTUNET");
-               }
-               if(map_regions_set[ix])
-               {
-                       iy++;
-                       printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
-                               " address %x size %x\n",
-                               map_regions[ix].map_info.name,
-                               map_regions[ix].window_addr_physical,
-                               map_regions[ix].map_info.size);
-
-                       map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
-
-                       map_regions[ix].map_info.virt =
-                               ioremap_nocache(
-                               map_regions[ix].window_addr_physical,
-                               map_regions[ix].map_info.size);
-                       if(!map_regions[ix].map_info.virt)
-                       {
-                               int j = 0;
-                               printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
-                                       map_regions[ix].map_info.name);
-                               for (j = 0 ; j < ix; j++)
-                                       iounmap(map_regions[j].map_info.virt);
-                               return -ENXIO;
-                       }
-                       simple_map_init(&map_regions[ix].map_info);
-
-                       printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
-                               map_regions[ix].map_info.name,
-                               map_regions[ix].map_info.virt);
-                       map_regions[ix].mymtd = do_map_probe("cfi_probe",
-                               &map_regions[ix].map_info);
-                       if((!map_regions[ix].mymtd)&&(
-                               map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth))
-                       {
-                               printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth "
-                                       "for %s flash.\n",
-                                       map_regions[ix].map_info.name);
-                               map_regions[ix].map_info.bankwidth =
-                                       map_regions[ix].altbankwidth;
-                               map_regions[ix].mymtd = do_map_probe("cfi_probe",
-                                       &map_regions[ix].map_info);
-                       }
-                       map_regions[ix].mymtd->owner = THIS_MODULE;
-                       mtd_device_register(map_regions[ix].mymtd,
-                                           map_regions[ix].parts,
-                                           map_regions_parts[ix]);
-               }
-       }
-       if(iy)
-               return 0;
-       return -ENXIO;
-}
-
-static void __exit cleanup_fortunet(void)
-{
-       int     ix;
-       for(ix=0;ix<MAX_NUM_REGIONS;ix++)
-       {
-               if(map_regions_set[ix])
-               {
-                       if( map_regions[ix].mymtd )
-                       {
-                               mtd_device_unregister(map_regions[ix].mymtd);
-                               map_destroy( map_regions[ix].mymtd );
-                       }
-                       iounmap((void *)map_regions[ix].map_info.virt);
-               }
-       }
-}
-
-module_init(init_fortunet);
-module_exit(cleanup_fortunet);
-
-MODULE_AUTHOR("FortuNet, Inc.");
-MODULE_DESCRIPTION("MTD map driver for FortuNet boards");
index e4de96b..7b643de 100644 (file)
@@ -26,7 +26,8 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
-#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
+#define pr_devinit(fmt, args...) \
+       ({ static const char __fmt[] = fmt; printk(__fmt, ## args); })
 
 #define DRIVER_NAME "gpio-addr-flash"
 #define PFX DRIVER_NAME ": "
@@ -142,7 +143,8 @@ static void gf_write(struct map_info *map, map_word d1, unsigned long ofs)
  *
  * See gf_copy_from() caveat.
  */
-static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+static void gf_copy_to(struct map_info *map, unsigned long to,
+                      const void *from, ssize_t len)
 {
        struct async_state *state = gf_map_info_to_state(map);
 
@@ -185,7 +187,7 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  *     ...
  * };
  */
-static int __devinit gpio_flash_probe(struct platform_device *pdev)
+static int gpio_flash_probe(struct platform_device *pdev)
 {
        size_t i, arr_size;
        struct physmap_flash_data *pdata;
@@ -258,7 +260,7 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __devexit gpio_flash_remove(struct platform_device *pdev)
+static int gpio_flash_remove(struct platform_device *pdev)
 {
        struct async_state *state = platform_get_drvdata(pdev);
        size_t i = 0;
@@ -273,7 +275,7 @@ static int __devexit gpio_flash_remove(struct platform_device *pdev)
 
 static struct platform_driver gpio_flash_driver = {
        .probe          = gpio_flash_probe,
-       .remove         = __devexit_p(gpio_flash_remove),
+       .remove         = gpio_flash_remove,
        .driver         = {
                .name   = DRIVER_NAME,
        },
index 6689dcb..c7478e1 100644 (file)
@@ -84,8 +84,8 @@ static void ichxrom_cleanup(struct ichxrom_window *window)
 }
 
 
-static int __devinit ichxrom_init_one (struct pci_dev *pdev,
-       const struct pci_device_id *ent)
+static int ichxrom_init_one(struct pci_dev *pdev,
+                           const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
        struct ichxrom_window *window = &ichxrom_window;
@@ -315,13 +315,13 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
 }
 
 
-static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
+static void ichxrom_remove_one(struct pci_dev *pdev)
 {
        struct ichxrom_window *window = &ichxrom_window;
        ichxrom_cleanup(window);
 }
 
-static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
+static struct pci_device_id ichxrom_pci_tbl[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
          PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
index 93f0317..3ee2ad1 100644 (file)
@@ -63,24 +63,24 @@ struct vr_nor_mtd {
 #define TIMING_BYTE_EN         (1 <<  0)       /* 8-bit vs 16-bit bus */
 #define TIMING_MASK            0x3FFF0000
 
-static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p)
+static void vr_nor_destroy_partitions(struct vr_nor_mtd *p)
 {
        mtd_device_unregister(p->info);
 }
 
-static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p)
+static int vr_nor_init_partitions(struct vr_nor_mtd *p)
 {
        /* register the flash bank */
        /* partition the flash bank */
        return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0);
 }
 
-static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
+static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
 {
        map_destroy(p->info);
 }
 
-static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p)
+static int vr_nor_mtd_setup(struct vr_nor_mtd *p)
 {
        static const char *probe_types[] =
            { "cfi_probe", "jedec_probe", NULL };
@@ -96,7 +96,7 @@ static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p)
        return 0;
 }
 
-static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p)
+static void vr_nor_destroy_maps(struct vr_nor_mtd *p)
 {
        unsigned int exp_timing_cs0;
 
@@ -116,7 +116,7 @@ static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p)
  * Initialize the map_info structure and map the flash.
  * Returns 0 on success, nonzero otherwise.
  */
-static int __devinit vr_nor_init_maps(struct vr_nor_mtd *p)
+static int vr_nor_init_maps(struct vr_nor_mtd *p)
 {
        unsigned long csr_phys, csr_len;
        unsigned long win_phys, win_len;
@@ -176,7 +176,7 @@ static struct pci_device_id vr_nor_pci_ids[] = {
        {0,}
 };
 
-static void __devexit vr_nor_pci_remove(struct pci_dev *dev)
+static void vr_nor_pci_remove(struct pci_dev *dev)
 {
        struct vr_nor_mtd *p = pci_get_drvdata(dev);
 
@@ -189,7 +189,7 @@ static void __devexit vr_nor_pci_remove(struct pci_dev *dev)
        pci_disable_device(dev);
 }
 
-static int __devinit
+static int
 vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
        struct vr_nor_mtd *p = NULL;
@@ -256,7 +256,7 @@ vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 static struct pci_driver vr_nor_pci_driver = {
        .name = DRV_NAME,
        .probe = vr_nor_pci_probe,
-       .remove = __devexit_p(vr_nor_pci_remove),
+       .remove = vr_nor_pci_remove,
        .id_table = vr_nor_pci_ids,
 };
 
index c03456f..3c3c791 100644 (file)
@@ -45,7 +45,7 @@ struct ltq_mtd {
 };
 
 static const char ltq_map_name[] = "ltq_nor";
-static const char *ltq_probe_types[] __devinitconst = {
+static const char *ltq_probe_types[] = {
                                        "cmdlinepart", "ofpart", NULL };
 
 static map_word
@@ -109,7 +109,7 @@ ltq_copy_to(struct map_info *map, unsigned long to,
        spin_unlock_irqrestore(&ebu_lock, flags);
 }
 
-static int __devinit
+static int
 ltq_mtd_probe(struct platform_device *pdev)
 {
        struct mtd_part_parser_data ppdata;
@@ -185,7 +185,7 @@ err_out:
        return err;
 }
 
-static int __devexit
+static int
 ltq_mtd_remove(struct platform_device *pdev)
 {
        struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
@@ -209,7 +209,7 @@ MODULE_DEVICE_TABLE(of, ltq_mtd_match);
 
 static struct platform_driver ltq_mtd_driver = {
        .probe = ltq_mtd_probe,
-       .remove = __devexit_p(ltq_mtd_remove),
+       .remove = ltq_mtd_remove,
        .driver = {
                .name = "ltq-nor",
                .owner = THIS_MODULE,
index 3c7ad17..ab0fead 100644 (file)
@@ -125,7 +125,7 @@ static int latch_addr_flash_remove(struct platform_device *dev)
        return 0;
 }
 
-static int __devinit latch_addr_flash_probe(struct platform_device *dev)
+static int latch_addr_flash_probe(struct platform_device *dev)
 {
        struct latch_addr_flash_data *latch_addr_data;
        struct latch_addr_flash_info *info;
@@ -218,7 +218,7 @@ done:
 
 static struct platform_driver latch_addr_flash_driver = {
        .probe          = latch_addr_flash_probe,
-       .remove         = __devexit_p(latch_addr_flash_remove),
+       .remove         = latch_addr_flash_remove,
        .driver         = {
                .name   = DRIVER_NAME,
        },
index 1c30c1a..ed82914 100644 (file)
@@ -253,7 +253,7 @@ static struct pci_device_id mtd_pci_ids[] = {
  * Generic code follows.
  */
 
-static int __devinit
+static int
 mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
        struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data;
@@ -308,7 +308,7 @@ out:
        return err;
 }
 
-static void __devexit
+static void
 mtd_pci_remove(struct pci_dev *dev)
 {
        struct mtd_info *mtd = pci_get_drvdata(dev);
@@ -326,7 +326,7 @@ mtd_pci_remove(struct pci_dev *dev)
 static struct pci_driver mtd_pci_driver = {
        .name =         "MTD PCI",
        .probe =        mtd_pci_probe,
-       .remove =       __devexit_p(mtd_pci_remove),
+       .remove =       mtd_pci_remove,
        .id_table =     mtd_pci_ids,
 };
 
index 6f19aca..37cdc20 100644 (file)
@@ -77,7 +77,7 @@ static int of_flash_remove(struct platform_device *dev)
 /* Helper function to handle probing of the obsolete "direct-mapped"
  * compatible binding, which has an extra "probe-type" property
  * describing the type of flash probe necessary. */
-static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
+static struct mtd_info *obsolete_probe(struct platform_device *dev,
                                                  struct map_info *map)
 {
        struct device_node *dp = dev->dev.of_node;
@@ -116,7 +116,7 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
    information. */
 static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
                                        "ofpart", "ofoldpart", NULL };
-static const char ** __devinit of_get_probes(struct device_node *dp)
+static const char **of_get_probes(struct device_node *dp)
 {
        const char *cp;
        int cplen;
@@ -145,14 +145,14 @@ static const char ** __devinit of_get_probes(struct device_node *dp)
        return res;
 }
 
-static void __devinit of_free_probes(const char **probes)
+static void of_free_probes(const char **probes)
 {
        if (probes != part_probe_types_def)
                kfree(probes);
 }
 
 static struct of_device_id of_flash_match[];
-static int __devinit of_flash_probe(struct platform_device *dev)
+static int of_flash_probe(struct platform_device *dev)
 {
        const char **part_probe_types;
        const struct of_device_id *match;
@@ -170,6 +170,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        resource_size_t res_size;
        struct mtd_part_parser_data ppdata;
        bool map_indirect;
+       const char *mtd_name;
 
        match = of_match_device(of_flash_match, &dev->dev);
        if (!match)
@@ -178,6 +179,8 @@ static int __devinit of_flash_probe(struct platform_device *dev)
 
        reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);
 
+       of_property_read_string(dp, "linux,mtd-name", &mtd_name);
+
        /*
         * Get number of "reg" tuples. Scan for MTD devices on area's
         * described by each "reg" region. This makes it possible (including
@@ -234,7 +237,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
                        goto err_out;
                }
 
-               info->list[i].map.name = dev_name(&dev->dev);
+               info->list[i].map.name = mtd_name ?: dev_name(&dev->dev);
                info->list[i].map.phys = res.start;
                info->list[i].map.size = res_size;
                info->list[i].map.bankwidth = be32_to_cpup(width);
@@ -282,6 +285,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        }
 
        err = 0;
+       info->cmtd = NULL;
        if (info->list_size == 1) {
                info->cmtd = info->list[0].mtd;
        } else if (info->list_size > 1) {
@@ -290,9 +294,10 @@ static int __devinit of_flash_probe(struct platform_device *dev)
                 */
                info->cmtd = mtd_concat_create(mtd_list, info->list_size,
                                               dev_name(&dev->dev));
-               if (info->cmtd == NULL)
-                       err = -ENXIO;
        }
+       if (info->cmtd == NULL)
+               err = -ENXIO;
+
        if (err)
                goto err_out;
 
index 65bd1cd..afea93b 100644 (file)
@@ -58,7 +58,7 @@ static void pismo_set_vpp(struct platform_device *pdev, int on)
        pismo->vpp(pismo->vpp_data, on);
 }
 
-static unsigned int __devinit pismo_width_to_bytes(unsigned int width)
+static unsigned int pismo_width_to_bytes(unsigned int width)
 {
        width &= 15;
        if (width > 2)
@@ -66,7 +66,7 @@ static unsigned int __devinit pismo_width_to_bytes(unsigned int width)
        return 1 << width;
 }
 
-static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf,
+static int pismo_eeprom_read(struct i2c_client *client, void *buf,
        u8 addr, size_t size)
 {
        int ret;
@@ -88,7 +88,7 @@ static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf,
        return ret == ARRAY_SIZE(msg) ? size : -EIO;
 }
 
-static int __devinit pismo_add_device(struct pismo_data *pismo, int i,
+static int pismo_add_device(struct pismo_data *pismo, int i,
        struct pismo_mem *region, const char *name, void *pdata, size_t psize)
 {
        struct platform_device *dev;
@@ -129,7 +129,7 @@ static int __devinit pismo_add_device(struct pismo_data *pismo, int i,
        return ret;
 }
 
-static int __devinit pismo_add_nor(struct pismo_data *pismo, int i,
+static int pismo_add_nor(struct pismo_data *pismo, int i,
        struct pismo_mem *region)
 {
        struct physmap_flash_data data = {
@@ -143,7 +143,7 @@ static int __devinit pismo_add_nor(struct pismo_data *pismo, int i,
                &data, sizeof(data));
 }
 
-static int __devinit pismo_add_sram(struct pismo_data *pismo, int i,
+static int pismo_add_sram(struct pismo_data *pismo, int i,
        struct pismo_mem *region)
 {
        struct platdata_mtd_ram data = {
@@ -154,7 +154,7 @@ static int __devinit pismo_add_sram(struct pismo_data *pismo, int i,
                &data, sizeof(data));
 }
 
-static void __devinit pismo_add_one(struct pismo_data *pismo, int i,
+static void pismo_add_one(struct pismo_data *pismo, int i,
        const struct pismo_cs_block *cs, phys_addr_t base)
 {
        struct device *dev = &pismo->client->dev;
@@ -197,7 +197,7 @@ static void __devinit pismo_add_one(struct pismo_data *pismo, int i,
        }
 }
 
-static int __devexit pismo_remove(struct i2c_client *client)
+static int pismo_remove(struct i2c_client *client)
 {
        struct pismo_data *pismo = i2c_get_clientdata(client);
        int i;
@@ -210,7 +210,7 @@ static int __devexit pismo_remove(struct i2c_client *client)
        return 0;
 }
 
-static int __devinit pismo_probe(struct i2c_client *client,
+static int pismo_probe(struct i2c_client *client,
                                 const struct i2c_device_id *id)
 {
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -267,7 +267,7 @@ static struct i2c_driver pismo_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = pismo_probe,
-       .remove         = __devexit_p(pismo_remove),
+       .remove         = pismo_remove,
        .id_table       = pismo_id,
 };
 
index 81884c2..43e3dbb 100644 (file)
@@ -49,7 +49,7 @@ struct pxa2xx_flash_info {
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 
-static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
+static int pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
@@ -105,7 +105,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
+static int pxa2xx_flash_remove(struct platform_device *dev)
 {
        struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 
@@ -139,7 +139,7 @@ static struct platform_driver pxa2xx_flash_driver = {
                .owner          = THIS_MODULE,
        },
        .probe          = pxa2xx_flash_probe,
-       .remove         = __devexit_p(pxa2xx_flash_remove),
+       .remove         = pxa2xx_flash_remove,
        .shutdown       = pxa2xx_flash_shutdown,
 };
 
index a675bdb..f694417 100644 (file)
@@ -149,8 +149,8 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
                plat->exit();
 }
 
-static struct sa_info *__devinit
-sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
+static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev,
+                                       struct flash_platform_data *plat)
 {
        struct sa_info *info;
        int nr, size, i, ret = 0;
@@ -246,7 +246,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
 
 static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 
-static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
+static int sa1100_mtd_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *plat = pdev->dev.platform_data;
        struct sa_info *info;
index 9dcbc68..7179613 100644 (file)
@@ -69,7 +69,7 @@ static struct map_info scb2_map = {
 };
 static int region_fail;
 
-static int __devinit
+static int
 scb2_fixup_mtd(struct mtd_info *mtd)
 {
        int i;
@@ -133,7 +133,7 @@ scb2_fixup_mtd(struct mtd_info *mtd)
 /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */
 #define CSB5_FCR       0x41
 #define CSB5_FCR_DECODE_ALL 0x0e
-static int __devinit
+static int
 scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 {
        u8 reg;
@@ -197,7 +197,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)
        return 0;
 }
 
-static void __devexit
+static void
 scb2_flash_remove(struct pci_dev *dev)
 {
        if (!scb2_mtd)
@@ -231,7 +231,7 @@ static struct pci_driver scb2_flash_driver = {
        .name =     "Intel SCB2 BIOS Flash",
        .id_table = scb2_flash_pci_ids,
        .probe =    scb2_flash_probe,
-       .remove =   __devexit_p(scb2_flash_remove),
+       .remove =   scb2_flash_remove,
 };
 
 module_pci_driver(scb2_flash_driver);
index 175e537..d467f3b 100644 (file)
@@ -108,7 +108,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)
        return 0;
 }
 
-static int __devinit uflash_probe(struct platform_device *op)
+static int uflash_probe(struct platform_device *op)
 {
        struct device_node *dp = op->dev.of_node;
 
@@ -121,7 +121,7 @@ static int __devinit uflash_probe(struct platform_device *op)
        return uflash_devinit(op, dp);
 }
 
-static int __devexit uflash_remove(struct platform_device *op)
+static int uflash_remove(struct platform_device *op)
 {
        struct uflash_dev *up = dev_get_drvdata(&op->dev);
 
@@ -155,7 +155,7 @@ static struct platform_driver uflash_driver = {
                .of_match_table = uflash_match,
        },
        .probe          = uflash_probe,
-       .remove         = __devexit_p(uflash_remove),
+       .remove         = uflash_remove,
 };
 
 module_platform_driver(uflash_driver);
index 2e2b094..6b223cf 100644 (file)
@@ -596,7 +596,7 @@ fail_name:
 }
 
 /* Handles very basic info about the flash, queries for details */
-static int __devinit vmu_connect(struct maple_device *mdev)
+static int vmu_connect(struct maple_device *mdev)
 {
        unsigned long test_flash_data, basic_flash_data;
        int c, error;
@@ -690,7 +690,7 @@ fail_nomem:
        return error;
 }
 
-static void __devexit vmu_disconnect(struct maple_device *mdev)
+static void vmu_disconnect(struct maple_device *mdev)
 {
        struct memcard *card;
        struct mdev_part *mpart;
@@ -772,7 +772,7 @@ static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
 }
 
 
-static int __devinit probe_maple_vmu(struct device *dev)
+static int probe_maple_vmu(struct device *dev)
 {
        int error;
        struct maple_device *mdev = to_maple_dev(dev);
@@ -789,7 +789,7 @@ static int __devinit probe_maple_vmu(struct device *dev)
        return 0;
 }
 
-static int __devexit remove_maple_vmu(struct device *dev)
+static int remove_maple_vmu(struct device *dev)
 {
        struct maple_device *mdev = to_maple_dev(dev);
 
@@ -802,7 +802,7 @@ static struct maple_driver vmu_flash_driver = {
        .drv = {
                .name =         "Dreamcast_visual_memory",
                .probe =        probe_maple_vmu,
-               .remove =       __devexit_p(remove_maple_vmu),
+               .remove =       remove_maple_vmu,
        },
 };
 
index f1f0671..5ad39bb 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/hdreg.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
-#include <linux/kthread.h>
 #include <asm/uaccess.h>
 
 #include "mtdcore.h"
@@ -121,16 +120,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 
 int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
 {
-       if (kthread_should_stop())
-               return 1;
-
        return dev->bg_stop;
 }
 EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
 
-static int mtd_blktrans_thread(void *arg)
+static void mtd_blktrans_work(struct work_struct *work)
 {
-       struct mtd_blktrans_dev *dev = arg;
+       struct mtd_blktrans_dev *dev =
+               container_of(work, struct mtd_blktrans_dev, work);
        struct mtd_blktrans_ops *tr = dev->tr;
        struct request_queue *rq = dev->rq;
        struct request *req = NULL;
@@ -138,7 +135,7 @@ static int mtd_blktrans_thread(void *arg)
 
        spin_lock_irq(rq->queue_lock);
 
-       while (!kthread_should_stop()) {
+       while (1) {
                int res;
 
                dev->bg_stop = false;
@@ -156,15 +153,7 @@ static int mtd_blktrans_thread(void *arg)
                                background_done = !dev->bg_stop;
                                continue;
                        }
-                       set_current_state(TASK_INTERRUPTIBLE);
-
-                       if (kthread_should_stop())
-                               set_current_state(TASK_RUNNING);
-
-                       spin_unlock_irq(rq->queue_lock);
-                       schedule();
-                       spin_lock_irq(rq->queue_lock);
-                       continue;
+                       break;
                }
 
                spin_unlock_irq(rq->queue_lock);
@@ -185,8 +174,6 @@ static int mtd_blktrans_thread(void *arg)
                __blk_end_request_all(req, -EIO);
 
        spin_unlock_irq(rq->queue_lock);
-
-       return 0;
 }
 
 static void mtd_blktrans_request(struct request_queue *rq)
@@ -199,10 +186,8 @@ static void mtd_blktrans_request(struct request_queue *rq)
        if (!dev)
                while ((req = blk_fetch_request(rq)) != NULL)
                        __blk_end_request_all(req, -ENODEV);
-       else {
-               dev->bg_stop = true;
-               wake_up_process(dev->thread);
-       }
+       else
+               queue_work(dev->wq, &dev->work);
 }
 
 static int blktrans_open(struct block_device *bdev, fmode_t mode)
@@ -325,7 +310,7 @@ unlock:
        return ret;
 }
 
-static const struct block_device_operations mtd_blktrans_ops = {
+static const struct block_device_operations mtd_block_ops = {
        .owner          = THIS_MODULE,
        .open           = blktrans_open,
        .release        = blktrans_release,
@@ -401,7 +386,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        gd->private_data = new;
        gd->major = tr->major;
        gd->first_minor = (new->devnum) << tr->part_bits;
-       gd->fops = &mtd_blktrans_ops;
+       gd->fops = &mtd_block_ops;
 
        if (tr->part_bits)
                if (new->devnum < 26)
@@ -437,14 +422,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
        gd->queue = new->rq;
 
-       /* Create processing thread */
-       /* TODO: workqueue ? */
-       new->thread = kthread_run(mtd_blktrans_thread, new,
-                       "%s%d", tr->name, new->mtd->index);
-       if (IS_ERR(new->thread)) {
-               ret = PTR_ERR(new->thread);
+       /* Create processing workqueue */
+       new->wq = alloc_workqueue("%s%d", 0, 0,
+                                 tr->name, new->mtd->index);
+       if (!new->wq)
                goto error4;
-       }
+       INIT_WORK(&new->work, mtd_blktrans_work);
+
        gd->driverfs_dev = &new->mtd->dev;
 
        if (new->readonly)
@@ -484,9 +468,8 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
        /* Stop new requests to arrive */
        del_gendisk(old->disk);
 
-
-       /* Stop the thread */
-       kthread_stop(old->thread);
+       /* Stop workqueue. This will perform any pending request. */
+       destroy_workqueue(old->wq);
 
        /* Kill current requests */
        spin_lock_irqsave(&old->queue_lock, flags);
index f5b3f91..97bb8f6 100644 (file)
@@ -271,7 +271,7 @@ static void find_next_position(struct mtdoops_context *cxt)
 
                if (count[0] == 0xffffffff && count[1] == 0xffffffff)
                        mark_page_unused(cxt, page);
-               if (count[0] == 0xffffffff)
+               if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC)
                        continue;
                if (maxcount == 0xffffffff) {
                        maxcount = count[0];
@@ -289,14 +289,13 @@ static void find_next_position(struct mtdoops_context *cxt)
                }
        }
        if (maxcount == 0xffffffff) {
-               cxt->nextpage = 0;
-               cxt->nextcount = 1;
-               schedule_work(&cxt->work_erase);
-               return;
+               cxt->nextpage = cxt->oops_pages - 1;
+               cxt->nextcount = 0;
+       }
+       else {
+               cxt->nextpage = maxpos;
+               cxt->nextcount = maxcount;
        }
-
-       cxt->nextpage = maxpos;
-       cxt->nextcount = maxcount;
 
        mtdoops_inc_counter(cxt);
 }
index dae191b..5819eb5 100644 (file)
@@ -50,16 +50,30 @@ config MTD_NAND_MUSEUM_IDS
          of these chips were reused by later, larger chips.
 
 config MTD_NAND_DENALI
-       depends on PCI
+        tristate "Support Denali NAND controller"
+        help
+         Enable support for the Denali NAND controller.  This should be
+         combined with either the PCI or platform drivers to provide device
+         registration.
+
+config MTD_NAND_DENALI_PCI
         tristate "Support Denali NAND controller on Intel Moorestown"
+       depends on PCI && MTD_NAND_DENALI
         help
           Enable the driver for NAND flash on Intel Moorestown, using the
           Denali NAND controller core.
+
+config MTD_NAND_DENALI_DT
+       tristate "Support Denali NAND controller as a DT device"
+       depends on HAVE_CLK && MTD_NAND_DENALI
+       help
+         Enable the driver for NAND flash on platforms using a Denali NAND
+         controller as a DT device.
+
 config MTD_NAND_DENALI_SCRATCH_REG_ADDR
         hex "Denali NAND size scratch register address"
         default "0xFF108018"
-        depends on MTD_NAND_DENALI
+        depends on MTD_NAND_DENALI_PCI
         help
           Some platforms place the NAND chip size in a scratch register
           because (some versions of) the driver aren't able to automatically
@@ -433,6 +447,14 @@ config MTD_NAND_GPMI_NAND
         block, such as SD card. So pay attention to it when you enable
         the GPMI.
 
+config MTD_NAND_BCM47XXNFLASH
+       tristate "Support for NAND flash on BCM4706 BCMA bus"
+       depends on BCMA_NFLASH
+       help
+         BCMA bus can have various flash memories attached, they are
+         registered by bcma as platform devices. This enables driver for
+         NAND flash memories. For now only BCM4706 is supported.
+
 config MTD_NAND_PLATFORM
        tristate "Support for generic platform NAND driver"
        depends on HAS_IOMEM
@@ -499,12 +521,6 @@ config MTD_NAND_MXC
          This enables the driver for the NAND flash controller on the
          MXC processors.
 
-config MTD_NAND_NOMADIK
-       tristate "ST Nomadik 8815 NAND support"
-       depends on ARCH_NOMADIK
-       help
-         Driver for the NAND flash controller on the Nomadik, with ECC.
-
 config MTD_NAND_SH_FLCTL
        tristate "Support for NAND on Renesas SuperH FLCTL"
        depends on SUPERH || ARCH_SHMOBILE
index 6c7f2b3..d76d912 100644 (file)
@@ -11,6 +11,8 @@ obj-$(CONFIG_MTD_SM_COMMON)           += sm_common.o
 obj-$(CONFIG_MTD_NAND_CAFE)            += cafe_nand.o
 obj-$(CONFIG_MTD_NAND_AMS_DELTA)       += ams-delta.o
 obj-$(CONFIG_MTD_NAND_DENALI)          += denali.o
+obj-$(CONFIG_MTD_NAND_DENALI_PCI)      += denali_pci.o
+obj-$(CONFIG_MTD_NAND_DENALI_DT)       += denali_dt.o
 obj-$(CONFIG_MTD_NAND_AU1550)          += au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)           += bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)  += ppchameleonevb.o
@@ -45,11 +47,11 @@ obj-$(CONFIG_MTD_NAND_MXC)          += mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)                += socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)       += txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)          += nuc900_nand.o
-obj-$(CONFIG_MTD_NAND_NOMADIK)         += nomadik_nand.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)     += mpc5121_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)           += r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)          += jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)       += gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)            += xway_nand.o
+obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)   += bcm47xxnflash/
 
 nand-objs := nand_base.o nand_bbt.o
index 9e7723a..f1d71cd 100644 (file)
@@ -173,7 +173,7 @@ static const struct gpio _mandatory_gpio[] = {
 /*
  * Main initialization routine
  */
-static int __devinit ams_delta_init(struct platform_device *pdev)
+static int ams_delta_init(struct platform_device *pdev)
 {
        struct nand_chip *this;
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -270,7 +270,7 @@ out_free:
 /*
  * Clean up routine
  */
-static int __devexit ams_delta_cleanup(struct platform_device *pdev)
+static int ams_delta_cleanup(struct platform_device *pdev)
 {
        void __iomem *io_base = platform_get_drvdata(pdev);
 
@@ -289,7 +289,7 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev)
 
 static struct platform_driver ams_delta_nand_driver = {
        .probe          = ams_delta_init,
-       .remove         = __devexit_p(ams_delta_cleanup),
+       .remove         = ams_delta_cleanup,
        .driver         = {
                .name   = "ams-delta-nand",
                .owner  = THIS_MODULE,
index 92623ac..90bdca6 100644 (file)
@@ -331,13 +331,13 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  *               12-bits                20-bytes                 21-bytes
  *               24-bits                39-bytes                 42-bytes
  */
-static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size)
+static int pmecc_get_ecc_bytes(int cap, int sector_size)
 {
        int m = 12 + sector_size / 512;
        return (m * cap + 7) / 8;
 }
 
-static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,
+static void pmecc_config_ecc_layout(struct nand_ecclayout *layout,
        int oobsize, int ecc_len)
 {
        int i;
@@ -353,7 +353,7 @@ static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,
                oobsize - ecc_len - layout->oobfree[0].offset;
 }
 
-static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
+static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
 {
        int table_size;
 
@@ -375,7 +375,7 @@ static void pmecc_data_free(struct atmel_nand_host *host)
        kfree(host->pmecc_delta);
 }
 
-static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
+static int pmecc_data_alloc(struct atmel_nand_host *host)
 {
        const int cap = host->pmecc_corr_cap;
 
@@ -724,6 +724,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
        struct atmel_nand_host *host = nand_chip->priv;
        int i, err_nbr, eccbytes;
        uint8_t *buf_pos;
+       int total_err = 0;
 
        eccbytes = nand_chip->ecc.bytes;
        for (i = 0; i < eccbytes; i++)
@@ -751,12 +752,13 @@ normal_check:
                                pmecc_correct_data(mtd, buf_pos, ecc, i,
                                        host->pmecc_bytes_per_sector, err_nbr);
                                mtd->ecc_stats.corrected += err_nbr;
+                               total_err += err_nbr;
                        }
                }
                pmecc_stat >>= 1;
        }
 
-       return 0;
+       return total_err;
 }
 
 static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
@@ -768,6 +770,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
        uint32_t *eccpos = chip->ecc.layout->eccpos;
        uint32_t stat;
        unsigned long end_time;
+       int bitflips = 0;
 
        pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
        pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
@@ -790,11 +793,14 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
        }
 
        stat = pmecc_readl_relaxed(host->ecc, ISR);
-       if (stat != 0)
-               if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0)
-                       return -EIO;
+       if (stat != 0) {
+               bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
+               if (bitflips < 0)
+                       /* uncorrectable errors */
+                       return 0;
+       }
 
-       return 0;
+       return bitflips;
 }
 
 static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
@@ -1206,7 +1212,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
 }
 
 #if defined(CONFIG_OF)
-static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
+static int atmel_of_init_port(struct atmel_nand_host *host,
                                         struct device_node *np)
 {
        u32 val, table_offset;
@@ -1293,7 +1299,7 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
        return 0;
 }
 #else
-static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
+static int atmel_of_init_port(struct atmel_nand_host *host,
                                         struct device_node *np)
 {
        return -EINVAL;
index 5c47b20..217459d 100644 (file)
@@ -382,7 +382,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
        while(!this->dev_ready(mtd));
 }
 
-static int __devinit find_nand_cs(unsigned long nand_base)
+static int find_nand_cs(unsigned long nand_base)
 {
        void __iomem *base =
                        (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR);
@@ -403,7 +403,7 @@ static int __devinit find_nand_cs(unsigned long nand_base)
        return -ENODEV;
 }
 
-static int __devinit au1550nd_probe(struct platform_device *pdev)
+static int au1550nd_probe(struct platform_device *pdev)
 {
        struct au1550nd_platdata *pd;
        struct au1550nd_ctx *ctx;
@@ -491,7 +491,7 @@ out1:
        return ret;
 }
 
-static int __devexit au1550nd_remove(struct platform_device *pdev)
+static int au1550nd_remove(struct platform_device *pdev)
 {
        struct au1550nd_ctx *ctx = platform_get_drvdata(pdev);
        struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -509,7 +509,7 @@ static struct platform_driver au1550nd_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = au1550nd_probe,
-       .remove         = __devexit_p(au1550nd_remove),
+       .remove         = au1550nd_remove,
 };
 
 module_platform_driver(au1550nd_driver);
diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/bcm47xxnflash/Makefile
new file mode 100644 (file)
index 0000000..f05b119
--- /dev/null
@@ -0,0 +1,4 @@
+bcm47xxnflash-y                                += main.o
+bcm47xxnflash-y                                += ops_bcm4706.o
+
+obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)   += bcm47xxnflash.o
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h
new file mode 100644 (file)
index 0000000..0bdb2ce
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __BCM47XXNFLASH_H
+#define __BCM47XXNFLASH_H
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+
+struct bcm47xxnflash {
+       struct bcma_drv_cc *cc;
+
+       struct nand_chip nand_chip;
+       struct mtd_info mtd;
+
+       unsigned curr_command;
+       int curr_page_addr;
+       int curr_column;
+
+       u8 id_data[8];
+};
+
+int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n);
+
+#endif /* BCM47XXNFLASH */
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c
new file mode 100644 (file)
index 0000000..2b8b05b
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * BCM47XX NAND flash driver
+ *
+ * Copyright (C) 2012 RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/bcma/bcma.h>
+
+#include "bcm47xxnflash.h"
+
+MODULE_DESCRIPTION("NAND flash driver for BCMA bus");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("RafaÅ‚ MiÅ‚ecki");
+
+static const char *probes[] = { "bcm47xxpart", NULL };
+
+static int bcm47xxnflash_probe(struct platform_device *pdev)
+{
+       struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+       struct bcm47xxnflash *b47n;
+       int err = 0;
+
+       b47n = kzalloc(sizeof(*b47n), GFP_KERNEL);
+       if (!b47n) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       b47n->nand_chip.priv = b47n;
+       b47n->mtd.owner = THIS_MODULE;
+       b47n->mtd.priv = &b47n->nand_chip; /* Required */
+       b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash);
+
+       if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
+               err = bcm47xxnflash_ops_bcm4706_init(b47n);
+       } else {
+               pr_err("Device not supported\n");
+               err = -ENOTSUPP;
+       }
+       if (err) {
+               pr_err("Initialization failed: %d\n", err);
+               goto err_init;
+       }
+
+       err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0);
+       if (err) {
+               pr_err("Failed to register MTD device: %d\n", err);
+               goto err_dev_reg;
+       }
+
+       return 0;
+
+err_dev_reg:
+err_init:
+       kfree(b47n);
+out:
+       return err;
+}
+
+static int __devexit bcm47xxnflash_remove(struct platform_device *pdev)
+{
+       struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+
+       if (nflash->mtd)
+               mtd_device_unregister(nflash->mtd);
+
+       return 0;
+}
+
+static struct platform_driver bcm47xxnflash_driver = {
+       .remove = __devexit_p(bcm47xxnflash_remove),
+       .driver = {
+               .name = "bcma_nflash",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init bcm47xxnflash_init(void)
+{
+       int err;
+
+       /*
+        * Platform device "bcma_nflash" exists on SoCs and is registered very
+        * early, it won't be added during runtime (use platform_driver_probe).
+        */
+       err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe);
+       if (err)
+               pr_err("Failed to register serial flash driver: %d\n", err);
+
+       return err;
+}
+
+static void __exit bcm47xxnflash_exit(void)
+{
+       platform_driver_unregister(&bcm47xxnflash_driver);
+}
+
+module_init(bcm47xxnflash_init);
+module_exit(bcm47xxnflash_exit);
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
new file mode 100644 (file)
index 0000000..86c9a79
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * BCM47XX NAND flash driver
+ *
+ * Copyright (C) 2012 RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/bcma/bcma.h>
+
+#include "bcm47xxnflash.h"
+
+/* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has
+ * shown 164 retries as maxiumum. */
+#define NFLASH_READY_RETRIES           1000
+
+#define NFLASH_SECTOR_SIZE             512
+
+#define NCTL_CMD0                      0x00010000
+#define NCTL_CMD1W                     0x00080000
+#define NCTL_READ                      0x00100000
+#define NCTL_WRITE                     0x00200000
+#define NCTL_SPECADDR                  0x01000000
+#define NCTL_READY                     0x04000000
+#define NCTL_ERR                       0x08000000
+#define NCTL_CSA                       0x40000000
+#define NCTL_START                     0x80000000
+
+/**************************************************
+ * Various helpers
+ **************************************************/
+
+static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock)
+{
+       return ((ns * 1000 * clock) / 1000000) + 1;
+}
+
+static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code)
+{
+       int i = 0;
+
+       bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code);
+       for (i = 0; i < NFLASH_READY_RETRIES; i++) {
+               if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) {
+                       i = 0;
+                       break;
+               }
+       }
+       if (i) {
+               pr_err("NFLASH control command not ready!\n");
+               return -EBUSY;
+       }
+       return 0;
+}
+
+static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc)
+{
+       int i;
+
+       for (i = 0; i < NFLASH_READY_RETRIES; i++) {
+               if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) {
+                       if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) &
+                           BCMA_CC_NFLASH_CTL_ERR) {
+                               pr_err("Error on polling\n");
+                               return -EBUSY;
+                       } else {
+                               return 0;
+                       }
+               }
+       }
+
+       pr_err("Polling timeout!\n");
+       return -EBUSY;
+}
+
+/**************************************************
+ * R/W
+ **************************************************/
+
+static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf,
+                                          int len)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+       u32 ctlcode;
+       u32 *dest = (u32 *)buf;
+       int i;
+       int toread;
+
+       BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask);
+       /* Don't validate column using nand_chip->page_shift, it may be bigger
+        * when accessing OOB */
+
+       while (len) {
+               /* We can read maximum of 0x200 bytes at once */
+               toread = min(len, 0x200);
+
+               /* Set page and column */
+               bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR,
+                               b47n->curr_column);
+               bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR,
+                               b47n->curr_page_addr);
+
+               /* Prepare to read */
+               ctlcode = NCTL_CSA | NCTL_CMD1W | 0x00040000 | 0x00020000 |
+                         NCTL_CMD0;
+               ctlcode |= NAND_CMD_READSTART << 8;
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode))
+                       return;
+               if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc))
+                       return;
+
+               /* Eventually read some data :) */
+               for (i = 0; i < toread; i += 4, dest++) {
+                       ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ;
+                       if (i == toread - 4) /* Last read goes without that */
+                               ctlcode &= ~NCTL_CSA;
+                       if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
+                                                             ctlcode))
+                               return;
+                       *dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA);
+               }
+
+               b47n->curr_column += toread;
+               len -= toread;
+       }
+}
+
+static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd,
+                                           const uint8_t *buf, int len)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+       struct bcma_drv_cc *cc = b47n->cc;
+
+       u32 ctlcode;
+       const u32 *data = (u32 *)buf;
+       int i;
+
+       BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask);
+       /* Don't validate column using nand_chip->page_shift, it may be bigger
+        * when accessing OOB */
+
+       for (i = 0; i < len; i += 4, data++) {
+               bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data);
+
+               ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE;
+               if (i == len - 4) /* Last read goes without that */
+                       ctlcode &= ~NCTL_CSA;
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) {
+                       pr_err("%s ctl_cmd didn't work!\n", __func__);
+                       return;
+               }
+       }
+
+       b47n->curr_column += len;
+}
+
+/**************************************************
+ * NAND chip ops
+ **************************************************/
+
+/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */
+static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd,
+                                                 int chip)
+{
+       return;
+}
+
+/*
+ * Default nand_command and nand_command_lp don't match BCM4706 hardware layout.
+ * For example, reading chip id is performed in a non-standard way.
+ * Setting column and page is also handled differently, we use a special
+ * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert
+ * standard commands would be much more complicated.
+ */
+static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd,
+                                             unsigned command, int column,
+                                             int page_addr)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+       struct bcma_drv_cc *cc = b47n->cc;
+       u32 ctlcode;
+       int i;
+
+       if (column != -1)
+               b47n->curr_column = column;
+       if (page_addr != -1)
+               b47n->curr_page_addr = page_addr;
+
+       switch (command) {
+       case NAND_CMD_RESET:
+               pr_warn("Chip reset not implemented yet\n");
+               break;
+       case NAND_CMD_READID:
+               ctlcode = NCTL_CSA | 0x01000000 | NCTL_CMD1W | NCTL_CMD0;
+               ctlcode |= NAND_CMD_READID;
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) {
+                       pr_err("READID error\n");
+                       break;
+               }
+
+               /*
+                * Reading is specific, last one has to go without NCTL_CSA
+                * bit. We don't know how many reads NAND subsystem is going
+                * to perform, so cache everything.
+                */
+               for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) {
+                       ctlcode = NCTL_CSA | NCTL_READ;
+                       if (i == ARRAY_SIZE(b47n->id_data) - 1)
+                               ctlcode &= ~NCTL_CSA;
+                       if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
+                                                             ctlcode)) {
+                               pr_err("READID error\n");
+                               break;
+                       }
+                       b47n->id_data[i] =
+                               bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA)
+                               & 0xFF;
+               }
+
+               break;
+       case NAND_CMD_STATUS:
+               ctlcode = NCTL_CSA | NCTL_CMD0 | NAND_CMD_STATUS;
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
+                       pr_err("STATUS command error\n");
+               break;
+       case NAND_CMD_READ0:
+               break;
+       case NAND_CMD_READOOB:
+               if (page_addr != -1)
+                       b47n->curr_column += mtd->writesize;
+               break;
+       case NAND_CMD_ERASE1:
+               bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR,
+                               b47n->curr_page_addr);
+               ctlcode = 0x00040000 | NCTL_CMD1W | NCTL_CMD0 |
+                         NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8);
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
+                       pr_err("ERASE1 failed\n");
+               break;
+       case NAND_CMD_ERASE2:
+               break;
+       case NAND_CMD_SEQIN:
+               /* Set page and column */
+               bcma_cc_write32(cc, BCMA_CC_NFLASH_COL_ADDR,
+                               b47n->curr_column);
+               bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR,
+                               b47n->curr_page_addr);
+
+               /* Prepare to write */
+               ctlcode = 0x40000000 | 0x00040000 | 0x00020000 | 0x00010000;
+               ctlcode |= NAND_CMD_SEQIN;
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
+                       pr_err("SEQIN failed\n");
+               break;
+       case NAND_CMD_PAGEPROG:
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, 0x00010000 |
+                                                         NAND_CMD_PAGEPROG))
+                       pr_err("PAGEPROG failed\n");
+               if (bcm47xxnflash_ops_bcm4706_poll(cc))
+                       pr_err("PAGEPROG not ready\n");
+               break;
+       default:
+               pr_err("Command 0x%X unsupported\n", command);
+               break;
+       }
+       b47n->curr_command = command;
+}
+
+static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+       struct bcma_drv_cc *cc = b47n->cc;
+       u32 tmp = 0;
+
+       switch (b47n->curr_command) {
+       case NAND_CMD_READID:
+               if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) {
+                       pr_err("Requested invalid id_data: %d\n",
+                              b47n->curr_column);
+                       return 0;
+               }
+               return b47n->id_data[b47n->curr_column++];
+       case NAND_CMD_STATUS:
+               if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_READ))
+                       return 0;
+               return bcma_cc_read32(cc, BCMA_CC_NFLASH_DATA) & 0xff;
+       case NAND_CMD_READOOB:
+               bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4);
+               return tmp & 0xFF;
+       }
+
+       pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command);
+       return 0;
+}
+
+static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd,
+                                              uint8_t *buf, int len)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+       switch (b47n->curr_command) {
+       case NAND_CMD_READ0:
+       case NAND_CMD_READOOB:
+               bcm47xxnflash_ops_bcm4706_read(mtd, buf, len);
+               return;
+       }
+
+       pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command);
+}
+
+static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd,
+                                               const uint8_t *buf, int len)
+{
+       struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
+       struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
+
+       switch (b47n->curr_command) {
+       case NAND_CMD_SEQIN:
+               bcm47xxnflash_ops_bcm4706_write(mtd, buf, len);
+               return;
+       }
+
+       pr_err("Invalid command for buf write: 0x%X\n", b47n->curr_command);
+}
+
+/**************************************************
+ * Init
+ **************************************************/
+
+int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
+{
+       int err;
+       u32 freq;
+       u16 clock;
+       u8 w0, w1, w2, w3, w4;
+
+       unsigned long chipsize; /* MiB */
+       u8 tbits, col_bits, col_size, row_bits, row_bsize;
+       u32 val;
+
+       b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
+       b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc;
+       b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte;
+       b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf;
+       b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf;
+       b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH;
+       b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */
+
+       /* Enable NAND flash access */
+       bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG,
+                     BCMA_CC_4706_FLASHSCFG_NF1);
+
+       /* Configure wait counters */
+       if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) {
+               freq = 100000000;
+       } else {
+               freq = bcma_chipco_pll_read(b47n->cc, 4);
+               freq = (freq * 0xFFF) >> 3;
+               freq = (freq * 25000000) >> 3;
+       }
+       clock = freq / 1000000;
+       w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock);
+       w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock);
+       w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);
+       w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);
+       w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock);
+       bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0,
+                       (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0));
+
+       /* Scan NAND */
+       err = nand_scan(&b47n->mtd, 1);
+       if (err) {
+               pr_err("Could not scan NAND flash: %d\n", err);
+               goto exit;
+       }
+
+       /* Configure FLASH */
+       chipsize = b47n->nand_chip.chipsize >> 20;
+       tbits = ffs(chipsize); /* find first bit set */
+       if (!tbits || tbits != fls(chipsize)) {
+               pr_err("Invalid flash size: 0x%lX\n", chipsize);
+               err = -ENOTSUPP;
+               goto exit;
+       }
+       tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */
+
+       col_bits = b47n->nand_chip.page_shift + 1;
+       col_size = (col_bits + 7) / 8;
+
+       row_bits = tbits - col_bits + 1;
+       row_bsize = (row_bits + 7) / 8;
+
+       val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2;
+       bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val);
+
+exit:
+       if (err)
+               bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG,
+                              ~BCMA_CC_4706_FLASHSCFG_NF1);
+       return err;
+}
index ab0caa7..4271e94 100644 (file)
@@ -658,7 +658,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
 /*
  * Device management interface
  */
-static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
+static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
 {
        struct mtd_info *mtd = &info->mtd;
        struct mtd_partition *parts = info->platform->partitions;
@@ -667,7 +667,7 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
        return mtd_device_register(mtd, parts, nr);
 }
 
-static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
+static int bf5xx_nand_remove(struct platform_device *pdev)
 {
        struct bf5xx_nand_info *info = to_nand_info(pdev);
 
@@ -725,7 +725,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd)
  * it can allocate all necessary resources then calls the
  * nand layer to look for devices
  */
-static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
+static int bf5xx_nand_probe(struct platform_device *pdev)
 {
        struct bf5xx_nand_platform *plat = to_nand_plat(pdev);
        struct bf5xx_nand_info *info = NULL;
@@ -865,7 +865,7 @@ static int bf5xx_nand_resume(struct platform_device *dev)
 /* driver device registration */
 static struct platform_driver bf5xx_nand_driver = {
        .probe          = bf5xx_nand_probe,
-       .remove         = __devexit_p(bf5xx_nand_remove),
+       .remove         = bf5xx_nand_remove,
        .suspend        = bf5xx_nand_suspend,
        .resume         = bf5xx_nand_resume,
        .driver         = {
index 2bb7170..010d612 100644 (file)
@@ -585,7 +585,7 @@ static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 }
 
 /* F_2[X]/(X**6+X+1)  */
-static unsigned short __devinit gf64_mul(u8 a, u8 b)
+static unsigned short gf64_mul(u8 a, u8 b)
 {
        u8 c;
        unsigned int i;
@@ -604,7 +604,7 @@ static unsigned short __devinit gf64_mul(u8 a, u8 b)
 }
 
 /* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X]  */
-static u16 __devinit gf4096_mul(u16 a, u16 b)
+static u16 gf4096_mul(u16 a, u16 b)
 {
        u8 ah, al, bh, bl, ch, cl;
 
@@ -619,14 +619,14 @@ static u16 __devinit gf4096_mul(u16 a, u16 b)
        return (ch << 6) ^ cl;
 }
 
-static int __devinit cafe_mul(int x)
+static int cafe_mul(int x)
 {
        if (x == 0)
                return 1;
        return gf4096_mul(x, 0xe01);
 }
 
-static int __devinit cafe_nand_probe(struct pci_dev *pdev,
+static int cafe_nand_probe(struct pci_dev *pdev,
                                     const struct pci_device_id *ent)
 {
        struct mtd_info *mtd;
@@ -821,7 +821,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
        return err;
 }
 
-static void __devexit cafe_nand_remove(struct pci_dev *pdev)
+static void cafe_nand_remove(struct pci_dev *pdev)
 {
        struct mtd_info *mtd = pci_get_drvdata(pdev);
        struct cafe_priv *cafe = mtd->priv;
@@ -887,7 +887,7 @@ static struct pci_driver cafe_nand_pci_driver = {
        .name = "CAFÉ NAND",
        .id_table = cafe_nand_tbl,
        .probe = cafe_nand_probe,
-       .remove = __devexit_p(cafe_nand_remove),
+       .remove = cafe_nand_remove,
        .resume = cafe_nand_resume,
 };
 
index adb6c3e..2cdeab8 100644 (file)
@@ -237,6 +237,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        this->ecc.hwctl  = cs_enable_hwecc;
        this->ecc.calculate = cs_calculate_ecc;
        this->ecc.correct  = nand_correct_data;
+       this->ecc.strength = 1;
 
        /* Enable the following for a flash based bad block table */
        this->bbt_options = NAND_BBT_USE_FLASH;
@@ -247,8 +248,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
                goto out_ior;
        }
 
-       this->ecc.strength = 1;
-
        new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs);
 
        cs553x_mtd[cs] = new_mtd;
index 945047a..3502606 100644 (file)
@@ -821,9 +821,16 @@ syndrome_done:
        if (ret < 0)
                goto err_scan;
 
-       ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts,
-                                       pdata->nr_parts);
-
+       if (pdata->parts)
+               ret = mtd_device_parse_register(&info->mtd, NULL, NULL,
+                                       pdata->parts, pdata->nr_parts);
+       else {
+               struct mtd_part_parser_data     ppdata;
+
+               ppdata.of_node = pdev->dev.of_node;
+               ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata,
+                                               NULL, 0);
+       }
        if (ret < 0)
                goto err_scan;
 
index e706a23..0c8bb6b 100644 (file)
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
-
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/mtd/mtd.h>
 #include <linux/module.h>
 
@@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."
  * format the bank into the proper bits for the controller */
 #define BANK(x) ((x) << 24)
 
-/* List of platforms this NAND controller has be integrated into */
-static const struct pci_device_id denali_pci_ids[] = {
-       { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
-       { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
-       { /* end: all zeroes */ }
-};
-
 /* forward declarations */
 static void clear_interrupts(struct denali_nand_info *denali);
 static uint32_t wait_for_irq(struct denali_nand_info *denali,
@@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)
 
        if (comp_res == 0) {
                /* timeout */
-               printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n",
+               pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n",
                                intr_status, irq_mask);
 
                intr_status = 0;
@@ -1305,8 +1296,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
                /* TODO: Read OOB data */
                break;
        default:
-               printk(KERN_ERR ": unsupported command"
-                               " received 0x%x\n", cmd);
+               pr_err(": unsupported command received 0x%x\n", cmd);
                break;
        }
 }
@@ -1425,107 +1415,48 @@ void denali_drv_init(struct denali_nand_info *denali)
        denali->irq_status = 0;
 }
 
-/* driver entry point */
-static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+int denali_init(struct denali_nand_info *denali)
 {
-       int ret = -ENODEV;
-       resource_size_t csr_base, mem_base;
-       unsigned long csr_len, mem_len;
-       struct denali_nand_info *denali;
-
-       denali = kzalloc(sizeof(*denali), GFP_KERNEL);
-       if (!denali)
-               return -ENOMEM;
+       int ret;
 
-       ret = pci_enable_device(dev);
-       if (ret) {
-               printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
-               goto failed_alloc_memery;
-       }
-
-       if (id->driver_data == INTEL_CE4100) {
+       if (denali->platform == INTEL_CE4100) {
                /* Due to a silicon limitation, we can only support
                 * ONFI timing mode 1 and below.
                 */
                if (onfi_timing_mode < -1 || onfi_timing_mode > 1) {
-                       printk(KERN_ERR "Intel CE4100 only supports"
-                                       " ONFI timing mode 1 or below\n");
-                       ret = -EINVAL;
-                       goto failed_enable_dev;
-               }
-               denali->platform = INTEL_CE4100;
-               mem_base = pci_resource_start(dev, 0);
-               mem_len = pci_resource_len(dev, 1);
-               csr_base = pci_resource_start(dev, 1);
-               csr_len = pci_resource_len(dev, 1);
-       } else {
-               denali->platform = INTEL_MRST;
-               csr_base = pci_resource_start(dev, 0);
-               csr_len = pci_resource_len(dev, 0);
-               mem_base = pci_resource_start(dev, 1);
-               mem_len = pci_resource_len(dev, 1);
-               if (!mem_len) {
-                       mem_base = csr_base + csr_len;
-                       mem_len = csr_len;
+                       pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n");
+                       return -EINVAL;
                }
        }
 
        /* Is 32-bit DMA supported? */
-       ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
+       ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
        if (ret) {
-               printk(KERN_ERR "Spectra: no usable DMA configuration\n");
-               goto failed_enable_dev;
+               pr_err("Spectra: no usable DMA configuration\n");
+               return ret;
        }
-       denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf,
+       denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
                                             DENALI_BUF_SIZE,
                                             DMA_BIDIRECTIONAL);
 
-       if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) {
-               dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n");
-               goto failed_enable_dev;
-       }
-
-       pci_set_master(dev);
-       denali->dev = &dev->dev;
-       denali->mtd.dev.parent = &dev->dev;
-
-       ret = pci_request_regions(dev, DENALI_NAND_NAME);
-       if (ret) {
-               printk(KERN_ERR "Spectra: Unable to request memory regions\n");
-               goto failed_dma_map;
-       }
-
-       denali->flash_reg = ioremap_nocache(csr_base, csr_len);
-       if (!denali->flash_reg) {
-               printk(KERN_ERR "Spectra: Unable to remap memory region\n");
-               ret = -ENOMEM;
-               goto failed_req_regions;
-       }
-
-       denali->flash_mem = ioremap_nocache(mem_base, mem_len);
-       if (!denali->flash_mem) {
-               printk(KERN_ERR "Spectra: ioremap_nocache failed!");
-               ret = -ENOMEM;
-               goto failed_remap_reg;
+       if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
+               dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
+               return -EIO;
        }
-
+       denali->mtd.dev.parent = denali->dev;
        denali_hw_init(denali);
        denali_drv_init(denali);
 
        /* denali_isr register is done after all the hardware
         * initilization is finished*/
-       if (request_irq(dev->irq, denali_isr, IRQF_SHARED,
+       if (request_irq(denali->irq, denali_isr, IRQF_SHARED,
                        DENALI_NAND_NAME, denali)) {
-               printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
-               ret = -ENODEV;
-               goto failed_remap_mem;
+               pr_err("Spectra: Unable to allocate IRQ\n");
+               return -ENODEV;
        }
 
        /* now that our ISR is registered, we can enable interrupts */
        denali_set_intr_modes(denali, true);
-
-       pci_set_drvdata(dev, denali);
-
        denali->mtd.name = "denali-nand";
        denali->mtd.owner = THIS_MODULE;
        denali->mtd.priv = &denali->nand;
@@ -1549,8 +1480,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
         */
        if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
                ret = -ENODEV;
-               printk(KERN_ERR "Spectra: device size not supported by this "
-                       "version of MTD.");
+               pr_err("Spectra: device size not supported by this version of MTD.");
                goto failed_req_irq;
        }
 
@@ -1602,8 +1532,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        } else if (denali->mtd.oobsize < (denali->bbtskipbytes +
                        ECC_8BITS * (denali->mtd.writesize /
                        ECC_SECTOR_SIZE))) {
-               printk(KERN_ERR "Your NAND chip OOB is not large enough to"
-                               contain 8bit ECC correction codes");
+               pr_err("Your NAND chip OOB is not large enough to \
+                               contain 8bit ECC correction codes");
                goto failed_req_irq;
        } else {
                denali->nand.ecc.strength = 8;
@@ -1655,56 +1585,24 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
        ret = mtd_device_register(&denali->mtd, NULL, 0);
        if (ret) {
-               dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n",
+               dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",
                                ret);
                goto failed_req_irq;
        }
        return 0;
 
 failed_req_irq:
-       denali_irq_cleanup(dev->irq, denali);
-failed_remap_mem:
-       iounmap(denali->flash_mem);
-failed_remap_reg:
-       iounmap(denali->flash_reg);
-failed_req_regions:
-       pci_release_regions(dev);
-failed_dma_map:
-       dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-                        DMA_BIDIRECTIONAL);
-failed_enable_dev:
-       pci_disable_device(dev);
-failed_alloc_memery:
-       kfree(denali);
+       denali_irq_cleanup(denali->irq, denali);
+
        return ret;
 }
+EXPORT_SYMBOL(denali_init);
 
 /* driver exit point */
-static void denali_pci_remove(struct pci_dev *dev)
+void denali_remove(struct denali_nand_info *denali)
 {
-       struct denali_nand_info *denali = pci_get_drvdata(dev);
-
-       nand_release(&denali->mtd);
-
-       denali_irq_cleanup(dev->irq, denali);
-
-       iounmap(denali->flash_reg);
-       iounmap(denali->flash_mem);
-       pci_release_regions(dev);
-       pci_disable_device(dev);
-       dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-                        DMA_BIDIRECTIONAL);
-       pci_set_drvdata(dev, NULL);
-       kfree(denali);
+       denali_irq_cleanup(denali->irq, denali);
+       dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
+                       DMA_BIDIRECTIONAL);
 }
-
-MODULE_DEVICE_TABLE(pci, denali_pci_ids);
-
-static struct pci_driver denali_pci_driver = {
-       .name = DENALI_NAND_NAME,
-       .id_table = denali_pci_ids,
-       .probe = denali_pci_probe,
-       .remove = denali_pci_remove,
-};
-
-module_pci_driver(denali_pci_driver);
+EXPORT_SYMBOL(denali_remove);
index fabb9d5..cec5712 100644 (file)
@@ -466,6 +466,7 @@ struct nand_buf {
 
 #define INTEL_CE4100   1
 #define INTEL_MRST     2
+#define DT             3
 
 struct denali_nand_info {
        struct mtd_info mtd;
@@ -487,6 +488,7 @@ struct denali_nand_info {
        uint32_t irq_status;
        int irq_debug_array[32];
        int idx;
+       int irq;
 
        uint32_t devnum;        /* represent how many nands connected */
        uint32_t fwblks; /* represent how many blocks FW used */
@@ -496,4 +498,7 @@ struct denali_nand_info {
        uint32_t max_banks;
 };
 
+extern int denali_init(struct denali_nand_info *denali);
+extern void denali_remove(struct denali_nand_info *denali);
+
 #endif /*_LLD_NAND_*/
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c
new file mode 100644 (file)
index 0000000..546f8cb
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * NAND Flash Controller Device Driver for DT
+ *
+ * Copyright Â© 2011, Picochip.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "denali.h"
+
+struct denali_dt {
+       struct denali_nand_info denali;
+       struct clk              *clk;
+};
+
+static void __iomem *request_and_map(struct device *dev,
+                                    const struct resource *res)
+{
+       void __iomem *ptr;
+
+       if (!devm_request_mem_region(dev, res->start, resource_size(res),
+                                    "denali-dt")) {
+               dev_err(dev, "unable to request %s\n", res->name);
+               return NULL;
+       }
+
+       ptr = devm_ioremap_nocache(dev, res->start, resource_size(res));
+       if (!res)
+               dev_err(dev, "ioremap_nocache of %s failed!", res->name);
+
+       return ptr;
+}
+
+static const struct of_device_id denali_nand_dt_ids[] = {
+               { .compatible = "denali,denali-nand-dt" },
+               { /* sentinel */ }
+       };
+
+MODULE_DEVICE_TABLE(of, denali_nand_dt_ids);
+
+static u64 denali_dma_mask;
+
+static int denali_dt_probe(struct platform_device *ofdev)
+{
+       struct resource *denali_reg, *nand_data;
+       struct denali_dt *dt;
+       struct denali_nand_info *denali;
+       int ret;
+       const struct of_device_id *of_id;
+
+       of_id = of_match_device(denali_nand_dt_ids, &ofdev->dev);
+       if (of_id) {
+               ofdev->id_entry = of_id->data;
+       } else {
+               pr_err("Failed to find the right device id.\n");
+               return -ENOMEM;
+       }
+
+       dt = devm_kzalloc(&ofdev->dev, sizeof(*dt), GFP_KERNEL);
+       if (!dt)
+               return -ENOMEM;
+       denali = &dt->denali;
+
+       denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg");
+       nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data");
+       if (!denali_reg || !nand_data) {
+               dev_err(&ofdev->dev, "resources not completely defined\n");
+               return -EINVAL;
+       }
+
+       denali->platform = DT;
+       denali->dev = &ofdev->dev;
+       denali->irq = platform_get_irq(ofdev, 0);
+       if (denali->irq < 0) {
+               dev_err(&ofdev->dev, "no irq defined\n");
+               return -ENXIO;
+       }
+
+       denali->flash_reg = request_and_map(&ofdev->dev, denali_reg);
+       if (!denali->flash_reg)
+               return -ENOMEM;
+
+       denali->flash_mem = request_and_map(&ofdev->dev, nand_data);
+       if (!denali->flash_mem)
+               return -ENOMEM;
+
+       if (!of_property_read_u32(ofdev->dev.of_node,
+               "dma-mask", (u32 *)&denali_dma_mask)) {
+               denali->dev->dma_mask = &denali_dma_mask;
+       } else {
+               denali->dev->dma_mask = NULL;
+       }
+
+       dt->clk = clk_get(&ofdev->dev, NULL);
+       if (IS_ERR(dt->clk)) {
+               dev_err(&ofdev->dev, "no clk available\n");
+               return PTR_ERR(dt->clk);
+       }
+       clk_prepare_enable(dt->clk);
+
+       ret = denali_init(denali);
+       if (ret)
+               goto out_disable_clk;
+
+       platform_set_drvdata(ofdev, dt);
+       return 0;
+
+out_disable_clk:
+       clk_disable_unprepare(dt->clk);
+       clk_put(dt->clk);
+
+       return ret;
+}
+
+static int denali_dt_remove(struct platform_device *ofdev)
+{
+       struct denali_dt *dt = platform_get_drvdata(ofdev);
+
+       denali_remove(&dt->denali);
+       clk_disable(dt->clk);
+       clk_put(dt->clk);
+
+       return 0;
+}
+
+static struct platform_driver denali_dt_driver = {
+       .probe          = denali_dt_probe,
+       .remove         = denali_dt_remove,
+       .driver         = {
+               .name   = "denali-nand-dt",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(denali_nand_dt_ids),
+       },
+};
+
+static int __init denali_init_dt(void)
+{
+       return platform_driver_register(&denali_dt_driver);
+}
+module_init(denali_init_dt);
+
+static void __exit denali_exit_dt(void)
+{
+       platform_driver_unregister(&denali_dt_driver);
+}
+module_exit(denali_exit_dt);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamie Iles");
+MODULE_DESCRIPTION("DT driver for Denali NAND controller");
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
new file mode 100644 (file)
index 0000000..e3e4662
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright Â© 2009-2010, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#include "denali.h"
+
+#define DENALI_NAND_NAME    "denali-nand-pci"
+
+/* List of platforms this NAND controller has be integrated into */
+static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = {
+       { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
+       { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
+       { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, denali_pci_ids);
+
+static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+       int ret = -ENODEV;
+       resource_size_t csr_base, mem_base;
+       unsigned long csr_len, mem_len;
+       struct denali_nand_info *denali;
+
+       denali = kzalloc(sizeof(*denali), GFP_KERNEL);
+       if (!denali)
+               return -ENOMEM;
+
+       ret = pci_enable_device(dev);
+       if (ret) {
+               pr_err("Spectra: pci_enable_device failed.\n");
+               goto failed_alloc_memery;
+       }
+
+       if (id->driver_data == INTEL_CE4100) {
+               denali->platform = INTEL_CE4100;
+               mem_base = pci_resource_start(dev, 0);
+               mem_len = pci_resource_len(dev, 1);
+               csr_base = pci_resource_start(dev, 1);
+               csr_len = pci_resource_len(dev, 1);
+       } else {
+               denali->platform = INTEL_MRST;
+               csr_base = pci_resource_start(dev, 0);
+               csr_len = pci_resource_len(dev, 0);
+               mem_base = pci_resource_start(dev, 1);
+               mem_len = pci_resource_len(dev, 1);
+               if (!mem_len) {
+                       mem_base = csr_base + csr_len;
+                       mem_len = csr_len;
+               }
+       }
+
+       pci_set_master(dev);
+       denali->dev = &dev->dev;
+       denali->irq = dev->irq;
+
+       ret = pci_request_regions(dev, DENALI_NAND_NAME);
+       if (ret) {
+               pr_err("Spectra: Unable to request memory regions\n");
+               goto failed_enable_dev;
+       }
+
+       denali->flash_reg = ioremap_nocache(csr_base, csr_len);
+       if (!denali->flash_reg) {
+               pr_err("Spectra: Unable to remap memory region\n");
+               ret = -ENOMEM;
+               goto failed_req_regions;
+       }
+
+       denali->flash_mem = ioremap_nocache(mem_base, mem_len);
+       if (!denali->flash_mem) {
+               pr_err("Spectra: ioremap_nocache failed!");
+               ret = -ENOMEM;
+               goto failed_remap_reg;
+       }
+
+       ret = denali_init(denali);
+       if (ret)
+               goto failed_remap_mem;
+
+       pci_set_drvdata(dev, denali);
+
+       return 0;
+
+failed_remap_mem:
+       iounmap(denali->flash_mem);
+failed_remap_reg:
+       iounmap(denali->flash_reg);
+failed_req_regions:
+       pci_release_regions(dev);
+failed_enable_dev:
+       pci_disable_device(dev);
+failed_alloc_memery:
+       kfree(denali);
+
+       return ret;
+}
+
+/* driver exit point */
+static void denali_pci_remove(struct pci_dev *dev)
+{
+       struct denali_nand_info *denali = pci_get_drvdata(dev);
+
+       denali_remove(denali);
+       iounmap(denali->flash_reg);
+       iounmap(denali->flash_mem);
+       pci_release_regions(dev);
+       pci_disable_device(dev);
+       pci_set_drvdata(dev, NULL);
+       kfree(denali);
+}
+
+static struct pci_driver denali_pci_driver = {
+       .name = DENALI_NAND_NAME,
+       .id_table = denali_pci_ids,
+       .probe = denali_pci_probe,
+       .remove = denali_pci_remove,
+};
+
+static int denali_init_pci(void)
+{
+       pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__);
+       return pci_register_driver(&denali_pci_driver);
+}
+module_init(denali_init_pci);
+
+static void denali_exit_pci(void)
+{
+       pci_unregister_driver(&denali_pci_driver);
+}
+module_exit(denali_exit_pci);
index 256eb30..81fa578 100644 (file)
@@ -53,8 +53,6 @@ static unsigned long __initdata doc_locations[] = {
        0xe0000, 0xe2000, 0xe4000, 0xe6000,
        0xe8000, 0xea000, 0xec000, 0xee000,
 #endif /*  CONFIG_MTD_DOCPROBE_HIGH */
-#else
-#warning Unknown architecture for DiskOnChip. No default probe locations defined
 #endif
        0xffffffff };
 
index 799da5d..18fa448 100644 (file)
 #include <linux/bitrev.h>
 
 /*
+ * In "reliable mode" consecutive 2k pages are used in parallel (in some
+ * fashion) to store the same data.  The data can be read back from the
+ * even-numbered pages in the normal manner; odd-numbered pages will appear to
+ * contain junk.  Systems that boot from the docg4 typically write the secondary
+ * program loader (SPL) code in this mode.  The SPL is loaded by the initial
+ * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped
+ * to the reset vector address).  This module parameter enables you to use this
+ * driver to write the SPL.  When in this mode, no more than 2k of data can be
+ * written at a time, because the addresses do not increment in the normal
+ * manner, and the starting offset must be within an even-numbered 2k region;
+ * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800,
+ * 0x1a00, ...  Reliable mode is a special case and should not be used unless
+ * you know what you're doing.
+ */
+static bool reliable_mode;
+module_param(reliable_mode, bool, 0);
+MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode");
+
+/*
  * You'll want to ignore badblocks if you're reading a partition that contains
  * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since
  * it does not use mtd nand's method for marking bad blocks (using oob area).
@@ -113,6 +132,7 @@ struct docg4_priv {
 #define DOCG4_SEQ_PAGEWRITE            0x16
 #define DOCG4_SEQ_PAGEPROG             0x1e
 #define DOCG4_SEQ_BLOCKERASE           0x24
+#define DOCG4_SEQ_SETMODE              0x45
 
 /* DOC_FLASHCOMMAND register commands */
 #define DOCG4_CMD_PAGE_READ             0x00
@@ -122,6 +142,8 @@ struct docg4_priv {
 #define DOC_CMD_PROG_BLOCK_ADDR                0x60
 #define DOCG4_CMD_PAGEWRITE            0x80
 #define DOC_CMD_PROG_CYCLE2            0x10
+#define DOCG4_CMD_FAST_MODE            0xa3 /* functionality guessed */
+#define DOC_CMD_RELIABLE_MODE          0x22
 #define DOC_CMD_RESET                  0xff
 
 /* DOC_POWERMODE register bits */
@@ -190,17 +212,20 @@ struct docg4_priv {
 #define DOCG4_T                4   /* BCH alg corrects up to 4 bit errors */
 
 #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */
+#define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */
 
 /*
- * Oob bytes 0 - 6 are available to the user.
- * Byte 7 is hamming ecc for first 7 bytes.  Bytes 8 - 14 are hw-generated ecc.
+ * Bytes 0, 1 are used as badblock marker.
+ * Bytes 2 - 6 are available to the user.
+ * Byte 7 is hamming ecc for first 7 oob bytes only.
+ * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14.
  * Byte 15 (the last) is used by the driver as a "page written" flag.
  */
 static struct nand_ecclayout docg4_oobinfo = {
        .eccbytes = 9,
        .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
-       .oobavail = 7,
-       .oobfree = { {0, 7} }
+       .oobavail = 5,
+       .oobfree = { {.offset = 2, .length = 5} }
 };
 
 /*
@@ -611,6 +636,14 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr)
        dev_dbg(doc->dev,
              "docg4: %s: g4 addr: %x\n", __func__, docg4_addr);
        sequence_reset(mtd);
+
+       if (unlikely(reliable_mode)) {
+               writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE);
+               writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND);
+               writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND);
+               write_nop(docptr);
+       }
+
        writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);
        writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);
        write_nop(docptr);
@@ -691,6 +724,15 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column,
                break;
 
        case NAND_CMD_SEQIN:
+               if (unlikely(reliable_mode)) {
+                       uint16_t g4_page = g4_addr >> 16;
+
+                       /* writes to odd-numbered 2k pages are invalid */
+                       if (g4_page & 0x01)
+                               dev_warn(doc->dev,
+                                        "invalid reliable mode address\n");
+               }
+
                write_page_prologue(mtd, g4_addr);
 
                /* hack for deferred write of oob bytes */
@@ -979,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
        struct docg4_priv *doc = nand->priv;
        uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
        uint8_t *buf;
-       int i, block, status;
+       int i, block;
+       __u32 eccfailed_stats = mtd->ecc_stats.failed;
 
        buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
        if (buf == NULL)
                return -ENOMEM;
 
        read_page_prologue(mtd, g4_addr);
-       status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
-       if (status)
-               goto exit;
+       docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
 
        /*
         * If no memory-based bbt was created, exit.  This will happen if module
@@ -1000,6 +1041,20 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
        if (nand->bbt == NULL)  /* no memory-based bbt */
                goto exit;
 
+       if (mtd->ecc_stats.failed > eccfailed_stats) {
+               /*
+                * Whoops, an ecc failure ocurred reading the factory bbt.
+                * It is stored redundantly, so we get another chance.
+                */
+               eccfailed_stats = mtd->ecc_stats.failed;
+               docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE);
+               if (mtd->ecc_stats.failed > eccfailed_stats) {
+                       dev_warn(doc->dev,
+                                "The factory bbt could not be read!\n");
+                       goto exit;
+               }
+       }
+
        /*
         * Parse factory bbt and update memory-based bbt.  Factory bbt format is
         * simple: one bit per block, block numbers increase left to right (msb
@@ -1019,7 +1074,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
        }
  exit:
        kfree(buf);
-       return status;
+       return 0;
 }
 
 static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
index cc1480a..2065720 100644 (file)
@@ -109,20 +109,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {
 };
 
 /*
- * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset
- * 1, so we have to adjust bad block pattern. This pattern should be used for
- * x8 chips only. So far hardware does not support x16 chips anyway.
- */
-static u8 scan_ff_pattern[] = { 0xff, };
-
-static struct nand_bbt_descr largepage_memorybased = {
-       .options = 0,
-       .offs = 0,
-       .len = 1,
-       .pattern = scan_ff_pattern,
-};
-
-/*
  * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt,
  * interfere with ECC positions, that's why we implement our own descriptors.
  * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0.
@@ -699,7 +685,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
                        chip->ecc.layout = (priv->fmr & FMR_ECCM) ?
                                           &fsl_elbc_oob_lp_eccm1 :
                                           &fsl_elbc_oob_lp_eccm0;
-                       chip->badblock_pattern = &largepage_memorybased;
                }
        } else {
                dev_err(priv->dev,
@@ -814,7 +799,7 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
 
 static DEFINE_MUTEX(fsl_elbc_nand_mutex);
 
-static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
+static int fsl_elbc_nand_probe(struct platform_device *pdev)
 {
        struct fsl_lbc_regs __iomem *lbc;
        struct fsl_elbc_mtd *priv;
index 3551a99..ad62226 100644 (file)
@@ -389,7 +389,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                        timing = IFC_FIR_OP_RBCD;
 
                out_be32(&ifc->ifc_nand.nand_fir0,
-                               (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
+                               (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
                                (IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |
                                (timing << IFC_NAND_FIR0_OP2_SHIFT));
                out_be32(&ifc->ifc_nand.nand_fcr0,
@@ -754,7 +754,7 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
 
        /* READID */
        out_be32(&ifc->ifc_nand.nand_fir0,
-                       (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
+                       (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
                        (IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |
                        (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
        out_be32(&ifc->ifc_nand.nand_fcr0,
@@ -922,7 +922,7 @@ static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank,
 
 static DEFINE_MUTEX(fsl_ifc_nand_mutex);
 
-static int __devinit fsl_ifc_nand_probe(struct platform_device *dev)
+static int fsl_ifc_nand_probe(struct platform_device *dev)
 {
        struct fsl_ifc_regs __iomem *ifc;
        struct fsl_ifc_mtd *priv;
index 45df542..5a8f5c4 100644 (file)
@@ -152,7 +152,7 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
                fun_wait_rnb(fun);
 }
 
-static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
+static int fun_chip_init(struct fsl_upm_nand *fun,
                                   const struct device_node *upm_np,
                                   const struct resource *io_res)
 {
@@ -201,7 +201,7 @@ err:
        return ret;
 }
 
-static int __devinit fun_probe(struct platform_device *ofdev)
+static int fun_probe(struct platform_device *ofdev)
 {
        struct fsl_upm_nand *fun;
        struct resource io_res;
@@ -318,7 +318,7 @@ err1:
        return ret;
 }
 
-static int __devexit fun_remove(struct platform_device *ofdev)
+static int fun_remove(struct platform_device *ofdev)
 {
        struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
        int i;
@@ -350,7 +350,7 @@ static struct platform_driver of_fun_driver = {
                .of_match_table = of_fun_match,
        },
        .probe          = fun_probe,
-       .remove         = __devexit_p(fun_remove),
+       .remove         = fun_remove,
 };
 
 module_platform_driver(of_fun_driver);
index 38d2624..1d74464 100644 (file)
@@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
        struct nand_chip *this = mtd->priv;
        struct fsmc_nand_data *host = container_of(mtd,
                                        struct fsmc_nand_data, mtd);
-       void *__iomem *regs = host->regs_va;
+       void __iomem *regs = host->regs_va;
        unsigned int bank = host->bank;
 
        if (ctrl & NAND_CTRL_CHANGE) {
@@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
                        pc |= FSMC_ENABLE;
                else
                        pc &= ~FSMC_ENABLE;
-               writel(pc, FSMC_NAND_REG(regs, bank, PC));
+               writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));
        }
 
        mb();
 
        if (cmd != NAND_CMD_NONE)
-               writeb(cmd, this->IO_ADDR_W);
+               writeb_relaxed(cmd, this->IO_ADDR_W);
 }
 
 /*
@@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
        tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
 
        if (busw)
-               writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
+               writel_relaxed(value | FSMC_DEVWID_16,
+                               FSMC_NAND_REG(regs, bank, PC));
        else
-               writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC));
+               writel_relaxed(value | FSMC_DEVWID_8,
+                               FSMC_NAND_REG(regs, bank, PC));
 
-       writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
+       writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
                        FSMC_NAND_REG(regs, bank, PC));
-       writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM));
-       writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB));
+       writel_relaxed(thiz | thold | twait | tset,
+                       FSMC_NAND_REG(regs, bank, COMM));
+       writel_relaxed(thiz | thold | twait | tset,
+                       FSMC_NAND_REG(regs, bank, ATTRIB));
 }
 
 /*
@@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
        void __iomem *regs = host->regs_va;
        uint32_t bank = host->bank;
 
-       writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
+       writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
                        FSMC_NAND_REG(regs, bank, PC));
-       writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
+       writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
                        FSMC_NAND_REG(regs, bank, PC));
-       writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
+       writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
                        FSMC_NAND_REG(regs, bank, PC));
 }
 
@@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
        unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
 
        do {
-               if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
+               if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
                        break;
                else
                        cond_resched();
@@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
                return -ETIMEDOUT;
        }
 
-       ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1));
+       ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
        ecc[0] = (uint8_t) (ecc_tmp >> 0);
        ecc[1] = (uint8_t) (ecc_tmp >> 8);
        ecc[2] = (uint8_t) (ecc_tmp >> 16);
        ecc[3] = (uint8_t) (ecc_tmp >> 24);
 
-       ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2));
+       ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
        ecc[4] = (uint8_t) (ecc_tmp >> 0);
        ecc[5] = (uint8_t) (ecc_tmp >> 8);
        ecc[6] = (uint8_t) (ecc_tmp >> 16);
        ecc[7] = (uint8_t) (ecc_tmp >> 24);
 
-       ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3));
+       ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
        ecc[8] = (uint8_t) (ecc_tmp >> 0);
        ecc[9] = (uint8_t) (ecc_tmp >> 8);
        ecc[10] = (uint8_t) (ecc_tmp >> 16);
        ecc[11] = (uint8_t) (ecc_tmp >> 24);
 
-       ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS));
+       ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
        ecc[12] = (uint8_t) (ecc_tmp >> 16);
 
        return 0;
@@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
        uint32_t bank = host->bank;
        uint32_t ecc_tmp;
 
-       ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1));
+       ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
        ecc[0] = (uint8_t) (ecc_tmp >> 0);
        ecc[1] = (uint8_t) (ecc_tmp >> 8);
        ecc[2] = (uint8_t) (ecc_tmp >> 16);
@@ -601,7 +605,7 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len,
        dma_async_issue_pending(chan);
 
        ret =
-       wait_for_completion_interruptible_timeout(&host->dma_access_complete,
+       wait_for_completion_timeout(&host->dma_access_complete,
                                msecs_to_jiffies(3000));
        if (ret <= 0) {
                chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
@@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
                uint32_t *p = (uint32_t *)buf;
                len = len >> 2;
                for (i = 0; i < len; i++)
-                       writel(p[i], chip->IO_ADDR_W);
+                       writel_relaxed(p[i], chip->IO_ADDR_W);
        } else {
                for (i = 0; i < len; i++)
-                       writeb(buf[i], chip->IO_ADDR_W);
+                       writeb_relaxed(buf[i], chip->IO_ADDR_W);
        }
 }
 
@@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
                uint32_t *p = (uint32_t *)buf;
                len = len >> 2;
                for (i = 0; i < len; i++)
-                       p[i] = readl(chip->IO_ADDR_R);
+                       p[i] = readl_relaxed(chip->IO_ADDR_R);
        } else {
                for (i = 0; i < len; i++)
-                       buf[i] = readb(chip->IO_ADDR_R);
+                       buf[i] = readb_relaxed(chip->IO_ADDR_R);
        }
 }
 
@@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
        uint32_t num_err, i;
        uint32_t ecc1, ecc2, ecc3, ecc4;
 
-       num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
+       num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
 
        /* no bit flipping */
        if (likely(num_err == 0))
@@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
         * uint64_t array and error offset indexes are populated in err_idx
         * array
         */
-       ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1));
-       ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2));
-       ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3));
-       ecc4 = readl(FSMC_NAND_REG(regs, bank, STS));
+       ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
+       ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
+       ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
+       ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
 
        err_idx[0] = (ecc1 >> 0) & 0x1FFF;
        err_idx[1] = (ecc1 >> 13) & 0x1FFF;
@@ -860,7 +864,7 @@ static bool filter(struct dma_chan *chan, void *slave)
 }
 
 #ifdef CONFIG_OF
-static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
+static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
                                               struct device_node *np)
 {
        struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -876,15 +880,13 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
                        return -EINVAL;
                }
        }
-       of_property_read_u32(np, "st,ale-off", &pdata->ale_off);
-       of_property_read_u32(np, "st,cle-off", &pdata->cle_off);
        if (of_get_property(np, "nand-skip-bbtscan", NULL))
                pdata->options = NAND_SKIP_BBTSCAN;
 
        return 0;
 }
 #else
-static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
+static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
                                               struct device_node *np)
 {
        return -ENOSYS;
@@ -935,41 +937,28 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
        if (!res)
                return -EINVAL;
 
-       if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
-                               pdev->name)) {
-               dev_err(&pdev->dev, "Failed to get memory data resourse\n");
-               return -ENOENT;
-       }
-
-       host->data_pa = (dma_addr_t)res->start;
-       host->data_va = devm_ioremap(&pdev->dev, res->start,
-                       resource_size(res));
+       host->data_va = devm_request_and_ioremap(&pdev->dev, res);
        if (!host->data_va) {
                dev_err(&pdev->dev, "data ioremap failed\n");
                return -ENOMEM;
        }
+       host->data_pa = (dma_addr_t)res->start;
 
-       if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off,
-                       resource_size(res), pdev->name)) {
-               dev_err(&pdev->dev, "Failed to get memory ale resourse\n");
-               return -ENOENT;
-       }
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
+       if (!res)
+               return -EINVAL;
 
-       host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off,
-                       resource_size(res));
+       host->addr_va = devm_request_and_ioremap(&pdev->dev, res);
        if (!host->addr_va) {
                dev_err(&pdev->dev, "ale ioremap failed\n");
                return -ENOMEM;
        }
 
-       if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off,
-                       resource_size(res), pdev->name)) {
-               dev_err(&pdev->dev, "Failed to get memory cle resourse\n");
-               return -ENOENT;
-       }
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
+       if (!res)
+               return -EINVAL;
 
-       host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off,
-                       resource_size(res));
+       host->cmd_va = devm_request_and_ioremap(&pdev->dev, res);
        if (!host->cmd_va) {
                dev_err(&pdev->dev, "ale ioremap failed\n");
                return -ENOMEM;
@@ -979,14 +968,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
        if (!res)
                return -EINVAL;
 
-       if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
-                       pdev->name)) {
-               dev_err(&pdev->dev, "Failed to get memory regs resourse\n");
-               return -ENOENT;
-       }
-
-       host->regs_va = devm_ioremap(&pdev->dev, res->start,
-                       resource_size(res));
+       host->regs_va = devm_request_and_ioremap(&pdev->dev, res);
        if (!host->regs_va) {
                dev_err(&pdev->dev, "regs ioremap failed\n");
                return -ENOMEM;
index bc73bc5..e789e3f 100644 (file)
@@ -90,14 +90,14 @@ static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
 
-       writesb(this->IO_ADDR_W, buf, len);
+       iowrite8_rep(this->IO_ADDR_W, buf, len);
 }
 
 static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
 
-       readsb(this->IO_ADDR_R, buf, len);
+       ioread8_rep(this->IO_ADDR_R, buf, len);
 }
 
 static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
@@ -106,7 +106,7 @@ static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
        struct nand_chip *this = mtd->priv;
 
        if (IS_ALIGNED((unsigned long)buf, 2)) {
-               writesw(this->IO_ADDR_W, buf, len>>1);
+               iowrite16_rep(this->IO_ADDR_W, buf, len>>1);
        } else {
                int i;
                unsigned short *ptr = (unsigned short *)buf;
@@ -121,7 +121,7 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
        struct nand_chip *this = mtd->priv;
 
        if (IS_ALIGNED((unsigned long)buf, 2)) {
-               readsw(this->IO_ADDR_R, buf, len>>1);
+               ioread16_rep(this->IO_ADDR_R, buf, len>>1);
        } else {
                int i;
                unsigned short *ptr = (unsigned short *)buf;
@@ -134,7 +134,11 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
 static int gpio_nand_devready(struct mtd_info *mtd)
 {
        struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
-       return gpio_get_value(gpiomtd->plat.gpio_rdy);
+
+       if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+               return gpio_get_value(gpiomtd->plat.gpio_rdy);
+
+       return 1;
 }
 
 #ifdef CONFIG_OF
@@ -227,7 +231,7 @@ gpio_nand_get_io_sync(struct platform_device *pdev)
        return platform_get_resource(pdev, IORESOURCE_MEM, 1);
 }
 
-static int __devexit gpio_nand_remove(struct platform_device *dev)
+static int gpio_nand_remove(struct platform_device *dev)
 {
        struct gpiomtd *gpiomtd = platform_get_drvdata(dev);
        struct resource *res;
@@ -252,7 +256,8 @@ static int __devexit gpio_nand_remove(struct platform_device *dev)
        gpio_free(gpiomtd->plat.gpio_nce);
        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
                gpio_free(gpiomtd->plat.gpio_nwp);
-       gpio_free(gpiomtd->plat.gpio_rdy);
+       if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+               gpio_free(gpiomtd->plat.gpio_rdy);
 
        kfree(gpiomtd);
 
@@ -277,7 +282,7 @@ static void __iomem *request_and_remap(struct resource *res, size_t size,
        return ptr;
 }
 
-static int __devinit gpio_nand_probe(struct platform_device *dev)
+static int gpio_nand_probe(struct platform_device *dev)
 {
        struct gpiomtd *gpiomtd;
        struct nand_chip *this;
@@ -336,10 +341,12 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
        if (ret)
                goto err_cle;
        gpio_direction_output(gpiomtd->plat.gpio_cle, 0);
-       ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
-       if (ret)
-               goto err_rdy;
-       gpio_direction_input(gpiomtd->plat.gpio_rdy);
+       if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) {
+               ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
+               if (ret)
+                       goto err_rdy;
+               gpio_direction_input(gpiomtd->plat.gpio_rdy);
+       }
 
 
        this->IO_ADDR_W  = this->IO_ADDR_R;
@@ -386,7 +393,8 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
 err_wp:
        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
                gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
-       gpio_free(gpiomtd->plat.gpio_rdy);
+       if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+               gpio_free(gpiomtd->plat.gpio_rdy);
 err_rdy:
        gpio_free(gpiomtd->plat.gpio_cle);
 err_cle:
index 3502acc..d84699c 100644 (file)
@@ -18,7 +18,6 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#include <linux/mtd/gpmi-nand.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 
@@ -166,6 +165,15 @@ int gpmi_init(struct gpmi_nand_data *this)
        if (ret)
                goto err_out;
 
+       /*
+        * Reset BCH here, too. We got failures otherwise :(
+        * See later BCH reset for explanation of MX23 handling
+        */
+       ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
+       if (ret)
+               goto err_out;
+
+
        /* Choose NAND mode. */
        writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
 
index d79696b..5cd141f 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/mtd/gpmi-nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/of.h>
 #include <linux/of_mtd.h>
 #include "gpmi-nand.h"
 
+/* Resource names for the GPMI NAND driver. */
+#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
+#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
+#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
+#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
+
 /* add our owner bbt descriptor */
 static uint8_t scan_ff_pattern[] = { 0xff };
 static struct nand_bbt_descr gpmi_bbt_descr = {
@@ -222,7 +227,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
 
                ret = dma_map_sg(this->dev, sgl, 1, dr);
                if (ret == 0)
-                       pr_err("map failed.\n");
+                       pr_err("DMA mapping failed.\n");
 
                this->direct_dma_map_ok = false;
        }
@@ -314,7 +319,7 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this,
        return 0;
 }
 
-static int __devinit
+static int
 acquire_register_block(struct gpmi_nand_data *this, const char *res_name)
 {
        struct platform_device *pdev = this->pdev;
@@ -355,7 +360,7 @@ static void release_register_block(struct gpmi_nand_data *this)
        res->bch_regs = NULL;
 }
 
-static int __devinit
+static int
 acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)
 {
        struct platform_device *pdev = this->pdev;
@@ -422,7 +427,7 @@ static void release_dma_channels(struct gpmi_nand_data *this)
                }
 }
 
-static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
+static int acquire_dma_channels(struct gpmi_nand_data *this)
 {
        struct platform_device *pdev = this->pdev;
        struct resource *r_dma;
@@ -456,7 +461,7 @@ static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
 
        dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
        if (!dma_chan) {
-               pr_err("dma_request_channel failed.\n");
+               pr_err("Failed to request DMA channel.\n");
                goto acquire_err;
        }
 
@@ -487,7 +492,7 @@ static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {
        "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
 };
 
-static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
+static int gpmi_get_clks(struct gpmi_nand_data *this)
 {
        struct resources *r = &this->resources;
        char **extra_clks = NULL;
@@ -533,7 +538,7 @@ err_clock:
        return -ENOMEM;
 }
 
-static int __devinit acquire_resources(struct gpmi_nand_data *this)
+static int acquire_resources(struct gpmi_nand_data *this)
 {
        struct pinctrl *pinctrl;
        int ret;
@@ -583,7 +588,7 @@ static void release_resources(struct gpmi_nand_data *this)
        release_dma_channels(this);
 }
 
-static int __devinit init_hardware(struct gpmi_nand_data *this)
+static int init_hardware(struct gpmi_nand_data *this)
 {
        int ret;
 
@@ -625,7 +630,8 @@ static int read_page_prepare(struct gpmi_nand_data *this,
                                                length, DMA_FROM_DEVICE);
                if (dma_mapping_error(dev, dest_phys)) {
                        if (alt_size < length) {
-                               pr_err("Alternate buffer is too small\n");
+                               pr_err("%s, Alternate buffer is too small\n",
+                                       __func__);
                                return -ENOMEM;
                        }
                        goto map_failed;
@@ -675,7 +681,8 @@ static int send_page_prepare(struct gpmi_nand_data *this,
                                                DMA_TO_DEVICE);
                if (dma_mapping_error(dev, source_phys)) {
                        if (alt_size < length) {
-                               pr_err("Alternate buffer is too small\n");
+                               pr_err("%s, Alternate buffer is too small\n",
+                                       __func__);
                                return -ENOMEM;
                        }
                        goto map_failed;
@@ -763,7 +770,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
 
 error_alloc:
        gpmi_free_dma_buffer(this);
-       pr_err("allocate DMA buffer ret!!\n");
+       pr_err("Error allocating DMA buffers!\n");
        return -ENOMEM;
 }
 
@@ -1474,7 +1481,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this)
        /* Set up the NFC geometry which is used by BCH. */
        ret = bch_set_geometry(this);
        if (ret) {
-               pr_err("set geometry ret : %d\n", ret);
+               pr_err("Error setting BCH geometry : %d\n", ret);
                return ret;
        }
 
@@ -1535,7 +1542,7 @@ static void gpmi_nfc_exit(struct gpmi_nand_data *this)
        gpmi_free_dma_buffer(this);
 }
 
-static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this)
+static int gpmi_nfc_init(struct gpmi_nand_data *this)
 {
        struct mtd_info  *mtd = &this->mtd;
        struct nand_chip *chip = &this->nand;
@@ -1618,7 +1625,7 @@ static const struct of_device_id gpmi_nand_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
 
-static int __devinit gpmi_nand_probe(struct platform_device *pdev)
+static int gpmi_nand_probe(struct platform_device *pdev)
 {
        struct gpmi_nand_data *this;
        const struct of_device_id *of_id;
@@ -1668,7 +1675,7 @@ exit_acquire_resources:
        return ret;
 }
 
-static int __devexit gpmi_nand_remove(struct platform_device *pdev)
+static int gpmi_nand_remove(struct platform_device *pdev)
 {
        struct gpmi_nand_data *this = platform_get_drvdata(pdev);
 
@@ -1685,7 +1692,7 @@ static struct platform_driver gpmi_nand_driver = {
                .of_match_table = gpmi_nand_id_table,
        },
        .probe   = gpmi_nand_probe,
-       .remove  = __devexit_p(gpmi_nand_remove),
+       .remove  = gpmi_nand_remove,
        .id_table = gpmi_ids,
 };
 module_platform_driver(gpmi_nand_driver);
index 7ac25c1..3d93a5e 100644 (file)
@@ -130,7 +130,6 @@ struct gpmi_nand_data {
        /* System Interface */
        struct device           *dev;
        struct platform_device  *pdev;
-       struct gpmi_nand_platform_data  *pdata;
 
        /* Resources */
        struct resources        resources;
index 100b677..8d415f0 100644 (file)
@@ -316,13 +316,17 @@ err:
        return ret;
 }
 
-static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base)
+static inline void jz_nand_iounmap_resource(struct resource *res,
+                                           void __iomem *base)
 {
        iounmap(base);
        release_mem_region(res->start, resource_size(res));
 }
 
-static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) {
+static int jz_nand_detect_bank(struct platform_device *pdev,
+                              struct jz_nand *nand, unsigned char bank,
+                              size_t chipnr, uint8_t *nand_maf_id,
+                              uint8_t *nand_dev_id) {
        int ret;
        int gpio;
        char gpio_name[9];
@@ -400,7 +404,7 @@ notfound_gpio:
        return ret;
 }
 
-static int __devinit jz_nand_probe(struct platform_device *pdev)
+static int jz_nand_probe(struct platform_device *pdev)
 {
        int ret;
        struct jz_nand *nand;
@@ -541,7 +545,7 @@ err_free:
        return ret;
 }
 
-static int __devexit jz_nand_remove(struct platform_device *pdev)
+static int jz_nand_remove(struct platform_device *pdev)
 {
        struct jz_nand *nand = platform_get_drvdata(pdev);
        struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
@@ -573,7 +577,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev)
 
 static struct platform_driver jz_nand_driver = {
        .probe = jz_nand_probe,
-       .remove = __devexit_p(jz_nand_remove),
+       .remove = jz_nand_remove,
        .driver = {
                .name = "jz4740-nand",
                .owner = THIS_MODULE,
index c29b7ac..f182bef 100644 (file)
@@ -655,7 +655,7 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev)
 /*
  * Probe for NAND controller
  */
-static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+static int lpc32xx_nand_probe(struct platform_device *pdev)
 {
        struct lpc32xx_nand_host *host;
        struct mtd_info *mtd;
@@ -845,7 +845,7 @@ err_exit1:
 /*
  * Remove NAND device
  */
-static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+static int lpc32xx_nand_remove(struct platform_device *pdev)
 {
        struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
        struct mtd_info *mtd = &host->mtd;
@@ -907,7 +907,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
 
 static struct platform_driver lpc32xx_nand_driver = {
        .probe          = lpc32xx_nand_probe,
-       .remove         = __devexit_p(lpc32xx_nand_remove),
+       .remove         = lpc32xx_nand_remove,
        .resume         = lpc32xx_nand_resume,
        .suspend        = lpc32xx_nand_suspend,
        .driver         = {
index 32409c4..030b78c 100644 (file)
@@ -755,7 +755,7 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev)
 /*
  * Probe for NAND controller
  */
-static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+static int lpc32xx_nand_probe(struct platform_device *pdev)
 {
        struct lpc32xx_nand_host *host;
        struct mtd_info *mtd;
@@ -949,7 +949,7 @@ err_exit1:
 /*
  * Remove NAND device.
  */
-static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+static int lpc32xx_nand_remove(struct platform_device *pdev)
 {
        uint32_t tmp;
        struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
@@ -1021,7 +1021,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
 
 static struct platform_driver lpc32xx_nand_driver = {
        .probe          = lpc32xx_nand_probe,
-       .remove         = __devexit_p(lpc32xx_nand_remove),
+       .remove         = lpc32xx_nand_remove,
        .resume         = lpc32xx_nand_resume,
        .suspend        = lpc32xx_nand_suspend,
        .driver         = {
index f776c85..3c9cdcb 100644 (file)
@@ -626,7 +626,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
                iounmap(prv->csreg);
 }
 
-static int __devinit mpc5121_nfc_probe(struct platform_device *op)
+static int mpc5121_nfc_probe(struct platform_device *op)
 {
        struct device_node *rootnode, *dn = op->dev.of_node;
        struct device *dev = &op->dev;
@@ -827,7 +827,7 @@ error:
        return retval;
 }
 
-static int __devexit mpc5121_nfc_remove(struct platform_device *op)
+static int mpc5121_nfc_remove(struct platform_device *op)
 {
        struct device *dev = &op->dev;
        struct mtd_info *mtd = dev_get_drvdata(dev);
@@ -841,14 +841,14 @@ static int __devexit mpc5121_nfc_remove(struct platform_device *op)
        return 0;
 }
 
-static struct of_device_id mpc5121_nfc_match[] __devinitdata = {
+static struct of_device_id mpc5121_nfc_match[] = {
        { .compatible = "fsl,mpc5121-nfc", },
        {},
 };
 
 static struct platform_driver mpc5121_nfc_driver = {
        .probe          = mpc5121_nfc_probe,
-       .remove         = __devexit_p(mpc5121_nfc_remove),
+       .remove         = mpc5121_nfc_remove,
        .driver         = {
                .name = DRV_NAME,
                .owner = THIS_MODULE,
index 022dcdc..45204e4 100644 (file)
@@ -266,7 +266,8 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = {
        }
 };
 
-static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL };
+static const char const *part_probes[] = {
+       "cmdlinepart", "RedBoot", "ofpart", NULL };
 
 static void memcpy32_fromio(void *trg, const void __iomem  *src, size_t size)
 {
@@ -1378,7 +1379,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
 }
 #endif
 
-static int __devinit mxcnd_probe(struct platform_device *pdev)
+static int mxcnd_probe(struct platform_device *pdev)
 {
        struct nand_chip *this;
        struct mtd_info *mtd;
@@ -1556,12 +1557,13 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)
        return 0;
 
 escan:
-       clk_disable_unprepare(host->clk);
+       if (host->clk_act)
+               clk_disable_unprepare(host->clk);
 
        return err;
 }
 
-static int __devexit mxcnd_remove(struct platform_device *pdev)
+static int mxcnd_remove(struct platform_device *pdev)
 {
        struct mxc_nand_host *host = platform_get_drvdata(pdev);
 
@@ -1580,7 +1582,7 @@ static struct platform_driver mxcnd_driver = {
        },
        .id_table = mxcnd_devtype,
        .probe = mxcnd_probe,
-       .remove = __devexit_p(mxcnd_remove),
+       .remove = mxcnd_remove,
 };
 module_platform_driver(mxcnd_driver);
 
index 1a03b7f..8323ac9 100644 (file)
@@ -93,8 +93,7 @@ static struct nand_ecclayout nand_oob_128 = {
                 .length = 78} }
 };
 
-static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
-                          int new_state);
+static int nand_get_device(struct mtd_info *mtd, int new_state);
 
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops);
@@ -130,15 +129,12 @@ static int check_offs_len(struct mtd_info *mtd,
  * nand_release_device - [GENERIC] release chip
  * @mtd: MTD device structure
  *
- * Deselect, release chip lock and wake up anyone waiting on the device.
+ * Release chip lock and wake up anyone waiting on the device.
  */
 static void nand_release_device(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       /* De-select the NAND device */
-       chip->select_chip(mtd, -1);
-
        /* Release the controller and the chip */
        spin_lock(&chip->controller->lock);
        chip->controller->active = NULL;
@@ -160,7 +156,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
 }
 
 /**
- * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
+ * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
  * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
  * @mtd: MTD device structure
  *
@@ -303,7 +299,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
        if (getchip) {
                chipnr = (int)(ofs >> chip->chip_shift);
 
-               nand_get_device(chip, mtd, FL_READING);
+               nand_get_device(mtd, FL_READING);
 
                /* Select the NAND device */
                chip->select_chip(mtd, chipnr);
@@ -333,8 +329,10 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                i++;
        } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
 
-       if (getchip)
+       if (getchip) {
+               chip->select_chip(mtd, -1);
                nand_release_device(mtd);
+       }
 
        return res;
 }
@@ -383,7 +381,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
                struct mtd_oob_ops ops;
                loff_t wr_ofs = ofs;
 
-               nand_get_device(chip, mtd, FL_WRITING);
+               nand_get_device(mtd, FL_WRITING);
 
                ops.datbuf = NULL;
                ops.oobbuf = buf;
@@ -492,7 +490,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
 void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
-       unsigned long timeo = jiffies + 2;
+       unsigned long timeo = jiffies + msecs_to_jiffies(20);
 
        /* 400ms timeout */
        if (in_interrupt() || oops_in_progress)
@@ -750,15 +748,15 @@ static void panic_nand_get_device(struct nand_chip *chip,
 
 /**
  * nand_get_device - [GENERIC] Get chip for selected access
- * @chip: the nand chip descriptor
  * @mtd: MTD device structure
  * @new_state: the state which is requested
  *
  * Get the device and lock it for exclusive access
  */
 static int
-nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
+nand_get_device(struct mtd_info *mtd, int new_state)
 {
+       struct nand_chip *chip = mtd->priv;
        spinlock_t *lock = &chip->controller->lock;
        wait_queue_head_t *wq = &chip->controller->wq;
        DECLARE_WAITQUEUE(wait, current);
@@ -865,6 +863,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
        led_trigger_event(nand_led_trigger, LED_OFF);
 
        status = (int)chip->read_byte(mtd);
+       /* This can happen if in case of timeout or buggy dev_ready */
+       WARN_ON(!(status & NAND_STATUS_READY));
        return status;
 }
 
@@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
        /* See if device thinks it succeeded */
-       if (status & 0x01) {
+       if (status & NAND_STATUS_FAIL) {
                pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
@@ -932,7 +932,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        if (ofs + len == mtd->size)
                len -= mtd->erasesize;
 
-       nand_get_device(chip, mtd, FL_UNLOCKING);
+       nand_get_device(mtd, FL_UNLOCKING);
 
        /* Shift to get chip number */
        chipnr = ofs >> chip->chip_shift;
@@ -950,6 +950,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        ret = __nand_unlock(mtd, ofs, len, 0);
 
 out:
+       chip->select_chip(mtd, -1);
        nand_release_device(mtd);
 
        return ret;
@@ -981,7 +982,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        if (check_offs_len(mtd, ofs, len))
                ret = -EINVAL;
 
-       nand_get_device(chip, mtd, FL_LOCKING);
+       nand_get_device(mtd, FL_LOCKING);
 
        /* Shift to get chip number */
        chipnr = ofs >> chip->chip_shift;
@@ -1004,7 +1005,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
        /* See if device thinks it succeeded */
-       if (status & 0x01) {
+       if (status & NAND_STATUS_FAIL) {
                pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
@@ -1014,6 +1015,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        ret = __nand_unlock(mtd, ofs, len, 0x1);
 
 out:
+       chip->select_chip(mtd, -1);
        nand_release_device(mtd);
 
        return ret;
@@ -1550,6 +1552,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
        }
+       chip->select_chip(mtd, -1);
 
        ops->retlen = ops->len - (size_t) readlen;
        if (oob)
@@ -1577,11 +1580,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, uint8_t *buf)
 {
-       struct nand_chip *chip = mtd->priv;
        struct mtd_oob_ops ops;
        int ret;
 
-       nand_get_device(chip, mtd, FL_READING);
+       nand_get_device(mtd, FL_READING);
        ops.len = len;
        ops.datbuf = buf;
        ops.oobbuf = NULL;
@@ -1804,6 +1806,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
        }
+       chip->select_chip(mtd, -1);
 
        ops->oobretlen = ops->ooblen - readlen;
 
@@ -1827,7 +1830,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
 {
-       struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
 
        ops->retlen = 0;
@@ -1839,7 +1841,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                return -EINVAL;
        }
 
-       nand_get_device(chip, mtd, FL_READING);
+       nand_get_device(mtd, FL_READING);
 
        switch (ops->mode) {
        case MTD_OPS_PLACE_OOB:
@@ -2186,8 +2188,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        chip->select_chip(mtd, chipnr);
 
        /* Check, if it is write protected */
-       if (nand_check_wp(mtd))
-               return -EIO;
+       if (nand_check_wp(mtd)) {
+               ret = -EIO;
+               goto err_out;
+       }
 
        realpage = (int)(to >> chip->page_shift);
        page = realpage & chip->pagemask;
@@ -2199,8 +2203,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                chip->pagebuf = -1;
 
        /* Don't allow multipage oob writes with offset */
-       if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
-               return -EINVAL;
+       if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) {
+               ret = -EINVAL;
+               goto err_out;
+       }
 
        while (1) {
                int bytes = mtd->writesize;
@@ -2251,6 +2257,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        ops->retlen = ops->len - writelen;
        if (unlikely(oob))
                ops->oobretlen = ops->ooblen;
+
+err_out:
+       chip->select_chip(mtd, -1);
        return ret;
 }
 
@@ -2302,11 +2311,10 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                          size_t *retlen, const uint8_t *buf)
 {
-       struct nand_chip *chip = mtd->priv;
        struct mtd_oob_ops ops;
        int ret;
 
-       nand_get_device(chip, mtd, FL_WRITING);
+       nand_get_device(mtd, FL_WRITING);
        ops.len = len;
        ops.datbuf = (uint8_t *)buf;
        ops.oobbuf = NULL;
@@ -2377,8 +2385,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
 
        /* Check, if it is write protected */
-       if (nand_check_wp(mtd))
+       if (nand_check_wp(mtd)) {
+               chip->select_chip(mtd, -1);
                return -EROFS;
+       }
 
        /* Invalidate the page cache, if we write to the cached page */
        if (page == chip->pagebuf)
@@ -2391,6 +2401,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        else
                status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
 
+       chip->select_chip(mtd, -1);
+
        if (status)
                return status;
 
@@ -2408,7 +2420,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
 {
-       struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
 
        ops->retlen = 0;
@@ -2420,7 +2431,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                return -EINVAL;
        }
 
-       nand_get_device(chip, mtd, FL_WRITING);
+       nand_get_device(mtd, FL_WRITING);
 
        switch (ops->mode) {
        case MTD_OPS_PLACE_OOB:
@@ -2513,7 +2524,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                return -EINVAL;
 
        /* Grab the lock and see if the device is available */
-       nand_get_device(chip, mtd, FL_ERASING);
+       nand_get_device(mtd, FL_ERASING);
 
        /* Shift to get first page */
        page = (int)(instr->addr >> chip->page_shift);
@@ -2623,6 +2634,7 @@ erase_exit:
        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
 
        /* Deselect and wake up anyone waiting on the device */
+       chip->select_chip(mtd, -1);
        nand_release_device(mtd);
 
        /* Do call back function */
@@ -2658,12 +2670,10 @@ erase_exit:
  */
 static void nand_sync(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
-
        pr_debug("%s: called\n", __func__);
 
        /* Grab the lock and see if the device is available */
-       nand_get_device(chip, mtd, FL_SYNCING);
+       nand_get_device(mtd, FL_SYNCING);
        /* Release it and go back */
        nand_release_device(mtd);
 }
@@ -2749,9 +2759,7 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
  */
 static int nand_suspend(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
-
-       return nand_get_device(chip, mtd, FL_PM_SUSPENDED);
+       return nand_get_device(mtd, FL_PM_SUSPENDED);
 }
 
 /**
@@ -2849,6 +2857,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        int i;
        int val;
 
+       /* ONFI need to be probed in 8 bits mode */
+       WARN_ON(chip->options & NAND_BUSWIDTH_16);
        /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
@@ -2913,7 +2923,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
  *
  * Check if an ID string is repeated within a given sequence of bytes at
  * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
- * period of 2). This is a helper function for nand_id_len(). Returns non-zero
+ * period of 3). This is a helper function for nand_id_len(). Returns non-zero
  * if the repetition has a period of @period; otherwise, returns zero.
  */
 static int nand_id_has_period(u8 *id_data, int arrlen, int period)
@@ -3242,11 +3252,15 @@ ident_done:
                        break;
        }
 
-       /*
-        * Check, if buswidth is correct. Hardware drivers should set
-        * chip correct!
-        */
-       if (busw != (chip->options & NAND_BUSWIDTH_16)) {
+       if (chip->options & NAND_BUSWIDTH_AUTO) {
+               WARN_ON(chip->options & NAND_BUSWIDTH_16);
+               chip->options |= busw;
+               nand_set_defaults(chip, busw);
+       } else if (busw != (chip->options & NAND_BUSWIDTH_16)) {
+               /*
+                * Check, if buswidth is correct. Hardware drivers should set
+                * chip correct!
+                */
                pr_info("NAND device: Manufacturer ID:"
                        " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
                        *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
@@ -3285,10 +3299,10 @@ ident_done:
                chip->cmdfunc = nand_command_lp;
 
        pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
-               " page size: %d, OOB size: %d\n",
+               " %dMiB, page size: %d, OOB size: %d\n",
                *maf_id, *dev_id, nand_manuf_ids[maf_idx].name,
                chip->onfi_version ? chip->onfi_params.model : type->name,
-               mtd->writesize, mtd->oobsize);
+               (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize);
 
        return type;
 }
@@ -3327,6 +3341,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                return PTR_ERR(type);
        }
 
+       chip->select_chip(mtd, -1);
+
        /* Check for a chip array */
        for (i = 1; i < maxchips; i++) {
                chip->select_chip(mtd, i);
@@ -3336,8 +3352,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
                /* Read manufacturer and device IDs */
                if (nand_maf_id != chip->read_byte(mtd) ||
-                   nand_dev_id != chip->read_byte(mtd))
+                   nand_dev_id != chip->read_byte(mtd)) {
+                       chip->select_chip(mtd, -1);
                        break;
+               }
+               chip->select_chip(mtd, -1);
        }
        if (i > 1)
                pr_info("%d NAND chips detected\n", i);
@@ -3596,9 +3615,6 @@ int nand_scan_tail(struct mtd_info *mtd)
        /* Initialize state */
        chip->state = FL_READY;
 
-       /* De-select the device */
-       chip->select_chip(mtd, -1);
-
        /* Invalidate the pagebuffer reference */
        chip->pagebuf = -1;
 
index c3c13e6..818b65c 100644 (file)
@@ -42,6 +42,8 @@
 #include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
 
 /* Default simulator parameters values */
 #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE)  || \
@@ -105,7 +107,6 @@ static char *weakblocks = NULL;
 static char *weakpages = NULL;
 static unsigned int bitflips = 0;
 static char *gravepages = NULL;
-static unsigned int rptwear = 0;
 static unsigned int overridesize = 0;
 static char *cache_file = NULL;
 static unsigned int bbt;
@@ -130,7 +131,6 @@ module_param(weakblocks,     charp, 0400);
 module_param(weakpages,      charp, 0400);
 module_param(bitflips,       uint, 0400);
 module_param(gravepages,     charp, 0400);
-module_param(rptwear,        uint, 0400);
 module_param(overridesize,   uint, 0400);
 module_param(cache_file,     charp, 0400);
 module_param(bbt,           uint, 0400);
@@ -162,7 +162,6 @@ MODULE_PARM_DESC(bitflips,       "Maximum number of random bit flips per page (z
 MODULE_PARM_DESC(gravepages,     "Pages that lose data [: maximum reads (defaults to 3)]"
                                 " separated by commas e.g. 1401:2 means page 1401"
                                 " can be read only twice before failing");
-MODULE_PARM_DESC(rptwear,        "Number of erases between reporting wear, if not zero");
 MODULE_PARM_DESC(overridesize,   "Specifies the NAND Flash size overriding the ID bytes. "
                                 "The size is specified in erase blocks and as the exponent of a power of two"
                                 " e.g. 5 means a size of 32 erase blocks");
@@ -286,6 +285,11 @@ MODULE_PARM_DESC(bch,               "Enable BCH ecc and set how many bits should "
 /* Maximum page cache pages needed to read or write a NAND page to the cache_file */
 #define NS_MAX_HELD_PAGES 16
 
+struct nandsim_debug_info {
+       struct dentry *dfs_root;
+       struct dentry *dfs_wear_report;
+};
+
 /*
  * A union to represent flash memory contents and flash buffer.
  */
@@ -365,6 +369,8 @@ struct nandsim {
        void *file_buf;
        struct page *held_pages[NS_MAX_HELD_PAGES];
        int held_cnt;
+
+       struct nandsim_debug_info dbg;
 };
 
 /*
@@ -442,11 +448,123 @@ static LIST_HEAD(grave_pages);
 static unsigned long *erase_block_wear = NULL;
 static unsigned int wear_eb_count = 0;
 static unsigned long total_wear = 0;
-static unsigned int rptwear_cnt = 0;
 
 /* MTD structure for NAND controller */
 static struct mtd_info *nsmtd;
 
+static int nandsim_debugfs_show(struct seq_file *m, void *private)
+{
+       unsigned long wmin = -1, wmax = 0, avg;
+       unsigned long deciles[10], decile_max[10], tot = 0;
+       unsigned int i;
+
+       /* Calc wear stats */
+       for (i = 0; i < wear_eb_count; ++i) {
+               unsigned long wear = erase_block_wear[i];
+               if (wear < wmin)
+                       wmin = wear;
+               if (wear > wmax)
+                       wmax = wear;
+               tot += wear;
+       }
+
+       for (i = 0; i < 9; ++i) {
+               deciles[i] = 0;
+               decile_max[i] = (wmax * (i + 1) + 5) / 10;
+       }
+       deciles[9] = 0;
+       decile_max[9] = wmax;
+       for (i = 0; i < wear_eb_count; ++i) {
+               int d;
+               unsigned long wear = erase_block_wear[i];
+               for (d = 0; d < 10; ++d)
+                       if (wear <= decile_max[d]) {
+                               deciles[d] += 1;
+                               break;
+                       }
+       }
+       avg = tot / wear_eb_count;
+
+       /* Output wear report */
+       seq_printf(m, "Total numbers of erases:  %lu\n", tot);
+       seq_printf(m, "Number of erase blocks:   %u\n", wear_eb_count);
+       seq_printf(m, "Average number of erases: %lu\n", avg);
+       seq_printf(m, "Maximum number of erases: %lu\n", wmax);
+       seq_printf(m, "Minimum number of erases: %lu\n", wmin);
+       for (i = 0; i < 10; ++i) {
+               unsigned long from = (i ? decile_max[i - 1] + 1 : 0);
+               if (from > decile_max[i])
+                       continue;
+               seq_printf(m, "Number of ebs with erase counts from %lu to %lu : %lu\n",
+                       from,
+                       decile_max[i],
+                       deciles[i]);
+       }
+
+       return 0;
+}
+
+static int nandsim_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, nandsim_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations dfs_fops = {
+       .open           = nandsim_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+/**
+ * nandsim_debugfs_create - initialize debugfs
+ * @dev: nandsim device description object
+ *
+ * This function creates all debugfs files for UBI device @ubi. Returns zero in
+ * case of success and a negative error code in case of failure.
+ */
+static int nandsim_debugfs_create(struct nandsim *dev)
+{
+       struct nandsim_debug_info *dbg = &dev->dbg;
+       struct dentry *dent;
+       int err;
+
+       if (!IS_ENABLED(CONFIG_DEBUG_FS))
+               return 0;
+
+       dent = debugfs_create_dir("nandsim", NULL);
+       if (IS_ERR_OR_NULL(dent)) {
+               int err = dent ? -ENODEV : PTR_ERR(dent);
+
+               NS_ERR("cannot create \"nandsim\" debugfs directory, err %d\n",
+                       err);
+               return err;
+       }
+       dbg->dfs_root = dent;
+
+       dent = debugfs_create_file("wear_report", S_IRUSR,
+                                  dbg->dfs_root, dev, &dfs_fops);
+       if (IS_ERR_OR_NULL(dent))
+               goto out_remove;
+       dbg->dfs_wear_report = dent;
+
+       return 0;
+
+out_remove:
+       debugfs_remove_recursive(dbg->dfs_root);
+       err = dent ? PTR_ERR(dent) : -ENODEV;
+       return err;
+}
+
+/**
+ * nandsim_debugfs_remove - destroy all debugfs files
+ */
+static void nandsim_debugfs_remove(struct nandsim *ns)
+{
+       if (IS_ENABLED(CONFIG_DEBUG_FS))
+               debugfs_remove_recursive(ns->dbg.dfs_root);
+}
+
 /*
  * Allocate array of page pointers, create slab allocation for an array
  * and initialize the array by NULL pointers.
@@ -911,8 +1029,6 @@ static int setup_wear_reporting(struct mtd_info *mtd)
 {
        size_t mem;
 
-       if (!rptwear)
-               return 0;
        wear_eb_count = div_u64(mtd->size, mtd->erasesize);
        mem = wear_eb_count * sizeof(unsigned long);
        if (mem / sizeof(unsigned long) != wear_eb_count) {
@@ -929,64 +1045,18 @@ static int setup_wear_reporting(struct mtd_info *mtd)
 
 static void update_wear(unsigned int erase_block_no)
 {
-       unsigned long wmin = -1, wmax = 0, avg;
-       unsigned long deciles[10], decile_max[10], tot = 0;
-       unsigned int i;
-
        if (!erase_block_wear)
                return;
        total_wear += 1;
+       /*
+        * TODO: Notify this through a debugfs entry,
+        * instead of showing an error message.
+        */
        if (total_wear == 0)
                NS_ERR("Erase counter total overflow\n");
        erase_block_wear[erase_block_no] += 1;
        if (erase_block_wear[erase_block_no] == 0)
                NS_ERR("Erase counter overflow for erase block %u\n", erase_block_no);
-       rptwear_cnt += 1;
-       if (rptwear_cnt < rptwear)
-               return;
-       rptwear_cnt = 0;
-       /* Calc wear stats */
-       for (i = 0; i < wear_eb_count; ++i) {
-               unsigned long wear = erase_block_wear[i];
-               if (wear < wmin)
-                       wmin = wear;
-               if (wear > wmax)
-                       wmax = wear;
-               tot += wear;
-       }
-       for (i = 0; i < 9; ++i) {
-               deciles[i] = 0;
-               decile_max[i] = (wmax * (i + 1) + 5) / 10;
-       }
-       deciles[9] = 0;
-       decile_max[9] = wmax;
-       for (i = 0; i < wear_eb_count; ++i) {
-               int d;
-               unsigned long wear = erase_block_wear[i];
-               for (d = 0; d < 10; ++d)
-                       if (wear <= decile_max[d]) {
-                               deciles[d] += 1;
-                               break;
-                       }
-       }
-       avg = tot / wear_eb_count;
-       /* Output wear report */
-       NS_INFO("*** Wear Report ***\n");
-       NS_INFO("Total numbers of erases:  %lu\n", tot);
-       NS_INFO("Number of erase blocks:   %u\n", wear_eb_count);
-       NS_INFO("Average number of erases: %lu\n", avg);
-       NS_INFO("Maximum number of erases: %lu\n", wmax);
-       NS_INFO("Minimum number of erases: %lu\n", wmin);
-       for (i = 0; i < 10; ++i) {
-               unsigned long from = (i ? decile_max[i - 1] + 1 : 0);
-               if (from > decile_max[i])
-                       continue;
-               NS_INFO("Number of ebs with erase counts from %lu to %lu : %lu\n",
-                       from,
-                       decile_max[i],
-                       deciles[i]);
-       }
-       NS_INFO("*** End of Wear Report ***\n");
 }
 
 /*
@@ -2327,6 +2397,9 @@ static int __init ns_init_module(void)
        if ((retval = setup_wear_reporting(nsmtd)) != 0)
                goto err_exit;
 
+       if ((retval = nandsim_debugfs_create(nand)) != 0)
+               goto err_exit;
+
        if ((retval = init_nandsim(nsmtd)) != 0)
                goto err_exit;
 
@@ -2366,6 +2439,7 @@ static void __exit ns_cleanup_module(void)
        struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv;
        int i;
 
+       nandsim_debugfs_remove(ns);
        free_nandsim(ns);    /* Free nandsim private resources */
        nand_release(nsmtd); /* Unregister driver */
        for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
index 5fd3f01..8e148f1 100644 (file)
@@ -197,7 +197,7 @@ err:
        return ret;
 }
 
-static int __devinit ndfc_probe(struct platform_device *ofdev)
+static int ndfc_probe(struct platform_device *ofdev)
 {
        struct ndfc_controller *ndfc;
        const __be32 *reg;
@@ -256,7 +256,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev)
        return 0;
 }
 
-static int __devexit ndfc_remove(struct platform_device *ofdev)
+static int ndfc_remove(struct platform_device *ofdev)
 {
        struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev);
 
@@ -279,7 +279,7 @@ static struct platform_driver ndfc_driver = {
                .of_match_table = ndfc_match,
        },
        .probe = ndfc_probe,
-       .remove = __devexit_p(ndfc_remove),
+       .remove = ndfc_remove,
 };
 
 module_platform_driver(ndfc_driver);
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c
deleted file mode 100644 (file)
index 9ee0c4e..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *  drivers/mtd/nand/nomadik_nand.c
- *
- *  Overview:
- *     Driver for on-board NAND flash on Nomadik Platforms
- *
- * Copyright Â© 2007 STMicroelectronics Pvt. Ltd.
- * Author: Sachin Verma <sachin.verma@st.com>
- *
- * Copyright Â© 2009 Alessandro Rubini
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/platform_data/mtd-nomadik-nand.h>
-#include <mach/fsmc.h>
-
-#include <mtd/mtd-abi.h>
-
-struct nomadik_nand_host {
-       struct mtd_info         mtd;
-       struct nand_chip        nand;
-       void __iomem *data_va;
-       void __iomem *cmd_va;
-       void __iomem *addr_va;
-       struct nand_bbt_descr *bbt_desc;
-};
-
-static struct nand_ecclayout nomadik_ecc_layout = {
-       .eccbytes = 3 * 4,
-       .eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */
-               0x02, 0x03, 0x04,
-               0x12, 0x13, 0x14,
-               0x22, 0x23, 0x24,
-               0x32, 0x33, 0x34},
-       /* let's keep bytes 5,6,7 for us, just in case we change ECC algo */
-       .oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} },
-};
-
-static void nomadik_ecc_control(struct mtd_info *mtd, int mode)
-{
-       /* No need to enable hw ecc, it's on by default */
-}
-
-static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-       struct nand_chip *nand = mtd->priv;
-       struct nomadik_nand_host *host = nand->priv;
-
-       if (cmd == NAND_CMD_NONE)
-               return;
-
-       if (ctrl & NAND_CLE)
-               writeb(cmd, host->cmd_va);
-       else
-               writeb(cmd, host->addr_va);
-}
-
-static int nomadik_nand_probe(struct platform_device *pdev)
-{
-       struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;
-       struct nomadik_nand_host *host;
-       struct mtd_info *mtd;
-       struct nand_chip *nand;
-       struct resource *res;
-       int ret = 0;
-
-       /* Allocate memory for the device structure (and zero it) */
-       host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL);
-       if (!host) {
-               dev_err(&pdev->dev, "Failed to allocate device structure.\n");
-               return -ENOMEM;
-       }
-
-       /* Call the client's init function, if any */
-       if (pdata->init)
-               ret = pdata->init();
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Init function failed\n");
-               goto err;
-       }
-
-       /* ioremap three regions */
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
-       if (!res) {
-               ret = -EIO;
-               goto err_unmap;
-       }
-       host->addr_va = ioremap(res->start, resource_size(res));
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
-       if (!res) {
-               ret = -EIO;
-               goto err_unmap;
-       }
-       host->data_va = ioremap(res->start, resource_size(res));
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
-       if (!res) {
-               ret = -EIO;
-               goto err_unmap;
-       }
-       host->cmd_va = ioremap(res->start, resource_size(res));
-
-       if (!host->addr_va || !host->data_va || !host->cmd_va) {
-               ret = -ENOMEM;
-               goto err_unmap;
-       }
-
-       /* Link all private pointers */
-       mtd = &host->mtd;
-       nand = &host->nand;
-       mtd->priv = nand;
-       nand->priv = host;
-
-       host->mtd.owner = THIS_MODULE;
-       nand->IO_ADDR_R = host->data_va;
-       nand->IO_ADDR_W = host->data_va;
-       nand->cmd_ctrl = nomadik_cmd_ctrl;
-
-       /*
-        * This stanza declares ECC_HW but uses soft routines. It's because
-        * HW claims to make the calculation but not the correction. However,
-        * I haven't managed to get the desired data out of it until now.
-        */
-       nand->ecc.mode = NAND_ECC_SOFT;
-       nand->ecc.layout = &nomadik_ecc_layout;
-       nand->ecc.hwctl = nomadik_ecc_control;
-       nand->ecc.size = 512;
-       nand->ecc.bytes = 3;
-
-       nand->options = pdata->options;
-
-       /*
-        * Scan to find existence of the device
-        */
-       if (nand_scan(&host->mtd, 1)) {
-               ret = -ENXIO;
-               goto err_unmap;
-       }
-
-       mtd_device_register(&host->mtd, pdata->parts, pdata->nparts);
-
-       platform_set_drvdata(pdev, host);
-       return 0;
-
- err_unmap:
-       if (host->cmd_va)
-               iounmap(host->cmd_va);
-       if (host->data_va)
-               iounmap(host->data_va);
-       if (host->addr_va)
-               iounmap(host->addr_va);
- err:
-       kfree(host);
-       return ret;
-}
-
-/*
- * Clean up routine
- */
-static int nomadik_nand_remove(struct platform_device *pdev)
-{
-       struct nomadik_nand_host *host = platform_get_drvdata(pdev);
-       struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;
-
-       if (pdata->exit)
-               pdata->exit();
-
-       if (host) {
-               nand_release(&host->mtd);
-               iounmap(host->cmd_va);
-               iounmap(host->data_va);
-               iounmap(host->addr_va);
-               kfree(host);
-       }
-       return 0;
-}
-
-static int nomadik_nand_suspend(struct device *dev)
-{
-       struct nomadik_nand_host *host = dev_get_drvdata(dev);
-       int ret = 0;
-       if (host)
-               ret = mtd_suspend(&host->mtd);
-       return ret;
-}
-
-static int nomadik_nand_resume(struct device *dev)
-{
-       struct nomadik_nand_host *host = dev_get_drvdata(dev);
-       if (host)
-               mtd_resume(&host->mtd);
-       return 0;
-}
-
-static const struct dev_pm_ops nomadik_nand_pm_ops = {
-       .suspend = nomadik_nand_suspend,
-       .resume = nomadik_nand_resume,
-};
-
-static struct platform_driver nomadik_nand_driver = {
-       .probe = nomadik_nand_probe,
-       .remove = nomadik_nand_remove,
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = "nomadik_nand",
-               .pm = &nomadik_nand_pm_ops,
-       },
-};
-
-module_platform_driver(nomadik_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
-MODULE_DESCRIPTION("NAND driver for Nomadik Platform");
index 94dc46b..a619119 100644 (file)
@@ -246,7 +246,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand)
        spin_unlock(&nand->lock);
 }
 
-static int __devinit nuc900_nand_probe(struct platform_device *pdev)
+static int nuc900_nand_probe(struct platform_device *pdev)
 {
        struct nuc900_nand *nuc900_nand;
        struct nand_chip *chip;
@@ -317,7 +317,7 @@ fail1:      kfree(nuc900_nand);
        return retval;
 }
 
-static int __devexit nuc900_nand_remove(struct platform_device *pdev)
+static int nuc900_nand_remove(struct platform_device *pdev)
 {
        struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);
        struct resource *res;
@@ -340,7 +340,7 @@ static int __devexit nuc900_nand_remove(struct platform_device *pdev)
 
 static struct platform_driver nuc900_nand_driver = {
        .probe          = nuc900_nand_probe,
-       .remove         = __devexit_p(nuc900_nand_remove),
+       .remove         = nuc900_nand_remove,
        .driver         = {
                .name   = "nuc900-fmi",
                .owner  = THIS_MODULE,
index 1f34ba1..0002d5e 100644 (file)
@@ -1323,7 +1323,7 @@ static void omap3_free_bch(struct mtd_info *mtd)
 }
 #endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-static int __devinit omap_nand_probe(struct platform_device *pdev)
+static int omap_nand_probe(struct platform_device *pdev)
 {
        struct omap_nand_info           *info;
        struct omap_nand_platform_data  *pdata;
index aefaf8c..cd72b92 100644 (file)
@@ -194,7 +194,7 @@ no_res:
        return ret;
 }
 
-static int __devexit orion_nand_remove(struct platform_device *pdev)
+static int orion_nand_remove(struct platform_device *pdev)
 {
        struct mtd_info *mtd = platform_get_drvdata(pdev);
        struct nand_chip *nc = mtd->priv;
@@ -223,7 +223,7 @@ static struct of_device_id orion_nand_of_match_table[] = {
 #endif
 
 static struct platform_driver orion_nand_driver = {
-       .remove         = __devexit_p(orion_nand_remove),
+       .remove         = orion_nand_remove,
        .driver         = {
                .name   = "orion_nand",
                .owner  = THIS_MODULE,
index 1440e51..5a67082 100644 (file)
@@ -89,7 +89,7 @@ int pasemi_device_ready(struct mtd_info *mtd)
        return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR);
 }
 
-static int __devinit pasemi_nand_probe(struct platform_device *ofdev)
+static int pasemi_nand_probe(struct platform_device *ofdev)
 {
        struct pci_dev *pdev;
        struct device_node *np = ofdev->dev.of_node;
@@ -184,7 +184,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev)
        return err;
 }
 
-static int __devexit pasemi_nand_remove(struct platform_device *ofdev)
+static int pasemi_nand_remove(struct platform_device *ofdev)
 {
        struct nand_chip *chip;
 
index a47ee68..c004566 100644 (file)
@@ -28,7 +28,7 @@ static const char *part_probe_types[] = { "cmdlinepart", NULL };
 /*
  * Probe for the NAND device.
  */
-static int __devinit plat_nand_probe(struct platform_device *pdev)
+static int plat_nand_probe(struct platform_device *pdev)
 {
        struct platform_nand_data *pdata = pdev->dev.platform_data;
        struct mtd_part_parser_data ppdata;
@@ -134,7 +134,7 @@ out_free:
 /*
  * Remove a NAND device.
  */
-static int __devexit plat_nand_remove(struct platform_device *pdev)
+static int plat_nand_remove(struct platform_device *pdev)
 {
        struct plat_nand_data *data = platform_get_drvdata(pdev);
        struct platform_nand_data *pdata = pdev->dev.platform_data;
@@ -160,7 +160,7 @@ MODULE_DEVICE_TABLE(of, plat_nand_match);
 
 static struct platform_driver plat_nand_driver = {
        .probe  = plat_nand_probe,
-       .remove = __devexit_p(plat_nand_remove),
+       .remove = plat_nand_remove,
        .driver = {
                .name           = "gen_nand",
                .owner          = THIS_MODULE,
index 79ded48..df954b4 100644 (file)
@@ -730,11 +730,14 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
                                      struct s3c2410_nand_mtd *mtd,
                                      struct s3c2410_nand_set *set)
 {
-       if (set)
+       if (set) {
                mtd->mtd.name = set->name;
 
-       return mtd_device_parse_register(&mtd->mtd, NULL, NULL,
+               return mtd_device_parse_register(&mtd->mtd, NULL, NULL,
                                         set->partitions, set->nr_partitions);
+       }
+
+       return -ENODEV;
 }
 
 /**
index f48ac5d..57b3971 100644 (file)
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mtd.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
@@ -106,6 +113,84 @@ static void wait_completion(struct sh_flctl *flctl)
        writeb(0x0, FLTRCR(flctl));
 }
 
+static void flctl_dma_complete(void *param)
+{
+       struct sh_flctl *flctl = param;
+
+       complete(&flctl->dma_complete);
+}
+
+static void flctl_release_dma(struct sh_flctl *flctl)
+{
+       if (flctl->chan_fifo0_rx) {
+               dma_release_channel(flctl->chan_fifo0_rx);
+               flctl->chan_fifo0_rx = NULL;
+       }
+       if (flctl->chan_fifo0_tx) {
+               dma_release_channel(flctl->chan_fifo0_tx);
+               flctl->chan_fifo0_tx = NULL;
+       }
+}
+
+static void flctl_setup_dma(struct sh_flctl *flctl)
+{
+       dma_cap_mask_t mask;
+       struct dma_slave_config cfg;
+       struct platform_device *pdev = flctl->pdev;
+       struct sh_flctl_platform_data *pdata = pdev->dev.platform_data;
+       int ret;
+
+       if (!pdata)
+               return;
+
+       if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0)
+               return;
+
+       /* We can only either use DMA for both Tx and Rx or not use it at all */
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+
+       flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter,
+                                           (void *)pdata->slave_id_fifo0_tx);
+       dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__,
+               flctl->chan_fifo0_tx);
+
+       if (!flctl->chan_fifo0_tx)
+               return;
+
+       memset(&cfg, 0, sizeof(cfg));
+       cfg.slave_id = pdata->slave_id_fifo0_tx;
+       cfg.direction = DMA_MEM_TO_DEV;
+       cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl);
+       cfg.src_addr = 0;
+       ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg);
+       if (ret < 0)
+               goto err;
+
+       flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter,
+                                           (void *)pdata->slave_id_fifo0_rx);
+       dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__,
+               flctl->chan_fifo0_rx);
+
+       if (!flctl->chan_fifo0_rx)
+               goto err;
+
+       cfg.slave_id = pdata->slave_id_fifo0_rx;
+       cfg.direction = DMA_DEV_TO_MEM;
+       cfg.dst_addr = 0;
+       cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl);
+       ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg);
+       if (ret < 0)
+               goto err;
+
+       init_completion(&flctl->dma_complete);
+
+       return;
+
+err:
+       flctl_release_dma(flctl);
+}
+
 static void set_addr(struct mtd_info *mtd, int column, int page_addr)
 {
        struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -225,7 +310,7 @@ static enum flctl_ecc_res_t wait_recfifo_ready
 
                for (i = 0; i < 3; i++) {
                        uint8_t org;
-                       int index;
+                       unsigned int index;
 
                        data = readl(ecc_reg[i]);
 
@@ -261,6 +346,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
        timeout_error(flctl, __func__);
 }
 
+static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
+                                       int len, enum dma_data_direction dir)
+{
+       struct dma_async_tx_descriptor *desc = NULL;
+       struct dma_chan *chan;
+       enum dma_transfer_direction tr_dir;
+       dma_addr_t dma_addr;
+       dma_cookie_t cookie = -EINVAL;
+       uint32_t reg;
+       int ret;
+
+       if (dir == DMA_FROM_DEVICE) {
+               chan = flctl->chan_fifo0_rx;
+               tr_dir = DMA_DEV_TO_MEM;
+       } else {
+               chan = flctl->chan_fifo0_tx;
+               tr_dir = DMA_MEM_TO_DEV;
+       }
+
+       dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
+
+       if (dma_addr)
+               desc = dmaengine_prep_slave_single(chan, dma_addr, len,
+                       tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+       if (desc) {
+               reg = readl(FLINTDMACR(flctl));
+               reg |= DREQ0EN;
+               writel(reg, FLINTDMACR(flctl));
+
+               desc->callback = flctl_dma_complete;
+               desc->callback_param = flctl;
+               cookie = dmaengine_submit(desc);
+
+               dma_async_issue_pending(chan);
+       } else {
+               /* DMA failed, fall back to PIO */
+               flctl_release_dma(flctl);
+               dev_warn(&flctl->pdev->dev,
+                        "DMA failed, falling back to PIO\n");
+               ret = -EIO;
+               goto out;
+       }
+
+       ret =
+       wait_for_completion_timeout(&flctl->dma_complete,
+                               msecs_to_jiffies(3000));
+
+       if (ret <= 0) {
+               chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+               dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
+       }
+
+out:
+       reg = readl(FLINTDMACR(flctl));
+       reg &= ~DREQ0EN;
+       writel(reg, FLINTDMACR(flctl));
+
+       dma_unmap_single(chan->device->dev, dma_addr, len, dir);
+
+       /* ret > 0 is success */
+       return ret;
+}
+
 static void read_datareg(struct sh_flctl *flctl, int offset)
 {
        unsigned long data;
@@ -279,11 +428,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 
        len_4align = (rlen + 3) / 4;
 
+       /* initiate DMA transfer */
+       if (flctl->chan_fifo0_rx && rlen >= 32 &&
+               flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0)
+                       goto convert;   /* DMA success */
+
+       /* do polling transfer */
        for (i = 0; i < len_4align; i++) {
                wait_rfifo_ready(flctl);
                buf[i] = readl(FLDTFIFO(flctl));
-               buf[i] = be32_to_cpu(buf[i]);
        }
+
+convert:
+       for (i = 0; i < len_4align; i++)
+               buf[i] = be32_to_cpu(buf[i]);
 }
 
 static enum flctl_ecc_res_t read_ecfiforeg
@@ -305,28 +463,39 @@ static enum flctl_ecc_res_t read_ecfiforeg
        return res;
 }
 
-static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+static void write_fiforeg(struct sh_flctl *flctl, int rlen,
+                                               unsigned int offset)
 {
        int i, len_4align;
-       unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
-       void *fifo_addr = (void *)FLDTFIFO(flctl);
+       unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 
        len_4align = (rlen + 3) / 4;
        for (i = 0; i < len_4align; i++) {
                wait_wfifo_ready(flctl);
-               writel(cpu_to_be32(data[i]), fifo_addr);
+               writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl));
        }
 }
 
-static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
+                                               unsigned int offset)
 {
        int i, len_4align;
-       unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+       unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 
        len_4align = (rlen + 3) / 4;
+
+       for (i = 0; i < len_4align; i++)
+               buf[i] = cpu_to_be32(buf[i]);
+
+       /* initiate DMA transfer */
+       if (flctl->chan_fifo0_tx && rlen >= 32 &&
+               flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0)
+                       return; /* DMA success */
+
+       /* do polling transfer */
        for (i = 0; i < len_4align; i++) {
                wait_wecfifo_ready(flctl);
-               writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
+               writel(buf[i], FLECFIFO(flctl));
        }
 }
 
@@ -750,41 +919,35 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
 static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
        struct sh_flctl *flctl = mtd_to_flctl(mtd);
-       int index = flctl->index;
 
-       memcpy(&flctl->done_buff[index], buf, len);
+       memcpy(&flctl->done_buff[flctl->index], buf, len);
        flctl->index += len;
 }
 
 static uint8_t flctl_read_byte(struct mtd_info *mtd)
 {
        struct sh_flctl *flctl = mtd_to_flctl(mtd);
-       int index = flctl->index;
        uint8_t data;
 
-       data = flctl->done_buff[index];
+       data = flctl->done_buff[flctl->index];
        flctl->index++;
        return data;
 }
 
 static uint16_t flctl_read_word(struct mtd_info *mtd)
 {
-       struct sh_flctl *flctl = mtd_to_flctl(mtd);
-       int index = flctl->index;
-       uint16_t data;
-       uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
+       struct sh_flctl *flctl = mtd_to_flctl(mtd);
+       uint16_t *buf = (uint16_t *)&flctl->done_buff[flctl->index];
 
-       data = *buf;
-       flctl->index += 2;
-       return data;
+       flctl->index += 2;
+       return *buf;
 }
 
 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
        struct sh_flctl *flctl = mtd_to_flctl(mtd);
-       int index = flctl->index;
 
-       memcpy(buf, &flctl->done_buff[index], len);
+       memcpy(buf, &flctl->done_buff[flctl->index], len);
        flctl->index += len;
 }
 
@@ -858,7 +1021,74 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int __devinit flctl_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+struct flctl_soc_config {
+       unsigned long flcmncr_val;
+       unsigned has_hwecc:1;
+       unsigned use_holden:1;
+};
+
+static struct flctl_soc_config flctl_sh7372_config = {
+       .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL,
+       .has_hwecc = 1,
+       .use_holden = 1,
+};
+
+static const struct of_device_id of_flctl_match[] = {
+       { .compatible = "renesas,shmobile-flctl-sh7372",
+                               .data = &flctl_sh7372_config },
+       {},
+};
+MODULE_DEVICE_TABLE(of, of_flctl_match);
+
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+       const struct of_device_id *match;
+       struct flctl_soc_config *config;
+       struct sh_flctl_platform_data *pdata;
+       struct device_node *dn = dev->of_node;
+       int ret;
+
+       match = of_match_device(of_flctl_match, dev);
+       if (match)
+               config = (struct flctl_soc_config *)match->data;
+       else {
+               dev_err(dev, "%s: no OF configuration attached\n", __func__);
+               return NULL;
+       }
+
+       pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data),
+                                                               GFP_KERNEL);
+       if (!pdata) {
+               dev_err(dev, "%s: failed to allocate config data\n", __func__);
+               return NULL;
+       }
+
+       /* set SoC specific options */
+       pdata->flcmncr_val = config->flcmncr_val;
+       pdata->has_hwecc = config->has_hwecc;
+       pdata->use_holden = config->use_holden;
+
+       /* parse user defined options */
+       ret = of_get_nand_bus_width(dn);
+       if (ret == 16)
+               pdata->flcmncr_val |= SEL_16BIT;
+       else if (ret != 8) {
+               dev_err(dev, "%s: invalid bus width\n", __func__);
+               return NULL;
+       }
+
+       return pdata;
+}
+#else /* CONFIG_OF */
+#define of_flctl_match NULL
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+       return NULL;
+}
+#endif /* CONFIG_OF */
+
+static int flctl_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct sh_flctl *flctl;
@@ -867,12 +1097,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
        struct sh_flctl_platform_data *pdata;
        int ret = -ENXIO;
        int irq;
-
-       pdata = pdev->dev.platform_data;
-       if (pdata == NULL) {
-               dev_err(&pdev->dev, "no platform data defined\n");
-               return -EINVAL;
-       }
+       struct mtd_part_parser_data ppdata = {};
 
        flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
        if (!flctl) {
@@ -904,6 +1129,17 @@ static int __devinit flctl_probe(struct platform_device *pdev)
                goto err_flste;
        }
 
+       if (pdev->dev.of_node)
+               pdata = flctl_parse_dt(&pdev->dev);
+       else
+               pdata = pdev->dev.platform_data;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "no setup data defined\n");
+               ret = -EINVAL;
+               goto err_pdata;
+       }
+
        platform_set_drvdata(pdev, flctl);
        flctl_mtd = &flctl->mtd;
        nand = &flctl->chip;
@@ -932,6 +1168,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        pm_runtime_resume(&pdev->dev);
 
+       flctl_setup_dma(flctl);
+
        ret = nand_scan_ident(flctl_mtd, 1, NULL);
        if (ret)
                goto err_chip;
@@ -944,12 +1182,16 @@ static int __devinit flctl_probe(struct platform_device *pdev)
        if (ret)
                goto err_chip;
 
-       mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+       ppdata.of_node = pdev->dev.of_node;
+       ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts,
+                       pdata->nr_parts);
 
        return 0;
 
 err_chip:
+       flctl_release_dma(flctl);
        pm_runtime_disable(&pdev->dev);
+err_pdata:
        free_irq(irq, flctl);
 err_flste:
        iounmap(flctl->reg);
@@ -958,10 +1200,11 @@ err_iomap:
        return ret;
 }
 
-static int __devexit flctl_remove(struct platform_device *pdev)
+static int flctl_remove(struct platform_device *pdev)
 {
        struct sh_flctl *flctl = platform_get_drvdata(pdev);
 
+       flctl_release_dma(flctl);
        nand_release(&flctl->mtd);
        pm_runtime_disable(&pdev->dev);
        free_irq(platform_get_irq(pdev, 0), flctl);
@@ -976,6 +1219,7 @@ static struct platform_driver flctl_driver = {
        .driver = {
                .name   = "sh_flctl",
                .owner  = THIS_MODULE,
+               .of_match_table = of_flctl_match,
        },
 };
 
index 3421e37..127bc42 100644 (file)
@@ -106,7 +106,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat,
 /*
  * Main initialization routine
  */
-static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
+static int sharpsl_nand_probe(struct platform_device *pdev)
 {
        struct nand_chip *this;
        struct resource *r;
@@ -205,7 +205,7 @@ err_get_res:
 /*
  * Clean up routine
  */
-static int __devexit sharpsl_nand_remove(struct platform_device *pdev)
+static int sharpsl_nand_remove(struct platform_device *pdev)
 {
        struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev);
 
@@ -228,7 +228,7 @@ static struct platform_driver sharpsl_nand_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = sharpsl_nand_probe,
-       .remove         = __devexit_p(sharpsl_nand_remove),
+       .remove         = sharpsl_nand_remove,
 };
 
 module_platform_driver(sharpsl_nand_driver);
index f3f28fa..09dde7d 100644 (file)
@@ -140,7 +140,7 @@ static int socrates_nand_device_ready(struct mtd_info *mtd)
 /*
  * Probe for the NAND device.
  */
-static int __devinit socrates_nand_probe(struct platform_device *ofdev)
+static int socrates_nand_probe(struct platform_device *ofdev)
 {
        struct socrates_nand_host *host;
        struct mtd_info *mtd;
@@ -220,7 +220,7 @@ out:
 /*
  * Remove a NAND device.
  */
-static int __devexit socrates_nand_remove(struct platform_device *ofdev)
+static int socrates_nand_remove(struct platform_device *ofdev)
 {
        struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
        struct mtd_info *mtd = &host->mtd;
@@ -251,7 +251,7 @@ static struct platform_driver socrates_nand_driver = {
                .of_match_table = socrates_nand_match,
        },
        .probe          = socrates_nand_probe,
-       .remove         = __devexit_p(socrates_nand_remove),
+       .remove         = socrates_nand_remove,
 };
 
 module_platform_driver(socrates_nand_driver);
index d9127e2..dbd3aa5 100644 (file)
@@ -71,7 +71,10 @@ static int parse_ofpart_partitions(struct mtd_info *master,
                (*pparts)[i].name = (char *)partname;
 
                if (of_get_property(pp, "read-only", &len))
-                       (*pparts)[i].mask_flags = MTD_WRITEABLE;
+                       (*pparts)[i].mask_flags |= MTD_WRITEABLE;
+
+               if (of_get_property(pp, "lock", &len))
+                       (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK;
 
                i++;
        }
index 1c4f97c..9f11562 100644 (file)
@@ -35,7 +35,7 @@ struct onenand_info {
        struct onenand_chip     onenand;
 };
 
-static int __devinit generic_onenand_probe(struct platform_device *pdev)
+static int generic_onenand_probe(struct platform_device *pdev)
 {
        struct onenand_info *info;
        struct onenand_platform_data *pdata = pdev->dev.platform_data;
@@ -88,7 +88,7 @@ out_free_info:
        return err;
 }
 
-static int __devexit generic_onenand_remove(struct platform_device *pdev)
+static int generic_onenand_remove(struct platform_device *pdev)
 {
        struct onenand_info *info = platform_get_drvdata(pdev);
        struct resource *res = pdev->resource;
@@ -112,7 +112,7 @@ static struct platform_driver generic_onenand_driver = {
                .owner          = THIS_MODULE,
        },
        .probe          = generic_onenand_probe,
-       .remove         = __devexit_p(generic_onenand_remove),
+       .remove         = generic_onenand_remove,
 };
 
 module_platform_driver(generic_onenand_driver);
index 00cd3da..065f3fe 100644 (file)
@@ -630,7 +630,7 @@ static int omap2_onenand_disable(struct mtd_info *mtd)
        return ret;
 }
 
-static int __devinit omap2_onenand_probe(struct platform_device *pdev)
+static int omap2_onenand_probe(struct platform_device *pdev)
 {
        struct omap_onenand_platform_data *pdata;
        struct omap2_onenand *c;
@@ -799,7 +799,7 @@ err_kfree:
        return r;
 }
 
-static int __devexit omap2_onenand_remove(struct platform_device *pdev)
+static int omap2_onenand_remove(struct platform_device *pdev)
 {
        struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
@@ -822,7 +822,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
 
 static struct platform_driver omap2_onenand_driver = {
        .probe          = omap2_onenand_probe,
-       .remove         = __devexit_p(omap2_onenand_remove),
+       .remove         = omap2_onenand_remove,
        .shutdown       = omap2_onenand_shutdown,
        .driver         = {
                .name   = DRIVER_NAME,
index 8e4b3f2..33f2a8f 100644 (file)
@@ -1053,7 +1053,7 @@ onenand_fail:
        return err;
 }
 
-static int __devexit s3c_onenand_remove(struct platform_device *pdev)
+static int s3c_onenand_remove(struct platform_device *pdev)
 {
        struct mtd_info *mtd = platform_get_drvdata(pdev);
 
@@ -1130,7 +1130,7 @@ static struct platform_driver s3c_onenand_driver = {
        },
        .id_table       = s3c_onenand_driver_ids,
        .probe          = s3c_onenand_probe,
-       .remove         = __devexit_p(s3c_onenand_remove),
+       .remove         = s3c_onenand_remove,
 };
 
 module_platform_driver(s3c_onenand_driver);
index cc8d62c..207bf9a 100644 (file)
@@ -39,6 +39,9 @@
  * this program; see the file COPYING. If not, write to the Free Software
  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -47,8 +50,6 @@
 #include <linux/mtd/nand.h>
 #include <linux/slab.h>
 
-#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
-
 static int dev;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -103,7 +104,7 @@ static int erase_block(void)
        struct erase_info ei;
        loff_t addr = eraseblock * mtd->erasesize;
 
-       msg("erase_block\n");
+       pr_info("erase_block\n");
 
        memset(&ei, 0, sizeof(struct erase_info));
        ei.mtd  = mtd;
@@ -112,7 +113,7 @@ static int erase_block(void)
 
        err = mtd_erase(mtd, &ei);
        if (err || ei.state == MTD_ERASE_FAILED) {
-               msg("error %d while erasing\n", err);
+               pr_err("error %d while erasing\n", err);
                if (!err)
                        err = -EIO;
                return err;
@@ -128,11 +129,11 @@ static int write_page(int log)
        size_t written;
 
        if (log)
-               msg("write_page\n");
+               pr_info("write_page\n");
 
        err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);
        if (err || written != mtd->writesize) {
-               msg("error: write failed at %#llx\n", (long long)offset);
+               pr_err("error: write failed at %#llx\n", (long long)offset);
                if (!err)
                        err = -EIO;
        }
@@ -147,7 +148,7 @@ static int rewrite_page(int log)
        struct mtd_oob_ops ops;
 
        if (log)
-               msg("rewrite page\n");
+               pr_info("rewrite page\n");
 
        ops.mode      = MTD_OPS_RAW; /* No ECC */
        ops.len       = mtd->writesize;
@@ -160,7 +161,7 @@ static int rewrite_page(int log)
 
        err = mtd_write_oob(mtd, offset, &ops);
        if (err || ops.retlen != mtd->writesize) {
-               msg("error: write_oob failed (%d)\n", err);
+               pr_err("error: write_oob failed (%d)\n", err);
                if (!err)
                        err = -EIO;
        }
@@ -177,7 +178,7 @@ static int read_page(int log)
        struct mtd_ecc_stats oldstats;
 
        if (log)
-               msg("read_page\n");
+               pr_info("read_page\n");
 
        /* Saving last mtd stats */
        memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
@@ -187,7 +188,7 @@ static int read_page(int log)
                err = mtd->ecc_stats.corrected - oldstats.corrected;
 
        if (err < 0 || read != mtd->writesize) {
-               msg("error: read failed at %#llx\n", (long long)offset);
+               pr_err("error: read failed at %#llx\n", (long long)offset);
                if (err >= 0)
                        err = -EIO;
        }
@@ -201,11 +202,11 @@ static int verify_page(int log)
        unsigned i, errs = 0;
 
        if (log)
-               msg("verify_page\n");
+               pr_info("verify_page\n");
 
        for (i = 0; i < mtd->writesize; i++) {
                if (rbuffer[i] != hash(i+seed)) {
-                       msg("Error: page offset %u, expected %02x, got %02x\n",
+                       pr_err("Error: page offset %u, expected %02x, got %02x\n",
                                i, hash(i+seed), rbuffer[i]);
                        errs++;
                }
@@ -230,13 +231,13 @@ static int insert_biterror(unsigned byte)
                for (bit = 7; bit >= 0; bit--) {
                        if (CBIT(wbuffer[byte], bit)) {
                                BCLR(wbuffer[byte], bit);
-                               msg("Inserted biterror @ %u/%u\n", byte, bit);
+                               pr_info("Inserted biterror @ %u/%u\n", byte, bit);
                                return 0;
                        }
                }
                byte++;
        }
-       msg("biterror: Failed to find a '1' bit\n");
+       pr_err("biterror: Failed to find a '1' bit\n");
        return -EIO;
 }
 
@@ -248,7 +249,7 @@ static int incremental_errors_test(void)
        unsigned i;
        unsigned errs_per_subpage = 0;
 
-       msg("incremental biterrors test\n");
+       pr_info("incremental biterrors test\n");
 
        for (i = 0; i < mtd->writesize; i++)
                wbuffer[i] = hash(i+seed);
@@ -265,9 +266,9 @@ static int incremental_errors_test(void)
 
                err = read_page(1);
                if (err > 0)
-                       msg("Read reported %d corrected bit errors\n", err);
+                       pr_info("Read reported %d corrected bit errors\n", err);
                if (err < 0) {
-                       msg("After %d biterrors per subpage, read reported error %d\n",
+                       pr_err("After %d biterrors per subpage, read reported error %d\n",
                                errs_per_subpage, err);
                        err = 0;
                        goto exit;
@@ -275,11 +276,11 @@ static int incremental_errors_test(void)
 
                err = verify_page(1);
                if (err) {
-                       msg("ECC failure, read data is incorrect despite read success\n");
+                       pr_err("ECC failure, read data is incorrect despite read success\n");
                        goto exit;
                }
 
-               msg("Successfully corrected %d bit errors per subpage\n",
+               pr_info("Successfully corrected %d bit errors per subpage\n",
                        errs_per_subpage);
 
                for (i = 0; i < subcount; i++) {
@@ -311,7 +312,7 @@ static int overwrite_test(void)
 
        memset(bitstats, 0, sizeof(bitstats));
 
-       msg("overwrite biterrors test\n");
+       pr_info("overwrite biterrors test\n");
 
        for (i = 0; i < mtd->writesize; i++)
                wbuffer[i] = hash(i+seed);
@@ -329,18 +330,18 @@ static int overwrite_test(void)
                err = read_page(0);
                if (err >= 0) {
                        if (err >= MAXBITS) {
-                               msg("Implausible number of bit errors corrected\n");
+                               pr_info("Implausible number of bit errors corrected\n");
                                err = -EIO;
                                break;
                        }
                        bitstats[err]++;
                        if (err > max_corrected) {
                                max_corrected = err;
-                               msg("Read reported %d corrected bit errors\n",
+                               pr_info("Read reported %d corrected bit errors\n",
                                        err);
                        }
                } else { /* err < 0 */
-                       msg("Read reported error %d\n", err);
+                       pr_info("Read reported error %d\n", err);
                        err = 0;
                        break;
                }
@@ -348,7 +349,7 @@ static int overwrite_test(void)
                err = verify_page(0);
                if (err) {
                        bitstats[max_corrected] = opno;
-                       msg("ECC failure, read data is incorrect despite read success\n");
+                       pr_info("ECC failure, read data is incorrect despite read success\n");
                        break;
                }
 
@@ -357,9 +358,9 @@ static int overwrite_test(void)
 
        /* At this point bitstats[0] contains the number of ops with no bit
         * errors, bitstats[1] the number of ops with 1 bit error, etc. */
-       msg("Bit error histogram (%d operations total):\n", opno);
+       pr_info("Bit error histogram (%d operations total):\n", opno);
        for (i = 0; i < max_corrected; i++)
-               msg("Page reads with %3d corrected bit errors: %d\n",
+               pr_info("Page reads with %3d corrected bit errors: %d\n",
                        i, bitstats[i]);
 
 exit:
@@ -370,36 +371,36 @@ static int __init mtd_nandbiterrs_init(void)
 {
        int err = 0;
 
-       msg("\n");
-       msg("==================================================\n");
-       msg("MTD device: %d\n", dev);
+       printk("\n");
+       printk(KERN_INFO "==================================================\n");
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               msg("error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                goto exit_mtddev;
        }
 
        if (mtd->type != MTD_NANDFLASH) {
-               msg("this test requires NAND flash\n");
+               pr_info("this test requires NAND flash\n");
                err = -ENODEV;
                goto exit_nand;
        }
 
-       msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
+       pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
                (unsigned long long)mtd->size, mtd->erasesize,
                mtd->writesize, mtd->oobsize);
 
        subsize  = mtd->writesize >> mtd->subpage_sft;
        subcount = mtd->writesize / subsize;
 
-       msg("Device uses %d subpages of %d bytes\n", subcount, subsize);
+       pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);
 
        offset     = page_offset * mtd->writesize;
        eraseblock = mtd_div_by_eb(offset, mtd);
 
-       msg("Using page=%u, offset=%llu, eraseblock=%u\n",
+       pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",
                page_offset, offset, eraseblock);
 
        wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
@@ -432,8 +433,8 @@ static int __init mtd_nandbiterrs_init(void)
                goto exit_error;
 
        err = -EIO;
-       msg("finished successfully.\n");
-       msg("==================================================\n");
+       pr_info("finished successfully.\n");
+       printk(KERN_INFO "==================================================\n");
 
 exit_error:
        kfree(rbuffer);
index b437fa4..1eee264 100644 (file)
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/list.h>
@@ -264,13 +266,13 @@ static int nand_ecc_test_run(const size_t size)
                                                correct_data, size);
 
                if (err) {
-                       pr_err("mtd_nandecctest: not ok - %s-%zd\n",
+                       pr_err("not ok - %s-%zd\n",
                                nand_ecc_test[i].name, size);
                        dump_data_ecc(error_data, error_ecc,
                                correct_data, correct_ecc, size);
                        break;
                }
-               pr_info("mtd_nandecctest: ok - %s-%zd\n",
+               pr_info("ok - %s-%zd\n",
                        nand_ecc_test[i].name, size);
        }
 error:
index ed9b628..e827fa8 100644 (file)
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -28,8 +30,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_oobtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -80,13 +80,12 @@ static int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
-                      ebnum);
+               pr_err("some erase error occurred at EB %d\n", ebnum);
                return -EIO;
        }
 
@@ -98,7 +97,7 @@ static int erase_whole_device(void)
        int err;
        unsigned int i;
 
-       printk(PRINT_PREF "erasing whole device\n");
+       pr_info("erasing whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -107,7 +106,7 @@ static int erase_whole_device(void)
                        return err;
                cond_resched();
        }
-       printk(PRINT_PREF "erased %u eraseblocks\n", i);
+       pr_info("erased %u eraseblocks\n", i);
        return 0;
 }
 
@@ -141,9 +140,9 @@ static int write_eraseblock(int ebnum)
                ops.oobbuf    = writebuf;
                err = mtd_write_oob(mtd, addr, &ops);
                if (err || ops.oobretlen != use_len) {
-                       printk(PRINT_PREF "error: writeoob failed at %#llx\n",
+                       pr_err("error: writeoob failed at %#llx\n",
                               (long long)addr);
-                       printk(PRINT_PREF "error: use_len %d, use_offset %d\n",
+                       pr_err("error: use_len %d, use_offset %d\n",
                               use_len, use_offset);
                        errcnt += 1;
                        return err ? err : -1;
@@ -160,7 +159,7 @@ static int write_whole_device(void)
        int err;
        unsigned int i;
 
-       printk(PRINT_PREF "writing OOBs of whole device\n");
+       pr_info("writing OOBs of whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -168,10 +167,10 @@ static int write_whole_device(void)
                if (err)
                        return err;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "written up to eraseblock %u\n", i);
+                       pr_info("written up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "written %u eraseblocks\n", i);
+       pr_info("written %u eraseblocks\n", i);
        return 0;
 }
 
@@ -194,17 +193,17 @@ static int verify_eraseblock(int ebnum)
                ops.oobbuf    = readbuf;
                err = mtd_read_oob(mtd, addr, &ops);
                if (err || ops.oobretlen != use_len) {
-                       printk(PRINT_PREF "error: readoob failed at %#llx\n",
+                       pr_err("error: readoob failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                        return err ? err : -1;
                }
                if (memcmp(readbuf, writebuf, use_len)) {
-                       printk(PRINT_PREF "error: verify failed at %#llx\n",
+                       pr_err("error: verify failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                        if (errcnt > 1000) {
-                               printk(PRINT_PREF "error: too many errors\n");
+                               pr_err("error: too many errors\n");
                                return -1;
                        }
                }
@@ -221,29 +220,28 @@ static int verify_eraseblock(int ebnum)
                        ops.oobbuf    = readbuf;
                        err = mtd_read_oob(mtd, addr, &ops);
                        if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
-                               printk(PRINT_PREF "error: readoob failed at "
-                                      "%#llx\n", (long long)addr);
+                               pr_err("error: readoob failed at %#llx\n",
+                                               (long long)addr);
                                errcnt += 1;
                                return err ? err : -1;
                        }
                        if (memcmp(readbuf + use_offset, writebuf, use_len)) {
-                               printk(PRINT_PREF "error: verify failed at "
-                                      "%#llx\n", (long long)addr);
+                               pr_err("error: verify failed at %#llx\n",
+                                               (long long)addr);
                                errcnt += 1;
                                if (errcnt > 1000) {
-                                       printk(PRINT_PREF "error: too many "
-                                              "errors\n");
+                                       pr_err("error: too many errors\n");
                                        return -1;
                                }
                        }
                        for (k = 0; k < use_offset; ++k)
                                if (readbuf[k] != 0xff) {
-                                       printk(PRINT_PREF "error: verify 0xff "
+                                       pr_err("error: verify 0xff "
                                               "failed at %#llx\n",
                                               (long long)addr);
                                        errcnt += 1;
                                        if (errcnt > 1000) {
-                                               printk(PRINT_PREF "error: too "
+                                               pr_err("error: too "
                                                       "many errors\n");
                                                return -1;
                                        }
@@ -251,12 +249,12 @@ static int verify_eraseblock(int ebnum)
                        for (k = use_offset + use_len;
                             k < mtd->ecclayout->oobavail; ++k)
                                if (readbuf[k] != 0xff) {
-                                       printk(PRINT_PREF "error: verify 0xff "
+                                       pr_err("error: verify 0xff "
                                               "failed at %#llx\n",
                                               (long long)addr);
                                        errcnt += 1;
                                        if (errcnt > 1000) {
-                                               printk(PRINT_PREF "error: too "
+                                               pr_err("error: too "
                                                       "many errors\n");
                                                return -1;
                                        }
@@ -286,17 +284,17 @@ static int verify_eraseblock_in_one_go(int ebnum)
        ops.oobbuf    = readbuf;
        err = mtd_read_oob(mtd, addr, &ops);
        if (err || ops.oobretlen != len) {
-               printk(PRINT_PREF "error: readoob failed at %#llx\n",
+               pr_err("error: readoob failed at %#llx\n",
                       (long long)addr);
                errcnt += 1;
                return err ? err : -1;
        }
        if (memcmp(readbuf, writebuf, len)) {
-               printk(PRINT_PREF "error: verify failed at %#llx\n",
+               pr_err("error: verify failed at %#llx\n",
                       (long long)addr);
                errcnt += 1;
                if (errcnt > 1000) {
-                       printk(PRINT_PREF "error: too many errors\n");
+                       pr_err("error: too many errors\n");
                        return -1;
                }
        }
@@ -309,7 +307,7 @@ static int verify_all_eraseblocks(void)
        int err;
        unsigned int i;
 
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -317,10 +315,10 @@ static int verify_all_eraseblocks(void)
                if (err)
                        return err;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
        return 0;
 }
 
@@ -331,7 +329,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -341,18 +339,18 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kmalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
        return 0;
 }
 
@@ -368,22 +366,22 @@ static int __init mtd_oobtest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->type != MTD_NANDFLASH) {
-               printk(PRINT_PREF "this test requires NAND flash\n");
+               pr_info("this test requires NAND flash\n");
                goto out;
        }
 
@@ -392,7 +390,7 @@ static int __init mtd_oobtest_init(void)
        ebcnt = tmp;
        pgcnt = mtd->erasesize / mtd->writesize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, count of eraseblocks %u, pages per "
               "eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
@@ -401,12 +399,12 @@ static int __init mtd_oobtest_init(void)
        err = -ENOMEM;
        readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!readbuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
        writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!writebuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
 
@@ -420,7 +418,7 @@ static int __init mtd_oobtest_init(void)
        vary_offset = 0;
 
        /* First test: write all OOB, read it back and verify */
-       printk(PRINT_PREF "test 1 of 5\n");
+       pr_info("test 1 of 5\n");
 
        err = erase_whole_device();
        if (err)
@@ -440,7 +438,7 @@ static int __init mtd_oobtest_init(void)
         * Second test: write all OOB, a block at a time, read it back and
         * verify.
         */
-       printk(PRINT_PREF "test 2 of 5\n");
+       pr_info("test 2 of 5\n");
 
        err = erase_whole_device();
        if (err)
@@ -453,7 +451,7 @@ static int __init mtd_oobtest_init(void)
 
        /* Check all eraseblocks */
        simple_srand(3);
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -461,16 +459,16 @@ static int __init mtd_oobtest_init(void)
                if (err)
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
 
        /*
         * Third test: write OOB at varying offsets and lengths, read it back
         * and verify.
         */
-       printk(PRINT_PREF "test 3 of 5\n");
+       pr_info("test 3 of 5\n");
 
        err = erase_whole_device();
        if (err)
@@ -503,7 +501,7 @@ static int __init mtd_oobtest_init(void)
        vary_offset = 0;
 
        /* Fourth test: try to write off end of device */
-       printk(PRINT_PREF "test 4 of 5\n");
+       pr_info("test 4 of 5\n");
 
        err = erase_whole_device();
        if (err)
@@ -522,14 +520,14 @@ static int __init mtd_oobtest_init(void)
        ops.ooboffs   = mtd->ecclayout->oobavail;
        ops.datbuf    = NULL;
        ops.oobbuf    = writebuf;
-       printk(PRINT_PREF "attempting to start write past end of OOB\n");
-       printk(PRINT_PREF "an error is expected...\n");
+       pr_info("attempting to start write past end of OOB\n");
+       pr_info("an error is expected...\n");
        err = mtd_write_oob(mtd, addr0, &ops);
        if (err) {
-               printk(PRINT_PREF "error occurred as expected\n");
+               pr_info("error occurred as expected\n");
                err = 0;
        } else {
-               printk(PRINT_PREF "error: can write past end of OOB\n");
+               pr_err("error: can write past end of OOB\n");
                errcnt += 1;
        }
 
@@ -542,19 +540,19 @@ static int __init mtd_oobtest_init(void)
        ops.ooboffs   = mtd->ecclayout->oobavail;
        ops.datbuf    = NULL;
        ops.oobbuf    = readbuf;
-       printk(PRINT_PREF "attempting to start read past end of OOB\n");
-       printk(PRINT_PREF "an error is expected...\n");
+       pr_info("attempting to start read past end of OOB\n");
+       pr_info("an error is expected...\n");
        err = mtd_read_oob(mtd, addr0, &ops);
        if (err) {
-               printk(PRINT_PREF "error occurred as expected\n");
+               pr_info("error occurred as expected\n");
                err = 0;
        } else {
-               printk(PRINT_PREF "error: can read past end of OOB\n");
+               pr_err("error: can read past end of OOB\n");
                errcnt += 1;
        }
 
        if (bbt[ebcnt - 1])
-               printk(PRINT_PREF "skipping end of device tests because last "
+               pr_info("skipping end of device tests because last "
                       "block is bad\n");
        else {
                /* Attempt to write off end of device */
@@ -566,14 +564,14 @@ static int __init mtd_oobtest_init(void)
                ops.ooboffs   = 0;
                ops.datbuf    = NULL;
                ops.oobbuf    = writebuf;
-               printk(PRINT_PREF "attempting to write past end of device\n");
-               printk(PRINT_PREF "an error is expected...\n");
+               pr_info("attempting to write past end of device\n");
+               pr_info("an error is expected...\n");
                err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
                if (err) {
-                       printk(PRINT_PREF "error occurred as expected\n");
+                       pr_info("error occurred as expected\n");
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: wrote past end of device\n");
+                       pr_err("error: wrote past end of device\n");
                        errcnt += 1;
                }
 
@@ -586,14 +584,14 @@ static int __init mtd_oobtest_init(void)
                ops.ooboffs   = 0;
                ops.datbuf    = NULL;
                ops.oobbuf    = readbuf;
-               printk(PRINT_PREF "attempting to read past end of device\n");
-               printk(PRINT_PREF "an error is expected...\n");
+               pr_info("attempting to read past end of device\n");
+               pr_info("an error is expected...\n");
                err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
                if (err) {
-                       printk(PRINT_PREF "error occurred as expected\n");
+                       pr_info("error occurred as expected\n");
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: read past end of device\n");
+                       pr_err("error: read past end of device\n");
                        errcnt += 1;
                }
 
@@ -610,14 +608,14 @@ static int __init mtd_oobtest_init(void)
                ops.ooboffs   = 1;
                ops.datbuf    = NULL;
                ops.oobbuf    = writebuf;
-               printk(PRINT_PREF "attempting to write past end of device\n");
-               printk(PRINT_PREF "an error is expected...\n");
+               pr_info("attempting to write past end of device\n");
+               pr_info("an error is expected...\n");
                err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
                if (err) {
-                       printk(PRINT_PREF "error occurred as expected\n");
+                       pr_info("error occurred as expected\n");
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: wrote past end of device\n");
+                       pr_err("error: wrote past end of device\n");
                        errcnt += 1;
                }
 
@@ -630,20 +628,20 @@ static int __init mtd_oobtest_init(void)
                ops.ooboffs   = 1;
                ops.datbuf    = NULL;
                ops.oobbuf    = readbuf;
-               printk(PRINT_PREF "attempting to read past end of device\n");
-               printk(PRINT_PREF "an error is expected...\n");
+               pr_info("attempting to read past end of device\n");
+               pr_info("an error is expected...\n");
                err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
                if (err) {
-                       printk(PRINT_PREF "error occurred as expected\n");
+                       pr_info("error occurred as expected\n");
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: read past end of device\n");
+                       pr_err("error: read past end of device\n");
                        errcnt += 1;
                }
        }
 
        /* Fifth test: write / read across block boundaries */
-       printk(PRINT_PREF "test 5 of 5\n");
+       pr_info("test 5 of 5\n");
 
        /* Erase all eraseblocks */
        err = erase_whole_device();
@@ -652,7 +650,7 @@ static int __init mtd_oobtest_init(void)
 
        /* Write all eraseblocks */
        simple_srand(11);
-       printk(PRINT_PREF "writing OOBs of whole device\n");
+       pr_info("writing OOBs of whole device\n");
        for (i = 0; i < ebcnt - 1; ++i) {
                int cnt = 2;
                int pg;
@@ -674,17 +672,16 @@ static int __init mtd_oobtest_init(void)
                        if (err)
                                goto out;
                        if (i % 256 == 0)
-                               printk(PRINT_PREF "written up to eraseblock "
-                                      "%u\n", i);
+                               pr_info("written up to eraseblock %u\n", i);
                        cond_resched();
                        addr += mtd->writesize;
                }
        }
-       printk(PRINT_PREF "written %u eraseblocks\n", i);
+       pr_info("written %u eraseblocks\n", i);
 
        /* Check all eraseblocks */
        simple_srand(11);
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt - 1; ++i) {
                if (bbt[i] || bbt[i + 1])
                        continue;
@@ -702,28 +699,28 @@ static int __init mtd_oobtest_init(void)
                if (err)
                        goto out;
                if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
-                       printk(PRINT_PREF "error: verify failed at %#llx\n",
+                       pr_err("error: verify failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                        if (errcnt > 1000) {
-                               printk(PRINT_PREF "error: too many errors\n");
+                               pr_err("error: too many errors\n");
                                goto out;
                        }
                }
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
 
-       printk(PRINT_PREF "finished with %d errors\n", errcnt);
+       pr_info("finished with %d errors\n", errcnt);
 out:
        kfree(bbt);
        kfree(writebuf);
        kfree(readbuf);
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index 252ddb0..f93a76f 100644 (file)
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -28,8 +30,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_pagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -79,12 +79,12 @@ static int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
+               pr_err("some erase error occurred at EB %d\n",
                       ebnum);
                return -EIO;
        }
@@ -102,7 +102,7 @@ static int write_eraseblock(int ebnum)
        cond_resched();
        err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
        if (err || written != mtd->erasesize)
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_err("error: write failed at %#llx\n",
                       (long long)addr);
 
        return err;
@@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr0);
                        return err;
                }
@@ -139,7 +139,7 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)(addrn - bufsize));
                        return err;
                }
@@ -148,12 +148,12 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr);
                        break;
                }
                if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) {
-                       printk(PRINT_PREF "error: verify failed at %#llx\n",
+                       pr_err("error: verify failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                }
@@ -166,7 +166,7 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr0);
                        return err;
                }
@@ -174,7 +174,7 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)(addrn - bufsize));
                        return err;
                }
@@ -183,14 +183,14 @@ static int verify_eraseblock(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr);
                        return err;
                }
                memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);
                set_random_data(boundary + pgsize, pgsize);
                if (memcmp(twopages, boundary, bufsize)) {
-                       printk(PRINT_PREF "error: verify failed at %#llx\n",
+                       pr_err("error: verify failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                }
@@ -206,10 +206,10 @@ static int crosstest(void)
        loff_t addr, addr0, addrn;
        unsigned char *pp1, *pp2, *pp3, *pp4;
 
-       printk(PRINT_PREF "crosstest\n");
+       pr_info("crosstest\n");
        pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
        if (!pp1) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
        pp2 = pp1 + pgsize;
@@ -231,7 +231,7 @@ static int crosstest(void)
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr);
                kfree(pp1);
                return err;
@@ -243,7 +243,7 @@ static int crosstest(void)
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr);
                kfree(pp1);
                return err;
@@ -251,12 +251,12 @@ static int crosstest(void)
 
        /* Read first page to pp2 */
        addr = addr0;
-       printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+       pr_info("reading page at %#llx\n", (long long)addr);
        err = mtd_read(mtd, addr, pgsize, &read, pp2);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr);
                kfree(pp1);
                return err;
@@ -264,12 +264,12 @@ static int crosstest(void)
 
        /* Read last page to pp3 */
        addr = addrn - pgsize;
-       printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+       pr_info("reading page at %#llx\n", (long long)addr);
        err = mtd_read(mtd, addr, pgsize, &read, pp3);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr);
                kfree(pp1);
                return err;
@@ -277,25 +277,25 @@ static int crosstest(void)
 
        /* Read first page again to pp4 */
        addr = addr0;
-       printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+       pr_info("reading page at %#llx\n", (long long)addr);
        err = mtd_read(mtd, addr, pgsize, &read, pp4);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr);
                kfree(pp1);
                return err;
        }
 
        /* pp2 and pp4 should be the same */
-       printk(PRINT_PREF "verifying pages read at %#llx match\n",
+       pr_info("verifying pages read at %#llx match\n",
               (long long)addr0);
        if (memcmp(pp2, pp4, pgsize)) {
-               printk(PRINT_PREF "verify failed!\n");
+               pr_err("verify failed!\n");
                errcnt += 1;
        } else if (!err)
-               printk(PRINT_PREF "crosstest ok\n");
+               pr_info("crosstest ok\n");
        kfree(pp1);
        return err;
 }
@@ -307,7 +307,7 @@ static int erasecrosstest(void)
        loff_t addr0;
        char *readbuf = twopages;
 
-       printk(PRINT_PREF "erasecrosstest\n");
+       pr_info("erasecrosstest\n");
 
        ebnum = 0;
        addr0 = 0;
@@ -320,79 +320,79 @@ static int erasecrosstest(void)
        while (ebnum2 && bbt[ebnum2])
                ebnum2 -= 1;
 
-       printk(PRINT_PREF "erasing block %d\n", ebnum);
+       pr_info("erasing block %d\n", ebnum);
        err = erase_eraseblock(ebnum);
        if (err)
                return err;
 
-       printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+       pr_info("writing 1st page of block %d\n", ebnum);
        set_random_data(writebuf, pgsize);
        strcpy(writebuf, "There is no data like this!");
        err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
        if (err || written != pgsize) {
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_info("error: write failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+       pr_info("reading 1st page of block %d\n", ebnum);
        memset(readbuf, 0, pgsize);
        err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+       pr_info("verifying 1st page of block %d\n", ebnum);
        if (memcmp(writebuf, readbuf, pgsize)) {
-               printk(PRINT_PREF "verify failed!\n");
+               pr_err("verify failed!\n");
                errcnt += 1;
                return -1;
        }
 
-       printk(PRINT_PREF "erasing block %d\n", ebnum);
+       pr_info("erasing block %d\n", ebnum);
        err = erase_eraseblock(ebnum);
        if (err)
                return err;
 
-       printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+       pr_info("writing 1st page of block %d\n", ebnum);
        set_random_data(writebuf, pgsize);
        strcpy(writebuf, "There is no data like this!");
        err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
        if (err || written != pgsize) {
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_err("error: write failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "erasing block %d\n", ebnum2);
+       pr_info("erasing block %d\n", ebnum2);
        err = erase_eraseblock(ebnum2);
        if (err)
                return err;
 
-       printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+       pr_info("reading 1st page of block %d\n", ebnum);
        memset(readbuf, 0, pgsize);
        err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+       pr_info("verifying 1st page of block %d\n", ebnum);
        if (memcmp(writebuf, readbuf, pgsize)) {
-               printk(PRINT_PREF "verify failed!\n");
+               pr_err("verify failed!\n");
                errcnt += 1;
                return -1;
        }
 
        if (!err)
-               printk(PRINT_PREF "erasecrosstest ok\n");
+               pr_info("erasecrosstest ok\n");
        return err;
 }
 
@@ -402,7 +402,7 @@ static int erasetest(void)
        int err = 0, i, ebnum, ok = 1;
        loff_t addr0;
 
-       printk(PRINT_PREF "erasetest\n");
+       pr_info("erasetest\n");
 
        ebnum = 0;
        addr0 = 0;
@@ -411,40 +411,40 @@ static int erasetest(void)
                ebnum += 1;
        }
 
-       printk(PRINT_PREF "erasing block %d\n", ebnum);
+       pr_info("erasing block %d\n", ebnum);
        err = erase_eraseblock(ebnum);
        if (err)
                return err;
 
-       printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+       pr_info("writing 1st page of block %d\n", ebnum);
        set_random_data(writebuf, pgsize);
        err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
        if (err || written != pgsize) {
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_err("error: write failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "erasing block %d\n", ebnum);
+       pr_info("erasing block %d\n", ebnum);
        err = erase_eraseblock(ebnum);
        if (err)
                return err;
 
-       printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+       pr_info("reading 1st page of block %d\n", ebnum);
        err = mtd_read(mtd, addr0, pgsize, &read, twopages);
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n",
+               pr_err("error: read failed at %#llx\n",
                       (long long)addr0);
                return err ? err : -1;
        }
 
-       printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n",
+       pr_info("verifying 1st page of block %d is all 0xff\n",
               ebnum);
        for (i = 0; i < pgsize; ++i)
                if (twopages[i] != 0xff) {
-                       printk(PRINT_PREF "verifying all 0xff failed at %d\n",
+                       pr_err("verifying all 0xff failed at %d\n",
                               i);
                        errcnt += 1;
                        ok = 0;
@@ -452,7 +452,7 @@ static int erasetest(void)
                }
 
        if (ok && !err)
-               printk(PRINT_PREF "erasetest ok\n");
+               pr_info("erasetest ok\n");
 
        return err;
 }
@@ -464,7 +464,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -474,18 +474,18 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kzalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
        return 0;
 }
 
@@ -499,22 +499,22 @@ static int __init mtd_pagetest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->type != MTD_NANDFLASH) {
-               printk(PRINT_PREF "this test requires NAND flash\n");
+               pr_info("this test requires NAND flash\n");
                goto out;
        }
 
@@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void)
        pgcnt = mtd->erasesize / mtd->writesize;
        pgsize = mtd->writesize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, count of eraseblocks %u, pages per "
               "eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
@@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void)
        bufsize = pgsize * 2;
        writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!writebuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
        twopages = kmalloc(bufsize, GFP_KERNEL);
        if (!twopages) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
        boundary = kmalloc(bufsize, GFP_KERNEL);
        if (!boundary) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
 
@@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void)
                goto out;
 
        /* Erase all eraseblocks */
-       printk(PRINT_PREF "erasing whole device\n");
+       pr_info("erasing whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void)
                        goto out;
                cond_resched();
        }
-       printk(PRINT_PREF "erased %u eraseblocks\n", i);
+       pr_info("erased %u eraseblocks\n", i);
 
        /* Write all eraseblocks */
        simple_srand(1);
-       printk(PRINT_PREF "writing whole device\n");
+       pr_info("writing whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void)
                if (err)
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "written up to eraseblock %u\n", i);
+                       pr_info("written up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "written %u eraseblocks\n", i);
+       pr_info("written %u eraseblocks\n", i);
 
        /* Check all eraseblocks */
        simple_srand(1);
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void)
                if (err)
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
 
        err = crosstest();
        if (err)
@@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void)
        if (err)
                goto out;
 
-       printk(PRINT_PREF "finished with %d errors\n", errcnt);
+       pr_info("finished with %d errors\n", errcnt);
 out:
 
        kfree(bbt);
@@ -615,7 +615,7 @@ out:
        kfree(writebuf);
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index 121aba1..266de04 100644 (file)
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,8 +29,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_readtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -51,12 +51,12 @@ static int read_eraseblock_by_page(int ebnum)
        void *oobbuf = iobuf1;
 
        for (i = 0; i < pgcnt; i++) {
-               memset(buf, 0 , pgcnt);
+               memset(buf, 0 , pgsize);
                ret = mtd_read(mtd, addr, pgsize, &read, buf);
                if (ret == -EUCLEAN)
                        ret = 0;
                if (ret || read != pgsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr);
                        if (!err)
                                err = ret;
@@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum)
                        ret = mtd_read_oob(mtd, addr, &ops);
                        if ((ret && !mtd_is_bitflip(ret)) ||
                                        ops.oobretlen != mtd->oobsize) {
-                               printk(PRINT_PREF "error: read oob failed at "
+                               pr_err("error: read oob failed at "
                                                  "%#llx\n", (long long)addr);
                                if (!err)
                                        err = ret;
@@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum)
        char line[128];
        int pg, oob;
 
-       printk(PRINT_PREF "dumping eraseblock %d\n", ebnum);
+       pr_info("dumping eraseblock %d\n", ebnum);
        n = mtd->erasesize;
        for (i = 0; i < n;) {
                char *p = line;
@@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum)
        }
        if (!mtd->oobsize)
                return;
-       printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum);
+       pr_info("dumping oob from eraseblock %d\n", ebnum);
        n = mtd->oobsize;
        for (pg = 0, i = 0; pg < pgcnt; pg++)
                for (oob = 0; oob < n;) {
@@ -134,7 +134,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kzalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
        if (!mtd_can_have_bb(mtd))
                return 0;
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
        return 0;
 }
 
@@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: Cannot get MTD device\n");
+               pr_err("error: Cannot get MTD device\n");
                return err;
        }
 
        if (mtd->writesize == 1) {
-               printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+               pr_info("not NAND flash, assume page size is 512 "
                       "bytes.\n");
                pgsize = 512;
        } else
@@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void)
        ebcnt = tmp;
        pgcnt = mtd->erasesize / pgsize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, count of eraseblocks %u, pages per "
               "eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
@@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void)
        err = -ENOMEM;
        iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!iobuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
        iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!iobuf1) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
 
@@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void)
                goto out;
 
        /* Read all eraseblocks 1 page at a time */
-       printk(PRINT_PREF "testing page read\n");
+       pr_info("testing page read\n");
        for (i = 0; i < ebcnt; ++i) {
                int ret;
 
@@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void)
        }
 
        if (err)
-               printk(PRINT_PREF "finished with errors\n");
+               pr_info("finished with errors\n");
        else
-               printk(PRINT_PREF "finished\n");
+               pr_info("finished\n");
 
 out:
 
@@ -246,7 +246,7 @@ out:
        kfree(bbt);
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index 42b0f74..596cbea 100644 (file)
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <adrian.hunter@nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -28,8 +30,6 @@
 #include <linux/sched.h>
 #include <linux/random.h>
 
-#define PRINT_PREF KERN_INFO "mtd_speedtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -70,12 +70,12 @@ static int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
+               pr_err("some erase error occurred at EB %d\n",
                       ebnum);
                return -EIO;
        }
@@ -96,13 +96,13 @@ static int multiblock_erase(int ebnum, int blocks)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n",
+               pr_err("error %d while erasing EB %d, blocks %d\n",
                       err, ebnum, blocks);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d,"
+               pr_err("some erase error occurred at EB %d,"
                       "blocks %d\n", ebnum, blocks);
                return -EIO;
        }
@@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum)
 
        err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf);
        if (err || written != mtd->erasesize) {
-               printk(PRINT_PREF "error: write failed at %#llx\n", addr);
+               pr_err("error: write failed at %#llx\n", addr);
                if (!err)
                        err = -EINVAL;
        }
@@ -152,7 +152,7 @@ static int write_eraseblock_by_page(int ebnum)
        for (i = 0; i < pgcnt; i++) {
                err = mtd_write(mtd, addr, pgsize, &written, buf);
                if (err || written != pgsize) {
-                       printk(PRINT_PREF "error: write failed at %#llx\n",
+                       pr_err("error: write failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -175,7 +175,7 @@ static int write_eraseblock_by_2pages(int ebnum)
        for (i = 0; i < n; i++) {
                err = mtd_write(mtd, addr, sz, &written, buf);
                if (err || written != sz) {
-                       printk(PRINT_PREF "error: write failed at %#llx\n",
+                       pr_err("error: write failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -187,7 +187,7 @@ static int write_eraseblock_by_2pages(int ebnum)
        if (pgcnt % 2) {
                err = mtd_write(mtd, addr, pgsize, &written, buf);
                if (err || written != pgsize) {
-                       printk(PRINT_PREF "error: write failed at %#llx\n",
+                       pr_err("error: write failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -208,7 +208,7 @@ static int read_eraseblock(int ebnum)
        if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != mtd->erasesize) {
-               printk(PRINT_PREF "error: read failed at %#llx\n", addr);
+               pr_err("error: read failed at %#llx\n", addr);
                if (!err)
                        err = -EINVAL;
        }
@@ -229,7 +229,7 @@ static int read_eraseblock_by_page(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != pgsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -255,7 +255,7 @@ static int read_eraseblock_by_2pages(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != sz) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -270,7 +270,7 @@ static int read_eraseblock_by_2pages(int ebnum)
                if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != pgsize) {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               addr);
                        if (!err)
                                err = -EINVAL;
@@ -287,7 +287,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -321,21 +321,21 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kzalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
        if (!mtd_can_have_bb(mtd))
                goto out;
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 out:
        goodebcnt = ebcnt - bad;
        return 0;
@@ -351,25 +351,25 @@ static int __init mtd_speedtest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
        if (count)
-               printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count);
+               pr_info("MTD device: %d    count: %d\n", dev, count);
        else
-               printk(PRINT_PREF "MTD device: %d\n", dev);
+               pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->writesize == 1) {
-               printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+               pr_info("not NAND flash, assume page size is 512 "
                       "bytes.\n");
                pgsize = 512;
        } else
@@ -380,7 +380,7 @@ static int __init mtd_speedtest_init(void)
        ebcnt = tmp;
        pgcnt = mtd->erasesize / pgsize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, count of eraseblocks %u, pages per "
               "eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
@@ -392,7 +392,7 @@ static int __init mtd_speedtest_init(void)
        err = -ENOMEM;
        iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!iobuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
 
@@ -407,7 +407,7 @@ static int __init mtd_speedtest_init(void)
                goto out;
 
        /* Write all eraseblocks, 1 eraseblock at a time */
-       printk(PRINT_PREF "testing eraseblock write speed\n");
+       pr_info("testing eraseblock write speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -419,10 +419,10 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed);
+       pr_info("eraseblock write speed is %ld KiB/s\n", speed);
 
        /* Read all eraseblocks, 1 eraseblock at a time */
-       printk(PRINT_PREF "testing eraseblock read speed\n");
+       pr_info("testing eraseblock read speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -434,14 +434,14 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed);
+       pr_info("eraseblock read speed is %ld KiB/s\n", speed);
 
        err = erase_whole_device();
        if (err)
                goto out;
 
        /* Write all eraseblocks, 1 page at a time */
-       printk(PRINT_PREF "testing page write speed\n");
+       pr_info("testing page write speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -453,10 +453,10 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed);
+       pr_info("page write speed is %ld KiB/s\n", speed);
 
        /* Read all eraseblocks, 1 page at a time */
-       printk(PRINT_PREF "testing page read speed\n");
+       pr_info("testing page read speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -468,14 +468,14 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed);
+       pr_info("page read speed is %ld KiB/s\n", speed);
 
        err = erase_whole_device();
        if (err)
                goto out;
 
        /* Write all eraseblocks, 2 pages at a time */
-       printk(PRINT_PREF "testing 2 page write speed\n");
+       pr_info("testing 2 page write speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -487,10 +487,10 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed);
+       pr_info("2 page write speed is %ld KiB/s\n", speed);
 
        /* Read all eraseblocks, 2 pages at a time */
-       printk(PRINT_PREF "testing 2 page read speed\n");
+       pr_info("testing 2 page read speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -502,10 +502,10 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed);
+       pr_info("2 page read speed is %ld KiB/s\n", speed);
 
        /* Erase all eraseblocks */
-       printk(PRINT_PREF "Testing erase speed\n");
+       pr_info("Testing erase speed\n");
        start_timing();
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -517,12 +517,12 @@ static int __init mtd_speedtest_init(void)
        }
        stop_timing();
        speed = calc_speed();
-       printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed);
+       pr_info("erase speed is %ld KiB/s\n", speed);
 
        /* Multi-block erase all eraseblocks */
        for (k = 1; k < 7; k++) {
                blocks = 1 << k;
-               printk(PRINT_PREF "Testing %dx multi-block erase speed\n",
+               pr_info("Testing %dx multi-block erase speed\n",
                       blocks);
                start_timing();
                for (i = 0; i < ebcnt; ) {
@@ -541,16 +541,16 @@ static int __init mtd_speedtest_init(void)
                }
                stop_timing();
                speed = calc_speed();
-               printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n",
+               pr_info("%dx multi-block erase speed is %ld KiB/s\n",
                       blocks, speed);
        }
-       printk(PRINT_PREF "finished\n");
+       pr_info("finished\n");
 out:
        kfree(iobuf);
        kfree(bbt);
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index cb268ce..3729f67 100644 (file)
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter@nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -29,8 +31,6 @@
 #include <linux/vmalloc.h>
 #include <linux/random.h>
 
-#define PRINT_PREF KERN_INFO "mtd_stresstest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -94,12 +94,12 @@ static int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (unlikely(err)) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (unlikely(ei.state == MTD_ERASE_FAILED)) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
+               pr_err("some erase error occurred at EB %d\n",
                       ebnum);
                return -EIO;
        }
@@ -114,7 +114,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -137,7 +137,7 @@ static int do_read(void)
        if (mtd_is_bitflip(err))
                err = 0;
        if (unlikely(err || read != len)) {
-               printk(PRINT_PREF "error: read failed at 0x%llx\n",
+               pr_err("error: read failed at 0x%llx\n",
                       (long long)addr);
                if (!err)
                        err = -EINVAL;
@@ -174,7 +174,7 @@ static int do_write(void)
        addr = eb * mtd->erasesize + offs;
        err = mtd_write(mtd, addr, len, &written, writebuf);
        if (unlikely(err || written != len)) {
-               printk(PRINT_PREF "error: write failed at 0x%llx\n",
+               pr_err("error: write failed at 0x%llx\n",
                       (long long)addr);
                if (!err)
                        err = -EINVAL;
@@ -203,21 +203,21 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kzalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
        if (!mtd_can_have_bb(mtd))
                return 0;
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
        return 0;
 }
 
@@ -231,22 +231,22 @@ static int __init mtd_stresstest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->writesize == 1) {
-               printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+               pr_info("not NAND flash, assume page size is 512 "
                       "bytes.\n");
                pgsize = 512;
        } else
@@ -257,14 +257,14 @@ static int __init mtd_stresstest_init(void)
        ebcnt = tmp;
        pgcnt = mtd->erasesize / pgsize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, count of eraseblocks %u, pages per "
               "eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
               pgsize, ebcnt, pgcnt, mtd->oobsize);
 
        if (ebcnt < 2) {
-               printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
+               pr_err("error: need at least 2 eraseblocks\n");
                err = -ENOSPC;
                goto out_put_mtd;
        }
@@ -277,7 +277,7 @@ static int __init mtd_stresstest_init(void)
        writebuf = vmalloc(bufsize);
        offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL);
        if (!readbuf || !writebuf || !offsets) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out;
        }
        for (i = 0; i < ebcnt; i++)
@@ -290,16 +290,16 @@ static int __init mtd_stresstest_init(void)
                goto out;
 
        /* Do operations */
-       printk(PRINT_PREF "doing operations\n");
+       pr_info("doing operations\n");
        for (op = 0; op < count; op++) {
                if ((op & 1023) == 0)
-                       printk(PRINT_PREF "%d operations done\n", op);
+                       pr_info("%d operations done\n", op);
                err = do_operation();
                if (err)
                        goto out;
                cond_resched();
        }
-       printk(PRINT_PREF "finished, %d operations done\n", op);
+       pr_info("finished, %d operations done\n", op);
 
 out:
        kfree(offsets);
@@ -309,7 +309,7 @@ out:
 out_put_mtd:
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index 9667bf5..c880c22 100644 (file)
@@ -19,6 +19,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,8 +29,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_subpagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -82,12 +82,12 @@ static int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
+               pr_err("some erase error occurred at EB %d\n",
                       ebnum);
                return -EIO;
        }
@@ -100,7 +100,7 @@ static int erase_whole_device(void)
        int err;
        unsigned int i;
 
-       printk(PRINT_PREF "erasing whole device\n");
+       pr_info("erasing whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -109,7 +109,7 @@ static int erase_whole_device(void)
                        return err;
                cond_resched();
        }
-       printk(PRINT_PREF "erased %u eraseblocks\n", i);
+       pr_info("erased %u eraseblocks\n", i);
        return 0;
 }
 
@@ -122,11 +122,11 @@ static int write_eraseblock(int ebnum)
        set_random_data(writebuf, subpgsize);
        err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
        if (unlikely(err || written != subpgsize)) {
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_err("error: write failed at %#llx\n",
                       (long long)addr);
                if (written != subpgsize) {
-                       printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-                       printk(PRINT_PREF "  written: %#zx\n", written);
+                       pr_err("  write size: %#x\n", subpgsize);
+                       pr_err("  written: %#zx\n", written);
                }
                return err ? err : -1;
        }
@@ -136,11 +136,11 @@ static int write_eraseblock(int ebnum)
        set_random_data(writebuf, subpgsize);
        err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
        if (unlikely(err || written != subpgsize)) {
-               printk(PRINT_PREF "error: write failed at %#llx\n",
+               pr_err("error: write failed at %#llx\n",
                       (long long)addr);
                if (written != subpgsize) {
-                       printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-                       printk(PRINT_PREF "  written: %#zx\n", written);
+                       pr_err("  write size: %#x\n", subpgsize);
+                       pr_err("  written: %#zx\n", written);
                }
                return err ? err : -1;
        }
@@ -160,12 +160,12 @@ static int write_eraseblock2(int ebnum)
                set_random_data(writebuf, subpgsize * k);
                err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
                if (unlikely(err || written != subpgsize * k)) {
-                       printk(PRINT_PREF "error: write failed at %#llx\n",
+                       pr_err("error: write failed at %#llx\n",
                               (long long)addr);
                        if (written != subpgsize) {
-                               printk(PRINT_PREF "  write size: %#x\n",
+                               pr_err("  write size: %#x\n",
                                       subpgsize * k);
-                               printk(PRINT_PREF "  written: %#08zx\n",
+                               pr_err("  written: %#08zx\n",
                                       written);
                        }
                        return err ? err : -1;
@@ -198,23 +198,23 @@ static int verify_eraseblock(int ebnum)
        err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
        if (unlikely(err || read != subpgsize)) {
                if (mtd_is_bitflip(err) && read == subpgsize) {
-                       printk(PRINT_PREF "ECC correction at %#llx\n",
+                       pr_info("ECC correction at %#llx\n",
                               (long long)addr);
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr);
                        return err ? err : -1;
                }
        }
        if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-               printk(PRINT_PREF "error: verify failed at %#llx\n",
+               pr_err("error: verify failed at %#llx\n",
                       (long long)addr);
-               printk(PRINT_PREF "------------- written----------------\n");
+               pr_info("------------- written----------------\n");
                print_subpage(writebuf);
-               printk(PRINT_PREF "------------- read ------------------\n");
+               pr_info("------------- read ------------------\n");
                print_subpage(readbuf);
-               printk(PRINT_PREF "-------------------------------------\n");
+               pr_info("-------------------------------------\n");
                errcnt += 1;
        }
 
@@ -225,23 +225,23 @@ static int verify_eraseblock(int ebnum)
        err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
        if (unlikely(err || read != subpgsize)) {
                if (mtd_is_bitflip(err) && read == subpgsize) {
-                       printk(PRINT_PREF "ECC correction at %#llx\n",
+                       pr_info("ECC correction at %#llx\n",
                               (long long)addr);
                        err = 0;
                } else {
-                       printk(PRINT_PREF "error: read failed at %#llx\n",
+                       pr_err("error: read failed at %#llx\n",
                               (long long)addr);
                        return err ? err : -1;
                }
        }
        if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-               printk(PRINT_PREF "error: verify failed at %#llx\n",
+               pr_info("error: verify failed at %#llx\n",
                       (long long)addr);
-               printk(PRINT_PREF "------------- written----------------\n");
+               pr_info("------------- written----------------\n");
                print_subpage(writebuf);
-               printk(PRINT_PREF "------------- read ------------------\n");
+               pr_info("------------- read ------------------\n");
                print_subpage(readbuf);
-               printk(PRINT_PREF "-------------------------------------\n");
+               pr_info("-------------------------------------\n");
                errcnt += 1;
        }
 
@@ -262,17 +262,17 @@ static int verify_eraseblock2(int ebnum)
                err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
                if (unlikely(err || read != subpgsize * k)) {
                        if (mtd_is_bitflip(err) && read == subpgsize * k) {
-                               printk(PRINT_PREF "ECC correction at %#llx\n",
+                               pr_info("ECC correction at %#llx\n",
                                       (long long)addr);
                                err = 0;
                        } else {
-                               printk(PRINT_PREF "error: read failed at "
+                               pr_err("error: read failed at "
                                       "%#llx\n", (long long)addr);
                                return err ? err : -1;
                        }
                }
                if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) {
-                       printk(PRINT_PREF "error: verify failed at %#llx\n",
+                       pr_err("error: verify failed at %#llx\n",
                               (long long)addr);
                        errcnt += 1;
                }
@@ -295,17 +295,17 @@ static int verify_eraseblock_ff(int ebnum)
                err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
                if (unlikely(err || read != subpgsize)) {
                        if (mtd_is_bitflip(err) && read == subpgsize) {
-                               printk(PRINT_PREF "ECC correction at %#llx\n",
+                               pr_info("ECC correction at %#llx\n",
                                       (long long)addr);
                                err = 0;
                        } else {
-                               printk(PRINT_PREF "error: read failed at "
+                               pr_err("error: read failed at "
                                       "%#llx\n", (long long)addr);
                                return err ? err : -1;
                        }
                }
                if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-                       printk(PRINT_PREF "error: verify 0xff failed at "
+                       pr_err("error: verify 0xff failed at "
                               "%#llx\n", (long long)addr);
                        errcnt += 1;
                }
@@ -320,7 +320,7 @@ static int verify_all_eraseblocks_ff(void)
        int err;
        unsigned int i;
 
-       printk(PRINT_PREF "verifying all eraseblocks for 0xff\n");
+       pr_info("verifying all eraseblocks for 0xff\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -328,10 +328,10 @@ static int verify_all_eraseblocks_ff(void)
                if (err)
                        return err;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
        return 0;
 }
 
@@ -342,7 +342,7 @@ static int is_block_bad(int ebnum)
 
        ret = mtd_block_isbad(mtd, addr);
        if (ret)
-               printk(PRINT_PREF "block %d is bad\n", ebnum);
+               pr_info("block %d is bad\n", ebnum);
        return ret;
 }
 
@@ -352,18 +352,18 @@ static int scan_for_bad_eraseblocks(void)
 
        bbt = kzalloc(ebcnt, GFP_KERNEL);
        if (!bbt) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                return -ENOMEM;
        }
 
-       printk(PRINT_PREF "scanning for bad eraseblocks\n");
+       pr_info("scanning for bad eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                bbt[i] = is_block_bad(i) ? 1 : 0;
                if (bbt[i])
                        bad += 1;
                cond_resched();
        }
-       printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+       pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
        return 0;
 }
 
@@ -377,22 +377,22 @@ static int __init mtd_subpagetest_init(void)
        printk(KERN_INFO "=================================================\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
+       pr_info("MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->type != MTD_NANDFLASH) {
-               printk(PRINT_PREF "this test requires NAND flash\n");
+               pr_info("this test requires NAND flash\n");
                goto out;
        }
 
@@ -402,7 +402,7 @@ static int __init mtd_subpagetest_init(void)
        ebcnt = tmp;
        pgcnt = mtd->erasesize / mtd->writesize;
 
-       printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+       pr_info("MTD device size %llu, eraseblock size %u, "
               "page size %u, subpage size %u, count of eraseblocks %u, "
               "pages per eraseblock %u, OOB size %u\n",
               (unsigned long long)mtd->size, mtd->erasesize,
@@ -412,12 +412,12 @@ static int __init mtd_subpagetest_init(void)
        bufsize = subpgsize * 32;
        writebuf = kmalloc(bufsize, GFP_KERNEL);
        if (!writebuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_info("error: cannot allocate memory\n");
                goto out;
        }
        readbuf = kmalloc(bufsize, GFP_KERNEL);
        if (!readbuf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_info("error: cannot allocate memory\n");
                goto out;
        }
 
@@ -429,7 +429,7 @@ static int __init mtd_subpagetest_init(void)
        if (err)
                goto out;
 
-       printk(PRINT_PREF "writing whole device\n");
+       pr_info("writing whole device\n");
        simple_srand(1);
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
@@ -438,13 +438,13 @@ static int __init mtd_subpagetest_init(void)
                if (unlikely(err))
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "written up to eraseblock %u\n", i);
+                       pr_info("written up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "written %u eraseblocks\n", i);
+       pr_info("written %u eraseblocks\n", i);
 
        simple_srand(1);
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -452,10 +452,10 @@ static int __init mtd_subpagetest_init(void)
                if (unlikely(err))
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
 
        err = erase_whole_device();
        if (err)
@@ -467,7 +467,7 @@ static int __init mtd_subpagetest_init(void)
 
        /* Write all eraseblocks */
        simple_srand(3);
-       printk(PRINT_PREF "writing whole device\n");
+       pr_info("writing whole device\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -475,14 +475,14 @@ static int __init mtd_subpagetest_init(void)
                if (unlikely(err))
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "written up to eraseblock %u\n", i);
+                       pr_info("written up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "written %u eraseblocks\n", i);
+       pr_info("written %u eraseblocks\n", i);
 
        /* Check all eraseblocks */
        simple_srand(3);
-       printk(PRINT_PREF "verifying all eraseblocks\n");
+       pr_info("verifying all eraseblocks\n");
        for (i = 0; i < ebcnt; ++i) {
                if (bbt[i])
                        continue;
@@ -490,10 +490,10 @@ static int __init mtd_subpagetest_init(void)
                if (unlikely(err))
                        goto out;
                if (i % 256 == 0)
-                       printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+                       pr_info("verified up to eraseblock %u\n", i);
                cond_resched();
        }
-       printk(PRINT_PREF "verified %u eraseblocks\n", i);
+       pr_info("verified %u eraseblocks\n", i);
 
        err = erase_whole_device();
        if (err)
@@ -503,7 +503,7 @@ static int __init mtd_subpagetest_init(void)
        if (err)
                goto out;
 
-       printk(PRINT_PREF "finished with %d errors\n", errcnt);
+       pr_info("finished with %d errors\n", errcnt);
 
 out:
        kfree(bbt);
@@ -511,7 +511,7 @@ out:
        kfree(writebuf);
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred\n", err);
+               pr_info("error %d occurred\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
index b65861b..c4cde1e 100644 (file)
@@ -23,6 +23,8 @@
  * damage caused by this program.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -31,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_torturetest: "
 #define RETRIES 3
 
 static int eb = 8;
@@ -107,12 +108,12 @@ static inline int erase_eraseblock(int ebnum)
 
        err = mtd_erase(mtd, &ei);
        if (err) {
-               printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+               pr_err("error %d while erasing EB %d\n", err, ebnum);
                return err;
        }
 
        if (ei.state == MTD_ERASE_FAILED) {
-               printk(PRINT_PREF "some erase error occurred at EB %d\n",
+               pr_err("some erase error occurred at EB %d\n",
                       ebnum);
                return -EIO;
        }
@@ -139,40 +140,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
 retry:
        err = mtd_read(mtd, addr, len, &read, check_buf);
        if (mtd_is_bitflip(err))
-               printk(PRINT_PREF "single bit flip occurred at EB %d "
+               pr_err("single bit flip occurred at EB %d "
                       "MTD reported that it was fixed.\n", ebnum);
        else if (err) {
-               printk(PRINT_PREF "error %d while reading EB %d, "
+               pr_err("error %d while reading EB %d, "
                       "read %zd\n", err, ebnum, read);
                return err;
        }
 
        if (read != len) {
-               printk(PRINT_PREF "failed to read %zd bytes from EB %d, "
+               pr_err("failed to read %zd bytes from EB %d, "
                       "read only %zd, but no error reported\n",
                       len, ebnum, read);
                return -EIO;
        }
 
        if (memcmp(buf, check_buf, len)) {
-               printk(PRINT_PREF "read wrong data from EB %d\n", ebnum);
+               pr_err("read wrong data from EB %d\n", ebnum);
                report_corrupt(check_buf, buf);
 
                if (retries++ < RETRIES) {
                        /* Try read again */
                        yield();
-                       printk(PRINT_PREF "re-try reading data from EB %d\n",
+                       pr_info("re-try reading data from EB %d\n",
                               ebnum);
                        goto retry;
                } else {
-                       printk(PRINT_PREF "retried %d times, still errors, "
+                       pr_info("retried %d times, still errors, "
                               "give-up\n", RETRIES);
                        return -EINVAL;
                }
        }
 
        if (retries != 0)
-               printk(PRINT_PREF "only attempt number %d was OK (!!!)\n",
+               pr_info("only attempt number %d was OK (!!!)\n",
                       retries);
 
        return 0;
@@ -191,12 +192,12 @@ static inline int write_pattern(int ebnum, void *buf)
        }
        err = mtd_write(mtd, addr, len, &written, buf);
        if (err) {
-               printk(PRINT_PREF "error %d while writing EB %d, written %zd"
+               pr_err("error %d while writing EB %d, written %zd"
                      " bytes\n", err, ebnum, written);
                return err;
        }
        if (written != len) {
-               printk(PRINT_PREF "written only %zd bytes of %zd, but no error"
+               pr_info("written only %zd bytes of %zd, but no error"
                       " reported\n", written, len);
                return -EIO;
        }
@@ -211,64 +212,64 @@ static int __init tort_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
-       printk(PRINT_PREF "Warning: this program is trying to wear out your "
+       pr_info("Warning: this program is trying to wear out your "
               "flash, stop it if this is not wanted.\n");
 
        if (dev < 0) {
-               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               pr_info("Please specify a valid mtd-device via module parameter\n");
+               pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
                return -EINVAL;
        }
 
-       printk(PRINT_PREF "MTD device: %d\n", dev);
-       printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
+       pr_info("MTD device: %d\n", dev);
+       pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n",
               ebcnt, eb, eb + ebcnt - 1, dev);
        if (pgcnt)
-               printk(PRINT_PREF "torturing just %d pages per eraseblock\n",
+               pr_info("torturing just %d pages per eraseblock\n",
                        pgcnt);
-       printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled");
+       pr_info("write verify %s\n", check ? "enabled" : "disabled");
 
        mtd = get_mtd_device(NULL, dev);
        if (IS_ERR(mtd)) {
                err = PTR_ERR(mtd);
-               printk(PRINT_PREF "error: cannot get MTD device\n");
+               pr_err("error: cannot get MTD device\n");
                return err;
        }
 
        if (mtd->writesize == 1) {
-               printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+               pr_info("not NAND flash, assume page size is 512 "
                       "bytes.\n");
                pgsize = 512;
        } else
                pgsize = mtd->writesize;
 
        if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) {
-               printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt);
+               pr_err("error: invalid pgcnt value %d\n", pgcnt);
                goto out_mtd;
        }
 
        err = -ENOMEM;
        patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!patt_5A5) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out_mtd;
        }
 
        patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!patt_A5A) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out_patt_5A5;
        }
 
        patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!patt_FF) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out_patt_A5A;
        }
 
        check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);
        if (!check_buf) {
-               printk(PRINT_PREF "error: cannot allocate memory\n");
+               pr_err("error: cannot allocate memory\n");
                goto out_patt_FF;
        }
 
@@ -295,13 +296,13 @@ static int __init tort_init(void)
                        err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize);
 
                        if (err < 0) {
-                               printk(PRINT_PREF "block_isbad() returned %d "
+                               pr_info("block_isbad() returned %d "
                                       "for EB %d\n", err, i);
                                goto out;
                        }
 
                        if (err) {
-                               printk("EB %d is bad. Skip it.\n", i);
+                               pr_err("EB %d is bad. Skip it.\n", i);
                                bad_ebs[i - eb] = 1;
                        }
                }
@@ -329,7 +330,7 @@ static int __init tort_init(void)
                                        continue;
                                err = check_eraseblock(i, patt_FF);
                                if (err) {
-                                       printk(PRINT_PREF "verify failed"
+                                       pr_info("verify failed"
                                               " for 0xFF... pattern\n");
                                        goto out;
                                }
@@ -362,7 +363,7 @@ static int __init tort_init(void)
                                        patt = patt_A5A;
                                err = check_eraseblock(i, patt);
                                if (err) {
-                                       printk(PRINT_PREF "verify failed for %s"
+                                       pr_info("verify failed for %s"
                                               " pattern\n",
                                               ((eb + erase_cycles) & 1) ?
                                               "0x55AA55..." : "0xAA55AA...");
@@ -380,7 +381,7 @@ static int __init tort_init(void)
                        stop_timing();
                        ms = (finish.tv_sec - start.tv_sec) * 1000 +
                             (finish.tv_usec - start.tv_usec) / 1000;
-                       printk(PRINT_PREF "%08u erase cycles done, took %lu "
+                       pr_info("%08u erase cycles done, took %lu "
                               "milliseconds (%lu seconds)\n",
                               erase_cycles, ms, ms / 1000);
                        start_timing();
@@ -391,7 +392,7 @@ static int __init tort_init(void)
        }
 out:
 
-       printk(PRINT_PREF "finished after %u erase cycles\n",
+       pr_info("finished after %u erase cycles\n",
               erase_cycles);
        kfree(check_buf);
 out_patt_FF:
@@ -403,7 +404,7 @@ out_patt_5A5:
 out_mtd:
        put_mtd_device(mtd);
        if (err)
-               printk(PRINT_PREF "error %d occurred during torturing\n", err);
+               pr_info("error %d occurred during torturing\n", err);
        printk(KERN_INFO "=================================================\n");
        return err;
 }
@@ -441,9 +442,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
                               &bits) >= 0)
                        pages++;
 
-       printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n",
+       pr_info("verify fails on %d pages, %d bytes/%d bits\n",
               pages, bytes, bits);
-       printk(PRINT_PREF "The following is a list of all differences between"
+       pr_info("The following is a list of all differences between"
               " what was read from flash and what was expected\n");
 
        for (i = 0; i < check_len; i += pgsize) {
@@ -457,7 +458,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
                printk("-------------------------------------------------------"
                       "----------------------------------\n");
 
-               printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify,"
+               pr_info("Page %zd has %d bytes/%d bits failing verify,"
                       " starting at offset 0x%x\n",
                       (mtd->erasesize - check_len + i) / pgsize,
                       bytes, bits, first);
index ef2cb24..b7d45f3 100644 (file)
@@ -4431,8 +4431,6 @@ static void bond_uninit(struct net_device *bond_dev)
 
        list_del(&bond->bond_list);
 
-       bond_work_cancel_all(bond);
-
        bond_debug_unregister(bond);
 
        __hw_addr_flush(&bond->mc_list);
index 0f59170..6433b81 100644 (file)
@@ -121,7 +121,7 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
        }
 
        irq = irq_of_parse_and_map(np, 0);
-       if (irq == NO_IRQ) {
+       if (irq == 0) {
                dev_err(&ofdev->dev, "no irq found\n");
                err = -ENODEV;
                goto exit_unmap_mem;
index abf26c7..3bc1912 100644 (file)
@@ -616,7 +616,7 @@ static inline bool be_error(struct be_adapter *adapter)
        return adapter->eeh_error || adapter->hw_error || adapter->fw_timeout;
 }
 
-static inline bool be_crit_error(struct be_adapter *adapter)
+static inline bool be_hw_error(struct be_adapter *adapter)
 {
        return adapter->eeh_error || adapter->hw_error;
 }
index f2875aa..8a250c3 100644 (file)
@@ -298,7 +298,12 @@ void be_async_mcc_enable(struct be_adapter *adapter)
 
 void be_async_mcc_disable(struct be_adapter *adapter)
 {
+       spin_lock_bh(&adapter->mcc_cq_lock);
+
        adapter->mcc_obj.rearm_cq = false;
+       be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
+
+       spin_unlock_bh(&adapter->mcc_cq_lock);
 }
 
 int be_process_mcc(struct be_adapter *adapter)
index f95612b..9dca22b 100644 (file)
@@ -1689,15 +1689,41 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
        struct be_queue_info *rxq = &rxo->q;
        struct be_queue_info *rx_cq = &rxo->cq;
        struct be_rx_compl_info *rxcp;
+       struct be_adapter *adapter = rxo->adapter;
+       int flush_wait = 0;
        u16 tail;
 
-       /* First cleanup pending rx completions */
-       while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
-               be_rx_compl_discard(rxo, rxcp);
-               be_cq_notify(rxo->adapter, rx_cq->id, false, 1);
+       /* Consume pending rx completions.
+        * Wait for the flush completion (identified by zero num_rcvd)
+        * to arrive. Notify CQ even when there are no more CQ entries
+        * for HW to flush partially coalesced CQ entries.
+        * In Lancer, there is no need to wait for flush compl.
+        */
+       for (;;) {
+               rxcp = be_rx_compl_get(rxo);
+               if (rxcp == NULL) {
+                       if (lancer_chip(adapter))
+                               break;
+
+                       if (flush_wait++ > 10 || be_hw_error(adapter)) {
+                               dev_warn(&adapter->pdev->dev,
+                                        "did not receive flush compl\n");
+                               break;
+                       }
+                       be_cq_notify(adapter, rx_cq->id, true, 0);
+                       mdelay(1);
+               } else {
+                       be_rx_compl_discard(rxo, rxcp);
+                       be_cq_notify(adapter, rx_cq->id, true, 1);
+                       if (rxcp->num_rcvd == 0)
+                               break;
+               }
        }
 
-       /* Then free posted rx buffer that were not used */
+       /* After cleanup, leave the CQ in unarmed state */
+       be_cq_notify(adapter, rx_cq->id, false, 0);
+
+       /* Then free posted rx buffers that were not used */
        tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
        for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
                page_info = get_rx_page_info(rxo, tail);
@@ -2157,7 +2183,7 @@ void be_detect_error(struct be_adapter *adapter)
        u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
        u32 i;
 
-       if (be_crit_error(adapter))
+       if (be_hw_error(adapter))
                return;
 
        if (lancer_chip(adapter)) {
@@ -2398,13 +2424,22 @@ static int be_close(struct net_device *netdev)
 
        be_roce_dev_close(adapter);
 
-       be_async_mcc_disable(adapter);
-
        if (!lancer_chip(adapter))
                be_intr_set(adapter, false);
 
-       for_all_evt_queues(adapter, eqo, i) {
+       for_all_evt_queues(adapter, eqo, i)
                napi_disable(&eqo->napi);
+
+       be_async_mcc_disable(adapter);
+
+       /* Wait for all pending tx completions to arrive so that
+        * all tx skbs are freed.
+        */
+       be_tx_compl_clean(adapter);
+
+       be_rx_qs_destroy(adapter);
+
+       for_all_evt_queues(adapter, eqo, i) {
                if (msix_enabled(adapter))
                        synchronize_irq(be_msix_vec_get(adapter, eqo));
                else
@@ -2414,12 +2449,6 @@ static int be_close(struct net_device *netdev)
 
        be_irq_unregister(adapter);
 
-       /* Wait for all pending tx completions to arrive so that
-        * all tx skbs are freed.
-        */
-       be_tx_compl_clean(adapter);
-
-       be_rx_qs_destroy(adapter);
        return 0;
 }
 
index 5ba6e1c..ec490d7 100644 (file)
@@ -94,9 +94,8 @@ config GIANFAR
 
 config FEC_PTP
        bool "PTP Hardware Clock (PHC)"
-       depends on FEC && ARCH_MXC
+       depends on FEC && ARCH_MXC && !SOC_IMX25 && !SOC_IMX27 && !SOC_IMX35 && !SOC_IMX5
        select PTP_1588_CLOCK
-       default y if SOC_IMX6Q
        --help---
          Say Y here if you want to use PTP Hardware Clock (PHC) in the
          driver.  Only the basic clock operations have been implemented.
index 83f0ea9..8ebc352 100644 (file)
@@ -4761,7 +4761,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal)
        struct ksz_dma_buf *dma_buf;
        struct net_device *dev = NULL;
 
-       spin_lock(&hw_priv->hwlock);
+       spin_lock_irq(&hw_priv->hwlock);
        last = info->last;
 
        while (info->avail < info->alloc) {
@@ -4795,7 +4795,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal)
                info->avail++;
        }
        info->last = last;
-       spin_unlock(&hw_priv->hwlock);
+       spin_unlock_irq(&hw_priv->hwlock);
 
        /* Notify the network subsystem that the packet has been sent. */
        if (dev)
@@ -5259,11 +5259,15 @@ static irqreturn_t netdev_intr(int irq, void *dev_id)
        struct dev_info *hw_priv = priv->adapter;
        struct ksz_hw *hw = &hw_priv->hw;
 
+       spin_lock(&hw_priv->hwlock);
+
        hw_read_intr(hw, &int_enable);
 
        /* Not our interrupt! */
-       if (!int_enable)
+       if (!int_enable) {
+               spin_unlock(&hw_priv->hwlock);
                return IRQ_NONE;
+       }
 
        do {
                hw_ack_intr(hw, int_enable);
@@ -5310,6 +5314,8 @@ static irqreturn_t netdev_intr(int irq, void *dev_id)
 
        hw_ena_intr(hw);
 
+       spin_unlock(&hw_priv->hwlock);
+
        return IRQ_HANDLED;
 }
 
index 5379024..bc7ec64 100644 (file)
@@ -36,8 +36,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 29
-#define QLCNIC_LINUX_VERSIONID  "5.0.29"
+#define _QLCNIC_LINUX_SUBVERSION 30
+#define QLCNIC_LINUX_VERSIONID  "5.0.30"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
                 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
index 58f094c..b14b8f0 100644 (file)
@@ -134,7 +134,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
        __le32 *tmp_buf;
        struct qlcnic_cmd_args cmd;
        struct qlcnic_hardware_context *ahw;
-       struct qlcnic_dump_template_hdr *tmpl_hdr, *tmp_tmpl;
+       struct qlcnic_dump_template_hdr *tmpl_hdr;
        dma_addr_t tmp_addr_t = 0;
 
        ahw = adapter->ahw;
@@ -150,6 +150,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
        }
        temp_size = cmd.rsp.arg2;
        version = cmd.rsp.arg3;
+       dev_info(&adapter->pdev->dev,
+                "minidump template version = 0x%x", version);
        if (!temp_size)
                return -EIO;
 
@@ -174,7 +176,6 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
                err = -EIO;
                goto error;
        }
-       tmp_tmpl = tmp_addr;
        ahw->fw_dump.tmpl_hdr = vzalloc(temp_size);
        if (!ahw->fw_dump.tmpl_hdr) {
                err = -EIO;
index fc48e00..7a6d5eb 100644 (file)
@@ -365,7 +365,7 @@ static int
 qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
                struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
 {
-       u32 i, producer, consumer;
+       u32 i, producer;
        struct qlcnic_cmd_buffer *pbuf;
        struct cmd_desc_type0 *cmd_desc;
        struct qlcnic_host_tx_ring *tx_ring;
@@ -379,7 +379,6 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
        __netif_tx_lock_bh(tx_ring->txq);
 
        producer = tx_ring->producer;
-       consumer = tx_ring->sw_consumer;
 
        if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
                netif_tx_stop_queue(tx_ring->txq);
@@ -402,7 +401,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
                pbuf->frag_count = 0;
 
                memcpy(&tx_ring->desc_head[producer],
-                       &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
+                      cmd_desc, sizeof(struct cmd_desc_type0));
 
                producer = get_next_index(producer, tx_ring->num_desc);
                i++;
index a7554d9..d833f59 100644 (file)
@@ -445,13 +445,10 @@ static int
 qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 {
        u8 id;
-       u32 ref_count;
        int i, ret = 1;
        u32 data = QLCNIC_MGMT_FUNC;
        struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-       /* If other drivers are not in use set their privilege level */
-       ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
        ret = qlcnic_api_lock(adapter);
        if (ret)
                goto err_lock;
@@ -531,11 +528,9 @@ static int qlcnic_setup_pci_map(struct pci_dev *pdev,
 {
        u32 offset;
        void __iomem *mem_ptr0 = NULL;
-       resource_size_t mem_base;
        unsigned long mem_len, pci_len0 = 0, bar0_len;
 
        /* remap phys address */
-       mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
        mem_len = pci_resource_len(pdev, 0);
 
        qlcnic_get_bar_length(pdev->device, &bar0_len);
index 12ff292..0b8d862 100644 (file)
@@ -197,7 +197,7 @@ static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
        int i, k, timeout = 0;
        void __iomem *base = adapter->ahw->pci_base0;
        u32 addr, data;
-       u8 opcode, no_ops;
+       u8 no_ops;
        struct __ctrl *ctr = &entry->region.ctrl;
        struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
 
@@ -206,7 +206,6 @@ static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
 
        for (i = 0; i < no_ops; i++) {
                k = 0;
-               opcode = 0;
                for (k = 0; k < 8; k++) {
                        if (!(ctr->opcode & (1 << k)))
                                continue;
index cb6fc5a..5ac9332 100644 (file)
@@ -577,28 +577,30 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct cp_private *cp;
+       int handled = 0;
        u16 status;
 
        if (unlikely(dev == NULL))
                return IRQ_NONE;
        cp = netdev_priv(dev);
 
+       spin_lock(&cp->lock);
+
        status = cpr16(IntrStatus);
        if (!status || (status == 0xFFFF))
-               return IRQ_NONE;
+               goto out_unlock;
+
+       handled = 1;
 
        netif_dbg(cp, intr, dev, "intr, status %04x cmd %02x cpcmd %04x\n",
                  status, cpr8(Cmd), cpr16(CpCmd));
 
        cpw16(IntrStatus, status & ~cp_rx_intr_mask);
 
-       spin_lock(&cp->lock);
-
        /* close possible race's with dev_close */
        if (unlikely(!netif_running(dev))) {
                cpw16(IntrMask, 0);
-               spin_unlock(&cp->lock);
-               return IRQ_HANDLED;
+               goto out_unlock;
        }
 
        if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
@@ -612,7 +614,6 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
        if (status & LinkChg)
                mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
 
-       spin_unlock(&cp->lock);
 
        if (status & PciErr) {
                u16 pci_status;
@@ -625,7 +626,10 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
                /* TODO: reset hardware */
        }
 
-       return IRQ_HANDLED;
+out_unlock:
+       spin_unlock(&cp->lock);
+
+       return IRQ_RETVAL(handled);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 022b45b..a670d23 100644 (file)
@@ -2386,8 +2386,6 @@ static const struct of_device_id smc91x_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, smc91x_match);
-#else
-#define smc91x_match NULL
 #endif
 
 static struct dev_pm_ops smc_drv_pm_ops = {
@@ -2402,7 +2400,7 @@ static struct platform_driver smc_driver = {
                .name   = CARDNAME,
                .owner  = THIS_MODULE,
                .pm     = &smc_drv_pm_ops,
-               .of_match_table = smc91x_match,
+               .of_match_table = of_match_ptr(smc91x_match),
        },
 };
 
index 4616bf2..e112877 100644 (file)
@@ -2575,11 +2575,13 @@ static const struct dev_pm_ops smsc911x_pm_ops = {
 #define SMSC911X_PM_OPS NULL
 #endif
 
+#ifdef CONFIG_OF
 static const struct of_device_id smsc911x_dt_ids[] = {
        { .compatible = "smsc,lan9115", },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
+#endif
 
 static struct platform_driver smsc911x_driver = {
        .probe = smsc911x_drv_probe,
@@ -2588,7 +2590,7 @@ static struct platform_driver smsc911x_driver = {
                .name   = SMSC_CHIPNAME,
                .owner  = THIS_MODULE,
                .pm     = SMSC911X_PM_OPS,
-               .of_match_table = smsc911x_dt_ids,
+               .of_match_table = of_match_ptr(smsc911x_dt_ids),
        },
 };
 
index 023a4fb..b05df89 100644 (file)
@@ -127,14 +127,14 @@ static inline int stmmac_register_platform(void)
 }
 static inline void stmmac_unregister_platform(void)
 {
-       platform_driver_register(&stmmac_pltfr_driver);
+       platform_driver_unregister(&stmmac_pltfr_driver);
 }
 #else
 static inline int stmmac_register_platform(void)
 {
        pr_debug("stmmac: do not register the platf driver\n");
 
-       return -EINVAL;
+       return 0;
 }
 static inline void stmmac_unregister_platform(void)
 {
@@ -162,7 +162,7 @@ static inline int stmmac_register_pci(void)
 {
        pr_debug("stmmac: do not register the PCI driver\n");
 
-       return -EINVAL;
+       return 0;
 }
 static inline void stmmac_unregister_pci(void)
 {
index 542edbc..f07c061 100644 (file)
@@ -2194,18 +2194,20 @@ int stmmac_restore(struct net_device *ndev)
  */
 static int __init stmmac_init(void)
 {
-       int err_plt = 0;
-       int err_pci = 0;
-
-       err_plt = stmmac_register_platform();
-       err_pci = stmmac_register_pci();
-
-       if ((err_pci) && (err_plt)) {
-               pr_err("stmmac: driver registration failed\n");
-               return -EINVAL;
-       }
+       int ret;
 
+       ret = stmmac_register_platform();
+       if (ret)
+               goto err;
+       ret = stmmac_register_pci();
+       if (ret)
+               goto err_pci;
        return 0;
+err_pci:
+       stmmac_unregister_platform();
+err:
+       pr_err("stmmac: driver registration failed\n");
+       return ret;
 }
 
 static void __exit stmmac_exit(void)
index 3377667..5e62c1a 100644 (file)
@@ -27,8 +27,6 @@
 #include <linux/uaccess.h>
 #include <linux/workqueue.h>
 
-#include <plat/clock.h>
-
 #include "cpts.h"
 
 #ifdef CONFIG_TI_CPTS
index 40b426e..504f7f1 100644 (file)
@@ -138,6 +138,8 @@ struct tun_file {
        /* only used for fasnyc */
        unsigned int flags;
        u16 queue_index;
+       struct list_head next;
+       struct tun_struct *detached;
 };
 
 struct tun_flow_entry {
@@ -182,6 +184,8 @@ struct tun_struct {
        struct hlist_head flows[TUN_NUM_FLOW_ENTRIES];
        struct timer_list flow_gc_timer;
        unsigned long ageing_time;
+       unsigned int numdisabled;
+       struct list_head disabled;
 };
 
 static inline u32 tun_hashfn(u32 rxhash)
@@ -385,6 +389,23 @@ static void tun_set_real_num_queues(struct tun_struct *tun)
        netif_set_real_num_rx_queues(tun->dev, tun->numqueues);
 }
 
+static void tun_disable_queue(struct tun_struct *tun, struct tun_file *tfile)
+{
+       tfile->detached = tun;
+       list_add_tail(&tfile->next, &tun->disabled);
+       ++tun->numdisabled;
+}
+
+static struct tun_struct *tun_enable_queue(struct tun_file *tfile)
+{
+       struct tun_struct *tun = tfile->detached;
+
+       tfile->detached = NULL;
+       list_del_init(&tfile->next);
+       --tun->numdisabled;
+       return tun;
+}
+
 static void __tun_detach(struct tun_file *tfile, bool clean)
 {
        struct tun_file *ntfile;
@@ -406,20 +427,25 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
                ntfile->queue_index = index;
 
                --tun->numqueues;
-               sock_put(&tfile->sk);
+               if (clean)
+                       sock_put(&tfile->sk);
+               else
+                       tun_disable_queue(tun, tfile);
 
                synchronize_net();
                tun_flow_delete_by_queue(tun, tun->numqueues + 1);
                /* Drop read queue */
                skb_queue_purge(&tfile->sk.sk_receive_queue);
                tun_set_real_num_queues(tun);
-
-               if (tun->numqueues == 0 && !(tun->flags & TUN_PERSIST))
-                       if (dev->reg_state == NETREG_REGISTERED)
-                               unregister_netdevice(dev);
-       }
+       } else if (tfile->detached && clean)
+               tun = tun_enable_queue(tfile);
 
        if (clean) {
+               if (tun && tun->numqueues == 0 && tun->numdisabled == 0 &&
+                   !(tun->flags & TUN_PERSIST))
+                       if (tun->dev->reg_state == NETREG_REGISTERED)
+                               unregister_netdevice(tun->dev);
+
                BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,
                                 &tfile->socket.flags));
                sk_release_kernel(&tfile->sk);
@@ -436,7 +462,7 @@ static void tun_detach(struct tun_file *tfile, bool clean)
 static void tun_detach_all(struct net_device *dev)
 {
        struct tun_struct *tun = netdev_priv(dev);
-       struct tun_file *tfile;
+       struct tun_file *tfile, *tmp;
        int i, n = tun->numqueues;
 
        for (i = 0; i < n; i++) {
@@ -457,6 +483,12 @@ static void tun_detach_all(struct net_device *dev)
                skb_queue_purge(&tfile->sk.sk_receive_queue);
                sock_put(&tfile->sk);
        }
+       list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) {
+               tun_enable_queue(tfile);
+               skb_queue_purge(&tfile->sk.sk_receive_queue);
+               sock_put(&tfile->sk);
+       }
+       BUG_ON(tun->numdisabled != 0);
 }
 
 static int tun_attach(struct tun_struct *tun, struct file *file)
@@ -473,7 +505,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
                goto out;
 
        err = -E2BIG;
-       if (tun->numqueues == MAX_TAP_QUEUES)
+       if (!tfile->detached &&
+           tun->numqueues + tun->numdisabled == MAX_TAP_QUEUES)
                goto out;
 
        err = 0;
@@ -487,9 +520,13 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
        tfile->queue_index = tun->numqueues;
        rcu_assign_pointer(tfile->tun, tun);
        rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
-       sock_hold(&tfile->sk);
        tun->numqueues++;
 
+       if (tfile->detached)
+               tun_enable_queue(tfile);
+       else
+               sock_hold(&tfile->sk);
+
        tun_set_real_num_queues(tun);
 
        /* device is allowed to go away first, so no need to hold extra
@@ -1162,6 +1199,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
                skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
        }
 
+       skb_reset_network_header(skb);
        rxhash = skb_get_rxhash(skb);
        netif_rx_ni(skb);
 
@@ -1349,6 +1387,7 @@ static void tun_free_netdev(struct net_device *dev)
 {
        struct tun_struct *tun = netdev_priv(dev);
 
+       BUG_ON(!(list_empty(&tun->disabled)));
        tun_flow_uninit(tun);
        free_netdev(dev);
 }
@@ -1543,6 +1582,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                err = tun_attach(tun, file);
                if (err < 0)
                        return err;
+
+               if (tun->flags & TUN_TAP_MQ &&
+                   (tun->numqueues + tun->numdisabled > 1))
+                       return err;
        }
        else {
                char *name;
@@ -1601,6 +1644,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                        TUN_USER_FEATURES;
                dev->features = dev->hw_features;
 
+               INIT_LIST_HEAD(&tun->disabled);
                err = tun_attach(tun, file);
                if (err < 0)
                        goto err_free_dev;
@@ -1755,32 +1799,28 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
 {
        struct tun_file *tfile = file->private_data;
        struct tun_struct *tun;
-       struct net_device *dev;
        int ret = 0;
 
        rtnl_lock();
 
        if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {
-               dev = __dev_get_by_name(tfile->net, ifr->ifr_name);
-               if (!dev) {
-                       ret = -EINVAL;
-                       goto unlock;
-               }
-
-               tun = netdev_priv(dev);
-               if (dev->netdev_ops != &tap_netdev_ops &&
-                       dev->netdev_ops != &tun_netdev_ops)
+               tun = tfile->detached;
+               if (!tun)
                        ret = -EINVAL;
                else if (tun_not_capable(tun))
                        ret = -EPERM;
                else
                        ret = tun_attach(tun, file);
-       } else if (ifr->ifr_flags & IFF_DETACH_QUEUE)
-               __tun_detach(tfile, false);
-       else
+       } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
+               tun = rcu_dereference_protected(tfile->tun,
+                                               lockdep_rtnl_is_held());
+               if (!tun || !(tun->flags & TUN_TAP_MQ))
+                       ret = -EINVAL;
+               else
+                       __tun_detach(tfile, false);
+       } else
                ret = -EINVAL;
 
-unlock:
        rtnl_unlock();
        return ret;
 }
@@ -2092,6 +2132,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 
        file->private_data = tfile;
        set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
+       INIT_LIST_HEAD(&tfile->next);
 
        return 0;
 }
index d012982..3f3d12d 100644 (file)
@@ -457,12 +457,6 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
 
-static int cdc_manage_power(struct usbnet *dev, int on)
-{
-       dev->intf->needs_remote_wakeup = on;
-       return 0;
-}
-
 static const struct driver_info        cdc_info = {
        .description =  "CDC Ethernet Device",
        .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
@@ -470,7 +464,7 @@ static const struct driver_info     cdc_info = {
        .bind =         usbnet_cdc_bind,
        .unbind =       usbnet_cdc_unbind,
        .status =       usbnet_cdc_status,
-       .manage_power = cdc_manage_power,
+       .manage_power = usbnet_manage_power,
 };
 
 static const struct driver_info wwan_info = {
@@ -479,7 +473,7 @@ static const struct driver_info wwan_info = {
        .bind =         usbnet_cdc_bind,
        .unbind =       usbnet_cdc_unbind,
        .status =       usbnet_cdc_status,
-       .manage_power = cdc_manage_power,
+       .manage_power = usbnet_manage_power,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -487,6 +481,7 @@ static const struct driver_info wwan_info = {
 #define HUAWEI_VENDOR_ID       0x12D1
 #define NOVATEL_VENDOR_ID      0x1410
 #define ZTE_VENDOR_ID          0x19D2
+#define DELL_VENDOR_ID         0x413C
 
 static const struct usb_device_id      products [] = {
 /*
@@ -594,27 +589,29 @@ static const struct usb_device_id products [] = {
 
 /* Novatel USB551L and MC551 - handled by qmi_wwan */
 {
-       .match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
-                | USB_DEVICE_ID_MATCH_PRODUCT
-                | USB_DEVICE_ID_MATCH_INT_INFO,
-       .idVendor               = NOVATEL_VENDOR_ID,
-       .idProduct              = 0xB001,
-       .bInterfaceClass        = USB_CLASS_COMM,
-       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET,
-       .bInterfaceProtocol     = USB_CDC_PROTO_NONE,
+       USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0xB001, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
        .driver_info = 0,
 },
 
 /* Novatel E362 - handled by qmi_wwan */
 {
-       .match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
-                | USB_DEVICE_ID_MATCH_PRODUCT
-                | USB_DEVICE_ID_MATCH_INT_INFO,
-       .idVendor               = NOVATEL_VENDOR_ID,
-       .idProduct              = 0x9010,
-       .bInterfaceClass        = USB_CLASS_COMM,
-       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET,
-       .bInterfaceProtocol     = USB_CDC_PROTO_NONE,
+       USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0x9010, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = 0,
+},
+
+/* Dell Wireless 5800 (Novatel E362) - handled by qmi_wwan */
+{
+       USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x8195, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = 0,
+},
+
+/* Dell Wireless 5800 (Novatel E362) - handled by qmi_wwan */
+{
+       USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x8196, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
        .driver_info = 0,
 },
 
index d38bc20..71b6e92 100644 (file)
@@ -1129,19 +1129,13 @@ static void cdc_ncm_disconnect(struct usb_interface *intf)
        usbnet_disconnect(intf);
 }
 
-static int cdc_ncm_manage_power(struct usbnet *dev, int status)
-{
-       dev->intf->needs_remote_wakeup = status;
-       return 0;
-}
-
 static const struct driver_info cdc_ncm_info = {
        .description = "CDC NCM",
        .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET,
        .bind = cdc_ncm_bind,
        .unbind = cdc_ncm_unbind,
        .check_connect = cdc_ncm_check_connect,
-       .manage_power = cdc_ncm_manage_power,
+       .manage_power = usbnet_manage_power,
        .status = cdc_ncm_status,
        .rx_fixup = cdc_ncm_rx_fixup,
        .tx_fixup = cdc_ncm_tx_fixup,
@@ -1155,7 +1149,7 @@ static const struct driver_info wwan_info = {
        .bind = cdc_ncm_bind,
        .unbind = cdc_ncm_unbind,
        .check_connect = cdc_ncm_check_connect,
-       .manage_power = cdc_ncm_manage_power,
+       .manage_power = usbnet_manage_power,
        .status = cdc_ncm_status,
        .rx_fixup = cdc_ncm_rx_fixup,
        .tx_fixup = cdc_ncm_tx_fixup,
index 1ea91f4..91d7cb9 100644 (file)
@@ -383,6 +383,20 @@ static const struct usb_device_id products[] = {
                                              USB_CDC_PROTO_NONE),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
+       {       /* Dell Wireless 5800 (Novatel E362) */
+               USB_DEVICE_AND_INTERFACE_INFO(0x413C, 0x8195,
+                                             USB_CLASS_COMM,
+                                             USB_CDC_SUBCLASS_ETHERNET,
+                                             USB_CDC_PROTO_NONE),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
+       {       /* Dell Wireless 5800 V2 (Novatel E362) */
+               USB_DEVICE_AND_INTERFACE_INFO(0x413C, 0x8196,
+                                             USB_CLASS_COMM,
+                                             USB_CDC_SUBCLASS_ETHERNET,
+                                             USB_CDC_PROTO_NONE),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
 
        /* 3. Combined interface devices matching on interface number */
        {QMI_FIXED_INTF(0x12d1, 0x140c, 1)},    /* Huawei E173 */
@@ -419,6 +433,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x19d2, 0x0199, 1)},    /* ZTE MF820S */
        {QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0257, 3)},    /* ZTE MF821 */
+       {QMI_FIXED_INTF(0x19d2, 0x0284, 4)},    /* ZTE MF880 */
        {QMI_FIXED_INTF(0x19d2, 0x0326, 4)},    /* ZTE MF821D */
        {QMI_FIXED_INTF(0x19d2, 0x1008, 4)},    /* ZTE (Vodafone) K3570-Z */
        {QMI_FIXED_INTF(0x19d2, 0x1010, 4)},    /* ZTE (Vodafone) K3571-Z */
index c04110b..3d4bf01 100644 (file)
@@ -719,7 +719,8 @@ int usbnet_stop (struct net_device *net)
        dev->flags = 0;
        del_timer_sync (&dev->delay);
        tasklet_kill (&dev->bh);
-       if (info->manage_power)
+       if (info->manage_power &&
+           !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags))
                info->manage_power(dev, 0);
        else
                usb_autopm_put_interface(dev->intf);
@@ -794,14 +795,14 @@ int usbnet_open (struct net_device *net)
        tasklet_schedule (&dev->bh);
        if (info->manage_power) {
                retval = info->manage_power(dev, 1);
-               if (retval < 0)
-                       goto done_manage_power_error;
-               usb_autopm_put_interface(dev->intf);
+               if (retval < 0) {
+                       retval = 0;
+                       set_bit(EVENT_NO_RUNTIME_PM, &dev->flags);
+               } else {
+                       usb_autopm_put_interface(dev->intf);
+               }
        }
        return retval;
-
-done_manage_power_error:
-       clear_bit(EVENT_DEV_OPEN, &dev->flags);
 done:
        usb_autopm_put_interface(dev->intf);
 done_nopm:
@@ -1615,6 +1616,16 @@ void usbnet_device_suggests_idle(struct usbnet *dev)
 }
 EXPORT_SYMBOL(usbnet_device_suggests_idle);
 
+/*
+ * For devices that can do without special commands
+ */
+int usbnet_manage_power(struct usbnet *dev, int on)
+{
+       dev->intf->needs_remote_wakeup = on;
+       return 0;
+}
+EXPORT_SYMBOL(usbnet_manage_power);
+
 /*-------------------------------------------------------------------------*/
 static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
                             u16 value, u16 index, void *data, u16 size)
index 6650fde..9f1e947 100644 (file)
@@ -152,6 +152,9 @@ enum {
        /* Device IDs */
        USB_DEVICE_ID_I6050 = 0x0186,
        USB_DEVICE_ID_I6050_2 = 0x0188,
+       USB_DEVICE_ID_I6150 = 0x07d6,
+       USB_DEVICE_ID_I6150_2 = 0x07d7,
+       USB_DEVICE_ID_I6150_3 = 0x07d9,
        USB_DEVICE_ID_I6250 = 0x0187,
 };
 
index 713d033..080f363 100644 (file)
@@ -510,6 +510,9 @@ int i2400mu_probe(struct usb_interface *iface,
        switch (id->idProduct) {
        case USB_DEVICE_ID_I6050:
        case USB_DEVICE_ID_I6050_2:
+       case USB_DEVICE_ID_I6150:
+       case USB_DEVICE_ID_I6150_2:
+       case USB_DEVICE_ID_I6150_3:
        case USB_DEVICE_ID_I6250:
                i2400mu->i6050 = 1;
                break;
@@ -759,6 +762,9 @@ static
 struct usb_device_id i2400mu_id_table[] = {
        { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) },
        { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) },
+       { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150) },
+       { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_2) },
+       { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_3) },
        { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) },
        { USB_DEVICE(0x8086, 0x0181) },
        { USB_DEVICE(0x8086, 0x1403) },
index 062dfdf..67156ef 100644 (file)
@@ -47,7 +47,7 @@ obj-$(CONFIG_RT2X00)  += rt2x00/
 
 obj-$(CONFIG_P54_COMMON)       += p54/
 
-obj-$(CONFIG_ATH_COMMON)       += ath/
+obj-$(CONFIG_ATH_CARDS)                += ath/
 
 obj-$(CONFIG_MAC80211_HWSIM)   += mac80211_hwsim.o
 
index 4ffb6a5..44f8b3f 100644 (file)
@@ -685,6 +685,14 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
         * to mac80211.
         */
        rx_status = IEEE80211_SKB_RXCB(entry->skb);
+
+       /* Ensure that all fields of rx_status are initialized
+        * properly. The skb->cb array was used for driver
+        * specific informations, so rx_status might contain
+        * garbage.
+        */
+       memset(rx_status, 0, sizeof(*rx_status));
+
        rx_status->mactime = rxdesc.timestamp;
        rx_status->band = rt2x00dev->curr_band;
        rx_status->freq = rt2x00dev->curr_freq;
index db8d211..2390ddb 100644 (file)
@@ -629,7 +629,7 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from,
        read_unlock(&devtree_lock);
        return np;
 }
-EXPORT_SYMBOL(of_find_matching_node);
+EXPORT_SYMBOL(of_find_matching_node_and_match);
 
 /**
  * of_modalias_node - Lookup appropriate modalias for a device node
index adb3a4b..6ba047f 100644 (file)
@@ -239,44 +239,37 @@ static bool is_full_charged(struct charger_manager *cm)
        int uV;
 
        /* If there is no battery, it cannot be charged */
-       if (!is_batt_present(cm)) {
-               val.intval = 0;
-               goto out;
-       }
+       if (!is_batt_present(cm))
+               return false;
 
        if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
+               val.intval = 0;
+
                /* Not full if capacity of fuel gauge isn't full */
                ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
                                POWER_SUPPLY_PROP_CHARGE_FULL, &val);
-               if (!ret && val.intval > desc->fullbatt_full_capacity) {
-                       val.intval = 1;
-                       goto out;
-               }
+               if (!ret && val.intval > desc->fullbatt_full_capacity)
+                       return true;
        }
 
        /* Full, if it's over the fullbatt voltage */
        if (desc->fullbatt_uV > 0) {
                ret = get_batt_uV(cm, &uV);
-               if (!ret && uV >= desc->fullbatt_uV) {
-                       val.intval = 1;
-                       goto out;
-               }
+               if (!ret && uV >= desc->fullbatt_uV)
+                       return true;
        }
 
        /* Full, if the capacity is more than fullbatt_soc */
        if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
+               val.intval = 0;
+
                ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
                                POWER_SUPPLY_PROP_CAPACITY, &val);
-               if (!ret && val.intval >= desc->fullbatt_soc) {
-                       val.intval = 1;
-                       goto out;
-               }
+               if (!ret && val.intval >= desc->fullbatt_soc)
+                       return true;
        }
 
-       val.intval = 0;
-
-out:
-       return val.intval ? true : false;
+       return false;
 }
 
 /**
@@ -489,8 +482,9 @@ static void fullbatt_vchk(struct work_struct *work)
                return;
        }
 
-       diff = desc->fullbatt_uV;
-       diff -= batt_uV;
+       diff = desc->fullbatt_uV - batt_uV;
+       if (diff < 0)
+               return;
 
        dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
 
index ed81720..e513cd9 100644 (file)
@@ -112,6 +112,17 @@ config PWM_SAMSUNG
          To compile this driver as a module, choose M here: the module
          will be called pwm-samsung.
 
+config PWM_SPEAR
+       tristate "STMicroelectronics SPEAr PWM support"
+       depends on PLAT_SPEAR
+       depends on OF
+       help
+         Generic PWM framework driver for the PWM controller on ST
+         SPEAr SoCs.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-spear.
+
 config PWM_TEGRA
        tristate "NVIDIA Tegra PWM support"
        depends on ARCH_TEGRA
@@ -125,6 +136,7 @@ config PWM_TEGRA
 config  PWM_TIECAP
        tristate "ECAP PWM support"
        depends on SOC_AM33XX
+       select PWM_TIPWMSS
        help
          PWM driver support for the ECAP APWM controller found on AM33XX
          TI SOC
@@ -135,6 +147,7 @@ config  PWM_TIECAP
 config  PWM_TIEHRPWM
        tristate "EHRPWM PWM support"
        depends on SOC_AM33XX
+       select PWM_TIPWMSS
        help
          PWM driver support for the EHRPWM controller found on AM33XX
          TI SOC
@@ -142,14 +155,32 @@ config  PWM_TIEHRPWM
          To compile this driver as a module, choose M here: the module
          will be called pwm-tiehrpwm.
 
-config PWM_TWL6030
-       tristate "TWL6030 PWM support"
+config  PWM_TIPWMSS
+       bool
+       depends on SOC_AM33XX && (PWM_TIEHRPWM || PWM_TIECAP)
+       help
+         PWM Subsystem driver support for AM33xx SOC.
+
+         PWM submodules require PWM config space access from submodule
+         drivers and require common parent driver support.
+
+config PWM_TWL
+       tristate "TWL4030/6030 PWM support"
+       depends on TWL4030_CORE
+       help
+         Generic PWM framework driver for TWL4030/6030.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-twl.
+
+config PWM_TWL_LED
+       tristate "TWL4030/6030 PWM support for LED drivers"
        depends on TWL4030_CORE
        help
-         Generic PWM framework driver for TWL6030.
+         Generic PWM framework driver for TWL4030/6030 LED terminals.
 
          To compile this driver as a module, choose M here: the module
-         will be called pwm-twl6030.
+         will be called pwm-twl-led.
 
 config PWM_VT8500
        tristate "vt8500 pwm support"
index acfe482..62a2963 100644 (file)
@@ -8,8 +8,11 @@ obj-$(CONFIG_PWM_MXS)          += pwm-mxs.o
 obj-$(CONFIG_PWM_PUV3)         += pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)          += pwm-pxa.o
 obj-$(CONFIG_PWM_SAMSUNG)      += pwm-samsung.o
+obj-$(CONFIG_PWM_SPEAR)                += pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)                += pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)       += pwm-tiecap.o
 obj-$(CONFIG_PWM_TIEHRPWM)     += pwm-tiehrpwm.o
-obj-$(CONFIG_PWM_TWL6030)      += pwm-twl6030.o
+obj-$(CONFIG_PWM_TIPWMSS)      += pwm-tipwmss.o
+obj-$(CONFIG_PWM_TWL)          += pwm-twl.o
+obj-$(CONFIG_PWM_TWL_LED)      += pwm-twl-led.o
 obj-$(CONFIG_PWM_VT8500)       += pwm-vt8500.o
index f5acdaa..903138b 100644 (file)
@@ -32,6 +32,9 @@
 
 #define MAX_PWMS 1024
 
+/* flags in the third cell of the DT PWM specifier */
+#define PWM_SPEC_POLARITY      (1 << 0)
+
 static DEFINE_MUTEX(pwm_lookup_lock);
 static LIST_HEAD(pwm_lookup_list);
 static DEFINE_MUTEX(pwm_lock);
@@ -129,6 +132,32 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
        return 0;
 }
 
+struct pwm_device *
+of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
+{
+       struct pwm_device *pwm;
+
+       if (pc->of_pwm_n_cells < 3)
+               return ERR_PTR(-EINVAL);
+
+       if (args->args[0] >= pc->npwm)
+               return ERR_PTR(-EINVAL);
+
+       pwm = pwm_request_from_chip(pc, args->args[0], NULL);
+       if (IS_ERR(pwm))
+               return pwm;
+
+       pwm_set_period(pwm, args->args[1]);
+
+       if (args->args[2] & PWM_SPEC_POLARITY)
+               pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
+       else
+               pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
+
+       return pwm;
+}
+EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
+
 static struct pwm_device *
 of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
 {
index 8f26e9f..65a86bd 100644 (file)
@@ -235,7 +235,7 @@ static int imx_pwm_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
                        of_match_device(imx_pwm_dt_ids, &pdev->dev);
-       struct imx_pwm_data *data;
+       const struct imx_pwm_data *data;
        struct imx_chip *imx;
        struct resource *r;
        int ret = 0;
index 015a822..1410644 100644 (file)
@@ -49,9 +49,24 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                c = 0; /* 0 set division by 256 */
        period_cycles = c;
 
+       /* The duty-cycle value is as follows:
+        *
+        *  DUTY-CYCLE     HIGH LEVEL
+        *      1            99.9%
+        *      25           90.0%
+        *      128          50.0%
+        *      220          10.0%
+        *      255           0.1%
+        *      0             0.0%
+        *
+        * In other words, the register value is duty-cycle % 256 with
+        * duty-cycle in the range 1-256.
+        */
        c = 256 * duty_ns;
        do_div(c, period_ns);
-       duty_cycles = c;
+       if (c > 255)
+               c = 255;
+       duty_cycles = 256 - c;
 
        writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles),
                lpc32xx->base + (pwm->hwpwm << 2));
@@ -106,6 +121,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
        lpc32xx->chip.dev = &pdev->dev;
        lpc32xx->chip.ops = &lpc32xx_pwm_ops;
        lpc32xx->chip.npwm = 2;
+       lpc32xx->chip.base = -1;
 
        ret = pwmchip_add(&lpc32xx->chip);
        if (ret < 0) {
@@ -121,8 +137,11 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
 static int lpc32xx_pwm_remove(struct platform_device *pdev)
 {
        struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev);
+       unsigned int i;
+
+       for (i = 0; i < lpc32xx->chip.npwm; i++)
+               pwm_disable(&lpc32xx->chip.pwms[i]);
 
-       clk_disable(lpc32xx->clk);
        return pwmchip_remove(&lpc32xx->chip);
 }
 
index e9b15d0..5207e6c 100644 (file)
@@ -222,6 +222,7 @@ static int s3c_pwm_probe(struct platform_device *pdev)
 
        /* calculate base of control bits in TCON */
        s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+       s3c->pwm_id = id;
        s3c->chip.dev = &pdev->dev;
        s3c->chip.ops = &s3c_pwm_ops;
        s3c->chip.base = -1;
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c
new file mode 100644 (file)
index 0000000..83b21d9
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * ST Microelectronics SPEAr Pulse Width Modulator driver
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define NUM_PWM                4
+
+/* PWM registers and bits definitions */
+#define PWMCR                  0x00    /* Control Register */
+#define PWMCR_PWM_ENABLE       0x1
+#define PWMCR_PRESCALE_SHIFT   2
+#define PWMCR_MIN_PRESCALE     0x00
+#define PWMCR_MAX_PRESCALE     0x3FFF
+
+#define PWMDCR                 0x04    /* Duty Cycle Register */
+#define PWMDCR_MIN_DUTY                0x0001
+#define PWMDCR_MAX_DUTY                0xFFFF
+
+#define PWMPCR                 0x08    /* Period Register */
+#define PWMPCR_MIN_PERIOD      0x0001
+#define PWMPCR_MAX_PERIOD      0xFFFF
+
+/* Following only available on 13xx SoCs */
+#define PWMMCR                 0x3C    /* Master Control Register */
+#define PWMMCR_PWM_ENABLE      0x1
+
+/**
+ * struct spear_pwm_chip - struct representing pwm chip
+ *
+ * @mmio_base: base address of pwm chip
+ * @clk: pointer to clk structure of pwm chip
+ * @chip: linux pwm chip representation
+ * @dev: pointer to device structure of pwm chip
+ */
+struct spear_pwm_chip {
+       void __iomem *mmio_base;
+       struct clk *clk;
+       struct pwm_chip chip;
+       struct device *dev;
+};
+
+static inline struct spear_pwm_chip *to_spear_pwm_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct spear_pwm_chip, chip);
+}
+
+static inline u32 spear_pwm_readl(struct spear_pwm_chip *chip, unsigned int num,
+                                 unsigned long offset)
+{
+       return readl_relaxed(chip->mmio_base + (num << 4) + offset);
+}
+
+static inline void spear_pwm_writel(struct spear_pwm_chip *chip,
+                                   unsigned int num, unsigned long offset,
+                                   unsigned long val)
+{
+       writel_relaxed(val, chip->mmio_base + (num << 4) + offset);
+}
+
+static int spear_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                           int duty_ns, int period_ns)
+{
+       struct spear_pwm_chip *pc = to_spear_pwm_chip(chip);
+       u64 val, div, clk_rate;
+       unsigned long prescale = PWMCR_MIN_PRESCALE, pv, dc;
+       int ret;
+
+       /*
+        * Find pv, dc and prescale to suit duty_ns and period_ns. This is done
+        * according to formulas described below:
+        *
+        * period_ns = 10^9 * (PRESCALE + 1) * PV / PWM_CLK_RATE
+        * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+        *
+        * PV = (PWM_CLK_RATE * period_ns) / (10^9 * (PRESCALE + 1))
+        * DC = (PWM_CLK_RATE * duty_ns) / (10^9 * (PRESCALE + 1))
+        */
+       clk_rate = clk_get_rate(pc->clk);
+       while (1) {
+               div = 1000000000;
+               div *= 1 + prescale;
+               val = clk_rate * period_ns;
+               pv = div64_u64(val, div);
+               val = clk_rate * duty_ns;
+               dc = div64_u64(val, div);
+
+               /* if duty_ns and period_ns are not achievable then return */
+               if (pv < PWMPCR_MIN_PERIOD || dc < PWMDCR_MIN_DUTY)
+                       return -EINVAL;
+
+               /*
+                * if pv and dc have crossed their upper limit, then increase
+                * prescale and recalculate pv and dc.
+                */
+               if (pv > PWMPCR_MAX_PERIOD || dc > PWMDCR_MAX_DUTY) {
+                       if (++prescale > PWMCR_MAX_PRESCALE)
+                               return -EINVAL;
+                       continue;
+               }
+               break;
+       }
+
+       /*
+        * NOTE: the clock to PWM has to be enabled first before writing to the
+        * registers.
+        */
+       ret = clk_enable(pc->clk);
+       if (ret)
+               return ret;
+
+       spear_pwm_writel(pc, pwm->hwpwm, PWMCR,
+                       prescale << PWMCR_PRESCALE_SHIFT);
+       spear_pwm_writel(pc, pwm->hwpwm, PWMDCR, dc);
+       spear_pwm_writel(pc, pwm->hwpwm, PWMPCR, pv);
+       clk_disable(pc->clk);
+
+       return 0;
+}
+
+static int spear_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct spear_pwm_chip *pc = to_spear_pwm_chip(chip);
+       int rc = 0;
+       u32 val;
+
+       rc = clk_enable(pc->clk);
+       if (!rc)
+               return rc;
+
+       val = spear_pwm_readl(pc, pwm->hwpwm, PWMCR);
+       val |= PWMCR_PWM_ENABLE;
+       spear_pwm_writel(pc, pwm->hwpwm, PWMCR, val);
+
+       return 0;
+}
+
+static void spear_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct spear_pwm_chip *pc = to_spear_pwm_chip(chip);
+       u32 val;
+
+       val = spear_pwm_readl(pc, pwm->hwpwm, PWMCR);
+       val &= ~PWMCR_PWM_ENABLE;
+       spear_pwm_writel(pc, pwm->hwpwm, PWMCR, val);
+
+       clk_disable(pc->clk);
+}
+
+static const struct pwm_ops spear_pwm_ops = {
+       .config = spear_pwm_config,
+       .enable = spear_pwm_enable,
+       .disable = spear_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static int spear_pwm_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct spear_pwm_chip *pc;
+       struct resource *r;
+       int ret;
+       u32 val;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               dev_err(&pdev->dev, "no memory resources defined\n");
+               return -ENODEV;
+       }
+
+       pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
+       if (!pc) {
+               dev_err(&pdev->dev, "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
+       if (!pc->mmio_base)
+               return -EADDRNOTAVAIL;
+
+       pc->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(pc->clk))
+               return PTR_ERR(pc->clk);
+
+       pc->dev = &pdev->dev;
+       platform_set_drvdata(pdev, pc);
+
+       pc->chip.dev = &pdev->dev;
+       pc->chip.ops = &spear_pwm_ops;
+       pc->chip.base = -1;
+       pc->chip.npwm = NUM_PWM;
+
+       ret = clk_prepare(pc->clk);
+       if (!ret)
+               return ret;
+
+       if (of_device_is_compatible(np, "st,spear1340-pwm")) {
+               ret = clk_enable(pc->clk);
+               if (!ret) {
+                       clk_unprepare(pc->clk);
+                       return ret;
+               }
+               /*
+                * Following enables PWM chip, channels would still be
+                * enabled individually through their control register
+                */
+               val = readl_relaxed(pc->mmio_base + PWMMCR);
+               val |= PWMMCR_PWM_ENABLE;
+               writel_relaxed(val, pc->mmio_base + PWMMCR);
+
+               clk_disable(pc->clk);
+       }
+
+       ret = pwmchip_add(&pc->chip);
+       if (!ret) {
+               clk_unprepare(pc->clk);
+               dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+       }
+
+       return ret;
+}
+
+static int spear_pwm_remove(struct platform_device *pdev)
+{
+       struct spear_pwm_chip *pc = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < NUM_PWM; i++)
+               pwm_disable(&pc->chip.pwms[i]);
+
+       /* clk was prepared in probe, hence unprepare it here */
+       clk_unprepare(pc->clk);
+       return pwmchip_remove(&pc->chip);
+}
+
+static struct of_device_id spear_pwm_of_match[] = {
+       { .compatible = "st,spear320-pwm" },
+       { .compatible = "st,spear1340-pwm" },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, spear_pwm_of_match);
+
+static struct platform_driver spear_pwm_driver = {
+       .driver = {
+               .name = "spear-pwm",
+               .of_match_table = spear_pwm_of_match,
+       },
+       .probe = spear_pwm_probe,
+       .remove = spear_pwm_remove,
+};
+
+module_platform_driver(spear_pwm_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.com>");
+MODULE_ALIAS("platform:spear-pwm");
index 87c091b..5cf016d 100644 (file)
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/pwm.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "pwm-tipwmss.h"
 
 /* ECAP registers and bits definitions */
 #define CAP1                   0x08
@@ -184,12 +188,24 @@ static const struct pwm_ops ecap_pwm_ops = {
        .owner          = THIS_MODULE,
 };
 
+static const struct of_device_id ecap_of_match[] = {
+       { .compatible   = "ti,am33xx-ecap" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ecap_of_match);
+
 static int ecap_pwm_probe(struct platform_device *pdev)
 {
        int ret;
        struct resource *r;
        struct clk *clk;
        struct ecap_pwm_chip *pc;
+       u16 status;
+       struct pinctrl *pinctrl;
+
+       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+       if (IS_ERR(pinctrl))
+               dev_warn(&pdev->dev, "unable to select pin group\n");
 
        pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
        if (!pc) {
@@ -211,6 +227,8 @@ static int ecap_pwm_probe(struct platform_device *pdev)
 
        pc->chip.dev = &pdev->dev;
        pc->chip.ops = &ecap_pwm_ops;
+       pc->chip.of_xlate = of_pwm_xlate_with_flags;
+       pc->chip.of_pwm_n_cells = 3;
        pc->chip.base = -1;
        pc->chip.npwm = 1;
 
@@ -231,14 +249,40 @@ static int ecap_pwm_probe(struct platform_device *pdev)
        }
 
        pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
+       status = pwmss_submodule_state_change(pdev->dev.parent,
+                       PWMSS_ECAPCLK_EN);
+       if (!(status & PWMSS_ECAPCLK_EN_ACK)) {
+               dev_err(&pdev->dev, "PWMSS config space clock enable failed\n");
+               ret = -EINVAL;
+               goto pwmss_clk_failure;
+       }
+
+       pm_runtime_put_sync(&pdev->dev);
+
        platform_set_drvdata(pdev, pc);
        return 0;
+
+pwmss_clk_failure:
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       pwmchip_remove(&pc->chip);
+       return ret;
 }
 
 static int ecap_pwm_remove(struct platform_device *pdev)
 {
        struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
 
+       pm_runtime_get_sync(&pdev->dev);
+       /*
+        * Due to hardware misbehaviour, acknowledge of the stop_req
+        * is missing. Hence checking of the status bit skipped.
+        */
+       pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ);
+       pm_runtime_put_sync(&pdev->dev);
+
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        return pwmchip_remove(&pc->chip);
@@ -246,7 +290,9 @@ static int ecap_pwm_remove(struct platform_device *pdev)
 
 static struct platform_driver ecap_pwm_driver = {
        .driver = {
-               .name = "ecap",
+               .name   = "ecap",
+               .owner  = THIS_MODULE,
+               .of_match_table = ecap_of_match,
        },
        .probe = ecap_pwm_probe,
        .remove = ecap_pwm_remove,
index 9ffd389..72a6dd4 100644 (file)
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "pwm-tipwmss.h"
 
 /* EHRPWM registers and bits definitions */
 
@@ -115,6 +119,7 @@ struct ehrpwm_pwm_chip {
        void __iomem    *mmio_base;
        unsigned long period_cycles[NUM_PWM_CHANNEL];
        enum pwm_polarity polarity[NUM_PWM_CHANNEL];
+       struct  clk     *tbclk;
 };
 
 static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -335,6 +340,9 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        /* Channels polarity can be configured from action qualifier module */
        configure_polarity(pc, pwm->hwpwm);
 
+       /* Enable TBCLK before enabling PWM device */
+       clk_enable(pc->tbclk);
+
        /* Enable time counter for free_run */
        ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
        return 0;
@@ -363,6 +371,9 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 
        ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
 
+       /* Disabling TBCLK on PWM disable */
+       clk_disable(pc->tbclk);
+
        /* Stop Time base counter */
        ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
 
@@ -392,12 +403,24 @@ static const struct pwm_ops ehrpwm_pwm_ops = {
        .owner          = THIS_MODULE,
 };
 
+static const struct of_device_id ehrpwm_of_match[] = {
+       { .compatible   = "ti,am33xx-ehrpwm" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
+
 static int ehrpwm_pwm_probe(struct platform_device *pdev)
 {
        int ret;
        struct resource *r;
        struct clk *clk;
        struct ehrpwm_pwm_chip *pc;
+       u16 status;
+       struct pinctrl *pinctrl;
+
+       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+       if (IS_ERR(pinctrl))
+               dev_warn(&pdev->dev, "unable to select pin group\n");
 
        pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
        if (!pc) {
@@ -419,6 +442,8 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
 
        pc->chip.dev = &pdev->dev;
        pc->chip.ops = &ehrpwm_pwm_ops;
+       pc->chip.of_xlate = of_pwm_xlate_with_flags;
+       pc->chip.of_pwm_n_cells = 3;
        pc->chip.base = -1;
        pc->chip.npwm = NUM_PWM_CHANNEL;
 
@@ -432,6 +457,13 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
        if (!pc->mmio_base)
                return  -EADDRNOTAVAIL;
 
+       /* Acquire tbclk for Time Base EHRPWM submodule */
+       pc->tbclk = devm_clk_get(&pdev->dev, "tbclk");
+       if (IS_ERR(pc->tbclk)) {
+               dev_err(&pdev->dev, "Failed to get tbclk\n");
+               return PTR_ERR(pc->tbclk);
+       }
+
        ret = pwmchip_add(&pc->chip);
        if (ret < 0) {
                dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
@@ -439,14 +471,40 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
        }
 
        pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
+       status = pwmss_submodule_state_change(pdev->dev.parent,
+                       PWMSS_EPWMCLK_EN);
+       if (!(status & PWMSS_EPWMCLK_EN_ACK)) {
+               dev_err(&pdev->dev, "PWMSS config space clock enable failed\n");
+               ret = -EINVAL;
+               goto pwmss_clk_failure;
+       }
+
+       pm_runtime_put_sync(&pdev->dev);
+
        platform_set_drvdata(pdev, pc);
        return 0;
+
+pwmss_clk_failure:
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       pwmchip_remove(&pc->chip);
+       return ret;
 }
 
 static int ehrpwm_pwm_remove(struct platform_device *pdev)
 {
        struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
 
+       pm_runtime_get_sync(&pdev->dev);
+       /*
+        * Due to hardware misbehaviour, acknowledge of the stop_req
+        * is missing. Hence checking of the status bit skipped.
+        */
+       pwmss_submodule_state_change(pdev->dev.parent, PWMSS_EPWMCLK_STOP_REQ);
+       pm_runtime_put_sync(&pdev->dev);
+
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        return pwmchip_remove(&pc->chip);
@@ -454,7 +512,9 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev)
 
 static struct platform_driver ehrpwm_pwm_driver = {
        .driver = {
-               .name = "ehrpwm",
+               .name   = "ehrpwm",
+               .owner  = THIS_MODULE,
+               .of_match_table = ehrpwm_of_match,
        },
        .probe = ehrpwm_pwm_probe,
        .remove = ehrpwm_pwm_remove,
diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c
new file mode 100644 (file)
index 0000000..3448a1c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * TI PWM Subsystem driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+
+#include "pwm-tipwmss.h"
+
+#define PWMSS_CLKCONFIG                0x8     /* Clock gating reg */
+#define PWMSS_CLKSTATUS                0xc     /* Clock gating status reg */
+
+struct pwmss_info {
+       void __iomem    *mmio_base;
+       struct mutex    pwmss_lock;
+       u16             pwmss_clkconfig;
+};
+
+u16 pwmss_submodule_state_change(struct device *dev, int set)
+{
+       struct pwmss_info *info = dev_get_drvdata(dev);
+       u16 val;
+
+       mutex_lock(&info->pwmss_lock);
+       val = readw(info->mmio_base + PWMSS_CLKCONFIG);
+       val |= set;
+       writew(val , info->mmio_base + PWMSS_CLKCONFIG);
+       mutex_unlock(&info->pwmss_lock);
+
+       return readw(info->mmio_base + PWMSS_CLKSTATUS);
+}
+EXPORT_SYMBOL(pwmss_submodule_state_change);
+
+static const struct of_device_id pwmss_of_match[] = {
+       { .compatible   = "ti,am33xx-pwmss" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, pwmss_of_match);
+
+static int pwmss_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct resource *r;
+       struct pwmss_info *info;
+       struct device_node *node = pdev->dev.of_node;
+
+       info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               dev_err(&pdev->dev, "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       mutex_init(&info->pwmss_lock);
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               return -ENODEV;
+       }
+
+       info->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
+       if (!info->mmio_base)
+               return -EADDRNOTAVAIL;
+
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+       platform_set_drvdata(pdev, info);
+
+       /* Populate all the child nodes here... */
+       ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+       if (ret)
+               dev_err(&pdev->dev, "no child node found\n");
+
+       return ret;
+}
+
+static int pwmss_remove(struct platform_device *pdev)
+{
+       struct pwmss_info *info = platform_get_drvdata(pdev);
+
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       mutex_destroy(&info->pwmss_lock);
+       return 0;
+}
+
+static int pwmss_suspend(struct device *dev)
+{
+       struct pwmss_info *info = dev_get_drvdata(dev);
+
+       info->pwmss_clkconfig = readw(info->mmio_base + PWMSS_CLKCONFIG);
+       pm_runtime_put_sync(dev);
+       return 0;
+}
+
+static int pwmss_resume(struct device *dev)
+{
+       struct pwmss_info *info = dev_get_drvdata(dev);
+
+       pm_runtime_get_sync(dev);
+       writew(info->pwmss_clkconfig, info->mmio_base + PWMSS_CLKCONFIG);
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume);
+
+static struct platform_driver pwmss_driver = {
+       .driver = {
+               .name   = "pwmss",
+               .owner  = THIS_MODULE,
+               .pm     = &pwmss_pm_ops,
+               .of_match_table = pwmss_of_match,
+       },
+       .probe  = pwmss_probe,
+       .remove = pwmss_remove,
+};
+
+module_platform_driver(pwmss_driver);
+
+MODULE_DESCRIPTION("PWM Subsystem driver");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-tipwmss.h b/drivers/pwm/pwm-tipwmss.h
new file mode 100644 (file)
index 0000000..11f76a1
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * TI PWM Subsystem driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TIPWMSS_H
+#define __TIPWMSS_H
+
+#ifdef CONFIG_PWM_TIPWMSS
+/* PWM substem clock gating */
+#define PWMSS_ECAPCLK_EN       BIT(0)
+#define PWMSS_ECAPCLK_STOP_REQ BIT(1)
+#define PWMSS_EPWMCLK_EN       BIT(8)
+#define PWMSS_EPWMCLK_STOP_REQ BIT(9)
+
+#define PWMSS_ECAPCLK_EN_ACK   BIT(0)
+#define PWMSS_EPWMCLK_EN_ACK   BIT(8)
+
+extern u16 pwmss_submodule_state_change(struct device *dev, int set);
+#else
+static inline u16 pwmss_submodule_state_change(struct device *dev, int set)
+{
+       /* return success status value */
+       return 0xFFFF;
+}
+#endif
+#endif /* __TIPWMSS_H */
diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c
new file mode 100644 (file)
index 0000000..9dfa0f3
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Driver for TWL4030/6030 Pulse Width Modulator used as LED driver
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This driver is a complete rewrite of the former pwm-twl6030.c authorded by:
+ * Hemanth V <hemanthv@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/i2c/twl.h>
+#include <linux/slab.h>
+
+/*
+ * This driver handles the PWM driven LED terminals of TWL4030 and TWL6030.
+ * To generate the signal on TWL4030:
+ *  - LEDA uses PWMA
+ *  - LEDB uses PWMB
+ * TWL6030 has one LED pin with dedicated LEDPWM
+ */
+
+#define TWL4030_LED_MAX                0x7f
+#define TWL6030_LED_MAX                0xff
+
+/* Registers, bits and macro for TWL4030 */
+#define TWL4030_LEDEN_REG      0x00
+#define TWL4030_PWMA_REG       0x01
+
+#define TWL4030_LEDXON         (1 << 0)
+#define TWL4030_LEDXPWM                (1 << 4)
+#define TWL4030_LED_PINS       (TWL4030_LEDXON | TWL4030_LEDXPWM)
+#define TWL4030_LED_TOGGLE(led, x)     ((x) << (led))
+
+/* Register, bits and macro for TWL6030 */
+#define TWL6030_LED_PWM_CTRL1  0xf4
+#define TWL6030_LED_PWM_CTRL2  0xf5
+
+#define TWL6040_LED_MODE_HW    0x00
+#define TWL6040_LED_MODE_ON    0x01
+#define TWL6040_LED_MODE_OFF   0x02
+#define TWL6040_LED_MODE_MASK  0x03
+
+struct twl_pwmled_chip {
+       struct pwm_chip chip;
+       struct mutex mutex;
+};
+
+static inline struct twl_pwmled_chip *to_twl(struct pwm_chip *chip)
+{
+       return container_of(chip, struct twl_pwmled_chip, chip);
+}
+
+static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                             int duty_ns, int period_ns)
+{
+       int duty_cycle = DIV_ROUND_UP(duty_ns * TWL4030_LED_MAX, period_ns) + 1;
+       u8 pwm_config[2] = { 1, 0 };
+       int base, ret;
+
+       /*
+        * To configure the duty period:
+        * On-cycle is set to 1 (the minimum allowed value)
+        * The off time of 0 is not configurable, so the mapping is:
+        * 0 -> off cycle = 2,
+        * 1 -> off cycle = 2,
+        * 2 -> off cycle = 3,
+        * 126 - > off cycle 127,
+        * 127 - > off cycle 1
+        * When on cycle == off cycle the PWM will be always on
+        */
+       if (duty_cycle == 1)
+               duty_cycle = 2;
+       else if (duty_cycle > TWL4030_LED_MAX)
+               duty_cycle = 1;
+
+       base = pwm->hwpwm * 2 + TWL4030_PWMA_REG;
+
+       pwm_config[1] = duty_cycle;
+
+       ret = twl_i2c_write(TWL4030_MODULE_LED, pwm_config, base, 2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
+
+       return ret;
+}
+
+static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label);
+               goto out;
+       }
+
+       val |= TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+       return ret;
+}
+
+static void twl4030_pwmled_disable(struct pwm_chip *chip,
+                                  struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                             int duty_ns, int period_ns)
+{
+       int duty_cycle = (duty_ns * TWL6030_LED_MAX) / period_ns;
+       u8 on_time;
+       int ret;
+
+       on_time = duty_cycle & 0xff;
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, on_time,
+                              TWL6030_LED_PWM_CTRL1);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
+
+       return ret;
+}
+
+static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
+                       pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL6040_LED_MODE_MASK;
+       val |= TWL6040_LED_MODE_ON;
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+       return ret;
+}
+
+static void twl6030_pwmled_disable(struct pwm_chip *chip,
+                                  struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
+                       pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL6040_LED_MODE_MASK;
+       val |= TWL6040_LED_MODE_OFF;
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
+                       pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL6040_LED_MODE_MASK;
+       val |= TWL6040_LED_MODE_OFF;
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+       return ret;
+}
+
+static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwmled_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
+                       pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL6040_LED_MODE_MASK;
+       val |= TWL6040_LED_MODE_HW;
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static const struct pwm_ops twl4030_pwmled_ops = {
+       .enable = twl4030_pwmled_enable,
+       .disable = twl4030_pwmled_disable,
+       .config = twl4030_pwmled_config,
+};
+
+static const struct pwm_ops twl6030_pwmled_ops = {
+       .enable = twl6030_pwmled_enable,
+       .disable = twl6030_pwmled_disable,
+       .config = twl6030_pwmled_config,
+       .request = twl6030_pwmled_request,
+       .free = twl6030_pwmled_free,
+};
+
+static int twl_pwmled_probe(struct platform_device *pdev)
+{
+       struct twl_pwmled_chip *twl;
+       int ret;
+
+       twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
+       if (!twl)
+               return -ENOMEM;
+
+       if (twl_class_is_4030()) {
+               twl->chip.ops = &twl4030_pwmled_ops;
+               twl->chip.npwm = 2;
+       } else {
+               twl->chip.ops = &twl6030_pwmled_ops;
+               twl->chip.npwm = 1;
+       }
+
+       twl->chip.dev = &pdev->dev;
+       twl->chip.base = -1;
+
+       mutex_init(&twl->mutex);
+
+       ret = pwmchip_add(&twl->chip);
+       if (ret < 0)
+               return ret;
+
+       platform_set_drvdata(pdev, twl);
+
+       return 0;
+}
+
+static int twl_pwmled_remove(struct platform_device *pdev)
+{
+       struct twl_pwmled_chip *twl = platform_get_drvdata(pdev);
+
+       return pwmchip_remove(&twl->chip);
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id twl_pwmled_of_match[] = {
+       { .compatible = "ti,twl4030-pwmled" },
+       { .compatible = "ti,twl6030-pwmled" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, twl_pwmled_of_match);
+#endif
+
+static struct platform_driver twl_pwmled_driver = {
+       .driver = {
+               .name = "twl-pwmled",
+               .of_match_table = of_match_ptr(twl_pwmled_of_match),
+       },
+       .probe = twl_pwmled_probe,
+       .remove = twl_pwmled_remove,
+};
+module_platform_driver(twl_pwmled_driver);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030 LED outputs");
+MODULE_ALIAS("platform:twl-pwmled");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
new file mode 100644 (file)
index 0000000..e65db95
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Driver for TWL4030/6030 Generic Pulse Width Modulator
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/i2c/twl.h>
+#include <linux/slab.h>
+
+/*
+ * This driver handles the PWMs of TWL4030 and TWL6030.
+ * The TRM names for the PWMs on TWL4030 are: PWM0, PWM1
+ * TWL6030 also have two PWMs named in the TRM as PWM1, PWM2
+ */
+
+#define TWL_PWM_MAX            0x7f
+
+/* Registers, bits and macro for TWL4030 */
+#define TWL4030_GPBR1_REG      0x0c
+#define TWL4030_PMBR1_REG      0x0d
+
+/* GPBR1 register bits */
+#define TWL4030_PWMXCLK_ENABLE (1 << 0)
+#define TWL4030_PWMX_ENABLE    (1 << 2)
+#define TWL4030_PWMX_BITS      (TWL4030_PWMX_ENABLE | TWL4030_PWMXCLK_ENABLE)
+#define TWL4030_PWM_TOGGLE(pwm, x)     ((x) << (pwm))
+
+/* PMBR1 register bits */
+#define TWL4030_GPIO6_PWM0_MUTE_MASK           (0x03 << 2)
+#define TWL4030_GPIO6_PWM0_MUTE_PWM0           (0x01 << 2)
+#define TWL4030_GPIO7_VIBRASYNC_PWM1_MASK      (0x03 << 4)
+#define TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1      (0x03 << 4)
+
+/* Register, bits and macro for TWL6030 */
+#define TWL6030_TOGGLE3_REG    0x92
+
+#define TWL6030_PWMXR          (1 << 0)
+#define TWL6030_PWMXS          (1 << 1)
+#define TWL6030_PWMXEN         (1 << 2)
+#define TWL6030_PWM_TOGGLE(pwm, x)     ((x) << (pwm * 3))
+
+struct twl_pwm_chip {
+       struct pwm_chip chip;
+       struct mutex mutex;
+       u8 twl6030_toggle3;
+       u8 twl4030_pwm_mux;
+};
+
+static inline struct twl_pwm_chip *to_twl(struct pwm_chip *chip)
+{
+       return container_of(chip, struct twl_pwm_chip, chip);
+}
+
+static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                             int duty_ns, int period_ns)
+{
+       int duty_cycle = DIV_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1;
+       u8 pwm_config[2] = { 1, 0 };
+       int base, ret;
+
+       /*
+        * To configure the duty period:
+        * On-cycle is set to 1 (the minimum allowed value)
+        * The off time of 0 is not configurable, so the mapping is:
+        * 0 -> off cycle = 2,
+        * 1 -> off cycle = 2,
+        * 2 -> off cycle = 3,
+        * 126 - > off cycle 127,
+        * 127 - > off cycle 1
+        * When on cycle == off cycle the PWM will be always on
+        */
+       if (duty_cycle == 1)
+               duty_cycle = 2;
+       else if (duty_cycle > TWL_PWM_MAX)
+               duty_cycle = 1;
+
+       base = pwm->hwpwm * 3;
+
+       pwm_config[1] = duty_cycle;
+
+       ret = twl_i2c_write(TWL_MODULE_PWM, pwm_config, base, 2);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
+
+       return ret;
+}
+
+static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label);
+               goto out;
+       }
+
+       val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
+
+       val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+       return ret;
+}
+
+static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = to_twl(chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label);
+               goto out;
+       }
+
+       val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
+
+       val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = to_twl(chip);
+       int ret;
+       u8 val, mask, bits;
+
+       if (pwm->hwpwm == 1) {
+               mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK;
+               bits = TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1;
+       } else {
+               mask = TWL4030_GPIO6_PWM0_MUTE_MASK;
+               bits = TWL4030_GPIO6_PWM0_MUTE_PWM0;
+       }
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label);
+               goto out;
+       }
+
+       /* Save the current MUX configuration for the PWM */
+       twl->twl4030_pwm_mux &= ~mask;
+       twl->twl4030_pwm_mux |= (val & mask);
+
+       /* Select PWM functionality */
+       val &= ~mask;
+       val |= bits;
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+       return ret;
+}
+
+static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip,
+                                               chip);
+       int ret;
+       u8 val, mask;
+
+       if (pwm->hwpwm == 1)
+               mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK;
+       else
+               mask = TWL4030_GPIO6_PWM0_MUTE_MASK;
+
+       mutex_lock(&twl->mutex);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label);
+               goto out;
+       }
+
+       /* Restore the MUX configuration for the PWM */
+       val &= ~mask;
+       val |= (twl->twl4030_pwm_mux & mask);
+
+       ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG);
+       if (ret < 0)
+               dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label);
+
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip,
+                                               chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       val = twl->twl6030_toggle3;
+       val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN);
+       val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR);
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
+               goto out;
+       }
+
+       twl->twl6030_toggle3 = val;
+out:
+       mutex_unlock(&twl->mutex);
+       return 0;
+}
+
+static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip,
+                                               chip);
+       int ret;
+       u8 val;
+
+       mutex_lock(&twl->mutex);
+       val = twl->twl6030_toggle3;
+       val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR);
+       val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN);
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to read TOGGLE3\n", pwm->label);
+               goto out;
+       }
+
+       val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN);
+
+       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
+       if (ret < 0) {
+               dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
+               goto out;
+       }
+
+       twl->twl6030_toggle3 = val;
+out:
+       mutex_unlock(&twl->mutex);
+}
+
+static const struct pwm_ops twl4030_pwm_ops = {
+       .config = twl_pwm_config,
+       .enable = twl4030_pwm_enable,
+       .disable = twl4030_pwm_disable,
+       .request = twl4030_pwm_request,
+       .free = twl4030_pwm_free,
+};
+
+static const struct pwm_ops twl6030_pwm_ops = {
+       .config = twl_pwm_config,
+       .enable = twl6030_pwm_enable,
+       .disable = twl6030_pwm_disable,
+};
+
+static int twl_pwm_probe(struct platform_device *pdev)
+{
+       struct twl_pwm_chip *twl;
+       int ret;
+
+       twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
+       if (!twl)
+               return -ENOMEM;
+
+       if (twl_class_is_4030())
+               twl->chip.ops = &twl4030_pwm_ops;
+       else
+               twl->chip.ops = &twl6030_pwm_ops;
+
+       twl->chip.dev = &pdev->dev;
+       twl->chip.base = -1;
+       twl->chip.npwm = 2;
+
+       mutex_init(&twl->mutex);
+
+       ret = pwmchip_add(&twl->chip);
+       if (ret < 0)
+               return ret;
+
+       platform_set_drvdata(pdev, twl);
+
+       return 0;
+}
+
+static int twl_pwm_remove(struct platform_device *pdev)
+{
+       struct twl_pwm_chip *twl = platform_get_drvdata(pdev);
+
+       return pwmchip_remove(&twl->chip);
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id twl_pwm_of_match[] = {
+       { .compatible = "ti,twl4030-pwm" },
+       { .compatible = "ti,twl6030-pwm" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, twl_pwm_of_match);
+#endif
+
+static struct platform_driver twl_pwm_driver = {
+       .driver = {
+               .name = "twl-pwm",
+               .of_match_table = of_match_ptr(twl_pwm_of_match),
+       },
+       .probe = twl_pwm_probe,
+       .remove = twl_pwm_remove,
+};
+module_platform_driver(twl_pwm_driver);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030");
+MODULE_ALIAS("platform:twl-pwm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-twl6030.c b/drivers/pwm/pwm-twl6030.c
deleted file mode 100644 (file)
index 378a7e2..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * twl6030_pwm.c
- * Driver for PHOENIX (TWL6030) Pulse Width Modulator
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Hemanth V <hemanthv@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pwm.h>
-#include <linux/i2c/twl.h>
-#include <linux/slab.h>
-
-#define LED_PWM_CTRL1  0xF4
-#define LED_PWM_CTRL2  0xF5
-
-/* Max value for CTRL1 register */
-#define PWM_CTRL1_MAX  255
-
-/* Pull down disable */
-#define PWM_CTRL2_DIS_PD       (1 << 6)
-
-/* Current control 2.5 milli Amps */
-#define PWM_CTRL2_CURR_02      (2 << 4)
-
-/* LED supply source */
-#define PWM_CTRL2_SRC_VAC      (1 << 2)
-
-/* LED modes */
-#define PWM_CTRL2_MODE_HW      (0 << 0)
-#define PWM_CTRL2_MODE_SW      (1 << 0)
-#define PWM_CTRL2_MODE_DIS     (2 << 0)
-
-#define PWM_CTRL2_MODE_MASK    0x3
-
-struct twl6030_pwm_chip {
-       struct pwm_chip chip;
-};
-
-static int twl6030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-       int ret;
-       u8 val;
-
-       /* Configure PWM */
-       val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
-             PWM_CTRL2_MODE_HW;
-
-       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-       if (ret < 0) {
-               dev_err(chip->dev, "%s: Failed to configure PWM, Error %d\n",
-                       pwm->label, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int twl6030_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-                             int duty_ns, int period_ns)
-{
-       u8 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
-       int ret;
-
-       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
-       if (ret < 0) {
-               pr_err("%s: Failed to configure PWM, Error %d\n",
-                       pwm->label, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-       int ret;
-       u8 val;
-
-       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-       if (ret < 0) {
-               dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
-                       pwm->label, ret);
-               return ret;
-       }
-
-       /* Change mode to software control */
-       val &= ~PWM_CTRL2_MODE_MASK;
-       val |= PWM_CTRL2_MODE_SW;
-
-       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-       if (ret < 0) {
-               dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
-                       pwm->label, ret);
-               return ret;
-       }
-
-       twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-       return 0;
-}
-
-static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-       int ret;
-       u8 val;
-
-       ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-       if (ret < 0) {
-               dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
-                       pwm->label, ret);
-               return;
-       }
-
-       val &= ~PWM_CTRL2_MODE_MASK;
-       val |= PWM_CTRL2_MODE_HW;
-
-       ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-       if (ret < 0) {
-               dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
-                       pwm->label, ret);
-       }
-}
-
-static const struct pwm_ops twl6030_pwm_ops = {
-       .request = twl6030_pwm_request,
-       .config = twl6030_pwm_config,
-       .enable = twl6030_pwm_enable,
-       .disable = twl6030_pwm_disable,
-};
-
-static int twl6030_pwm_probe(struct platform_device *pdev)
-{
-       struct twl6030_pwm_chip *twl6030;
-       int ret;
-
-       twl6030 = devm_kzalloc(&pdev->dev, sizeof(*twl6030), GFP_KERNEL);
-       if (!twl6030)
-               return -ENOMEM;
-
-       twl6030->chip.dev = &pdev->dev;
-       twl6030->chip.ops = &twl6030_pwm_ops;
-       twl6030->chip.base = -1;
-       twl6030->chip.npwm = 1;
-
-       ret = pwmchip_add(&twl6030->chip);
-       if (ret < 0)
-               return ret;
-
-       platform_set_drvdata(pdev, twl6030);
-
-       return 0;
-}
-
-static int twl6030_pwm_remove(struct platform_device *pdev)
-{
-       struct twl6030_pwm_chip *twl6030 = platform_get_drvdata(pdev);
-
-       return pwmchip_remove(&twl6030->chip);
-}
-
-static struct platform_driver twl6030_pwm_driver = {
-       .driver = {
-               .name = "twl6030-pwm",
-       },
-       .probe = twl6030_pwm_probe,
-       .remove = twl6030_pwm_remove,
-};
-module_platform_driver(twl6030_pwm_driver);
-
-MODULE_ALIAS("platform:twl6030-pwm");
-MODULE_LICENSE("GPL");
index ad14389..b0ba2d4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * drivers/pwm/pwm-vt8500.c
  *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
 #include <linux/io.h>
 #include <linux/pwm.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/div64.h>
 
-#define VT8500_NR_PWMS 4
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+/*
+ * SoC architecture allocates register space for 4 PWMs but only
+ * 2 are currently implemented.
+ */
+#define VT8500_NR_PWMS 2
 
 struct vt8500_chip {
        struct pwm_chip chip;
        void __iomem *base;
+       struct clk *clk;
 };
 
 #define to_vt8500_chip(chip)   container_of(chip, struct vt8500_chip, chip)
@@ -51,8 +62,15 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
        unsigned long long c;
        unsigned long period_cycles, prescale, pv, dc;
+       int err;
 
-       c = 25000000/2; /* wild guess --- need to implement clocks */
+       err = clk_enable(vt8500->clk);
+       if (err < 0) {
+               dev_err(chip->dev, "failed to enable clock\n");
+               return err;
+       }
+
+       c = clk_get_rate(vt8500->clk);
        c = c * period_ns;
        do_div(c, 1000000000);
        period_cycles = c;
@@ -64,8 +82,10 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        if (pv > 4095)
                pv = 4095;
 
-       if (prescale > 1023)
+       if (prescale > 1023) {
+               clk_disable(vt8500->clk);
                return -EINVAL;
+       }
 
        c = (unsigned long long)pv * duty_ns;
        do_div(c, period_ns);
@@ -80,13 +100,21 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 3));
        writel(dc, vt8500->base + 0xc + (pwm->hwpwm << 4));
 
+       clk_disable(vt8500->clk);
        return 0;
 }
 
 static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+       int err;
        struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
 
+       err = clk_enable(vt8500->clk);
+       if (err < 0) {
+               dev_err(chip->dev, "failed to enable clock\n");
+               return err;
+       }
+
        pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0));
        writel(5, vt8500->base + (pwm->hwpwm << 4));
        return 0;
@@ -98,6 +126,8 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 
        pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0));
        writel(0, vt8500->base + (pwm->hwpwm << 4));
+
+       clk_disable(vt8500->clk);
 }
 
 static struct pwm_ops vt8500_pwm_ops = {
@@ -107,12 +137,24 @@ static struct pwm_ops vt8500_pwm_ops = {
        .owner = THIS_MODULE,
 };
 
-static int __devinit pwm_probe(struct platform_device *pdev)
+static const struct of_device_id vt8500_pwm_dt_ids[] = {
+       { .compatible = "via,vt8500-pwm", },
+       { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids);
+
+static int vt8500_pwm_probe(struct platform_device *pdev)
 {
        struct vt8500_chip *chip;
        struct resource *r;
+       struct device_node *np = pdev->dev.of_node;
        int ret;
 
+       if (!np) {
+               dev_err(&pdev->dev, "invalid devicetree node\n");
+               return -EINVAL;
+       }
+
        chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
        if (chip == NULL) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
@@ -124,6 +166,12 @@ static int __devinit pwm_probe(struct platform_device *pdev)
        chip->chip.base = -1;
        chip->chip.npwm = VT8500_NR_PWMS;
 
+       chip->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(chip->clk)) {
+               dev_err(&pdev->dev, "clock source not specified\n");
+               return PTR_ERR(chip->clk);
+       }
+
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (r == NULL) {
                dev_err(&pdev->dev, "no memory resource defined\n");
@@ -131,18 +179,26 @@ static int __devinit pwm_probe(struct platform_device *pdev)
        }
 
        chip->base = devm_request_and_ioremap(&pdev->dev, r);
-       if (chip->base == NULL)
+       if (!chip->base)
                return -EADDRNOTAVAIL;
 
+       ret = clk_prepare(chip->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to prepare clock\n");
+               return ret;
+       }
+
        ret = pwmchip_add(&chip->chip);
-       if (ret < 0)
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to add PWM chip\n");
                return ret;
+       }
 
        platform_set_drvdata(pdev, chip);
        return ret;
 }
 
-static int __devexit pwm_remove(struct platform_device *pdev)
+static int vt8500_pwm_remove(struct platform_device *pdev)
 {
        struct vt8500_chip *chip;
 
@@ -150,28 +206,22 @@ static int __devexit pwm_remove(struct platform_device *pdev)
        if (chip == NULL)
                return -ENODEV;
 
+       clk_unprepare(chip->clk);
+
        return pwmchip_remove(&chip->chip);
 }
 
-static struct platform_driver pwm_driver = {
+static struct platform_driver vt8500_pwm_driver = {
+       .probe          = vt8500_pwm_probe,
+       .remove         = vt8500_pwm_remove,
        .driver         = {
                .name   = "vt8500-pwm",
                .owner  = THIS_MODULE,
+               .of_match_table = vt8500_pwm_dt_ids,
        },
-       .probe          = pwm_probe,
-       .remove         = __devexit_p(pwm_remove),
 };
+module_platform_driver(vt8500_pwm_driver);
 
-static int __init pwm_init(void)
-{
-       return platform_driver_register(&pwm_driver);
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
-       platform_driver_unregister(&pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VT8500 PWM Driver");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL v2");
index 75c0c4f..ab34497 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/of.h>
 
 #include <asm/io.h>
 #include <asm/gpio.h>
@@ -768,6 +769,10 @@ static int atmel_spi_setup(struct spi_device *spi)
 
        /* chipselect must have been muxed as GPIO (e.g. in board setup) */
        npcs_pin = (unsigned int)spi->controller_data;
+
+       if (gpio_is_valid(spi->cs_gpio))
+               npcs_pin = spi->cs_gpio;
+
        asd = spi->controller_state;
        if (!asd) {
                asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL);
@@ -937,8 +942,9 @@ static int atmel_spi_probe(struct platform_device *pdev)
        /* the spi->mode bits understood by this driver: */
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
+       master->dev.of_node = pdev->dev.of_node;
        master->bus_num = pdev->id;
-       master->num_chipselect = 4;
+       master->num_chipselect = master->dev.of_node ? 0 : 4;
        master->setup = atmel_spi_setup;
        master->transfer = atmel_spi_transfer;
        master->cleanup = atmel_spi_cleanup;
@@ -1064,11 +1070,20 @@ static int atmel_spi_resume(struct platform_device *pdev)
 #define        atmel_spi_resume        NULL
 #endif
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_spi_dt_ids[] = {
+       { .compatible = "atmel,at91rm9200-spi" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids);
+#endif
 
 static struct platform_driver atmel_spi_driver = {
        .driver         = {
                .name   = "atmel_spi",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(atmel_spi_dt_ids),
        },
        .suspend        = atmel_spi_suspend,
        .resume         = atmel_spi_resume,
index 4dd7b7c..ad93231 100644 (file)
@@ -215,6 +215,10 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
        writel(0, regs + S3C64XX_SPI_PACKET_CNT);
 
        val = readl(regs + S3C64XX_SPI_CH_CFG);
+       val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON);
+       writel(val, regs + S3C64XX_SPI_CH_CFG);
+
+       val = readl(regs + S3C64XX_SPI_CH_CFG);
        val |= S3C64XX_SPI_CH_SW_RST;
        val &= ~S3C64XX_SPI_CH_HS_EN;
        writel(val, regs + S3C64XX_SPI_CH_CFG);
@@ -248,10 +252,6 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
        val = readl(regs + S3C64XX_SPI_MODE_CFG);
        val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
        writel(val, regs + S3C64XX_SPI_MODE_CFG);
-
-       val = readl(regs + S3C64XX_SPI_CH_CFG);
-       val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON);
-       writel(val, regs + S3C64XX_SPI_CH_CFG);
 }
 
 static void s3c64xx_spi_dmacb(void *data)
@@ -771,8 +771,6 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
                        if (list_is_last(&xfer->transfer_list,
                                                &msg->transfers))
                                cs_toggle = 1;
-                       else
-                               disable_cs(sdd, spi);
                }
 
                msg->actual_length += xfer->len;
index 32f7b55..60cfae5 100644 (file)
@@ -290,7 +290,7 @@ static int hspi_probe(struct platform_device *pdev)
        }
 
        clk = clk_get(NULL, "shyway_clk");
-       if (!clk) {
+       if (IS_ERR(clk)) {
                dev_err(&pdev->dev, "shyway_clk is required\n");
                ret = -EINVAL;
                goto error0;
index ab095ac..19ee901 100644 (file)
@@ -824,6 +824,7 @@ static void of_register_spi_devices(struct spi_master *master)
        struct spi_device *spi;
        struct device_node *nc;
        const __be32 *prop;
+       char modalias[SPI_NAME_SIZE + 4];
        int rc;
        int len;
 
@@ -887,7 +888,9 @@ static void of_register_spi_devices(struct spi_master *master)
                spi->dev.of_node = nc;
 
                /* Register the new device */
-               request_module(spi->modalias);
+               snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX,
+                        spi->modalias);
+               request_module(modalias);
                rc = spi_add_device(spi);
                if (rc) {
                        dev_err(&master->dev, "spi_device register error %s\n",
index 23f797e..57d6b29 100644 (file)
@@ -41,8 +41,7 @@
 #include <linux/of.h>
 #include <linux/gpio.h>
 #include <linux/pinctrl/consumer.h>
-
-#include <plat/omap-serial.h>
+#include <linux/platform_data/serial-omap.h>
 
 #define OMAP_MAX_HSUART_PORTS  6
 
index 0c96eb5..0331072 100644 (file)
@@ -417,14 +417,16 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
                        spin_unlock(&c->erase_completion_lock);
 
                        ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
-                       if (ret)
-                               return ret;
+
                        /* Just lock it again and continue. Nothing much can change because
                           we hold c->alloc_sem anyway. In fact, it's not entirely clear why
                           we hold c->erase_completion_lock in the majority of this function...
                           but that's a question for another (more caffeine-rich) day. */
                        spin_lock(&c->erase_completion_lock);
 
+                       if (ret)
+                               return ret;
+
                        waste = jeb->free_size;
                        jffs2_link_node_ref(c, jeb,
                                            (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
index 5c3f4e4..eed6982 100644 (file)
@@ -64,4 +64,6 @@ enum asn1_tag {
        ASN1_LONG_TAG   = 31    /* Long form tag */
 };
 
+#define ASN1_INDEFINITE_LENGTH 0x80
+
 #endif /* _LINUX_ASN1_H */
index 93b1e09..e0ce311 100644 (file)
@@ -350,6 +350,7 @@ extern void bcma_core_set_clockmode(struct bcma_device *core,
                                    enum bcma_clkmode clkmode);
 extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
                              bool on);
+extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset);
 #define BCMA_DMA_TRANSLATION_MASK      0xC0000000
 #define  BCMA_DMA_TRANSLATION_NONE     0x00000000
 #define  BCMA_DMA_TRANSLATION_DMA32_CMT        0x40000000 /* Client Mode Translation for 32-bit DMA */
index acb4f7b..f94bc83 100644 (file)
@@ -1188,14 +1188,25 @@ static inline int queue_discard_alignment(struct request_queue *q)
 
 static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector_t sector)
 {
-       sector_t alignment = sector << 9;
-       alignment = sector_div(alignment, lim->discard_granularity);
+       unsigned int alignment, granularity, offset;
 
        if (!lim->max_discard_sectors)
                return 0;
 
-       alignment = lim->discard_granularity + lim->discard_alignment - alignment;
-       return sector_div(alignment, lim->discard_granularity);
+       /* Why are these in bytes, not sectors? */
+       alignment = lim->discard_alignment >> 9;
+       granularity = lim->discard_granularity >> 9;
+       if (!granularity)
+               return 0;
+
+       /* Offset of the partition start in 'granularity' sectors */
+       offset = sector_div(sector, granularity);
+
+       /* And why do we do this modulus *again* in blkdev_issue_discard()? */
+       offset = (granularity + alignment - offset) % granularity;
+
+       /* Turn it back into bytes, gaah */
+       return offset << 9;
 }
 
 static inline int bdev_discard_alignment(struct block_device *bdev)
index 412bc6c..662fd1b 100644 (file)
@@ -31,6 +31,8 @@
 
 #define __linktime_error(message) __attribute__((__error__(message)))
 
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
 #if __GNUC_MINOR__ >= 5
 /*
  * Mark a position in code as unreachable.  This can be used to
 #define __compiletime_warning(message) __attribute__((warning(message)))
 #define __compiletime_error(message) __attribute__((error(message)))
 #endif
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#if __GNUC_MINOR__ >= 4
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#endif
+#if __GNUC_MINOR__ >= 8 || (defined(__powerpc__) && __GNUC_MINOR__ >= 6)
+#define __HAVE_BUILTIN_BSWAP16__
+#endif
+#endif
index d8e636e..973ce10 100644 (file)
 #endif
 
 #define uninitialized_var(x) x
+
+#ifndef __HAVE_BUILTIN_BSWAP16__
+/* icc has this, but it's called _bswap16 */
+#define __HAVE_BUILTIN_BSWAP16__
+#define __builtin_bswap16 _bswap16
+#endif
+
index b121554..dd852b7 100644 (file)
@@ -44,6 +44,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __rcu
 #endif
 
+/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
+#define ___PASTE(a,b) a##b
+#define __PASTE(a,b) ___PASTE(a,b)
+
 #ifdef __KERNEL__
 
 #ifdef __GNUC__
@@ -166,6 +170,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
     (typeof(ptr)) (__ptr + (off)); })
 #endif
 
+/* Not-quite-unique ID. */
+#ifndef __UNIQUE_ID
+# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
index eb48f38..bd2e52c 100644 (file)
@@ -156,7 +156,6 @@ static inline void get_dma_buf(struct dma_buf *dmabuf)
        get_file(dmabuf->file);
 }
 
-#ifdef CONFIG_DMA_SHARED_BUFFER
 struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
                                                        struct device *dev);
 void dma_buf_detach(struct dma_buf *dmabuf,
@@ -184,103 +183,5 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
                 unsigned long);
 void *dma_buf_vmap(struct dma_buf *);
 void dma_buf_vunmap(struct dma_buf *, void *vaddr);
-#else
-
-static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
-                                                       struct device *dev)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline void dma_buf_detach(struct dma_buf *dmabuf,
-                                 struct dma_buf_attachment *dmabuf_attach)
-{
-       return;
-}
-
-static inline struct dma_buf *dma_buf_export(void *priv,
-                                            const struct dma_buf_ops *ops,
-                                            size_t size, int flags)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline int dma_buf_fd(struct dma_buf *dmabuf, int flags)
-{
-       return -ENODEV;
-}
-
-static inline struct dma_buf *dma_buf_get(int fd)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline void dma_buf_put(struct dma_buf *dmabuf)
-{
-       return;
-}
-
-static inline struct sg_table *dma_buf_map_attachment(
-       struct dma_buf_attachment *attach, enum dma_data_direction write)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
-                       struct sg_table *sg, enum dma_data_direction dir)
-{
-       return;
-}
-
-static inline int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
-                                          size_t start, size_t len,
-                                          enum dma_data_direction dir)
-{
-       return -ENODEV;
-}
-
-static inline void dma_buf_end_cpu_access(struct dma_buf *dmabuf,
-                                         size_t start, size_t len,
-                                         enum dma_data_direction dir)
-{
-}
-
-static inline void *dma_buf_kmap_atomic(struct dma_buf *dmabuf,
-                                       unsigned long pnum)
-{
-       return NULL;
-}
-
-static inline void dma_buf_kunmap_atomic(struct dma_buf *dmabuf,
-                                        unsigned long pnum, void *vaddr)
-{
-}
-
-static inline void *dma_buf_kmap(struct dma_buf *dmabuf, unsigned long pnum)
-{
-       return NULL;
-}
-
-static inline void dma_buf_kunmap(struct dma_buf *dmabuf,
-                                 unsigned long pnum, void *vaddr)
-{
-}
-
-static inline int dma_buf_mmap(struct dma_buf *dmabuf,
-                              struct vm_area_struct *vma,
-                              unsigned long pgoff)
-{
-       return -ENODEV;
-}
-
-static inline void *dma_buf_vmap(struct dma_buf *dmabuf)
-{
-       return NULL;
-}
-
-static inline void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
-{
-}
-#endif /* CONFIG_DMA_SHARED_BUFFER */
 
 #endif /* __DMA_BUF_H__ */
index 2c7223d..86c361e 100644 (file)
@@ -18,6 +18,7 @@ extern int ima_bprm_check(struct linux_binprm *bprm);
 extern int ima_file_check(struct file *file, int mask);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
+extern int ima_module_check(struct file *file);
 
 #else
 static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -40,6 +41,11 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
        return 0;
 }
 
+static inline int ima_module_check(struct file *file)
+{
+       return 0;
+}
+
 #endif /* CONFIG_IMA_H */
 
 #ifdef CONFIG_IMA_APPRAISE
index d6a5806..137b419 100644 (file)
 /* Chosen so that structs with an unsigned long line up. */
 #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
 
-#define ___module_cat(a,b) __mod_ ## a ## b
-#define __module_cat(a,b) ___module_cat(a,b)
 #ifdef MODULE
 #define __MODULE_INFO(tag, name, info)                                   \
-static const char __module_cat(name,__LINE__)[]                                  \
+static const char __UNIQUE_ID(name)[]                                    \
   __used __attribute__((section(".modinfo"), unused, aligned(1)))        \
   = __stringify(tag) "=" info
 #else  /* !MODULE */
 /* This struct is here for syntactic coherency, it is not used */
 #define __MODULE_INFO(tag, name, info)                                   \
-  struct __module_cat(name,__LINE__) {}
+  struct __UNIQUE_ID(name) {}
 #endif
 #define __MODULE_PARM_TYPE(name, _type)                                          \
   __MODULE_INFO(parmtype, name##type, #name ":" _type)
index ed270bd..4eb0a50 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/kref.h>
 #include <linux/sysfs.h>
+#include <linux/workqueue.h>
 
 struct hd_geometry;
 struct mtd_info;
@@ -43,7 +44,8 @@ struct mtd_blktrans_dev {
        struct kref ref;
        struct gendisk *disk;
        struct attribute_group *disk_attributes;
-       struct task_struct *thread;
+       struct workqueue_struct *wq;
+       struct work_struct work;
        struct request_queue *rq;
        spinlock_t queue_lock;
        void *priv;
index 0f6fea7..407d1e5 100644 (file)
  * Others use readb/writeb
  */
 #if defined(__arm__)
-#define ReadDOC_(adr, reg)      ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
-#define WriteDOC_(d, adr, reg)  do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
+static inline u8 ReadDOC_(u32 __iomem *addr, unsigned long reg)
+{
+       return __raw_readl(addr + reg);
+}
+static inline void WriteDOC_(u8 data, u32 __iomem *addr, unsigned long reg)
+{
+       __raw_writel(data, addr + reg);
+       wmb();
+}
 #define DOC_IOREMAP_LEN 0x8000
 #elif defined(__ppc__)
-#define ReadDOC_(adr, reg)      ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1))))
-#define WriteDOC_(d, adr, reg)  do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
+static inline u8 ReadDOC_(u16 __iomem *addr, unsigned long reg)
+{
+       return __raw_readw(addr + reg);
+}
+static inline void WriteDOC_(u8 data, u16 __iomem *addr, unsigned long reg)
+{
+       __raw_writew(data, addr + reg);
+       wmb();
+}
 #define DOC_IOREMAP_LEN 0x4000
 #else
 #define ReadDOC_(adr, reg)      readb((void __iomem *)(adr) + (reg))
index b200292..d6ed61e 100644 (file)
@@ -155,9 +155,6 @@ struct fsmc_nand_platform_data {
        unsigned int            width;
        unsigned int            bank;
 
-       /* CLE, ALE offsets */
-       unsigned int            cle_off;
-       unsigned int            ale_off;
        enum access_mode        mode;
 
        void                    (*select_bank)(uint32_t bank, uint32_t busw);
diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h
deleted file mode 100644 (file)
index ed3c4e0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __MACH_MXS_GPMI_NAND_H__
-#define __MACH_MXS_GPMI_NAND_H__
-
-/* The size of the resources is fixed. */
-#define GPMI_NAND_RES_SIZE     6
-
-/* Resource names for the GPMI NAND driver. */
-#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
-#define GPMI_NAND_GPMI_INTERRUPT_RES_NAME  "GPMI NAND GPMI Interrupt"
-#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
-#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
-#define GPMI_NAND_DMA_CHANNELS_RES_NAME    "GPMI NAND DMA Channels"
-#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
-
-/**
- * struct gpmi_nand_platform_data - GPMI NAND driver platform data.
- *
- * This structure communicates platform-specific information to the GPMI NAND
- * driver that can't be expressed as resources.
- *
- * @platform_init:           A pointer to a function the driver will call to
- *                           initialize the platform (e.g., set up the pin mux).
- * @min_prop_delay_in_ns:    Minimum propagation delay of GPMI signals to and
- *                           from the NAND Flash device, in nanoseconds.
- * @max_prop_delay_in_ns:    Maximum propagation delay of GPMI signals to and
- *                           from the NAND Flash device, in nanoseconds.
- * @max_chip_count:          The maximum number of chips for which the driver
- *                           should configure the hardware. This value most
- *                           likely reflects the number of pins that are
- *                           connected to a NAND Flash device. If this is
- *                           greater than the SoC hardware can support, the
- *                           driver will print a message and fail to initialize.
- * @partitions:              An optional pointer to an array of partition
- *                           descriptions.
- * @partition_count:         The number of elements in the partitions array.
- */
-struct gpmi_nand_platform_data {
-       /* SoC hardware information. */
-       int             (*platform_init)(void);
-
-       /* NAND Flash information. */
-       unsigned int    min_prop_delay_in_ns;
-       unsigned int    max_prop_delay_in_ns;
-       unsigned int    max_chip_count;
-
-       /* Medium information. */
-       struct          mtd_partition *partitions;
-       unsigned        partition_count;
-};
-#endif
index 3595a02..f6eb433 100644 (file)
@@ -328,7 +328,7 @@ static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word
 
 static inline map_word map_word_load(struct map_info *map, const void *ptr)
 {
-       map_word r;
+       map_word r = {{0} };
 
        if (map_bankwidth_is_1(map))
                r.x[0] = *(unsigned char *)ptr;
@@ -391,7 +391,7 @@ static inline map_word map_word_ff(struct map_info *map)
 
 static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
 {
-       map_word r;
+       map_word uninitialized_var(r);
 
        if (map_bankwidth_is_1(map))
                r.x[0] = __raw_readb(map->virt + ofs);
index 81d61e7..f9ac289 100644 (file)
@@ -98,7 +98,7 @@ struct mtd_oob_ops {
 };
 
 #define MTD_MAX_OOBFREE_ENTRIES_LARGE  32
-#define MTD_MAX_ECCPOS_ENTRIES_LARGE   448
+#define MTD_MAX_ECCPOS_ENTRIES_LARGE   640
 /*
  * Internal ECC layout control structure. For historical reasons, there is a
  * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
index 24e9159..7ccb3c5 100644 (file)
@@ -219,6 +219,13 @@ typedef enum {
 #define NAND_OWN_BUFFERS       0x00020000
 /* Chip may not exist, so silence any errors in scan */
 #define NAND_SCAN_SILENT_NODEV 0x00040000
+/*
+ * Autodetect nand buswidth with readid/onfi.
+ * This suppose the driver will configure the hardware in 8 bits mode
+ * when calling nand_scan_ident, and update its configuration
+ * before calling nand_scan_tail.
+ */
+#define NAND_BUSWIDTH_AUTO      0x00080000
 
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
@@ -471,8 +478,8 @@ struct nand_buffers {
  *                     non 0 if ONFI supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
- * @onfi_set_features  [REPLACEABLE] set the features for ONFI nand
- * @onfi_get_features  [REPLACEABLE] get the features for ONFI nand
+ * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
  * @ecclayout:         [REPLACEABLE] the default ECC placement scheme
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
index 01e4b15..1c28f88 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef __SH_FLCTL_H__
 #define __SH_FLCTL_H__
 
+#include <linux/completion.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #define ESTERINTE      (0x1 << 24)     /* ECC error interrupt enable */
 #define AC1CLR         (0x1 << 19)     /* ECC FIFO clear */
 #define AC0CLR         (0x1 << 18)     /* Data FIFO clear */
+#define DREQ0EN                (0x1 << 16)     /* FLDTFIFODMA Request Enable */
 #define ECERB          (0x1 << 9)      /* ECC error */
 #define STERB          (0x1 << 8)      /* Status error */
 #define STERINTE       (0x1 << 4)      /* Status error enable */
@@ -138,6 +140,8 @@ enum flctl_ecc_res_t {
        FL_TIMEOUT
 };
 
+struct dma_chan;
+
 struct sh_flctl {
        struct mtd_info         mtd;
        struct nand_chip        chip;
@@ -147,7 +151,7 @@ struct sh_flctl {
 
        uint8_t done_buff[2048 + 64];   /* max size 2048 + 64 */
        int     read_bytes;
-       int     index;
+       unsigned int index;
        int     seqin_column;           /* column in SEQIN cmd */
        int     seqin_page_addr;        /* page_addr in SEQIN cmd */
        uint32_t seqin_read_cmd;                /* read cmd in SEQIN cmd */
@@ -161,6 +165,11 @@ struct sh_flctl {
        unsigned hwecc:1;       /* Hardware ECC (0 = disabled, 1 = enabled) */
        unsigned holden:1;      /* Hardware has FLHOLDCR and HOLDEN is set */
        unsigned qos_request:1; /* QoS request to prevent deep power shutdown */
+
+       /* DMA related objects */
+       struct dma_chan         *chan_fifo0_rx;
+       struct dma_chan         *chan_fifo0_tx;
+       struct completion       dma_complete;
 };
 
 struct sh_flctl_platform_data {
@@ -170,6 +179,9 @@ struct sh_flctl_platform_data {
 
        unsigned has_hwecc:1;
        unsigned use_holden:1;
+
+       unsigned int            slave_id_fifo0_tx;
+       unsigned int            slave_id_fifo0_rx;
 };
 
 static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
index b47d204..3863a4d 100644 (file)
@@ -100,6 +100,7 @@ extern int of_platform_populate(struct device_node *root,
 
 #if !defined(CONFIG_OF_ADDRESS)
 struct of_dev_auxdata;
+struct device;
 static inline int of_platform_populate(struct device_node *root,
                                        const struct of_device_id *matches,
                                        const struct of_dev_auxdata *lookup,
diff --git a/include/linux/platform_data/mtd-nomadik-nand.h b/include/linux/platform_data/mtd-nomadik-nand.h
deleted file mode 100644 (file)
index c3c8254..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_ARCH_NAND_H
-#define __ASM_ARCH_NAND_H
-
-struct nomadik_nand_platform_data {
-       struct mtd_partition *parts;
-       int nparts;
-       int options;
-       int (*init) (void);
-       int (*exit) (void);
-};
-
-#define NAND_IO_DATA   0x40000000
-#define NAND_IO_CMD    0x40800000
-#define NAND_IO_ADDR   0x41000000
-
-#endif                         /* __ASM_ARCH_NAND_H */
index 8570bcf..ef65b67 100644 (file)
@@ -59,6 +59,9 @@ struct usbhs_omap_platform_data {
 
        struct ehci_hcd_omap_platform_data      *ehci_data;
        struct ohci_hcd_omap_platform_data      *ohci_data;
+
+       /* OMAP3 <= ES2.1 have a single ulpi bypass control bit */
+       unsigned                                single_ulpi_bypass:1;
 };
 
 /*-------------------------------------------------------------------------*/
index 112b314..6d661f3 100644 (file)
@@ -171,6 +171,9 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
                                         unsigned int index,
                                         const char *label);
 
+struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
+               const struct of_phandle_args *args);
+
 struct pwm_device *pwm_get(struct device *dev, const char *consumer);
 void pwm_put(struct pwm_device *pwm);
 
index 05e88bd..0f6afc6 100644 (file)
@@ -694,6 +694,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     userspace to load a kernel module with the given name.
  *     @kmod_name name of the module requested by the kernel
  *     Return 0 if successful.
+ * @kernel_module_from_file:
+ *     Load a kernel module from userspace.
+ *     @file contains the file structure pointing to the file containing
+ *     the kernel module to load. If the module is being loaded from a blob,
+ *     this argument will be NULL.
+ *     Return 0 if permission is granted.
  * @task_fix_setuid:
  *     Update the module's state after setting one or more of the user
  *     identity attributes of the current process.  The @flags parameter
@@ -1508,6 +1514,7 @@ struct security_operations {
        int (*kernel_act_as)(struct cred *new, u32 secid);
        int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
        int (*kernel_module_request)(char *kmod_name);
+       int (*kernel_module_from_file)(struct file *file);
        int (*task_fix_setuid) (struct cred *new, const struct cred *old,
                                int flags);
        int (*task_setpgid) (struct task_struct *p, pid_t pgid);
@@ -1765,6 +1772,7 @@ void security_transfer_creds(struct cred *new, const struct cred *old);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_module_request(char *kmod_name);
+int security_kernel_module_from_file(struct file *file);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags);
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
@@ -2278,6 +2286,11 @@ static inline int security_kernel_module_request(char *kmod_name)
        return 0;
 }
 
+static inline int security_kernel_module_from_file(struct file *file)
+{
+       return 0;
+}
+
 static inline int security_task_fix_setuid(struct cred *new,
                                           const struct cred *old,
                                           int flags)
index 36c3b07..6caee34 100644 (file)
@@ -880,4 +880,5 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
 
 asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
                         unsigned long idx1, unsigned long idx2);
+asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
 #endif
index 9bbeabf..bd45eb7 100644 (file)
@@ -69,6 +69,7 @@ struct usbnet {
 #              define EVENT_DEV_ASLEEP 6
 #              define EVENT_DEV_OPEN   7
 #              define EVENT_DEVICE_REPORT_IDLE 8
+#              define EVENT_NO_RUNTIME_PM      9
 };
 
 static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -240,4 +241,6 @@ extern void usbnet_set_msglevel(struct net_device *, u32);
 extern void usbnet_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
 extern int usbnet_nway_reset(struct net_device *net);
 
+extern int usbnet_manage_power(struct usbnet *, int);
+
 #endif /* __LINUX_USB_USBNET_H */
index ba1d361..1832927 100644 (file)
@@ -318,6 +318,7 @@ extern void inet_csk_reqsk_queue_prune(struct sock *parent,
                                       const unsigned long max_rto);
 
 extern void inet_csk_destroy_sock(struct sock *sk);
+extern void inet_csk_prepare_forced_close(struct sock *sk);
 
 /*
  * LISTEN is a special case for poll..
index 7af1ea8..23b3a7c 100644 (file)
@@ -78,6 +78,13 @@ struct ra_msg {
        __be32                  retrans_timer;
 };
 
+struct rd_msg {
+       struct icmp6hdr icmph;
+       struct in6_addr target;
+       struct in6_addr dest;
+       __u8            opt[0];
+};
+
 struct nd_opt_hdr {
        __u8            nd_opt_type;
        __u8            nd_opt_len;
index 6e595ba..2c531f4 100644 (file)
@@ -690,9 +690,11 @@ __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
           compat_sys_process_vm_writev)
 #define __NR_kcmp 272
 __SYSCALL(__NR_kcmp, sys_kcmp)
+#define __NR_finit_module 273
+__SYSCALL(__NR_finit_module, sys_finit_module)
 
 #undef __NR_syscalls
-#define __NR_syscalls 273
+#define __NR_syscalls 274
 
 /*
  * All syscalls below here should go away really,
index afbb18a..5db2975 100644 (file)
@@ -163,6 +163,9 @@ struct br_port_msg {
 
 struct br_mdb_entry {
        __u32 ifindex;
+#define MDB_TEMPORARY 0
+#define MDB_PERMANENT 1
+       __u8 state;
        struct {
                union {
                        __be32  ip4;
diff --git a/include/uapi/linux/module.h b/include/uapi/linux/module.h
new file mode 100644 (file)
index 0000000..38da425
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _UAPI_LINUX_MODULE_H
+#define _UAPI_LINUX_MODULE_H
+
+/* Flags for sys_finit_module: */
+#define MODULE_INIT_IGNORE_MODVERSIONS 1
+#define MODULE_INIT_IGNORE_VERMAGIC    2
+
+#endif /* _UAPI_LINUX_MODULE_H */
index e811474..0e011eb 100644 (file)
@@ -45,7 +45,9 @@
 
 static inline __attribute_const__ __u16 __fswab16(__u16 val)
 {
-#ifdef __arch_swab16
+#ifdef __HAVE_BUILTIN_BSWAP16__
+       return __builtin_bswap16(val);
+#elif defined (__arch_swab16)
        return __arch_swab16(val);
 #else
        return ___constant_swab16(val);
@@ -54,7 +56,9 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val)
 
 static inline __attribute_const__ __u32 __fswab32(__u32 val)
 {
-#ifdef __arch_swab32
+#ifdef __HAVE_BUILTIN_BSWAP32__
+       return __builtin_bswap32(val);
+#elif defined(__arch_swab32)
        return __arch_swab32(val);
 #else
        return ___constant_swab32(val);
@@ -63,7 +67,9 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val)
 
 static inline __attribute_const__ __u64 __fswab64(__u64 val)
 {
-#ifdef __arch_swab64
+#ifdef __HAVE_BUILTIN_BSWAP64__
+       return __builtin_bswap64(val);
+#elif defined (__arch_swab64)
        return __arch_swab64(val);
 #elif defined(__SWAB_64_THRU_32__)
        __u32 h = val >> 32;
index 68c31d7..aef35e4 100644 (file)
@@ -28,7 +28,7 @@ struct omap_dss_device;
  * @power_down_gpio: gpio number for PD pin (or -1 if not available)
  */
 struct tfp410_platform_data {
-       u16 i2c_bus_num;
+       int i2c_bus_num;
        int power_down_gpio;
 };
 
index ac0d533..6c072b6 100644 (file)
@@ -54,7 +54,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
 obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o
+obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_KEXEC) += kexec.o
@@ -137,10 +137,14 @@ ifeq ($(CONFIG_MODULE_SIG),y)
 #
 # Pull the signing certificate and any extra certificates into the kernel
 #
+
+quiet_cmd_touch = TOUCH   $@
+      cmd_touch = touch   $@
+
 extra_certificates:
-       touch $@
+       $(call cmd,touch)
 
-kernel/modsign_pubkey.o: signing_key.x509 extra_certificates
+kernel/modsign_certificate.o: signing_key.x509 extra_certificates
 
 ###############################################################################
 #
diff --git a/kernel/modsign_certificate.S b/kernel/modsign_certificate.S
new file mode 100644 (file)
index 0000000..246b4c6
--- /dev/null
@@ -0,0 +1,19 @@
+/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */
+#ifndef SYMBOL_PREFIX
+#define ASM_SYMBOL(sym) sym
+#else
+#define PASTE2(x,y) x##y
+#define PASTE(x,y) PASTE2(x,y)
+#define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym)
+#endif
+
+#define GLOBAL(name)   \
+       .globl ASM_SYMBOL(name);        \
+       ASM_SYMBOL(name):
+
+       .section ".init.data","aw"
+
+GLOBAL(modsign_certificate_list)
+       .incbin "signing_key.x509"
+       .incbin "extra_certificates"
+GLOBAL(modsign_certificate_list_end)
index 767e559..045504f 100644 (file)
@@ -20,12 +20,6 @@ struct key *modsign_keyring;
 
 extern __initdata const u8 modsign_certificate_list[];
 extern __initdata const u8 modsign_certificate_list_end[];
-asm(".section .init.data,\"aw\"\n"
-    SYMBOL_PREFIX "modsign_certificate_list:\n"
-    ".incbin \"signing_key.x509\"\n"
-    ".incbin \"extra_certificates\"\n"
-    SYMBOL_PREFIX "modsign_certificate_list_end:"
-    );
 
 /*
  * We need to make sure ccache doesn't cache the .o file as it doesn't notice
index 808bd62..250092c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ftrace_event.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
+#include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 #include <linux/kernel.h>
@@ -28,6 +29,7 @@
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/proc_fs.h>
+#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
@@ -59,6 +61,7 @@
 #include <linux/pfn.h>
 #include <linux/bsearch.h>
 #include <linux/fips.h>
+#include <uapi/linux/module.h>
 #include "module-internal.h"
 
 #define CREATE_TRACE_POINTS
@@ -2279,7 +2282,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
        Elf_Shdr *symsect = info->sechdrs + info->index.sym;
        Elf_Shdr *strsect = info->sechdrs + info->index.str;
        const Elf_Sym *src;
-       unsigned int i, nsrc, ndst, strtab_size;
+       unsigned int i, nsrc, ndst, strtab_size = 0;
 
        /* Put symbol section at end of init part of module. */
        symsect->sh_flags |= SHF_ALLOC;
@@ -2290,9 +2293,6 @@ static void layout_symtab(struct module *mod, struct load_info *info)
        src = (void *)info->hdr + symsect->sh_offset;
        nsrc = symsect->sh_size / sizeof(*src);
 
-       /* strtab always starts with a nul, so offset 0 is the empty string. */
-       strtab_size = 1;
-
        /* Compute total space required for the core symbols' strtab. */
        for (ndst = i = 0; i < nsrc; i++) {
                if (i == 0 ||
@@ -2334,7 +2334,6 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
        mod->core_symtab = dst = mod->module_core + info->symoffs;
        mod->core_strtab = s = mod->module_core + info->stroffs;
        src = mod->symtab;
-       *s++ = 0;
        for (ndst = i = 0; i < mod->num_symtab; i++) {
                if (i == 0 ||
                    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
@@ -2375,7 +2374,7 @@ static void dynamic_debug_remove(struct _ddebug *debug)
 
 void * __weak module_alloc(unsigned long size)
 {
-       return size == 0 ? NULL : vmalloc_exec(size);
+       return vmalloc_exec(size);
 }
 
 static void *module_alloc_update_bounds(unsigned long size)
@@ -2422,18 +2421,17 @@ static inline void kmemleak_load_module(const struct module *mod,
 #endif
 
 #ifdef CONFIG_MODULE_SIG
-static int module_sig_check(struct load_info *info,
-                           const void *mod, unsigned long *_len)
+static int module_sig_check(struct load_info *info)
 {
        int err = -ENOKEY;
-       unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-       unsigned long len = *_len;
+       const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+       const void *mod = info->hdr;
 
-       if (len > markerlen &&
-           memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
+       if (info->len > markerlen &&
+           memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
                /* We truncate the module to discard the signature */
-               *_len -= markerlen;
-               err = mod_verify_sig(mod, _len);
+               info->len -= markerlen;
+               err = mod_verify_sig(mod, &info->len);
        }
 
        if (!err) {
@@ -2451,59 +2449,107 @@ static int module_sig_check(struct load_info *info,
        return err;
 }
 #else /* !CONFIG_MODULE_SIG */
-static int module_sig_check(struct load_info *info,
-                           void *mod, unsigned long *len)
+static int module_sig_check(struct load_info *info)
 {
        return 0;
 }
 #endif /* !CONFIG_MODULE_SIG */
 
-/* Sets info->hdr, info->len and info->sig_ok. */
-static int copy_and_check(struct load_info *info,
-                         const void __user *umod, unsigned long len,
-                         const char __user *uargs)
+/* Sanity checks against invalid binaries, wrong arch, weird elf version. */
+static int elf_header_check(struct load_info *info)
+{
+       if (info->len < sizeof(*(info->hdr)))
+               return -ENOEXEC;
+
+       if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
+           || info->hdr->e_type != ET_REL
+           || !elf_check_arch(info->hdr)
+           || info->hdr->e_shentsize != sizeof(Elf_Shdr))
+               return -ENOEXEC;
+
+       if (info->hdr->e_shoff >= info->len
+           || (info->hdr->e_shnum * sizeof(Elf_Shdr) >
+               info->len - info->hdr->e_shoff))
+               return -ENOEXEC;
+
+       return 0;
+}
+
+/* Sets info->hdr and info->len. */
+static int copy_module_from_user(const void __user *umod, unsigned long len,
+                                 struct load_info *info)
 {
        int err;
-       Elf_Ehdr *hdr;
 
-       if (len < sizeof(*hdr))
+       info->len = len;
+       if (info->len < sizeof(*(info->hdr)))
                return -ENOEXEC;
 
+       err = security_kernel_module_from_file(NULL);
+       if (err)
+               return err;
+
        /* Suck in entire file: we'll want most of it. */
-       if ((hdr = vmalloc(len)) == NULL)
+       info->hdr = vmalloc(info->len);
+       if (!info->hdr)
                return -ENOMEM;
 
-       if (copy_from_user(hdr, umod, len) != 0) {
-               err = -EFAULT;
-               goto free_hdr;
+       if (copy_from_user(info->hdr, umod, info->len) != 0) {
+               vfree(info->hdr);
+               return -EFAULT;
        }
 
-       err = module_sig_check(info, hdr, &len);
+       return 0;
+}
+
+/* Sets info->hdr and info->len. */
+static int copy_module_from_fd(int fd, struct load_info *info)
+{
+       struct file *file;
+       int err;
+       struct kstat stat;
+       loff_t pos;
+       ssize_t bytes = 0;
+
+       file = fget(fd);
+       if (!file)
+               return -ENOEXEC;
+
+       err = security_kernel_module_from_file(file);
        if (err)
-               goto free_hdr;
+               goto out;
 
-       /* Sanity checks against insmoding binaries or wrong arch,
-          weird elf version */
-       if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
-           || hdr->e_type != ET_REL
-           || !elf_check_arch(hdr)
-           || hdr->e_shentsize != sizeof(Elf_Shdr)) {
-               err = -ENOEXEC;
-               goto free_hdr;
-       }
+       err = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
+       if (err)
+               goto out;
 
-       if (hdr->e_shoff >= len ||
-           hdr->e_shnum * sizeof(Elf_Shdr) > len - hdr->e_shoff) {
-               err = -ENOEXEC;
-               goto free_hdr;
+       if (stat.size > INT_MAX) {
+               err = -EFBIG;
+               goto out;
+       }
+       info->hdr = vmalloc(stat.size);
+       if (!info->hdr) {
+               err = -ENOMEM;
+               goto out;
        }
 
-       info->hdr = hdr;
-       info->len = len;
-       return 0;
+       pos = 0;
+       while (pos < stat.size) {
+               bytes = kernel_read(file, pos, (char *)(info->hdr) + pos,
+                                   stat.size - pos);
+               if (bytes < 0) {
+                       vfree(info->hdr);
+                       err = bytes;
+                       goto out;
+               }
+               if (bytes == 0)
+                       break;
+               pos += bytes;
+       }
+       info->len = pos;
 
-free_hdr:
-       vfree(hdr);
+out:
+       fput(file);
        return err;
 }
 
@@ -2512,7 +2558,7 @@ static void free_copy(struct load_info *info)
        vfree(info->hdr);
 }
 
-static int rewrite_section_headers(struct load_info *info)
+static int rewrite_section_headers(struct load_info *info, int flags)
 {
        unsigned int i;
 
@@ -2540,7 +2586,10 @@ static int rewrite_section_headers(struct load_info *info)
        }
 
        /* Track but don't keep modinfo and version sections. */
-       info->index.vers = find_sec(info, "__versions");
+       if (flags & MODULE_INIT_IGNORE_MODVERSIONS)
+               info->index.vers = 0; /* Pretend no __versions section! */
+       else
+               info->index.vers = find_sec(info, "__versions");
        info->index.info = find_sec(info, ".modinfo");
        info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
        info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
@@ -2555,7 +2604,7 @@ static int rewrite_section_headers(struct load_info *info)
  * Return the temporary module pointer (we'll replace it with the final
  * one when we move the module sections around).
  */
-static struct module *setup_load_info(struct load_info *info)
+static struct module *setup_load_info(struct load_info *info, int flags)
 {
        unsigned int i;
        int err;
@@ -2566,7 +2615,7 @@ static struct module *setup_load_info(struct load_info *info)
        info->secstrings = (void *)info->hdr
                + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
 
-       err = rewrite_section_headers(info);
+       err = rewrite_section_headers(info, flags);
        if (err)
                return ERR_PTR(err);
 
@@ -2604,11 +2653,14 @@ static struct module *setup_load_info(struct load_info *info)
        return mod;
 }
 
-static int check_modinfo(struct module *mod, struct load_info *info)
+static int check_modinfo(struct module *mod, struct load_info *info, int flags)
 {
        const char *modmagic = get_modinfo(info, "vermagic");
        int err;
 
+       if (flags & MODULE_INIT_IGNORE_VERMAGIC)
+               modmagic = NULL;
+
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
                err = try_to_force_load(mod, "bad vermagic");
@@ -2738,20 +2790,23 @@ static int move_module(struct module *mod, struct load_info *info)
        memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
-       ptr = module_alloc_update_bounds(mod->init_size);
-       /*
-        * The pointer to this block is stored in the module structure
-        * which is inside the block. This block doesn't need to be
-        * scanned as it contains data and code that will be freed
-        * after the module is initialized.
-        */
-       kmemleak_ignore(ptr);
-       if (!ptr && mod->init_size) {
-               module_free(mod, mod->module_core);
-               return -ENOMEM;
-       }
-       memset(ptr, 0, mod->init_size);
-       mod->module_init = ptr;
+       if (mod->init_size) {
+               ptr = module_alloc_update_bounds(mod->init_size);
+               /*
+                * The pointer to this block is stored in the module structure
+                * which is inside the block. This block doesn't need to be
+                * scanned as it contains data and code that will be freed
+                * after the module is initialized.
+                */
+               kmemleak_ignore(ptr);
+               if (!ptr) {
+                       module_free(mod, mod->module_core);
+                       return -ENOMEM;
+               }
+               memset(ptr, 0, mod->init_size);
+               mod->module_init = ptr;
+       } else
+               mod->module_init = NULL;
 
        /* Transfer each section which specifies SHF_ALLOC */
        pr_debug("final section addresses:\n");
@@ -2844,18 +2899,18 @@ int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
        return 0;
 }
 
-static struct module *layout_and_allocate(struct load_info *info)
+static struct module *layout_and_allocate(struct load_info *info, int flags)
 {
        /* Module within temporary copy. */
        struct module *mod;
        Elf_Shdr *pcpusec;
        int err;
 
-       mod = setup_load_info(info);
+       mod = setup_load_info(info, flags);
        if (IS_ERR(mod))
                return mod;
 
-       err = check_modinfo(mod, info);
+       err = check_modinfo(mod, info, flags);
        if (err)
                return ERR_PTR(err);
 
@@ -2942,33 +2997,124 @@ static bool finished_loading(const char *name)
        return ret;
 }
 
+/* Call module constructors. */
+static void do_mod_ctors(struct module *mod)
+{
+#ifdef CONFIG_CONSTRUCTORS
+       unsigned long i;
+
+       for (i = 0; i < mod->num_ctors; i++)
+               mod->ctors[i]();
+#endif
+}
+
+/* This is where the real work happens */
+static int do_init_module(struct module *mod)
+{
+       int ret = 0;
+
+       blocking_notifier_call_chain(&module_notify_list,
+                       MODULE_STATE_COMING, mod);
+
+       /* Set RO and NX regions for core */
+       set_section_ro_nx(mod->module_core,
+                               mod->core_text_size,
+                               mod->core_ro_size,
+                               mod->core_size);
+
+       /* Set RO and NX regions for init */
+       set_section_ro_nx(mod->module_init,
+                               mod->init_text_size,
+                               mod->init_ro_size,
+                               mod->init_size);
+
+       do_mod_ctors(mod);
+       /* Start the module */
+       if (mod->init != NULL)
+               ret = do_one_initcall(mod->init);
+       if (ret < 0) {
+               /* Init routine failed: abort.  Try to protect us from
+                   buggy refcounters. */
+               mod->state = MODULE_STATE_GOING;
+               synchronize_sched();
+               module_put(mod);
+               blocking_notifier_call_chain(&module_notify_list,
+                                            MODULE_STATE_GOING, mod);
+               free_module(mod);
+               wake_up_all(&module_wq);
+               return ret;
+       }
+       if (ret > 0) {
+               printk(KERN_WARNING
+"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
+"%s: loading module anyway...\n",
+                      __func__, mod->name, ret,
+                      __func__);
+               dump_stack();
+       }
+
+       /* Now it's a first class citizen! */
+       mod->state = MODULE_STATE_LIVE;
+       blocking_notifier_call_chain(&module_notify_list,
+                                    MODULE_STATE_LIVE, mod);
+
+       /* We need to finish all async code before the module init sequence is done */
+       async_synchronize_full();
+
+       mutex_lock(&module_mutex);
+       /* Drop initial reference. */
+       module_put(mod);
+       trim_init_extable(mod);
+#ifdef CONFIG_KALLSYMS
+       mod->num_symtab = mod->core_num_syms;
+       mod->symtab = mod->core_symtab;
+       mod->strtab = mod->core_strtab;
+#endif
+       unset_module_init_ro_nx(mod);
+       module_free(mod, mod->module_init);
+       mod->module_init = NULL;
+       mod->init_size = 0;
+       mod->init_ro_size = 0;
+       mod->init_text_size = 0;
+       mutex_unlock(&module_mutex);
+       wake_up_all(&module_wq);
+
+       return 0;
+}
+
+static int may_init_module(void)
+{
+       if (!capable(CAP_SYS_MODULE) || modules_disabled)
+               return -EPERM;
+
+       return 0;
+}
+
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
-static struct module *load_module(void __user *umod,
-                                 unsigned long len,
-                                 const char __user *uargs)
+static int load_module(struct load_info *info, const char __user *uargs,
+                      int flags)
 {
-       struct load_info info = { NULL, };
        struct module *mod, *old;
        long err;
 
-       pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n",
-              umod, len, uargs);
+       err = module_sig_check(info);
+       if (err)
+               goto free_copy;
 
-       /* Copy in the blobs from userspace, check they are vaguely sane. */
-       err = copy_and_check(&info, umod, len, uargs);
+       err = elf_header_check(info);
        if (err)
-               return ERR_PTR(err);
+               goto free_copy;
 
        /* Figure out module layout, and allocate all the memory. */
-       mod = layout_and_allocate(&info);
+       mod = layout_and_allocate(info, flags);
        if (IS_ERR(mod)) {
                err = PTR_ERR(mod);
                goto free_copy;
        }
 
 #ifdef CONFIG_MODULE_SIG
-       mod->sig_ok = info.sig_ok;
+       mod->sig_ok = info->sig_ok;
        if (!mod->sig_ok)
                add_taint_module(mod, TAINT_FORCED_MODULE);
 #endif
@@ -2980,25 +3126,25 @@ static struct module *load_module(void __user *umod,
 
        /* Now we've got everything in the final locations, we can
         * find optional sections. */
-       find_module_sections(mod, &info);
+       find_module_sections(mod, info);
 
        err = check_module_license_and_versions(mod);
        if (err)
                goto free_unload;
 
        /* Set up MODINFO_ATTR fields */
-       setup_modinfo(mod, &info);
+       setup_modinfo(mod, info);
 
        /* Fix up syms, so that st_value is a pointer to location. */
-       err = simplify_symbols(mod, &info);
+       err = simplify_symbols(mod, info);
        if (err < 0)
                goto free_modinfo;
 
-       err = apply_relocations(mod, &info);
+       err = apply_relocations(mod, info);
        if (err < 0)
                goto free_modinfo;
 
-       err = post_relocation(mod, &info);
+       err = post_relocation(mod, info);
        if (err < 0)
                goto free_modinfo;
 
@@ -3038,14 +3184,14 @@ again:
        }
 
        /* This has to be done once we're sure module name is unique. */
-       dynamic_debug_setup(info.debug, info.num_debug);
+       dynamic_debug_setup(info->debug, info->num_debug);
 
        /* Find duplicate symbols */
        err = verify_export_symbols(mod);
        if (err < 0)
                goto ddebug;
 
-       module_bug_finalize(info.hdr, info.sechdrs, mod);
+       module_bug_finalize(info->hdr, info->sechdrs, mod);
        list_add_rcu(&mod->list, &modules);
        mutex_unlock(&module_mutex);
 
@@ -3056,16 +3202,17 @@ again:
                goto unlink;
 
        /* Link in to syfs. */
-       err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp);
+       err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
        if (err < 0)
                goto unlink;
 
        /* Get rid of temporary copy. */
-       free_copy(&info);
+       free_copy(info);
 
        /* Done! */
        trace_module_load(mod);
-       return mod;
+
+       return do_init_module(mod);
 
  unlink:
        mutex_lock(&module_mutex);
@@ -3074,7 +3221,7 @@ again:
        module_bug_cleanup(mod);
        wake_up_all(&module_wq);
  ddebug:
-       dynamic_debug_remove(info.debug);
+       dynamic_debug_remove(info->debug);
  unlock:
        mutex_unlock(&module_mutex);
        synchronize_sched();
@@ -3086,106 +3233,52 @@ again:
  free_unload:
        module_unload_free(mod);
  free_module:
-       module_deallocate(mod, &info);
+       module_deallocate(mod, info);
  free_copy:
-       free_copy(&info);
-       return ERR_PTR(err);
-}
-
-/* Call module constructors. */
-static void do_mod_ctors(struct module *mod)
-{
-#ifdef CONFIG_CONSTRUCTORS
-       unsigned long i;
-
-       for (i = 0; i < mod->num_ctors; i++)
-               mod->ctors[i]();
-#endif
+       free_copy(info);
+       return err;
 }
 
-/* This is where the real work happens */
 SYSCALL_DEFINE3(init_module, void __user *, umod,
                unsigned long, len, const char __user *, uargs)
 {
-       struct module *mod;
-       int ret = 0;
+       int err;
+       struct load_info info = { };
 
-       /* Must have permission */
-       if (!capable(CAP_SYS_MODULE) || modules_disabled)
-               return -EPERM;
+       err = may_init_module();
+       if (err)
+               return err;
 
-       /* Do all the hard work */
-       mod = load_module(umod, len, uargs);
-       if (IS_ERR(mod))
-               return PTR_ERR(mod);
+       pr_debug("init_module: umod=%p, len=%lu, uargs=%p\n",
+              umod, len, uargs);
 
-       blocking_notifier_call_chain(&module_notify_list,
-                       MODULE_STATE_COMING, mod);
+       err = copy_module_from_user(umod, len, &info);
+       if (err)
+               return err;
 
-       /* Set RO and NX regions for core */
-       set_section_ro_nx(mod->module_core,
-                               mod->core_text_size,
-                               mod->core_ro_size,
-                               mod->core_size);
+       return load_module(&info, uargs, 0);
+}
 
-       /* Set RO and NX regions for init */
-       set_section_ro_nx(mod->module_init,
-                               mod->init_text_size,
-                               mod->init_ro_size,
-                               mod->init_size);
+SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+{
+       int err;
+       struct load_info info = { };
 
-       do_mod_ctors(mod);
-       /* Start the module */
-       if (mod->init != NULL)
-               ret = do_one_initcall(mod->init);
-       if (ret < 0) {
-               /* Init routine failed: abort.  Try to protect us from
-                   buggy refcounters. */
-               mod->state = MODULE_STATE_GOING;
-               synchronize_sched();
-               module_put(mod);
-               blocking_notifier_call_chain(&module_notify_list,
-                                            MODULE_STATE_GOING, mod);
-               free_module(mod);
-               wake_up_all(&module_wq);
-               return ret;
-       }
-       if (ret > 0) {
-               printk(KERN_WARNING
-"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
-"%s: loading module anyway...\n",
-                      __func__, mod->name, ret,
-                      __func__);
-               dump_stack();
-       }
+       err = may_init_module();
+       if (err)
+               return err;
 
-       /* Now it's a first class citizen! */
-       mod->state = MODULE_STATE_LIVE;
-       blocking_notifier_call_chain(&module_notify_list,
-                                    MODULE_STATE_LIVE, mod);
+       pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
 
-       /* We need to finish all async code before the module init sequence is done */
-       async_synchronize_full();
+       if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
+                     |MODULE_INIT_IGNORE_VERMAGIC))
+               return -EINVAL;
 
-       mutex_lock(&module_mutex);
-       /* Drop initial reference. */
-       module_put(mod);
-       trim_init_extable(mod);
-#ifdef CONFIG_KALLSYMS
-       mod->num_symtab = mod->core_num_syms;
-       mod->symtab = mod->core_symtab;
-       mod->strtab = mod->core_strtab;
-#endif
-       unset_module_init_ro_nx(mod);
-       module_free(mod, mod->module_init);
-       mod->module_init = NULL;
-       mod->init_size = 0;
-       mod->init_ro_size = 0;
-       mod->init_text_size = 0;
-       mutex_unlock(&module_mutex);
-       wake_up_all(&module_wq);
+       err = copy_module_from_fd(fd, &info);
+       if (err)
+               return err;
 
-       return 0;
+       return load_module(&info, uargs, flags);
 }
 
 static inline int within(unsigned long addr, void *start, unsigned long size)
index d738402..a278cad 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/uaccess.h>
 #include <linux/kernel_stat.h>
 #include <trace/events/timer.h>
+#include <linux/random.h>
 
 /*
  * Called after updating RLIMIT_CPU to run cpu timer and update
@@ -470,6 +471,8 @@ static void cleanup_timers(struct list_head *head,
  */
 void posix_cpu_timers_exit(struct task_struct *tsk)
 {
+       add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
+                                               sizeof(unsigned long long));
        cleanup_timers(tsk->cpu_timers,
                       tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
 
index 4603d6c..5eea870 100644 (file)
@@ -793,8 +793,11 @@ unsigned int sysctl_numa_balancing_scan_delay = 1000;
 
 static void task_numa_placement(struct task_struct *p)
 {
-       int seq = ACCESS_ONCE(p->mm->numa_scan_seq);
+       int seq;
 
+       if (!p->mm)     /* for example, ksmd faulting in a user's mm */
+               return;
+       seq = ACCESS_ONCE(p->mm->numa_scan_seq);
        if (p->numa_scan_seq == seq)
                return;
        p->numa_scan_seq = seq;
index dbff751..395084d 100644 (file)
@@ -25,6 +25,7 @@ cond_syscall(sys_swapoff);
 cond_syscall(sys_kexec_load);
 cond_syscall(compat_sys_kexec_load);
 cond_syscall(sys_init_module);
+cond_syscall(sys_finit_module);
 cond_syscall(sys_delete_module);
 cond_syscall(sys_socketpair);
 cond_syscall(sys_bind);
index 997c6a1..75a2ab3 100644 (file)
@@ -344,6 +344,10 @@ static void watchdog_enable(unsigned int cpu)
 {
        struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
 
+       /* kick off the timer for the hardlockup detector */
+       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer->function = watchdog_timer_fn;
+
        if (!watchdog_enabled) {
                kthread_park(current);
                return;
@@ -352,10 +356,6 @@ static void watchdog_enable(unsigned int cpu)
        /* Enable the perf event */
        watchdog_nmi_enable(cpu);
 
-       /* kick off the timer for the hardlockup detector */
-       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       hrtimer->function = watchdog_timer_fn;
-
        /* done here because hrtimer_start can only pin to smp_processor_id() */
        hrtimer_start(hrtimer, ns_to_ktime(sample_period),
                      HRTIMER_MODE_REL_PINNED);
@@ -369,9 +369,6 @@ static void watchdog_disable(unsigned int cpu)
 {
        struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
 
-       if (!watchdog_enabled)
-               return;
-
        watchdog_set_prio(SCHED_NORMAL, 0);
        hrtimer_cancel(hrtimer);
        /* disable the perf event */
index 5293d24..11b9b01 100644 (file)
@@ -81,7 +81,7 @@ next_tag:
                goto next_tag;
        }
 
-       if (unlikely((tag & 0x1f) == 0x1f)) {
+       if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) {
                do {
                        if (unlikely(datalen - dp < 2))
                                goto data_overrun_error;
@@ -96,7 +96,7 @@ next_tag:
                goto next_tag;
        }
 
-       if (unlikely(len == 0x80)) {
+       if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
                /* Indefinite length */
                if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5))
                        goto indefinite_len_primitive;
@@ -222,7 +222,7 @@ next_op:
                if (unlikely(dp >= datalen - 1))
                        goto data_overrun_error;
                tag = data[dp++];
-               if (unlikely((tag & 0x1f) == 0x1f))
+               if (unlikely((tag & 0x1f) == ASN1_LONG_TAG))
                        goto long_tag_not_supported;
 
                if (op & ASN1_OP_MATCH__ANY) {
@@ -254,7 +254,7 @@ next_op:
 
                len = data[dp++];
                if (len > 0x7f) {
-                       if (unlikely(len == 0x80)) {
+                       if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
                                /* Indefinite length */
                                if (unlikely(!(tag & ASN1_CONS_BIT)))
                                        goto indefinite_len_primitive;
index 82dfb4b..5157385 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1624,7 +1624,7 @@ again:
                struct anon_vma_chain *vmac;
                struct vm_area_struct *vma;
 
-               anon_vma_lock_write(anon_vma);
+               anon_vma_lock_read(anon_vma);
                anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
                                               0, ULONG_MAX) {
                        vma = vmac->vma;
@@ -1648,7 +1648,7 @@ again:
                        if (!search_new_forks || !mapcount)
                                break;
                }
-               anon_vma_unlock(anon_vma);
+               anon_vma_unlock_read(anon_vma);
                if (!mapcount)
                        goto out;
        }
@@ -1678,7 +1678,7 @@ again:
                struct anon_vma_chain *vmac;
                struct vm_area_struct *vma;
 
-               anon_vma_lock_write(anon_vma);
+               anon_vma_lock_read(anon_vma);
                anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
                                               0, ULONG_MAX) {
                        vma = vmac->vma;
@@ -1697,11 +1697,11 @@ again:
                        ret = try_to_unmap_one(page, vma,
                                        rmap_item->address, flags);
                        if (ret != SWAP_AGAIN || !page_mapped(page)) {
-                               anon_vma_unlock(anon_vma);
+                               anon_vma_unlock_read(anon_vma);
                                goto out;
                        }
                }
-               anon_vma_unlock(anon_vma);
+               anon_vma_unlock_read(anon_vma);
        }
        if (!search_new_forks++)
                goto again;
@@ -1731,7 +1731,7 @@ again:
                struct anon_vma_chain *vmac;
                struct vm_area_struct *vma;
 
-               anon_vma_lock_write(anon_vma);
+               anon_vma_lock_read(anon_vma);
                anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
                                               0, ULONG_MAX) {
                        vma = vmac->vma;
@@ -1749,11 +1749,11 @@ again:
 
                        ret = rmap_one(page, vma, rmap_item->address, arg);
                        if (ret != SWAP_AGAIN) {
-                               anon_vma_unlock(anon_vma);
+                               anon_vma_unlock_read(anon_vma);
                                goto out;
                        }
                }
-               anon_vma_unlock(anon_vma);
+               anon_vma_unlock_read(anon_vma);
        }
        if (!search_new_forks++)
                goto again;
index 828530e..adc7e90 100644 (file)
@@ -2570,7 +2570,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
 static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
                                                        int *classzone_idx)
 {
-       int all_zones_ok;
+       struct zone *unbalanced_zone;
        unsigned long balanced;
        int i;
        int end_zone = 0;       /* Inclusive.  0 = ZONE_DMA */
@@ -2604,7 +2604,7 @@ loop_again:
                unsigned long lru_pages = 0;
                int has_under_min_watermark_zone = 0;
 
-               all_zones_ok = 1;
+               unbalanced_zone = NULL;
                balanced = 0;
 
                /*
@@ -2743,7 +2743,7 @@ loop_again:
                        }
 
                        if (!zone_balanced(zone, testorder, 0, end_zone)) {
-                               all_zones_ok = 0;
+                               unbalanced_zone = zone;
                                /*
                                 * We are still under min water mark.  This
                                 * means that we have a GFP_ATOMIC allocation
@@ -2776,7 +2776,7 @@ loop_again:
                                pfmemalloc_watermark_ok(pgdat))
                        wake_up(&pgdat->pfmemalloc_wait);
 
-               if (all_zones_ok || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))
+               if (!unbalanced_zone || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))
                        break;          /* kswapd: all done */
                /*
                 * OK, kswapd is getting into trouble.  Take a nap, then take
@@ -2786,7 +2786,7 @@ loop_again:
                        if (has_under_min_watermark_zone)
                                count_vm_event(KSWAPD_SKIP_CONGESTION_WAIT);
                        else
-                               congestion_wait(BLK_RW_ASYNC, HZ/10);
+                               wait_iff_congested(unbalanced_zone, BLK_RW_ASYNC, HZ/10);
                }
 
                /*
@@ -2805,7 +2805,7 @@ out:
         * high-order: Balanced zones must make up at least 25% of the node
         *             for the node to be balanced
         */
-       if (!(all_zones_ok || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))) {
+       if (unbalanced_zone && (!order || !pgdat_balanced(pgdat, balanced, *classzone_idx))) {
                cond_resched();
 
                try_to_freeze();
index f49da58..350bf62 100644 (file)
@@ -14,49 +14,45 @@ static ssize_t show_type(struct device *cdev,
                         struct device_attribute *attr, char *buf)
 {
        struct atm_dev *adev = to_atm_dev(cdev);
-       return sprintf(buf, "%s\n", adev->type);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", adev->type);
 }
 
 static ssize_t show_address(struct device *cdev,
                            struct device_attribute *attr, char *buf)
 {
-       char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
-       int i;
-
-       for (i = 0; i < (ESI_LEN - 1); i++)
-               pos += sprintf(pos, "%02x:", adev->esi[i]);
-       pos += sprintf(pos, "%02x\n", adev->esi[i]);
 
-       return pos - buf;
+       return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
 }
 
 static ssize_t show_atmaddress(struct device *cdev,
                               struct device_attribute *attr, char *buf)
 {
        unsigned long flags;
-       char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
        struct atm_dev_addr *aaddr;
        int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
-       int i, j;
+       int i, j, count = 0;
 
        spin_lock_irqsave(&adev->lock, flags);
        list_for_each_entry(aaddr, &adev->local, entry) {
                for (i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
                        if (j == *fmt) {
-                               pos += sprintf(pos, ".");
+                               count += scnprintf(buf + count,
+                                                  PAGE_SIZE - count, ".");
                                ++fmt;
                                j = 0;
                        }
-                       pos += sprintf(pos, "%02x",
-                                      aaddr->addr.sas_addr.prv[i]);
+                       count += scnprintf(buf + count,
+                                          PAGE_SIZE - count, "%02x",
+                                          aaddr->addr.sas_addr.prv[i]);
                }
-               pos += sprintf(pos, "\n");
+               count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
        }
        spin_unlock_irqrestore(&adev->lock, flags);
 
-       return pos - buf;
+       return count;
 }
 
 static ssize_t show_atmindex(struct device *cdev,
@@ -64,25 +60,21 @@ static ssize_t show_atmindex(struct device *cdev,
 {
        struct atm_dev *adev = to_atm_dev(cdev);
 
-       return sprintf(buf, "%d\n", adev->number);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number);
 }
 
 static ssize_t show_carrier(struct device *cdev,
                            struct device_attribute *attr, char *buf)
 {
-       char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
 
-       pos += sprintf(pos, "%d\n",
-                      adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
-
-       return pos - buf;
+       return scnprintf(buf, PAGE_SIZE, "%d\n",
+                        adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
 }
 
 static ssize_t show_link_rate(struct device *cdev,
                              struct device_attribute *attr, char *buf)
 {
-       char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
        int link_rate;
 
@@ -100,9 +92,7 @@ static ssize_t show_link_rate(struct device *cdev,
        default:
                link_rate = adev->link_rate * 8 * 53;
        }
-       pos += sprintf(pos, "%d\n", link_rate);
-
-       return pos - buf;
+       return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate);
 }
 
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
index 6f0a2ee..acc9f4c 100644 (file)
@@ -83,9 +83,12 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
                                if (port) {
                                        struct br_mdb_entry e;
                                        e.ifindex = port->dev->ifindex;
-                                       e.addr.u.ip4 = p->addr.u.ip4;
+                                       e.state = p->state;
+                                       if (p->addr.proto == htons(ETH_P_IP))
+                                               e.addr.u.ip4 = p->addr.u.ip4;
 #if IS_ENABLED(CONFIG_IPV6)
-                                       e.addr.u.ip6 = p->addr.u.ip6;
+                                       if (p->addr.proto == htons(ETH_P_IPV6))
+                                               e.addr.u.ip6 = p->addr.u.ip6;
 #endif
                                        e.addr.proto = p->addr.proto;
                                        if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) {
@@ -253,6 +256,8 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
 #endif
        } else
                return false;
+       if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY)
+               return false;
 
        return true;
 }
@@ -310,7 +315,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
 }
 
 static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
-                           struct br_ip *group)
+                           struct br_ip *group, unsigned char state)
 {
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
@@ -336,7 +341,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
                        break;
        }
 
-       p = br_multicast_new_port_group(port, group, *pp);
+       p = br_multicast_new_port_group(port, group, *pp, state);
        if (unlikely(!p))
                return -ENOMEM;
        rcu_assign_pointer(*pp, p);
@@ -373,7 +378,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
 #endif
 
        spin_lock_bh(&br->multicast_lock);
-       ret = br_mdb_add_group(br, p, &ip);
+       ret = br_mdb_add_group(br, p, &ip, entry->state);
        spin_unlock_bh(&br->multicast_lock);
        return ret;
 }
@@ -479,3 +484,10 @@ void br_mdb_init(void)
        rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL);
        rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL);
 }
+
+void br_mdb_uninit(void)
+{
+       rtnl_unregister(PF_BRIDGE, RTM_GETMDB);
+       rtnl_unregister(PF_BRIDGE, RTM_NEWMDB);
+       rtnl_unregister(PF_BRIDGE, RTM_DELMDB);
+}
index 1093c89..5391ca4 100644 (file)
@@ -279,7 +279,7 @@ static void br_multicast_port_group_expired(unsigned long data)
 
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
-           hlist_unhashed(&pg->mglist))
+           hlist_unhashed(&pg->mglist) || pg->state & MDB_PERMANENT)
                goto out;
 
        br_multicast_del_pg(br, pg);
@@ -622,7 +622,8 @@ out:
 struct net_bridge_port_group *br_multicast_new_port_group(
                        struct net_bridge_port *port,
                        struct br_ip *group,
-                       struct net_bridge_port_group __rcu *next)
+                       struct net_bridge_port_group __rcu *next,
+                       unsigned char state)
 {
        struct net_bridge_port_group *p;
 
@@ -632,6 +633,7 @@ struct net_bridge_port_group *br_multicast_new_port_group(
 
        p->addr = *group;
        p->port = port;
+       p->state = state;
        rcu_assign_pointer(p->next, next);
        hlist_add_head(&p->mglist, &port->mglist);
        setup_timer(&p->timer, br_multicast_port_group_expired,
@@ -674,7 +676,7 @@ static int br_multicast_add_group(struct net_bridge *br,
                        break;
        }
 
-       p = br_multicast_new_port_group(port, group, *pp);
+       p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY);
        if (unlikely(!p))
                goto err;
        rcu_assign_pointer(*pp, p);
@@ -1165,7 +1167,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                if (max_delay)
                        group = &mld->mld_mca;
        } else if (skb->len >= sizeof(*mld2q)) {
-               u16 mrc;
                if (!pskb_may_pull(skb, sizeof(*mld2q))) {
                        err = -EINVAL;
                        goto out;
@@ -1173,8 +1174,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                mld2q = (struct mld2_query *)icmp6_hdr(skb);
                if (!mld2q->mld2q_nsrcs)
                        group = &mld2q->mld2q_mca;
-               mrc = ntohs(mld2q->mld2q_mrc);
-               max_delay = mrc ? MLDV2_MRC(mrc) : 1;
+               max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1;
        }
 
        if (!group)
@@ -1633,6 +1633,7 @@ void br_multicast_stop(struct net_bridge *br)
        del_timer_sync(&br->multicast_querier_timer);
        del_timer_sync(&br->multicast_query_timer);
 
+       br_mdb_uninit();
        spin_lock_bh(&br->multicast_lock);
        mdb = mlock_dereference(br->mdb, br);
        if (!mdb)
index dead9df..97ba018 100644 (file)
@@ -305,5 +305,4 @@ int __init br_netlink_init(void)
 void __exit br_netlink_fini(void)
 {
        rtnl_link_unregister(&br_link_ops);
-       rtnl_unregister_all(PF_BRIDGE);
 }
index f21a739..8d83be5 100644 (file)
@@ -83,6 +83,7 @@ struct net_bridge_port_group {
        struct rcu_head                 rcu;
        struct timer_list               timer;
        struct br_ip                    addr;
+       unsigned char                   state;
 };
 
 struct net_bridge_mdb_entry
@@ -443,8 +444,10 @@ extern void br_multicast_free_pg(struct rcu_head *head);
 extern struct net_bridge_port_group *br_multicast_new_port_group(
                                struct net_bridge_port *port,
                                struct br_ip *group,
-                               struct net_bridge_port_group *next);
+                               struct net_bridge_port_group *next,
+                               unsigned char state);
 extern void br_mdb_init(void);
+extern void br_mdb_uninit(void);
 extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
                          struct br_ip *group, int type);
 
index 176ecdb..4f9f5eb 100644 (file)
@@ -439,8 +439,8 @@ exit:
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return NULL;
 put_and_exit:
-       bh_unlock_sock(newsk);
-       sock_put(newsk);
+       inet_csk_prepare_forced_close(newsk);
+       dccp_done(newsk);
        goto exit;
 }
 
index 56840b2..6e05981 100644 (file)
@@ -585,7 +585,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
        newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
        if (__inet_inherit_port(sk, newsk) < 0) {
-               sock_put(newsk);
+               inet_csk_prepare_forced_close(newsk);
+               dccp_done(newsk);
                goto out;
        }
        __inet6_hash(newsk, NULL);
index 2026542..d0670f0 100644 (file)
@@ -710,6 +710,22 @@ void inet_csk_destroy_sock(struct sock *sk)
 }
 EXPORT_SYMBOL(inet_csk_destroy_sock);
 
+/* This function allows to force a closure of a socket after the call to
+ * tcp/dccp_create_openreq_child().
+ */
+void inet_csk_prepare_forced_close(struct sock *sk)
+{
+       /* sk_clone_lock locked the socket and set refcnt to 2 */
+       bh_unlock_sock(sk);
+       sock_put(sk);
+
+       /* The below has to be done to allow calling inet_csk_destroy_sock */
+       sock_set_flag(sk, SOCK_DEAD);
+       percpu_counter_inc(sk->sk_prot->orphan_count);
+       inet_sk(sk)->inet_num = 0;
+}
+EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+
 int inet_csk_listen_start(struct sock *sk, const int nr_table_entries)
 {
        struct inet_sock *inet = inet_sk(sk);
index 1ed2307..54139fa 100644 (file)
@@ -1767,10 +1767,8 @@ exit:
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return NULL;
 put_and_exit:
-       tcp_clear_xmit_timers(newsk);
-       tcp_cleanup_congestion_control(newsk);
-       bh_unlock_sock(newsk);
-       sock_put(newsk);
+       inet_csk_prepare_forced_close(newsk);
+       tcp_done(newsk);
        goto exit;
 }
 EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
index 2068ac4..4ea2448 100644 (file)
@@ -41,6 +41,6 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
 obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
 
 obj-y += addrconf_core.o exthdrs_core.o
-obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6_offload)
+obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
 
 obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
index 6fca01f..408cac4 100644 (file)
@@ -534,8 +534,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
        rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC);
        return;
 errout:
-       if (err < 0)
-               rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
+       rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
 }
 
 static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
index f2a007b..6574175 100644 (file)
@@ -1314,6 +1314,12 @@ out:
 
 static void ndisc_redirect_rcv(struct sk_buff *skb)
 {
+       u8 *hdr;
+       struct ndisc_options ndopts;
+       struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb);
+       u32 ndoptlen = skb->tail - (skb->transport_header +
+                                   offsetof(struct rd_msg, opt));
+
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
        switch (skb->ndisc_nodetype) {
        case NDISC_NODETYPE_HOST:
@@ -1330,6 +1336,17 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
                return;
        }
 
+       if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts))
+               return;
+
+       if (!ndopts.nd_opts_rh)
+               return;
+
+       hdr = (u8 *)ndopts.nd_opts_rh;
+       hdr += 8;
+       if (!pskb_pull(skb, hdr - skb_transport_header(skb)))
+               return;
+
        icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
 }
 
index 6565cf5..93825dd 100644 (file)
@@ -1288,7 +1288,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 #endif
 
        if (__inet_inherit_port(sk, newsk) < 0) {
-               sock_put(newsk);
+               inet_csk_prepare_forced_close(newsk);
+               tcp_done(newsk);
                goto out;
        }
        __inet6_hash(newsk, NULL);
index e748aed..b7c7f81 100644 (file)
@@ -224,9 +224,9 @@ void ieee802154_free_device(struct ieee802154_dev *hw)
 
        BUG_ON(!list_empty(&priv->slaves));
 
-       wpan_phy_free(priv->phy);
-
        mutex_destroy(&priv->slaves_mtx);
+
+       wpan_phy_free(priv->phy);
 }
 EXPORT_SYMBOL(ieee802154_free_device);
 
index c8a1eb6..c0353d5 100644 (file)
@@ -669,6 +669,9 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
        struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
        int err;
 
+       if (addr_len < sizeof(struct sockaddr_nl))
+               return -EINVAL;
+
        if (nladdr->nl_family != AF_NETLINK)
                return -EINVAL;
 
@@ -2059,7 +2062,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
                struct sock *s = v;
                struct netlink_sock *nlk = nlk_sk(s);
 
-               seq_printf(seq, "%pK %-3d %-6d %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
+               seq_printf(seq, "%pK %-3d %-6u %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
                           s,
                           s->sk_protocol,
                           nlk->portid,
index a9edd2e..c262106 100644 (file)
@@ -66,12 +66,36 @@ config SCTP_DBG_OBJCNT
          'cat /proc/net/sctp/sctp_dbg_objcnt'
 
          If unsure, say N
+choice
+       prompt "Default SCTP cookie HMAC encoding"
+       default SCTP_COOKIE_HMAC_MD5
+       help
+         This option sets the default sctp cookie hmac algorithm
+         when in doubt select 'md5'
+
+config SCTP_DEFAULT_COOKIE_HMAC_MD5
+       bool "Enable optional MD5 hmac cookie generation"
+       help
+         Enable optional MD5 hmac based SCTP cookie generation
+       select SCTP_COOKIE_HMAC_MD5
+
+config SCTP_DEFAULT_COOKIE_HMAC_SHA1
+       bool "Enable optional SHA1 hmac cookie generation"
+       help
+         Enable optional SHA1 hmac based SCTP cookie generation
+       select SCTP_COOKIE_HMAC_SHA1
+
+config SCTP_DEFAULT_COOKIE_HMAC_NONE
+       bool "Use no hmac alg in SCTP cookie generation"
+       help
+         Use no hmac algorithm in SCTP cookie generation
+
+endchoice
 
 config SCTP_COOKIE_HMAC_MD5
        bool "Enable optional MD5 hmac cookie generation"
        help
          Enable optional MD5 hmac based SCTP cookie generation
-       default y
        select CRYPTO_HMAC if SCTP_COOKIE_HMAC_MD5
        select CRYPTO_MD5 if SCTP_COOKIE_HMAC_MD5
 
@@ -79,7 +103,6 @@ config SCTP_COOKIE_HMAC_SHA1
        bool "Enable optional SHA1 hmac cookie generation"
        help
          Enable optional SHA1 hmac based SCTP cookie generation
-       default y
        select CRYPTO_HMAC if SCTP_COOKIE_HMAC_SHA1
        select CRYPTO_SHA1 if SCTP_COOKIE_HMAC_SHA1
 
index bc6cd75..5f7518d 100644 (file)
@@ -122,7 +122,8 @@ static const struct file_operations sctpprobe_fops = {
        .llseek = noop_llseek,
 };
 
-sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep,
+sctp_disposition_t jsctp_sf_eat_sack(struct net *net,
+                                    const struct sctp_endpoint *ep,
                                     const struct sctp_association *asoc,
                                     const sctp_subtype_t type,
                                     void *arg,
index 2c7785b..f898b1c 100644 (file)
@@ -1191,9 +1191,9 @@ static int __net_init sctp_net_init(struct net *net)
        net->sctp.cookie_preserve_enable        = 1;
 
        /* Default sctp sockets to use md5 as their hmac alg */
-#if defined (CONFIG_CRYPTO_MD5)
+#if defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5)
        net->sctp.sctp_hmac_alg                 = "md5";
-#elif defined (CONFIG_CRYPTO_SHA1)
+#elif defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1)
        net->sctp.sctp_hmac_alg                 = "sha1";
 #else
        net->sctp.sctp_hmac_alg                 = NULL;
diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign
new file mode 100644 (file)
index 0000000..abfda62
--- /dev/null
@@ -0,0 +1,32 @@
+# ==========================================================================
+# Signing modules
+# ==========================================================================
+
+PHONY := __modsign
+__modsign:
+
+include scripts/Kbuild.include
+
+__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
+
+PHONY += $(modules)
+__modsign: $(modules)
+       @:
+
+quiet_cmd_sign_ko = SIGN [M] $(2)/$(notdir $@)
+        cmd_sign_ko = $(mod_sign_cmd) $(2)/$(notdir $@)
+
+# Modules built outside the kernel source tree go into extra by default
+INSTALL_MOD_DIR ?= extra
+ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D))
+
+modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
+
+$(modules):
+       $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir))
+
+# Declare the contents of the .PHONY variable as phony.  We keep that
+# information in a variable se we can use it in if_changed and friends.
+
+.PHONY: $(PHONY)
index b14a30c..0fe5a02 100644 (file)
@@ -395,6 +395,11 @@ static int cap_kernel_module_request(char *kmod_name)
        return 0;
 }
 
+static int cap_kernel_module_from_file(struct file *file)
+{
+       return 0;
+}
+
 static int cap_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return 0;
@@ -967,6 +972,7 @@ void __init security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, kernel_act_as);
        set_to_cap_if_null(ops, kernel_create_files_as);
        set_to_cap_if_null(ops, kernel_module_request);
+       set_to_cap_if_null(ops, kernel_module_from_file);
        set_to_cap_if_null(ops, task_fix_setuid);
        set_to_cap_if_null(ops, task_setpgid);
        set_to_cap_if_null(ops, task_getpgid);
index 6ee8826..3b2adb7 100644 (file)
@@ -127,7 +127,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 
 /* IMA policy related functions */
-enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
+enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
 
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
                     int flags);
index b356884..0cea3db 100644 (file)
@@ -100,12 +100,12 @@ err_out:
  * ima_get_action - appraise & measure decision based on policy.
  * @inode: pointer to inode to measure
  * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
- * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
+ * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK)
  *
  * The policy is defined in terms of keypairs:
  *             subj=, obj=, type=, func=, mask=, fsmagic=
  *     subj,obj, and type: are LSM specific.
- *     func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
+ *     func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK
  *     mask: contains the permission mask
  *     fsmagic: hex value
  *
index 73c9a26..45de18e 100644 (file)
@@ -280,6 +280,27 @@ int ima_file_check(struct file *file, int mask)
 }
 EXPORT_SYMBOL_GPL(ima_file_check);
 
+/**
+ * ima_module_check - based on policy, collect/store/appraise measurement.
+ * @file: pointer to the file to be measured/appraised
+ *
+ * Measure/appraise kernel modules based on policy.
+ *
+ * Always return 0 and audit dentry_open failures.
+ * Return code is based upon measurement appraisal.
+ */
+int ima_module_check(struct file *file)
+{
+       int rc;
+
+       if (!file)
+               rc = INTEGRITY_UNKNOWN;
+       else
+               rc = process_measurement(file, file->f_dentry->d_name.name,
+                                        MAY_EXEC, MODULE_CHECK);
+       return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
+}
+
 static int __init init_ima(void)
 {
        int error;
index c7dacd2..af7d182 100644 (file)
@@ -80,6 +80,7 @@ static struct ima_rule_entry default_rules[] = {
         .flags = IMA_FUNC | IMA_MASK},
        {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID,
         .flags = IMA_FUNC | IMA_MASK | IMA_UID},
+       {.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry default_appraise_rules[] = {
@@ -401,6 +402,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
                        /* PATH_CHECK is for backwards compat */
                        else if (strcmp(args[0].from, "PATH_CHECK") == 0)
                                entry->func = FILE_CHECK;
+                       else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
+                               entry->func = MODULE_CHECK;
                        else if (strcmp(args[0].from, "FILE_MMAP") == 0)
                                entry->func = FILE_MMAP;
                        else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
index 8dcd4ae..daa97f4 100644 (file)
@@ -820,6 +820,16 @@ int security_kernel_module_request(char *kmod_name)
        return security_ops->kernel_module_request(kmod_name);
 }
 
+int security_kernel_module_from_file(struct file *file)
+{
+       int ret;
+
+       ret = security_ops->kernel_module_from_file(file);
+       if (ret)
+               return ret;
+       return ima_module_check(file);
+}
+
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags)
 {
index 370a646..855e464 100644 (file)
@@ -69,6 +69,8 @@ static struct nlmsg_perm nlmsg_route_perms[] =
        { RTM_SETDCB,           NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
        { RTM_NEWNETCONF,       NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
        { RTM_GETNETCONF,       NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+       { RTM_NEWMDB,           NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
+       { RTM_DELMDB,           NETLINK_ROUTE_SOCKET__NLMSG_WRITE  },
        { RTM_GETMDB,           NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 };