]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel-stable
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 19 Oct 2010 21:04:42 +0000 (22:04 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 19 Oct 2010 21:04:42 +0000 (22:04 +0100)
996 files changed:
CREDITS
Documentation/arm/00-INDEX
Documentation/arm/msm/gpiomux.txt [new file with mode: 0644]
Documentation/hwmon/sysfs-interface
Documentation/networking/e1000.txt
Documentation/networking/e1000e.txt [new file with mode: 0644]
Documentation/networking/ixgbevf.txt [changed mode: 0755->0644]
Documentation/power/regulator/overview.txt
Documentation/vm/page-types.c
Documentation/workqueue.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/include/asm/cacheflush.h
arch/alpha/include/asm/unistd.h
arch/alpha/kernel/entry.S
arch/alpha/kernel/err_ev6.c
arch/alpha/kernel/err_marvel.c
arch/alpha/kernel/err_titan.c
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/pci-sysfs.c
arch/alpha/kernel/process.c
arch/alpha/kernel/signal.c
arch/alpha/kernel/srm_env.c
arch/alpha/kernel/systbls.S
arch/alpha/kernel/time.c
arch/alpha/kernel/traps.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/common/gic.c
arch/arm/common/it8152.c
arch/arm/configs/at91sam9g20ek_defconfig
arch/arm/configs/kirkwood_defconfig
arch/arm/configs/s5p64x0_defconfig [moved from arch/arm/configs/s5p6440_defconfig with 97% similarity]
arch/arm/include/asm/elf.h
arch/arm/include/asm/io.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/seccomp.h [new file with mode: 0644]
arch/arm/include/asm/thread_info.h
arch/arm/kernel/entry-common.S
arch/arm/kernel/kprobes-decode.c
arch/arm/kernel/process.c
arch/arm/mach-aaec2000/include/mach/vmalloc.h
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/board-at572d940hf_ek.c
arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c [deleted file]
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/include/mach/at91x40.h
arch/arm/mach-at91/include/mach/system.h
arch/arm/mach-bcmring/include/mach/vmalloc.h
arch/arm/mach-clps711x/include/mach/vmalloc.h
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-dove/include/mach/io.h
arch/arm/mach-ebsa110/include/mach/vmalloc.h
arch/arm/mach-ep93xx/dma-m2p.c
arch/arm/mach-footbridge/include/mach/vmalloc.h
arch/arm/mach-h720x/include/mach/vmalloc.h
arch/arm/mach-imx/mach-cpuimx27.c
arch/arm/mach-integrator/include/mach/vmalloc.h
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-ixp4xx/include/mach/hardware.h
arch/arm/mach-kirkwood/Kconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/d2net_v2-setup.c [new file with mode: 0644]
arch/arm/mach-kirkwood/dockstar-setup.c [new file with mode: 0644]
arch/arm/mach-kirkwood/include/mach/kirkwood.h
arch/arm/mach-kirkwood/include/mach/leds-netxbig.h [new file with mode: 0644]
arch/arm/mach-kirkwood/lacie_v2-common.c [new file with mode: 0644]
arch/arm/mach-kirkwood/lacie_v2-common.h [new file with mode: 0644]
arch/arm/mach-kirkwood/netspace_v2-setup.c
arch/arm/mach-kirkwood/netxbig_v2-setup.c
arch/arm/mach-kirkwood/openrd-setup.c
arch/arm/mach-kirkwood/pcie.c
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/common.c
arch/arm/mach-mmp/flint.c
arch/arm/mach-mmp/include/mach/cputype.h
arch/arm/mach-mmp/include/mach/irqs.h
arch/arm/mach-mmp/include/mach/mfp-pxa168.h
arch/arm/mach-mmp/include/mach/pxa168.h
arch/arm/mach-mmp/include/mach/regs-apmu.h
arch/arm/mach-mmp/include/mach/system.h
arch/arm/mach-mmp/include/mach/teton_bga.h [new file with mode: 0644]
arch/arm/mach-mmp/jasper.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/teton_bga.c [new file with mode: 0644]
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/board-msm7x30.c
arch/arm/mach-msm/board-msm8x60.c [new file with mode: 0644]
arch/arm/mach-msm/board-qsd8x50.c
arch/arm/mach-msm/clock-dummy.c [new file with mode: 0644]
arch/arm/mach-msm/devices-msm7x30.c
arch/arm/mach-msm/devices-msm8x60-iommu.c [new file with mode: 0644]
arch/arm/mach-msm/devices-qsd8x50.c
arch/arm/mach-msm/gpio.c
arch/arm/mach-msm/gpio_hw.h [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-7x30.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-8x50.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-8x60.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-v1.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-v1.h [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-v2.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux-v2.h [new file with mode: 0644]
arch/arm/mach-msm/gpiomux.c [new file with mode: 0644]
arch/arm/mach-msm/gpiomux.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/board.h
arch/arm/mach-msm/include/mach/debug-macro.S
arch/arm/mach-msm/include/mach/dma.h
arch/arm/mach-msm/include/mach/entry-macro-qgic.S [new file with mode: 0644]
arch/arm/mach-msm/include/mach/entry-macro-vic.S [new file with mode: 0644]
arch/arm/mach-msm/include/mach/entry-macro.S
arch/arm/mach-msm/include/mach/gpio.h
arch/arm/mach-msm/include/mach/io.h
arch/arm/mach-msm/include/mach/iommu.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/irqs-8x60.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/irqs.h
arch/arm/mach-msm/include/mach/memory.h
arch/arm/mach-msm/include/mach/msm_iomap-8x60.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/msm_iomap.h
arch/arm/mach-msm/include/mach/smp.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/vmalloc.h
arch/arm/mach-msm/io.c
arch/arm/mach-msm/iommu.c [new file with mode: 0644]
arch/arm/mach-msm/iommu_dev.c [new file with mode: 0644]
arch/arm/mach-msm/timer.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-netx/include/mach/vmalloc.h
arch/arm/mach-omap1/include/mach/vmalloc.h
arch/arm/mach-omap2/include/mach/vmalloc.h
arch/arm/mach-pnx4008/include/mach/vmalloc.h
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/cpufreq-pxa2xx.c
arch/arm/mach-pxa/cpufreq-pxa3xx.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/devices.h
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/generic.h
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/include/mach/balloon3.h
arch/arm/mach-pxa/include/mach/eseries-irq.h
arch/arm/mach-pxa/include/mach/hardware.h
arch/arm/mach-pxa/include/mach/hx4700.h
arch/arm/mach-pxa/include/mach/io.h
arch/arm/mach-pxa/include/mach/irqs.h
arch/arm/mach-pxa/include/mach/littleton.h
arch/arm/mach-pxa/include/mach/lpd270.h
arch/arm/mach-pxa/include/mach/lubbock.h
arch/arm/mach-pxa/include/mach/magician.h
arch/arm/mach-pxa/include/mach/mainstone.h
arch/arm/mach-pxa/include/mach/mfp-pxa930.h
arch/arm/mach-pxa/include/mach/pcm027.h
arch/arm/mach-pxa/include/mach/poodle.h
arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h [new file with mode: 0644]
arch/arm/mach-pxa/include/mach/tosa.h
arch/arm/mach-pxa/include/mach/zeus.h
arch/arm/mach-pxa/include/mach/zylonite.h
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmtreo.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/pcm027.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa3xx-ulpi.c [new file with mode: 0644]
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa930.c
arch/arm/mach-pxa/stargate2.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/tavorevb3.c [new file with mode: 0644]
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zeus.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-rpc/include/mach/vmalloc.h
arch/arm/mach-s3c64xx/dev-spi.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s5p6440/Kconfig [deleted file]
arch/arm/mach-s5p6440/Makefile [deleted file]
arch/arm/mach-s5p6440/clock.c [deleted file]
arch/arm/mach-s5p6440/cpu.c [deleted file]
arch/arm/mach-s5p6440/dev-audio.c [deleted file]
arch/arm/mach-s5p6440/dev-spi.c [deleted file]
arch/arm/mach-s5p6440/include/mach/debug-macro.S [deleted file]
arch/arm/mach-s5p6440/include/mach/gpio.h [deleted file]
arch/arm/mach-s5p6440/include/mach/io.h [deleted file]
arch/arm/mach-s5p6440/include/mach/map.h [deleted file]
arch/arm/mach-s5p6440/include/mach/regs-clock.h [deleted file]
arch/arm/mach-s5p6440/include/mach/spi-clocks.h [deleted file]
arch/arm/mach-s5p6440/include/mach/uncompress.h [deleted file]
arch/arm/mach-s5p6440/init.c [deleted file]
arch/arm/mach-s5p6442/cpu.c
arch/arm/mach-s5p6442/include/mach/map.h
arch/arm/mach-s5p64x0/Kconfig [new file with mode: 0644]
arch/arm/mach-s5p64x0/Makefile [new file with mode: 0644]
arch/arm/mach-s5p64x0/Makefile.boot [moved from arch/arm/mach-s5p6440/Makefile.boot with 100% similarity]
arch/arm/mach-s5p64x0/clock-s5p6440.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/clock-s5p6450.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/clock.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/cpu.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/dev-spi.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/dma.c [moved from arch/arm/mach-s5p6440/dma.c with 55% similarity]
arch/arm/mach-s5p64x0/gpio.c [moved from arch/arm/mach-s5p6440/gpio.c with 74% similarity]
arch/arm/mach-s5p64x0/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/dma.h [moved from arch/arm/mach-s5p6440/include/mach/dma.h with 100% similarity]
arch/arm/mach-s5p64x0/include/mach/entry-macro.S [moved from arch/arm/mach-s5p6440/include/mach/entry-macro.S with 58% similarity]
arch/arm/mach-s5p64x0/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/hardware.h [moved from arch/arm/mach-s5p6440/include/mach/hardware.h with 67% similarity]
arch/arm/mach-s5p64x0/include/mach/i2c.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/irqs.h [moved from arch/arm/mach-s5p6440/include/mach/irqs.h with 71% similarity]
arch/arm/mach-s5p64x0/include/mach/map.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/memory.h [moved from arch/arm/mach-s5p6440/include/mach/memory.h with 55% similarity]
arch/arm/mach-s5p64x0/include/mach/pwm-clock.h [moved from arch/arm/mach-s5p6440/include/mach/pwm-clock.h with 86% similarity]
arch/arm/mach-s5p64x0/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/regs-gpio.h [moved from arch/arm/mach-s5p6440/include/mach/regs-gpio.h with 79% similarity]
arch/arm/mach-s5p64x0/include/mach/regs-irq.h [moved from arch/arm/mach-s5p6440/include/mach/regs-irq.h with 66% similarity]
arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/spi-clocks.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/system.h [moved from arch/arm/mach-s5p6440/include/mach/system.h with 69% similarity]
arch/arm/mach-s5p64x0/include/mach/tick.h [moved from arch/arm/mach-s5p6440/include/mach/tick.h with 60% similarity]
arch/arm/mach-s5p64x0/include/mach/timex.h [moved from arch/arm/mach-s5p6440/include/mach/timex.h with 80% similarity]
arch/arm/mach-s5p64x0/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/vmalloc.h [moved from arch/arm/mach-s5p6440/include/mach/vmalloc.h with 74% similarity]
arch/arm/mach-s5p64x0/init.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/mach-smdk6440.c [moved from arch/arm/mach-s5p6440/mach-smdk6440.c with 66% similarity]
arch/arm/mach-s5p64x0/mach-smdk6450.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/setup-i2c0.c [moved from arch/arm/mach-s5p6440/setup-i2c0.c with 52% similarity]
arch/arm/mach-s5p64x0/setup-i2c1.c [moved from arch/arm/mach-s5p6440/setup-i2c1.c with 55% similarity]
arch/arm/mach-s5pc100/cpu.c
arch/arm/mach-s5pc100/include/mach/map.h
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/cpu.c
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv310/cpu.c
arch/arm/mach-s5pv310/include/mach/irqs.h
arch/arm/mach-s5pv310/include/mach/map.h
arch/arm/mach-shark/include/mach/vmalloc.h
arch/arm/mach-tcc8k/Kconfig [new file with mode: 0644]
arch/arm/mach-tcc8k/Makefile [new file with mode: 0644]
arch/arm/mach-tcc8k/Makefile.boot [new file with mode: 0644]
arch/arm/mach-tcc8k/board-tcc8000-sdk.c [new file with mode: 0644]
arch/arm/mach-tcc8k/clock.c [new file with mode: 0644]
arch/arm/mach-tcc8k/common.h [new file with mode: 0644]
arch/arm/mach-tcc8k/devices.c [new file with mode: 0644]
arch/arm/mach-tcc8k/io.c [new file with mode: 0644]
arch/arm/mach-tcc8k/irq.c [new file with mode: 0644]
arch/arm/mach-tcc8k/time.c [new file with mode: 0644]
arch/arm/mach-u300/include/mach/gpio.h
arch/arm/mach-versatile/include/mach/vmalloc.h
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/v2m.c
arch/arm/mm/alignment.c
arch/arm/mm/ioremap.c
arch/arm/mm/mmap.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-v7.S
arch/arm/oprofile/common.c
arch/arm/plat-nomadik/timer.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/iommu.c
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/sram.c
arch/arm/plat-pxa/include/plat/pxa27x_keypad.h [moved from arch/arm/mach-pxa/include/mach/pxa27x_keypad.h with 83% similarity]
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/cpu.c
arch/arm/plat-s5p/dev-fimc0.c
arch/arm/plat-s5p/dev-fimc1.c
arch/arm/plat-s5p/dev-fimc2.c
arch/arm/plat-s5p/dev-onenand.c [moved from arch/arm/mach-s5pv210/dev-onenand.c with 59% similarity]
arch/arm/plat-s5p/dev-uart.c
arch/arm/plat-s5p/include/plat/pll.h
arch/arm/plat-s5p/include/plat/s5p-clock.h
arch/arm/plat-s5p/include/plat/s5p6440.h
arch/arm/plat-s5p/include/plat/s5p6450.h [new file with mode: 0644]
arch/arm/plat-samsung/adc.c
arch/arm/plat-samsung/clock.c
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
arch/arm/plat-tcc/Kconfig [new file with mode: 0644]
arch/arm/plat-tcc/Makefile [new file with mode: 0644]
arch/arm/plat-tcc/clock.c [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/clock.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/hardware.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/io.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/irqs.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/memory.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/system.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/tcc8k-regs.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/timex.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/plat-tcc/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/plat-tcc/system.c [new file with mode: 0644]
arch/avr32/Kconfig
arch/avr32/kernel/module.c
arch/frv/kernel/signal.c
arch/h8300/kernel/module.c
arch/ia64/include/asm/compat.h
arch/ia64/kernel/fsys.S
arch/m32r/include/asm/signal.h
arch/m32r/include/asm/unistd.h
arch/m32r/kernel/entry.S
arch/m32r/kernel/ptrace.c
arch/m32r/kernel/signal.c
arch/m68k/include/asm/unistd.h
arch/m68k/kernel/entry.S
arch/m68k/mac/macboing.c
arch/m68knommu/kernel/syscalltable.S
arch/mips/Kconfig
arch/mips/alchemy/common/prom.c
arch/mips/boot/compressed/Makefile
arch/mips/cavium-octeon/Kconfig
arch/mips/cavium-octeon/cpu.c
arch/mips/cavium-octeon/executive/Makefile
arch/mips/include/asm/atomic.h
arch/mips/include/asm/compat.h
arch/mips/include/asm/cop2.h
arch/mips/include/asm/gic.h
arch/mips/include/asm/mach-tx49xx/kmalloc.h
arch/mips/include/asm/mips-boards/maltaint.h
arch/mips/include/asm/page.h
arch/mips/include/asm/siginfo.h
arch/mips/include/asm/thread_info.h
arch/mips/include/asm/unistd.h
arch/mips/kernel/irq-gic.c
arch/mips/kernel/kgdb.c
arch/mips/kernel/kspd.c
arch/mips/kernel/linux32.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/mm/dma-default.c
arch/mips/mm/sc-rm7k.c
arch/mips/mti-malta/malta-int.c
arch/mips/pci/pci-rc32434.c
arch/mips/pnx8550/common/reset.c
arch/mips/pnx8550/common/setup.c
arch/mn10300/Kconfig
arch/mn10300/Kconfig.debug
arch/mn10300/include/asm/bitops.h
arch/mn10300/include/asm/signal.h
arch/mn10300/kernel/mn10300-serial.c
arch/mn10300/kernel/module.c
arch/mn10300/kernel/signal.c
arch/mn10300/mm/Makefile
arch/mn10300/mm/cache-disabled.c [new file with mode: 0644]
arch/mn10300/mm/cache.c
arch/parisc/include/asm/compat.h
arch/parisc/kernel/module.c
arch/powerpc/include/asm/compat.h
arch/powerpc/kernel/module.c
arch/powerpc/kernel/signal.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/platforms/512x/clock.c
arch/powerpc/platforms/52xx/efika.c
arch/powerpc/platforms/52xx/mpc52xx_common.c
arch/s390/include/asm/compat.h
arch/s390/kernel/module.c
arch/sh/kernel/module.c
arch/sparc/include/asm/compat.h
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/tile/include/arch/chip_tile64.h
arch/tile/include/arch/chip_tilepro.h
arch/tile/include/asm/compat.h
arch/tile/include/asm/io.h
arch/tile/include/asm/processor.h
arch/tile/include/asm/ptrace.h
arch/tile/include/asm/sigcontext.h
arch/tile/include/asm/signal.h
arch/tile/include/asm/syscalls.h
arch/tile/kernel/intvec_32.S
arch/tile/kernel/process.c
arch/tile/kernel/signal.c
arch/tile/kernel/stack.c
arch/um/drivers/net_kern.c
arch/um/kernel/exec.c
arch/um/kernel/internal.h
arch/um/kernel/syscall.c
arch/x86/Makefile
arch/x86/boot/early_serial_console.c
arch/x86/ia32/ia32_aout.c
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/amd_iommu_proto.h
arch/x86/include/asm/amd_iommu_types.h
arch/x86/include/asm/bitops.h
arch/x86/include/asm/compat.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/hpet.h
arch/x86/include/asm/hw_breakpoint.h
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/cstate.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpu.h
arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_p4.c
arch/x86/kernel/cpu/scattered.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/hpet.c
arch/x86/kernel/hw_breakpoint.c
arch/x86/kernel/module.c
arch/x86/kvm/svm.c
arch/x86/lguest/boot.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/nmi_int.c
arch/x86/xen/time.c
block/blk-map.c
block/blk-merge.c
block/cfq-iosched.c
block/elevator.c
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/acpi_pad.c
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/exutils.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/apei/Kconfig
drivers/acpi/apei/apei-base.c
drivers/acpi/apei/einj.c
drivers/acpi/apei/erst-dbg.c
drivers/acpi/apei/erst.c
drivers/acpi/apei/ghes.c
drivers/acpi/apei/hest.c
drivers/acpi/atomicio.c
drivers/acpi/battery.c
drivers/acpi/blacklist.c
drivers/acpi/bus.c
drivers/acpi/fan.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_perflib.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/video_detect.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ahci_platform.c
drivers/ata/libahci.c
drivers/atm/iphase.c
drivers/atm/iphase.h
drivers/atm/solos-pci.c
drivers/block/cciss.c
drivers/block/pktcdvd.c
drivers/block/virtio_blk.c
drivers/char/agp/intel-agp.c
drivers/char/agp/intel-agp.h
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/mem.c
drivers/char/virtio_console.c
drivers/cpuidle/governors/menu.c
drivers/dca/dca-core.c
drivers/dma/ioat/dma_v2.c
drivers/dma/mv_xor.c
drivers/dma/shdma.c
drivers/edac/edac_mc.c
drivers/edac/i7core_edac.c
drivers/firewire/ohci.c
drivers/gpu/drm/drm_buffer.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i830/i830_dma.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_blit_shaders.h
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_object.h
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/gpu/drm/ttm/ttm_page_alloc.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/gpu/vga/vgaarb.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-mosart.c
drivers/hid/hid-topseed.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/usbhid/hiddev.c
drivers/hid/usbhid/usbhid.h
drivers/hwmon/Kconfig
drivers/hwmon/adm1031.c
drivers/hwmon/coretemp.c
drivers/hwmon/emc1403.c
drivers/hwmon/f71882fg.c
drivers/hwmon/f75375s.c
drivers/hwmon/lis3lv02d.c
drivers/hwmon/lis3lv02d_i2c.c
drivers/hwmon/lis3lv02d_spi.c
drivers/hwmon/lm95241.c
drivers/hwmon/pkgtemp.c
drivers/hwmon/w83627ehf.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-octeon.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-pca-platform.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/i2c-core.c
drivers/ide/ide-probe.c
drivers/idle/intel_idle.c [changed mode: 0755->0644]
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/input/joydev.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/misc/uinput.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/isdn/sc/interrupt.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-netxbig.c [new file with mode: 0644]
drivers/leds/leds-ns2.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid1.c
drivers/media/IR/ir-keytable.c
drivers/media/IR/ir-lirc-codec.c
drivers/media/IR/ir-raw-event.c
drivers/media/IR/ir-sysfs.c
drivers/media/IR/keymaps/rc-rc6-mce.c
drivers/media/IR/mceusb.c
drivers/media/dvb/dvb-usb/dib0700_core.c
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/dvb-usb/opera1.c
drivers/media/dvb/frontends/dib7000p.c
drivers/media/dvb/frontends/dib7000p.h
drivers/media/dvb/siano/smscoreapi.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/video/cx231xx/Makefile
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/Kconfig
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/sn9c20x.c
drivers/media/video/ivtv/ivtvfb.c
drivers/media/video/mem2mem_testdev.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9v022.c
drivers/media/video/mx2_camera.c
drivers/media/video/pvrusb2/pvrusb2-ctrl.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7164/saa7164-buffer.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvcvideo.h
drivers/media/video/videobuf-dma-contig.c
drivers/media/video/videobuf-dma-sg.c
drivers/mfd/max8925-core.c
drivers/mfd/wm831x-irq.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/bh1780gli.c
drivers/misc/vmw_balloon.c [moved from drivers/misc/vmware_balloon.c with 100% similarity]
drivers/mmc/host/sdhci-s3c.c
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/onenand/samsung.c
drivers/net/3c59x.c
drivers/net/Kconfig
drivers/net/atlx/atl1.c
drivers/net/b44.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_qmr.h
drivers/net/eql.c
drivers/net/fec.c
drivers/net/ibm_newemac/core.c
drivers/net/ll_temac_main.c
drivers/net/ll_temac_mdio.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/phy/mdio_bus.c
drivers/net/ppp_generic.c
drivers/net/qlcnic/qlcnic_init.c
drivers/net/r8169.c
drivers/net/rionet.c
drivers/net/sgiseeq.c
drivers/net/skge.c
drivers/net/smsc911x.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tulip/de2104x.c
drivers/net/usb/hso.c
drivers/net/wimax/i2400m/rx.c
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/pci/intel-iommu.c
drivers/pci/iov.c
drivers/pci/pci.h
drivers/pci/quirks.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/platform/x86/intel_ips.c
drivers/platform/x86/thinkpad_acpi.c
drivers/power/apm_power.c
drivers/power/intel_mid_battery.c
drivers/regulator/88pm8607.c
drivers/regulator/ab3100.c
drivers/regulator/ab8500.c
drivers/regulator/ad5398.c
drivers/regulator/core.c
drivers/regulator/isl6271a-regulator.c
drivers/regulator/max1586.c
drivers/regulator/max8649.c
drivers/regulator/max8998.c
drivers/regulator/tps6507x-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/wm831x-ldo.c
drivers/regulator/wm8350-regulator.c
drivers/rtc/rtc-ab3100.c
drivers/rtc/rtc-ds3232.c
drivers/rtc/rtc-s3c.c
drivers/s390/net/ctcm_main.c
drivers/serial/Kconfig
drivers/serial/amba-pl010.c
drivers/serial/mfd.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mrst_max3110.c
drivers/serial/samsung.c
drivers/serial/serial_cs.c
drivers/spi/amba-pl022.c
drivers/spi/dw_spi.c
drivers/spi/spi.c
drivers/spi/spi_gpio.c
drivers/spi/spi_mpc8xxx.c
drivers/spi/spi_s3c64xx.c
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/send.c
drivers/staging/ti-st/st.h
drivers/staging/ti-st/st_core.c
drivers/staging/ti-st/st_core.h
drivers/staging/ti-st/st_kim.c
drivers/staging/tm6000/Kconfig
drivers/staging/tm6000/tm6000-input.c
drivers/staging/vt6655/wpactl.c
drivers/usb/core/Kconfig
drivers/usb/core/file.c
drivers/usb/core/message.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/musb_debugfs.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget.h
drivers/usb/musb/musb_gadget_ep0.c
drivers/usb/musb/musb_host.c
drivers/usb/otg/twl4030-usb.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/video/console/fbcon.c
drivers/video/efifb.c
drivers/video/pxa168fb.c
drivers/video/sis/sis_main.c
drivers/video/via/ioctl.c
drivers/watchdog/Kconfig
drivers/watchdog/sb_wdog.c
drivers/watchdog/ts72xx_wdt.c
drivers/xen/xenbus/xenbus_probe.c
fs/9p/vfs_dir.c
fs/9p/vfs_inode.c
fs/9p/vfs_super.c
fs/aio.c
fs/binfmt_aout.c
fs/ceph/Kconfig
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/export.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/osd_client.c
fs/ceph/pagelist.c
fs/ceph/snap.c
fs/ceph/super.h
fs/char_dev.c
fs/cifs/Kconfig
fs/cifs/asn1.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/netmisc.c
fs/cifs/ntlmssp.h
fs/cifs/sess.c
fs/cifs/transport.c
fs/coda/psdev.c
fs/compat.c
fs/exec.c
fs/exofs/inode.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/gfs2/log.c
fs/nfs/Kconfig
fs/nfs/client.c
fs/nfs/file.c
fs/nfs/super.c
fs/nfsd/Kconfig
fs/nfsd/nfsfh.h
fs/notify/Kconfig
fs/ocfs2/acl.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdebug.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlmglue.h
fs/ocfs2/ocfs2_fs.h
fs/ocfs2/ocfs2_ioctl.h
fs/ocfs2/refcounttree.c
fs/ocfs2/reservations.c
fs/ocfs2/suballoc.c
fs/ocfs2/symlink.c
fs/ocfs2/xattr.c
fs/proc/base.c
fs/proc/task_mmu.c
fs/proc/vmcore.c
fs/reiserfs/ioctl.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_log_priv.h
include/acpi/acpixf.h
include/drm/drmP.h
include/drm/drm_crtc.h
include/drm/drm_pciids.h
include/drm/ttm/ttm_bo_api.h
include/linux/Kbuild
include/linux/compat.h
include/linux/coredump.h
include/linux/cpuidle.h
include/linux/dma-mapping.h
include/linux/dmaengine.h
include/linux/elevator.h
include/linux/fs.h
include/linux/gpio.h
include/linux/module.h
include/linux/netlink.h
include/linux/netpoll.h
include/linux/pci_ids.h
include/linux/quotaops.h
include/linux/rcupdate.h
include/linux/socket.h
include/linux/spi/dw_spi.h
include/linux/sunrpc/clnt.h
include/linux/wait.h
include/linux/workqueue.h
include/media/videobuf-dma-sg.h
include/net/addrconf.h
include/net/bluetooth/bluetooth.h
include/net/dst.h
include/net/route.h
include/net/tcp.h
include/net/xfrm.h
ipc/sem.c
kernel/compat.c
kernel/fork.c
kernel/hw_breakpoint.c
kernel/kfifo.c
kernel/module.c
kernel/perf_event.c
kernel/sched.c
kernel/sched_fair.c
kernel/signal.c
kernel/smp.c
kernel/sysctl.c
kernel/trace/ring_buffer.c
kernel/workqueue.c
lib/bug.c
lib/list_sort.c
mm/backing-dev.c
mm/fremap.c
mm/hugetlb.c
mm/ksm.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory.c
mm/mmap.c
mm/oom_kill.c
mm/page_alloc.c
mm/percpu.c
mm/rmap.c
mm/vmscan.c
net/8021q/vlan_core.c
net/9p/client.c
net/9p/trans_rdma.c
net/9p/trans_virtio.c
net/Kconfig
net/atm/br2684.c
net/atm/mpc.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/caif/caif_socket.c
net/core/dev.c
net/core/ethtool.c
net/core/iovec.c
net/core/sock.c
net/core/stream.c
net/ipv4/Kconfig
net/ipv4/igmp.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/nf_defrag_ipv4.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_timer.c
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_state.c
net/ipv6/addrconf.c
net/ipv6/addrlabel.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/ipv6/xfrm6_state.c
net/llc/af_llc.c
net/llc/llc_station.c
net/mac80211/agg-tx.c
net/mac80211/rx.c
net/mac80211/status.c
net/netfilter/nf_conntrack_extend.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_tproxy_core.c
net/phonet/pep.c
net/rds/tcp_connect.c
net/rds/tcp_listen.c
net/rds/tcp_recv.c
net/rds/tcp_send.c
net/rose/af_rose.c
net/sched/cls_u32.c
net/sched/sch_atm.c
net/sctp/auth.c
net/sctp/output.c
net/sctp/socket.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/auth_gss/gss_spkm3_mech.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
net/sunrpc/xprtsock.c
net/wireless/wext-priv.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
samples/kfifo/dma-example.c
scripts/kconfig/conf.c
scripts/kconfig/expr.h
scripts/kconfig/menu.c
scripts/kconfig/symbol.c
security/tomoyo/common.c
security/tomoyo/common.h
sound/core/control.c
sound/core/pcm.c
sound/core/pcm_native.c
sound/i2c/other/ak4xxx-adda.c
sound/oss/soundcard.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/oxygen/oxygen.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/ppc/snd_ps3.c
sound/soc/s3c24xx/s3c-dma.c
sound/soc/sh/migor.c
sound/soc/soc-cache.c
tools/perf/Makefile
tools/perf/perf.h
tools/perf/util/trace-event-scripting.c
tools/perf/util/ui/browsers/hists.c
virt/kvm/eventfd.c
virt/kvm/kvm_main.c

diff --git a/CREDITS b/CREDITS
index 72b487869788c14cd40e9535b700f4be166aa12b..41d8e63d5165b5b786db6ab7d8c14fbc49fc0107 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -3554,12 +3554,12 @@ E: cvance@nai.com
 D: portions of the Linux Security Module (LSM) framework and security modules
 
 N: Petr Vandrovec
-E: vandrove@vc.cvut.cz
+E: petr@vandrovec.name
 D: Small contributions to ncpfs
 D: Matrox framebuffer driver
-S: Chudenicka 8
-S: 10200 Prague 10, Hostivar
-S: Czech Republic
+S: 21513 Conradia Ct
+S: Cupertino, CA 95014
+S: USA
 
 N: Thibaut Varene
 E: T-Bone@parisc-linux.org
index 7f5fc3ba9c912daf7824d96621b52121e6cae873..ecf7d04bca2601d79e8239b08a777c207198b451 100644 (file)
@@ -6,6 +6,8 @@ Interrupts
        - ARM Interrupt subsystem documentation
 IXP2000
        - Release Notes for Linux on Intel's IXP2000 Network Processor
+msm
+       - MSM specific documentation
 Netwinder
        - Netwinder specific documentation
 Porting
diff --git a/Documentation/arm/msm/gpiomux.txt b/Documentation/arm/msm/gpiomux.txt
new file mode 100644 (file)
index 0000000..67a8162
--- /dev/null
@@ -0,0 +1,176 @@
+This document provides an overview of the msm_gpiomux interface, which
+is used to provide gpio pin multiplexing and configuration on mach-msm
+targets.
+
+History
+=======
+
+The first-generation API for gpio configuration & multiplexing on msm
+is the function gpio_tlmm_config().  This function has a few notable
+shortcomings, which led to its deprecation and replacement by gpiomux:
+
+The 'disable' parameter:  Setting the second parameter to
+gpio_tlmm_config to GPIO_CFG_DISABLE tells the peripheral
+processor in charge of the subsystem to perform a look-up into a
+low-power table and apply the low-power/sleep setting for the pin.
+As the msm family evolved this became problematic. Not all pins
+have sleep settings, not all peripheral processors will accept requests
+to apply said sleep settings, and not all msm targets have their gpio
+subsystems managed by a peripheral processor. In order to get consistent
+behavior on all targets, drivers are forced to ignore this parameter,
+rendering it useless.
+
+The 'direction' flag: for all mux-settings other than raw-gpio (0),
+the output-enable bit of a gpio is hard-wired to a known
+input (usually VDD or ground).  For those settings, the direction flag
+is meaningless at best, and deceptive at worst.  In addition, using the
+direction flag to change output-enable (OE) directly can cause trouble in
+gpiolib, which has no visibility into gpio direction changes made
+in this way.  Direction control in gpio mode should be made through gpiolib.
+
+Key Features of gpiomux
+=======================
+
+- A consistent interface across all generations of msm.  Drivers can expect
+the same results on every target.
+- gpiomux plays nicely with gpiolib.  Functions that should belong to gpiolib
+are left to gpiolib and not duplicated here.  gpiomux is written with the
+intent that gpio_chips will call gpiomux reference-counting methods
+from their request() and free() hooks, providing full integration.
+- Tabular configuration.  Instead of having to call gpio_tlmm_config
+hundreds of times, gpio configuration is placed in a single table.
+- Per-gpio sleep.  Each gpio is individually reference counted, allowing only
+those lines which are in use to be put in high-power states.
+- 0 means 'do nothing': all flags are designed so that the default memset-zero
+equates to a sensible default of 'no configuration', preventing users
+from having to provide hundreds of 'no-op' configs for unused or
+unwanted lines.
+
+Usage
+=====
+
+To use gpiomux, provide configuration information for relevant gpio lines
+in the msm_gpiomux_configs table.  Since a 0 equates to "unconfigured",
+only those lines to be managed by gpiomux need to be specified.  Here
+is a completely fictional example:
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+       [12] = {
+               .active = GPIOMUX_VALID | GPIOMUX_DRV_8MA | GPIOMUX_FUNC_1,
+               .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
+       },
+       [34] = {
+               .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
+       },
+};
+
+To indicate that a gpio is in use, call msm_gpiomux_get() to increase
+its reference count.  To decrease the reference count, call msm_gpiomux_put().
+
+The effect of this configuration is as follows:
+
+When the system boots, gpios 12 and 34 will be initialized with their
+'suspended' configurations.  All other gpios, which were left unconfigured,
+will not be touched.
+
+When msm_gpiomux_get() is called on gpio 12 to raise its reference count
+above 0, its active configuration will be applied.  Since no other gpio
+line has a valid active configuration, msm_gpiomux_get() will have no
+effect on any other line.
+
+When msm_gpiomux_put() is called on gpio 12 or 34 to drop their reference
+count to 0, their suspended configurations will be applied.
+Since no other gpio line has a valid suspended configuration, no other
+gpio line will be effected by msm_gpiomux_put().  Since gpio 34 has no valid
+active configuration, this is effectively a no-op for gpio 34 as well,
+with one small caveat, see the section "About Output-Enable Settings".
+
+All of the GPIOMUX_VALID flags may seem like unnecessary overhead, but
+they address some important issues.  As unused entries (all those
+except 12 and 34) are zero-filled, gpiomux needs a way to distinguish
+the used fields from the unused.  In addition, the all-zero pattern
+is a valid configuration!  Therefore, gpiomux defines an additional bit
+which is used to indicate when a field is used.  This has the pleasant
+side-effect of allowing calls to msm_gpiomux_write to use '0' to indicate
+that a value should not be changed:
+
+  msm_gpiomux_write(0, GPIOMUX_VALID, 0);
+
+replaces the active configuration of gpio 0 with an all-zero configuration,
+but leaves the suspended configuration as it was.
+
+Static Configurations
+=====================
+
+To install a static configuration, which is applied at boot and does
+not change after that, install a configuration with a suspended component
+but no active component, as in the previous example:
+
+       [34] = {
+               .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
+       },
+
+The suspended setting is applied during boot, and the lack of any valid
+active setting prevents any other setting from being applied at runtime.
+If other subsystems attempting to access the line is a concern, one could
+*really* anchor the configuration down by calling msm_gpiomux_get on the
+line at initialization to move the line into active mode.  With the line
+held, it will never be re-suspended, and with no valid active configuration,
+no new configurations will be applied.
+
+But then, if having other subsystems grabbing for the line is truly a concern,
+it should be reserved with gpio_request instead, which carries an implicit
+msm_gpiomux_get.
+
+gpiomux and gpiolib
+===================
+
+It is expected that msm gpio_chips will call msm_gpiomux_get() and
+msm_gpiomux_put() from their request and free hooks, like this fictional
+example:
+
+static int request(struct gpio_chip *chip, unsigned offset)
+{
+        return msm_gpiomux_get(chip->base + offset);
+}
+
+static void free(struct gpio_chip *chip, unsigned offset)
+{
+        msm_gpiomux_put(chip->base + offset);
+}
+
+       ...somewhere in a gpio_chip declaration...
+       .request = request,
+       .free    = free,
+
+This provides important functionality:
+- It guarantees that a gpio line will have its 'active' config applied
+  when the line is requested, and will not be suspended while the line
+  remains requested; and
+- It guarantees that gpio-direction settings from gpiolib behave sensibly.
+  See "About Output-Enable Settings."
+
+This mechanism allows for "auto-request" of gpiomux lines via gpiolib
+when it is suitable.  Drivers wishing more exact control are, of course,
+free to also use msm_gpiomux_set and msm_gpiomux_get.
+
+About Output-Enable Settings
+============================
+
+Some msm targets do not have the ability to query the current gpio
+configuration setting.  This means that changes made to the output-enable
+(OE) bit by gpiolib cannot be consistently detected and preserved by gpiomux.
+Therefore, when gpiomux applies a configuration setting, any direction
+settings which may have been applied by gpiolib are lost and the default
+input settings are re-applied.
+
+For this reason, drivers should not assume that gpio direction settings
+continue to hold if they free and then re-request a gpio.  This seems like
+common sense - after all, anybody could have obtained the line in the
+meantime - but it needs saying.
+
+This also means that calls to msm_gpiomux_write will reset the OE bit,
+which means that if the gpio line is held by a client of gpiolib and
+msm_gpiomux_write is called, the direction setting has been lost and
+gpiolib's internal state has been broken.
+Release gpio lines before reconfiguring them.
index ff45d1f837c89ab6706726ae525083e22d05af16..48ceabedf55df87dddff2d62864f6f93db9d315b 100644 (file)
@@ -91,12 +91,11 @@ name                The chip name.
                I2C devices get this attribute created automatically.
                RO
 
-update_rate    The rate at which the chip will update readings.
+update_interval        The interval at which the chip will update readings.
                Unit: millisecond
                RW
-               Some devices have a variable update rate. This attribute
-               can be used to change the update rate to the desired
-               frequency.
+               Some devices have a variable update rate or interval.
+               This attribute can be used to change it to the desired value.
 
 
 ************
index 2df71861e578b6ebcb2b94371d4a32fbdf7fca61..d9271e74e488a54177c548a5ad859d51ffdaff28 100644 (file)
@@ -1,82 +1,35 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-September 26, 2006
-
+Intel Gigabit Linux driver.
+Copyright(c) 1999 - 2010 Intel Corporation.
 
 Contents
 ========
 
-- In This Release
 - Identifying Your Adapter
-- Building and Installation
 - Command Line Parameters
 - Speed and Duplex Configuration
 - Additional Configurations
-- Known Issues
 - Support
 
-
-In This Release
-===============
-
-This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
-of Adapters.  This driver includes support for Itanium(R)2-based systems.
-
-For questions related to hardware requirements, refer to the documentation
-supplied with your Intel PRO/1000 adapter. All hardware requirements listed
-apply to use with Linux.
-
-The following features are now available in supported kernels:
- - Native VLANs
- - Channel Bonding (teaming)
- - SNMP
-
-Channel Bonding documentation can be found in the Linux kernel source:
-/Documentation/networking/bonding.txt
-
-The driver information previously displayed in the /proc filesystem is not
-supported in this release.  Alternatively, you can use ethtool (version 1.6
-or later), lspci, and ifconfig to obtain the same information.
-
-Instructions on updating ethtool can be found in the section "Additional
-Configurations" later in this document.
-
-NOTE: The Intel(R) 82562v 10/100 Network Connection only provides 10/100
-support.
-
-
 Identifying Your Adapter
 ========================
 
 For more information on how to identify your adapter, go to the Adapter &
 Driver ID Guide at:
 
-    http://support.intel.com/support/network/adapter/pro100/21397.htm
+    http://support.intel.com/support/go/network/adapter/idguide.htm
 
 For the latest Intel network drivers for Linux, refer to the following
 website.  In the search field, enter your adapter name or type, or use the
 networking link on the left to search for your adapter:
 
-    http://downloadfinder.intel.com/scripts-df/support_intel.asp
-
+    http://support.intel.com/support/go/network/adapter/home.htm
 
 Command Line Parameters
 =======================
 
-If the driver is built as a module, the  following optional parameters
-are used by entering them on the command line with the modprobe command
-using this syntax:
-
-     modprobe e1000 [<option>=<VAL1>,<VAL2>,...]
-
-For example, with two PRO/1000 PCI adapters, entering:
-
-     modprobe e1000 TxDescriptors=80,128
-
-loads the e1000 driver with 80 TX descriptors for the first adapter and
-128 TX descriptors for the second adapter.
-
 The default value for each parameter is generally the recommended setting,
 unless otherwise noted.
 
@@ -89,10 +42,6 @@ NOTES:  For more information about the AutoNeg, Duplex, and Speed
         parameters, see the application note at:
         http://www.intel.com/design/network/applnots/ap450.htm
 
-        A descriptor describes a data buffer and attributes related to
-        the data buffer.  This information is accessed by the hardware.
-
-
 AutoNeg
 -------
 (Supported only on adapters with copper connections)
@@ -106,7 +55,6 @@ Duplex parameters must not be specified.
 NOTE:  Refer to the Speed and Duplex section of this readme for more
        information on the AutoNeg parameter.
 
-
 Duplex
 ------
 (Supported only on adapters with copper connections)
@@ -119,7 +67,6 @@ set to auto-negotiate, the board auto-detects the correct duplex.  If the
 link partner is forced (either full or half), Duplex defaults to half-
 duplex.
 
-
 FlowControl
 -----------
 Valid Range:   0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
@@ -128,16 +75,16 @@ Default Value: Reads flow control settings from the EEPROM
 This parameter controls the automatic generation(Tx) and response(Rx)
 to Ethernet PAUSE frames.
 
-
 InterruptThrottleRate
 ---------------------
 (not supported on Intel(R) 82542, 82543 or 82544-based adapters)
-Valid Range:   0,1,3,100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
+Valid Range:   0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative,
+                                   4=simplified balancing)
 Default Value: 3
 
 The driver can limit the amount of interrupts per second that the adapter
-will generate for incoming packets. It does this by writing a value to the 
-adapter that is based on the maximum amount of interrupts that the adapter 
+will generate for incoming packets. It does this by writing a value to the
+adapter that is based on the maximum amount of interrupts that the adapter
 will generate per second.
 
 Setting InterruptThrottleRate to a value greater or equal to 100
@@ -146,37 +93,43 @@ per second, even if more packets have come in. This reduces interrupt
 load on the system and can lower CPU utilization under heavy load,
 but will increase latency as packets are not processed as quickly.
 
-The default behaviour of the driver previously assumed a static 
-InterruptThrottleRate value of 8000, providing a good fallback value for 
-all traffic types,but lacking in small packet performance and latency. 
-The hardware can handle many more small packets per second however, and 
+The default behaviour of the driver previously assumed a static
+InterruptThrottleRate value of 8000, providing a good fallback value for
+all traffic types,but lacking in small packet performance and latency.
+The hardware can handle many more small packets per second however, and
 for this reason an adaptive interrupt moderation algorithm was implemented.
 
 Since 7.3.x, the driver has two adaptive modes (setting 1 or 3) in which
-it dynamically adjusts the InterruptThrottleRate value based on the traffic 
+it dynamically adjusts the InterruptThrottleRate value based on the traffic
 that it receives. After determining the type of incoming traffic in the last
-timeframe, it will adjust the InterruptThrottleRate to an appropriate value 
+timeframe, it will adjust the InterruptThrottleRate to an appropriate value
 for that traffic.
 
 The algorithm classifies the incoming traffic every interval into
-classes.  Once the class is determined, the InterruptThrottleRate value is 
-adjusted to suit that traffic type the best. There are three classes defined: 
+classes.  Once the class is determined, the InterruptThrottleRate value is
+adjusted to suit that traffic type the best. There are three classes defined:
 "Bulk traffic", for large amounts of packets of normal size; "Low latency",
 for small amounts of traffic and/or a significant percentage of small
-packets; and "Lowest latency", for almost completely small packets or 
+packets; and "Lowest latency", for almost completely small packets or
 minimal traffic.
 
-In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 
-for traffic that falls in class "Bulk traffic". If traffic falls in the "Low 
-latency" or "Lowest latency" class, the InterruptThrottleRate is increased 
+In dynamic conservative mode, the InterruptThrottleRate value is set to 4000
+for traffic that falls in class "Bulk traffic". If traffic falls in the "Low
+latency" or "Lowest latency" class, the InterruptThrottleRate is increased
 stepwise to 20000. This default mode is suitable for most applications.
 
 For situations where low latency is vital such as cluster or
 grid computing, the algorithm can reduce latency even more when
 InterruptThrottleRate is set to mode 1. In this mode, which operates
-the same as mode 3, the InterruptThrottleRate will be increased stepwise to 
+the same as mode 3, the InterruptThrottleRate will be increased stepwise to
 70000 for traffic in class "Lowest latency".
 
+In simplified mode the interrupt rate is based on the ratio of Tx and
+Rx traffic.  If the bytes per second rate is approximately equal, the
+interrupt rate will drop as low as 2000 interrupts per second.  If the
+traffic is mostly transmit or mostly receive, the interrupt rate could
+be as high as 8000.
+
 Setting InterruptThrottleRate to 0 turns off any interrupt moderation
 and may improve small packet latency, but is generally not suitable
 for bulk throughput traffic.
@@ -212,8 +165,6 @@ NOTE:  When e1000 is loaded with default settings and multiple adapters
        be platform-specific.  If CPU utilization is not a concern, use
        RX_POLLING (NAPI) and default driver settings.
 
-
-
 RxDescriptors
 -------------
 Valid Range:   80-256 for 82542 and 82543-based adapters
@@ -225,15 +176,14 @@ by the driver.  Increasing this value allows the driver to buffer more
 incoming packets, at the expense of increased system memory utilization.
 
 Each descriptor is 16 bytes.  A receive buffer is also allocated for each
-descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending 
+descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending
 on the MTU setting. The maximum MTU size is 16110.
 
-NOTE:  MTU designates the frame size.  It only needs to be set for Jumbo 
-       Frames.  Depending on the available system resources, the request 
-       for a higher number of receive descriptors may be denied.  In this 
+NOTE:  MTU designates the frame size.  It only needs to be set for Jumbo
+       Frames.  Depending on the available system resources, the request
+       for a higher number of receive descriptors may be denied.  In this
        case, use a lower number.
 
-
 RxIntDelay
 ----------
 Valid Range:   0-65535 (0=off)
@@ -254,7 +204,6 @@ CAUTION:  When setting RxIntDelay to a value other than 0, adapters may
           restoring the network connection.  To eliminate the potential
           for the hang ensure that RxIntDelay is set to 0.
 
-
 RxAbsIntDelay
 -------------
 (This parameter is supported only on 82540, 82545 and later adapters.)
@@ -268,7 +217,6 @@ packet is received within the set amount of time.  Proper tuning,
 along with RxIntDelay, may improve traffic throughput in specific network
 conditions.
 
-
 Speed
 -----
 (This parameter is supported only on adapters with copper connections.)
@@ -280,7 +228,6 @@ Speed forces the line speed to the specified value in megabits per second
 partner is set to auto-negotiate, the board will auto-detect the correct
 speed.  Duplex should also be set when Speed is set to either 10 or 100.
 
-
 TxDescriptors
 -------------
 Valid Range:   80-256 for 82542 and 82543-based adapters
@@ -295,6 +242,36 @@ NOTE:  Depending on the available system resources, the request for a
        higher number of transmit descriptors may be denied.  In this case,
        use a lower number.
 
+TxDescriptorStep
+----------------
+Valid Range:    1 (use every Tx Descriptor)
+               4 (use every 4th Tx Descriptor)
+
+Default Value:  1 (use every Tx Descriptor)
+
+On certain non-Intel architectures, it has been observed that intense TX
+traffic bursts of short packets may result in an improper descriptor
+writeback. If this occurs, the driver will report a "TX Timeout" and reset
+the adapter, after which the transmit flow will restart, though data may
+have stalled for as much as 10 seconds before it resumes.
+
+The improper writeback does not occur on the first descriptor in a system
+memory cache-line, which is typically 32 bytes, or 4 descriptors long.
+
+Setting TxDescriptorStep to a value of 4 will ensure that all TX descriptors
+are aligned to the start of a system memory cache line, and so this problem
+will not occur.
+
+NOTES: Setting TxDescriptorStep to 4 effectively reduces the number of
+       TxDescriptors available for transmits to 1/4 of the normal allocation.
+       This has a possible negative performance impact, which may be
+       compensated for by allocating more descriptors using the TxDescriptors
+       module parameter.
+
+       There are other conditions which may result in "TX Timeout", which will
+       not be resolved by the use of the TxDescriptorStep parameter. As the
+       issue addressed by this parameter has never been observed on Intel
+       Architecture platforms, it should not be used on Intel platforms.
 
 TxIntDelay
 ----------
@@ -307,7 +284,6 @@ efficiency if properly tuned for specific network traffic.  If the
 system is reporting dropped transmits, this value may be set too high
 causing the driver to run out of available transmit descriptors.
 
-
 TxAbsIntDelay
 -------------
 (This parameter is supported only on 82540, 82545 and later adapters.)
@@ -330,6 +306,35 @@ Default Value: 1
 A value of '1' indicates that the driver should enable IP checksum
 offload for received packets (both UDP and TCP) to the adapter hardware.
 
+Copybreak
+---------
+Valid Range:   0-xxxxxxx (0=off)
+Default Value: 256
+Usage: insmod e1000.ko copybreak=128
+
+Driver copies all packets below or equaling this size to a fresh Rx
+buffer before handing it up the stack.
+
+This parameter is different than other parameters, in that it is a
+single (not 1,1,1 etc.) parameter applied to all driver instances and
+it is also available during runtime at
+/sys/module/e1000/parameters/copybreak
+
+SmartPowerDownEnable
+--------------------
+Valid Range: 0-1
+Default Value:  0 (disabled)
+
+Allows PHY to turn off in lower power states. The user can turn off
+this parameter in supported chipsets.
+
+KumeranLockLoss
+---------------
+Valid Range: 0-1
+Default Value: 1 (enabled)
+
+This workaround skips resetting the PHY at shutdown for the initial
+silicon releases of ICH8 systems.
 
 Speed and Duplex Configuration
 ==============================
@@ -385,40 +390,9 @@ If the link partner is forced to a specific speed and duplex, then this
 parameter should not be used.  Instead, use the Speed and Duplex parameters
 previously mentioned to force the adapter to the same speed and duplex.
 
-
 Additional Configurations
 =========================
 
-  Configuring the Driver on Different Distributions
-  -------------------------------------------------
-  Configuring a network driver to load properly when the system is started
-  is distribution dependent.  Typically, the configuration process involves
-  adding an alias line to /etc/modules.conf or /etc/modprobe.conf as well
-  as editing other system startup scripts and/or configuration files.  Many
-  popular Linux distributions ship with tools to make these changes for you.
-  To learn the proper way to configure a network device for your system,
-  refer to your distribution documentation.  If during this process you are
-  asked for the driver or module name, the name for the Linux Base Driver
-  for the Intel(R) PRO/1000 Family of Adapters is e1000.
-
-  As an example, if you install the e1000 driver for two PRO/1000 adapters
-  (eth0 and eth1) and set the speed and duplex to 10full and 100half, add
-  the following to modules.conf or or modprobe.conf:
-
-       alias eth0 e1000
-       alias eth1 e1000
-       options e1000 Speed=10,100 Duplex=2,1
-
-  Viewing Link Messages
-  ---------------------
-  Link messages will not be displayed to the console if the distribution is
-  restricting system messages.  In order to see network driver link messages
-  on your console, set dmesg to eight by entering the following:
-
-       dmesg -n 8
-
-  NOTE: This setting is not saved across reboots.
-
   Jumbo Frames
   ------------
   Jumbo Frames support is enabled by changing the MTU to a value larger than
@@ -437,9 +411,11 @@ Additional Configurations
    setting in a different location.
 
   Notes:
-
-  - To enable Jumbo Frames, increase the MTU size on the interface beyond
-    1500.
+  Degradation in throughput performance may be observed in some Jumbo frames
+  environments. If this is observed, increasing the application's socket buffer
+  size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help.
+  See the specific application manual and /usr/src/linux*/Documentation/
+  networking/ip-sysctl.txt for more details.
 
   - The maximum MTU setting for Jumbo Frames is 16110.  This value coincides
     with the maximum Jumbo Frames size of 16128.
@@ -447,40 +423,11 @@ Additional Configurations
   - Using Jumbo Frames at 10 or 100 Mbps may result in poor performance or
     loss of link.
 
-  - Some Intel gigabit adapters that support Jumbo Frames have a frame size
-    limit of 9238 bytes, with a corresponding MTU size limit of 9216 bytes.
-    The adapters with this limitation are based on the Intel(R) 82571EB,
-    82572EI, 82573L and 80003ES2LAN controller.  These correspond to the
-    following product names:
-     Intel(R) PRO/1000 PT Server Adapter
-     Intel(R) PRO/1000 PT Desktop Adapter
-     Intel(R) PRO/1000 PT Network Connection
-     Intel(R) PRO/1000 PT Dual Port Server Adapter
-     Intel(R) PRO/1000 PT Dual Port Network Connection
-     Intel(R) PRO/1000 PF Server Adapter
-     Intel(R) PRO/1000 PF Network Connection
-     Intel(R) PRO/1000 PF Dual Port Server Adapter
-     Intel(R) PRO/1000 PB Server Connection
-     Intel(R) PRO/1000 PL Network Connection
-     Intel(R) PRO/1000 EB Network Connection with I/O Acceleration
-     Intel(R) PRO/1000 EB Backplane Connection with I/O Acceleration
-     Intel(R) PRO/1000 PT Quad Port Server Adapter
-
   - Adapters based on the Intel(R) 82542 and 82573V/E controller do not
     support Jumbo Frames. These correspond to the following product names:
      Intel(R) PRO/1000 Gigabit Server Adapter
      Intel(R) PRO/1000 PM Network Connection
 
-  - The following adapters do not support Jumbo Frames:
-     Intel(R) 82562V 10/100 Network Connection
-     Intel(R) 82566DM Gigabit Network Connection
-     Intel(R) 82566DC Gigabit Network Connection
-     Intel(R) 82566MM Gigabit Network Connection
-     Intel(R) 82566MC Gigabit Network Connection
-     Intel(R) 82562GT 10/100 Network Connection
-     Intel(R) 82562G 10/100 Network Connection
-
-
   Ethtool
   -------
   The driver utilizes the ethtool interface for driver configuration and
@@ -490,142 +437,14 @@ Additional Configurations
   The latest release of ethtool can be found from
   http://sourceforge.net/projects/gkernel.
 
-  NOTE: Ethtool 1.6 only supports a limited set of ethtool options.  Support
-  for a more complete ethtool feature set can be enabled by upgrading
-  ethtool to ethtool-1.8.1.
-
   Enabling Wake on LAN* (WoL)
   ---------------------------
-  WoL is configured through the Ethtool* utility.  Ethtool is included with
-  all versions of Red Hat after Red Hat 7.2.  For other Linux distributions,
-  download and install Ethtool from the following website:
-  http://sourceforge.net/projects/gkernel.
-
-  For instructions on enabling WoL with Ethtool, refer to the website listed
-  above.
+  WoL is configured through the Ethtool* utility.
 
   WoL will be enabled on the system during the next shut down or reboot.
   For this driver version, in order to enable WoL, the e1000 driver must be
   loaded when shutting down or rebooting the system.
 
-  Wake On LAN is only supported on port A for the following devices:
-  Intel(R) PRO/1000 PT Dual Port Network Connection
-  Intel(R) PRO/1000 PT Dual Port Server Connection
-  Intel(R) PRO/1000 PT Dual Port Server Adapter
-  Intel(R) PRO/1000 PF Dual Port Server Adapter
-  Intel(R) PRO/1000 PT Quad Port Server Adapter
-
-  NAPI
-  ----
-  NAPI (Rx polling mode) is enabled in the e1000 driver.
-
-  See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
-
-
-Known Issues
-============
-
-Dropped Receive Packets on Half-duplex 10/100 Networks
-------------------------------------------------------
-If you have an Intel PCI Express adapter running at 10mbps or 100mbps, half-
-duplex, you may observe occasional dropped receive packets.  There are no
-workarounds for this problem in this network configuration.  The network must
-be updated to operate in full-duplex, and/or 1000mbps only.
-
-Jumbo Frames System Requirement
--------------------------------
-Memory allocation failures have been observed on Linux systems with 64 MB
-of RAM or less that are running Jumbo Frames.  If you are using Jumbo
-Frames, your system may require more than the advertised minimum
-requirement of 64 MB of system memory.
-
-Performance Degradation with Jumbo Frames
------------------------------------------
-Degradation in throughput performance may be observed in some Jumbo frames
-environments.  If this is observed, increasing the application's socket
-buffer size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values
-may help.  See the specific application manual and
-/usr/src/linux*/Documentation/
-networking/ip-sysctl.txt for more details.
-
-Jumbo Frames on Foundry BigIron 8000 switch
--------------------------------------------
-There is a known issue using Jumbo frames when connected to a Foundry
-BigIron 8000 switch.  This is a 3rd party limitation.  If you experience
-loss of packets, lower the MTU size.
-
-Allocating Rx Buffers when Using Jumbo Frames 
----------------------------------------------
-Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if 
-the available memory is heavily fragmented. This issue may be seen with PCI-X 
-adapters or with packet split disabled. This can be reduced or eliminated 
-by changing the amount of available memory for receive buffer allocation, by
-increasing /proc/sys/vm/min_free_kbytes. 
-
-Multiple Interfaces on Same Ethernet Broadcast Network
-------------------------------------------------------
-Due to the default ARP behavior on Linux, it is not possible to have
-one system on two IP networks in the same Ethernet broadcast domain
-(non-partitioned switch) behave as expected.  All Ethernet interfaces
-will respond to IP traffic for any IP address assigned to the system.
-This results in unbalanced receive traffic.
-
-If you have multiple interfaces in a server, either turn on ARP
-filtering by entering:
-
-    echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
-(this only works if your kernel's version is higher than 2.4.5),
-
-NOTE: This setting is not saved across reboots.  The configuration
-change can be made permanent by adding the line:
-    net.ipv4.conf.all.arp_filter = 1
-to the file /etc/sysctl.conf
-
-      or,
-
-install the interfaces in separate broadcast domains (either in
-different switches or in a switch partitioned to VLANs).
-
-82541/82547 can't link or are slow to link with some link partners
------------------------------------------------------------------
-There is a known compatibility issue with 82541/82547 and some
-low-end switches where the link will not be established, or will
-be slow to establish.  In particular, these switches are known to
-be incompatible with 82541/82547:
-
-    Planex FXG-08TE
-    I-O Data ETG-SH8
-
-To workaround this issue, the driver can be compiled with an override
-of the PHY's master/slave setting.  Forcing master or forcing slave
-mode will improve time-to-link.
-
-    # make CFLAGS_EXTRA=-DE1000_MASTER_SLAVE=<n>
-
-Where <n> is:
-
-    0 = Hardware default
-    1 = Master mode
-    2 = Slave mode
-    3 = Auto master/slave
-
-Disable rx flow control with ethtool
-------------------------------------
-In order to disable receive flow control using ethtool, you must turn
-off auto-negotiation on the same command line.
-
-For example:
-
-   ethtool -A eth? autoneg off rx off
-
-Unplugging network cable while ethtool -p is running
-----------------------------------------------------
-In kernel versions 2.5.50 and later (including 2.6 kernel), unplugging
-the network cable while ethtool -p is running will cause the system to
-become unresponsive to keyboard commands, except for control-alt-delete.
-Restarting the system appears to be the only remedy.
-
-
 Support
 =======
 
diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt
new file mode 100644 (file)
index 0000000..6aa048b
--- /dev/null
@@ -0,0 +1,302 @@
+Linux* Driver for Intel(R) Network Connection
+===============================================================
+
+Intel Gigabit Linux driver.
+Copyright(c) 1999 - 2010 Intel Corporation.
+
+Contents
+========
+
+- Identifying Your Adapter
+- Command Line Parameters
+- Additional Configurations
+- Support
+
+Identifying Your Adapter
+========================
+
+The e1000e driver supports all PCI Express Intel(R) Gigabit Network
+Connections, except those that are 82575, 82576 and 82580-based*.
+
+* NOTE: The Intel(R) PRO/1000 P Dual Port Server Adapter is supported by
+  the e1000 driver, not the e1000e driver due to the 82546 part being used
+  behind a PCI Express bridge.
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+    http://support.intel.com/support/go/network/adapter/idguide.htm
+
+For the latest Intel network drivers for Linux, refer to the following
+website.  In the search field, enter your adapter name or type, or use the
+networking link on the left to search for your adapter:
+
+    http://support.intel.com/support/go/network/adapter/home.htm
+
+Command Line Parameters
+=======================
+
+The default value for each parameter is generally the recommended setting,
+unless otherwise noted.
+
+NOTES:  For more information about the InterruptThrottleRate,
+        RxIntDelay, TxIntDelay, RxAbsIntDelay, and TxAbsIntDelay
+        parameters, see the application note at:
+        http://www.intel.com/design/network/applnots/ap450.htm
+
+InterruptThrottleRate
+---------------------
+Valid Range:   0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative,
+                                   4=simplified balancing)
+Default Value: 3
+
+The driver can limit the amount of interrupts per second that the adapter
+will generate for incoming packets. It does this by writing a value to the
+adapter that is based on the maximum amount of interrupts that the adapter
+will generate per second.
+
+Setting InterruptThrottleRate to a value greater or equal to 100
+will program the adapter to send out a maximum of that many interrupts
+per second, even if more packets have come in. This reduces interrupt
+load on the system and can lower CPU utilization under heavy load,
+but will increase latency as packets are not processed as quickly.
+
+The driver has two adaptive modes (setting 1 or 3) in which
+it dynamically adjusts the InterruptThrottleRate value based on the traffic
+that it receives. After determining the type of incoming traffic in the last
+timeframe, it will adjust the InterruptThrottleRate to an appropriate value
+for that traffic.
+
+The algorithm classifies the incoming traffic every interval into
+classes.  Once the class is determined, the InterruptThrottleRate value is
+adjusted to suit that traffic type the best. There are three classes defined:
+"Bulk traffic", for large amounts of packets of normal size; "Low latency",
+for small amounts of traffic and/or a significant percentage of small
+packets; and "Lowest latency", for almost completely small packets or
+minimal traffic.
+
+In dynamic conservative mode, the InterruptThrottleRate value is set to 4000
+for traffic that falls in class "Bulk traffic". If traffic falls in the "Low
+latency" or "Lowest latency" class, the InterruptThrottleRate is increased
+stepwise to 20000. This default mode is suitable for most applications.
+
+For situations where low latency is vital such as cluster or
+grid computing, the algorithm can reduce latency even more when
+InterruptThrottleRate is set to mode 1. In this mode, which operates
+the same as mode 3, the InterruptThrottleRate will be increased stepwise to
+70000 for traffic in class "Lowest latency".
+
+In simplified mode the interrupt rate is based on the ratio of Tx and
+Rx traffic.  If the bytes per second rate is approximately equal the
+interrupt rate will drop as low as 2000 interrupts per second.  If the
+traffic is mostly transmit or mostly receive, the interrupt rate could
+be as high as 8000.
+
+Setting InterruptThrottleRate to 0 turns off any interrupt moderation
+and may improve small packet latency, but is generally not suitable
+for bulk throughput traffic.
+
+NOTE:  InterruptThrottleRate takes precedence over the TxAbsIntDelay and
+       RxAbsIntDelay parameters.  In other words, minimizing the receive
+       and/or transmit absolute delays does not force the controller to
+       generate more interrupts than what the Interrupt Throttle Rate
+       allows.
+
+NOTE:  When e1000e is loaded with default settings and multiple adapters
+       are in use simultaneously, the CPU utilization may increase non-
+       linearly.  In order to limit the CPU utilization without impacting
+       the overall throughput, we recommend that you load the driver as
+       follows:
+
+           modprobe e1000e InterruptThrottleRate=3000,3000,3000
+
+       This sets the InterruptThrottleRate to 3000 interrupts/sec for
+       the first, second, and third instances of the driver.  The range
+       of 2000 to 3000 interrupts per second works on a majority of
+       systems and is a good starting point, but the optimal value will
+       be platform-specific.  If CPU utilization is not a concern, use
+       RX_POLLING (NAPI) and default driver settings.
+
+RxIntDelay
+----------
+Valid Range:   0-65535 (0=off)
+Default Value: 0
+
+This value delays the generation of receive interrupts in units of 1.024
+microseconds.  Receive interrupt reduction can improve CPU efficiency if
+properly tuned for specific network traffic.  Increasing this value adds
+extra latency to frame reception and can end up decreasing the throughput
+of TCP traffic.  If the system is reporting dropped receives, this value
+may be set too high, causing the driver to run out of available receive
+descriptors.
+
+CAUTION:  When setting RxIntDelay to a value other than 0, adapters may
+          hang (stop transmitting) under certain network conditions.  If
+          this occurs a NETDEV WATCHDOG message is logged in the system
+          event log.  In addition, the controller is automatically reset,
+          restoring the network connection.  To eliminate the potential
+          for the hang ensure that RxIntDelay is set to 0.
+
+RxAbsIntDelay
+-------------
+Valid Range:   0-65535 (0=off)
+Default Value: 8
+
+This value, in units of 1.024 microseconds, limits the delay in which a
+receive interrupt is generated.  Useful only if RxIntDelay is non-zero,
+this value ensures that an interrupt is generated after the initial
+packet is received within the set amount of time.  Proper tuning,
+along with RxIntDelay, may improve traffic throughput in specific network
+conditions.
+
+TxIntDelay
+----------
+Valid Range:   0-65535 (0=off)
+Default Value: 8
+
+This value delays the generation of transmit interrupts in units of
+1.024 microseconds.  Transmit interrupt reduction can improve CPU
+efficiency if properly tuned for specific network traffic.  If the
+system is reporting dropped transmits, this value may be set too high
+causing the driver to run out of available transmit descriptors.
+
+TxAbsIntDelay
+-------------
+Valid Range:   0-65535 (0=off)
+Default Value: 32
+
+This value, in units of 1.024 microseconds, limits the delay in which a
+transmit interrupt is generated.  Useful only if TxIntDelay is non-zero,
+this value ensures that an interrupt is generated after the initial
+packet is sent on the wire within the set amount of time.  Proper tuning,
+along with TxIntDelay, may improve traffic throughput in specific
+network conditions.
+
+Copybreak
+---------
+Valid Range:   0-xxxxxxx (0=off)
+Default Value: 256
+
+Driver copies all packets below or equaling this size to a fresh Rx
+buffer before handing it up the stack.
+
+This parameter is different than other parameters, in that it is a
+single (not 1,1,1 etc.) parameter applied to all driver instances and
+it is also available during runtime at
+/sys/module/e1000e/parameters/copybreak
+
+SmartPowerDownEnable
+--------------------
+Valid Range: 0-1
+Default Value:  0 (disabled)
+
+Allows PHY to turn off in lower power states. The user can set this parameter
+in supported chipsets.
+
+KumeranLockLoss
+---------------
+Valid Range: 0-1
+Default Value: 1 (enabled)
+
+This workaround skips resetting the PHY at shutdown for the initial
+silicon releases of ICH8 systems.
+
+IntMode
+-------
+Valid Range: 0-2 (0=legacy, 1=MSI, 2=MSI-X)
+Default Value: 2
+
+Allows changing the interrupt mode at module load time, without requiring a
+recompile. If the driver load fails to enable a specific interrupt mode, the
+driver will try other interrupt modes, from least to most compatible.  The
+interrupt order is MSI-X, MSI, Legacy.  If specifying MSI (IntMode=1)
+interrupts, only MSI and Legacy will be attempted.
+
+CrcStripping
+------------
+Valid Range: 0-1
+Default Value: 1 (enabled)
+
+Strip the CRC from received packets before sending up the network stack.  If
+you have a machine with a BMC enabled but cannot receive IPMI traffic after
+loading or enabling the driver, try disabling this feature.
+
+WriteProtectNVM
+---------------
+Valid Range: 0-1
+Default Value: 1 (enabled)
+
+Set the hardware to ignore all write/erase cycles to the GbE region in the
+ICHx NVM (non-volatile memory).  This feature can be disabled by the
+WriteProtectNVM module parameter (enabled by default) only after a hardware
+reset, but the machine must be power cycled before trying to enable writes.
+
+Note: the kernel boot option iomem=relaxed may need to be set if the kernel
+config option CONFIG_STRICT_DEVMEM=y, if the root user wants to write the
+NVM from user space via ethtool.
+
+Additional Configurations
+=========================
+
+  Jumbo Frames
+  ------------
+  Jumbo Frames support is enabled by changing the MTU to a value larger than
+  the default of 1500.  Use the ifconfig command to increase the MTU size.
+  For example:
+
+       ifconfig eth<x> mtu 9000 up
+
+  This setting is not saved across reboots.
+
+  Notes:
+
+  - The maximum MTU setting for Jumbo Frames is 9216.  This value coincides
+    with the maximum Jumbo Frames size of 9234 bytes.
+
+  - Using Jumbo Frames at 10 or 100 Mbps is not supported and may result in
+    poor performance or loss of link.
+
+  - Some adapters limit Jumbo Frames sized packets to a maximum of
+    4096 bytes and some adapters do not support Jumbo Frames.
+
+
+  Ethtool
+  -------
+  The driver utilizes the ethtool interface for driver configuration and
+  diagnostics, as well as displaying statistical information.  We
+  strongly recommend downloading the latest version of Ethtool at:
+
+  http://sourceforge.net/projects/gkernel.
+
+  Speed and Duplex
+  ----------------
+  Speed and Duplex are configured through the Ethtool* utility. For
+  instructions,  refer to the Ethtool man page.
+
+  Enabling Wake on LAN* (WoL)
+  ---------------------------
+  WoL is configured through the Ethtool* utility. For instructions on
+  enabling WoL with Ethtool, refer to the Ethtool man page.
+
+  WoL will be enabled on the system during the next shut down or reboot.
+  For this driver version, in order to enable WoL, the e1000e driver must be
+  loaded when shutting down or rebooting the system.
+
+  In most cases Wake On LAN is only supported on port A for multiple port
+  adapters. To verify if a port supports Wake on LAN run ethtool eth<X>.
+
+
+Support
+=======
+
+For general information, go to the Intel support website at:
+
+    www.intel.com/support/
+
+or the Intel Wired Networking project hosted by Sourceforge at:
+
+    http://sourceforge.net/projects/e1000
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related
+to the issue to e1000-devel@lists.sf.net
old mode 100755 (executable)
new mode 100644 (file)
index 19015de..21dd5d1
@@ -1,19 +1,16 @@
 Linux* Base Driver for Intel(R) Network Connection
 ==================================================
 
-November 24, 2009
+Intel Gigabit Linux driver.
+Copyright(c) 1999 - 2010 Intel Corporation.
 
 Contents
 ========
 
-- In This Release
 - Identifying Your Adapter
 - Known Issues/Troubleshooting
 - Support
 
-In This Release
-===============
-
 This file describes the ixgbevf Linux* Base Driver for Intel Network
 Connection.
 
@@ -33,7 +30,7 @@ Identifying Your Adapter
 For more information on how to identify your adapter, go to the Adapter &
 Driver ID Guide at:
 
-    http://support.intel.com/support/network/sb/CS-008441.htm
+    http://support.intel.com/support/go/network/adapter/idguide.htm
 
 Known Issues/Troubleshooting
 ============================
@@ -57,34 +54,3 @@ or the Intel Wired Networking project hosted by Sourceforge at:
 If an issue is identified with the released source code on the supported
 kernel with a supported adapter, email the specific information related
 to the issue to e1000-devel@lists.sf.net
-
-License
-=======
-
-Intel 10 Gigabit Linux driver.
-Copyright(c) 1999 - 2009 Intel Corporation.
-
-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.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-The full GNU General Public License is included in this distribution in
-the file called "COPYING".
-
-Trademarks
-==========
-
-Intel, Itanium, and Pentium are trademarks or registered trademarks of
-Intel Corporation or its subsidiaries in the United States and other
-countries.
-
-* Other names and brands may be claimed as the property of others.
index 9363e056188ac87282c2477e25df2eebe6e837fa..8ed17587a74bdc006b2d2922b5709f0e16ec08ad 100644 (file)
@@ -13,7 +13,7 @@ regulators (where voltage output is controllable) and current sinks (where
 current limit is controllable).
 
 (C) 2008  Wolfson Microelectronics PLC.
-Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+Author: Liam Girdwood <lrg@slimlogic.co.uk>
 
 
 Nomenclature
index ccd951fa94eeda42a5a50c854b6b92e512fe6724..cc96ee2666f2e5f10f13b83b1fab72bcf8e18924 100644 (file)
@@ -478,7 +478,7 @@ static void prepare_hwpoison_fd(void)
        }
 
        if (opt_unpoison && !hwpoison_forget_fd) {
-               sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs);
+               sprintf(buf, "%s/unpoison-pfn", hwpoison_debug_fs);
                hwpoison_forget_fd = checked_open(buf, O_WRONLY);
        }
 }
diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt
new file mode 100644 (file)
index 0000000..e4498a2
--- /dev/null
@@ -0,0 +1,380 @@
+
+Concurrency Managed Workqueue (cmwq)
+
+September, 2010                Tejun Heo <tj@kernel.org>
+                       Florian Mickler <florian@mickler.org>
+
+CONTENTS
+
+1. Introduction
+2. Why cmwq?
+3. The Design
+4. Application Programming Interface (API)
+5. Example Execution Scenarios
+6. Guidelines
+
+
+1. Introduction
+
+There are many cases where an asynchronous process execution context
+is needed and the workqueue (wq) API is the most commonly used
+mechanism for such cases.
+
+When such an asynchronous execution context is needed, a work item
+describing which function to execute is put on a queue.  An
+independent thread serves as the asynchronous execution context.  The
+queue is called workqueue and the thread is called worker.
+
+While there are work items on the workqueue the worker executes the
+functions associated with the work items one after the other.  When
+there is no work item left on the workqueue the worker becomes idle.
+When a new work item gets queued, the worker begins executing again.
+
+
+2. Why cmwq?
+
+In the original wq implementation, a multi threaded (MT) wq had one
+worker thread per CPU and a single threaded (ST) wq had one worker
+thread system-wide.  A single MT wq needed to keep around the same
+number of workers as the number of CPUs.  The kernel grew a lot of MT
+wq users over the years and with the number of CPU cores continuously
+rising, some systems saturated the default 32k PID space just booting
+up.
+
+Although MT wq wasted a lot of resource, the level of concurrency
+provided was unsatisfactory.  The limitation was common to both ST and
+MT wq albeit less severe on MT.  Each wq maintained its own separate
+worker pool.  A MT wq could provide only one execution context per CPU
+while a ST wq one for the whole system.  Work items had to compete for
+those very limited execution contexts leading to various problems
+including proneness to deadlocks around the single execution context.
+
+The tension between the provided level of concurrency and resource
+usage also forced its users to make unnecessary tradeoffs like libata
+choosing to use ST wq for polling PIOs and accepting an unnecessary
+limitation that no two polling PIOs can progress at the same time.  As
+MT wq don't provide much better concurrency, users which require
+higher level of concurrency, like async or fscache, had to implement
+their own thread pool.
+
+Concurrency Managed Workqueue (cmwq) is a reimplementation of wq with
+focus on the following goals.
+
+* Maintain compatibility with the original workqueue API.
+
+* Use per-CPU unified worker pools shared by all wq to provide
+  flexible level of concurrency on demand without wasting a lot of
+  resource.
+
+* Automatically regulate worker pool and level of concurrency so that
+  the API users don't need to worry about such details.
+
+
+3. The Design
+
+In order to ease the asynchronous execution of functions a new
+abstraction, the work item, is introduced.
+
+A work item is a simple struct that holds a pointer to the function
+that is to be executed asynchronously.  Whenever a driver or subsystem
+wants a function to be executed asynchronously it has to set up a work
+item pointing to that function and queue that work item on a
+workqueue.
+
+Special purpose threads, called worker threads, execute the functions
+off of the queue, one after the other.  If no work is queued, the
+worker threads become idle.  These worker threads are managed in so
+called thread-pools.
+
+The cmwq design differentiates between the user-facing workqueues that
+subsystems and drivers queue work items on and the backend mechanism
+which manages thread-pool and processes the queued work items.
+
+The backend is called gcwq.  There is one gcwq for each possible CPU
+and one gcwq to serve work items queued on unbound workqueues.
+
+Subsystems and drivers can create and queue work items through special
+workqueue API functions as they see fit. They can influence some
+aspects of the way the work items are executed by setting flags on the
+workqueue they are putting the work item on. These flags include
+things like CPU locality, reentrancy, concurrency limits and more. To
+get a detailed overview refer to the API description of
+alloc_workqueue() below.
+
+When a work item is queued to a workqueue, the target gcwq is
+determined according to the queue parameters and workqueue attributes
+and appended on the shared worklist of the gcwq.  For example, unless
+specifically overridden, a work item of a bound workqueue will be
+queued on the worklist of exactly that gcwq that is associated to the
+CPU the issuer is running on.
+
+For any worker pool implementation, managing the concurrency level
+(how many execution contexts are active) is an important issue.  cmwq
+tries to keep the concurrency at a minimal but sufficient level.
+Minimal to save resources and sufficient in that the system is used at
+its full capacity.
+
+Each gcwq bound to an actual CPU implements concurrency management by
+hooking into the scheduler.  The gcwq is notified whenever an active
+worker wakes up or sleeps and keeps track of the number of the
+currently runnable workers.  Generally, work items are not expected to
+hog a CPU and consume many cycles.  That means maintaining just enough
+concurrency to prevent work processing from stalling should be
+optimal.  As long as there are one or more runnable workers on the
+CPU, the gcwq doesn't start execution of a new work, but, when the
+last running worker goes to sleep, it immediately schedules a new
+worker so that the CPU doesn't sit idle while there are pending work
+items.  This allows using a minimal number of workers without losing
+execution bandwidth.
+
+Keeping idle workers around doesn't cost other than the memory space
+for kthreads, so cmwq holds onto idle ones for a while before killing
+them.
+
+For an unbound wq, the above concurrency management doesn't apply and
+the gcwq for the pseudo unbound CPU tries to start executing all work
+items as soon as possible.  The responsibility of regulating
+concurrency level is on the users.  There is also a flag to mark a
+bound wq to ignore the concurrency management.  Please refer to the
+API section for details.
+
+Forward progress guarantee relies on that workers can be created when
+more execution contexts are necessary, which in turn is guaranteed
+through the use of rescue workers.  All work items which might be used
+on code paths that handle memory reclaim are required to be queued on
+wq's that have a rescue-worker reserved for execution under memory
+pressure.  Else it is possible that the thread-pool deadlocks waiting
+for execution contexts to free up.
+
+
+4. Application Programming Interface (API)
+
+alloc_workqueue() allocates a wq.  The original create_*workqueue()
+functions are deprecated and scheduled for removal.  alloc_workqueue()
+takes three arguments - @name, @flags and @max_active.  @name is the
+name of the wq and also used as the name of the rescuer thread if
+there is one.
+
+A wq no longer manages execution resources but serves as a domain for
+forward progress guarantee, flush and work item attributes.  @flags
+and @max_active control how work items are assigned execution
+resources, scheduled and executed.
+
+@flags:
+
+  WQ_NON_REENTRANT
+
+       By default, a wq guarantees non-reentrance only on the same
+       CPU.  A work item may not be executed concurrently on the same
+       CPU by multiple workers but is allowed to be executed
+       concurrently on multiple CPUs.  This flag makes sure
+       non-reentrance is enforced across all CPUs.  Work items queued
+       to a non-reentrant wq are guaranteed to be executed by at most
+       one worker system-wide at any given time.
+
+  WQ_UNBOUND
+
+       Work items queued to an unbound wq are served by a special
+       gcwq which hosts workers which are not bound to any specific
+       CPU.  This makes the wq behave as a simple execution context
+       provider without concurrency management.  The unbound gcwq
+       tries to start execution of work items as soon as possible.
+       Unbound wq sacrifices locality but is useful for the following
+       cases.
+
+       * Wide fluctuation in the concurrency level requirement is
+         expected and using bound wq may end up creating large number
+         of mostly unused workers across different CPUs as the issuer
+         hops through different CPUs.
+
+       * Long running CPU intensive workloads which can be better
+         managed by the system scheduler.
+
+  WQ_FREEZEABLE
+
+       A freezeable wq participates in the freeze phase of the system
+       suspend operations.  Work items on the wq are drained and no
+       new work item starts execution until thawed.
+
+  WQ_RESCUER
+
+       All wq which might be used in the memory reclaim paths _MUST_
+       have this flag set.  This reserves one worker exclusively for
+       the execution of this wq under memory pressure.
+
+  WQ_HIGHPRI
+
+       Work items of a highpri wq are queued at the head of the
+       worklist of the target gcwq and start execution regardless of
+       the current concurrency level.  In other words, highpri work
+       items will always start execution as soon as execution
+       resource is available.
+
+       Ordering among highpri work items is preserved - a highpri
+       work item queued after another highpri work item will start
+       execution after the earlier highpri work item starts.
+
+       Although highpri work items are not held back by other
+       runnable work items, they still contribute to the concurrency
+       level.  Highpri work items in runnable state will prevent
+       non-highpri work items from starting execution.
+
+       This flag is meaningless for unbound wq.
+
+  WQ_CPU_INTENSIVE
+
+       Work items of a CPU intensive wq do not contribute to the
+       concurrency level.  In other words, runnable CPU intensive
+       work items will not prevent other work items from starting
+       execution.  This is useful for bound work items which are
+       expected to hog CPU cycles so that their execution is
+       regulated by the system scheduler.
+
+       Although CPU intensive work items don't contribute to the
+       concurrency level, start of their executions is still
+       regulated by the concurrency management and runnable
+       non-CPU-intensive work items can delay execution of CPU
+       intensive work items.
+
+       This flag is meaningless for unbound wq.
+
+  WQ_HIGHPRI | WQ_CPU_INTENSIVE
+
+       This combination makes the wq avoid interaction with
+       concurrency management completely and behave as a simple
+       per-CPU execution context provider.  Work items queued on a
+       highpri CPU-intensive wq start execution as soon as resources
+       are available and don't affect execution of other work items.
+
+@max_active:
+
+@max_active determines the maximum number of execution contexts per
+CPU which can be assigned to the work items of a wq.  For example,
+with @max_active of 16, at most 16 work items of the wq can be
+executing at the same time per CPU.
+
+Currently, for a bound wq, the maximum limit for @max_active is 512
+and the default value used when 0 is specified is 256.  For an unbound
+wq, the limit is higher of 512 and 4 * num_possible_cpus().  These
+values are chosen sufficiently high such that they are not the
+limiting factor while providing protection in runaway cases.
+
+The number of active work items of a wq is usually regulated by the
+users of the wq, more specifically, by how many work items the users
+may queue at the same time.  Unless there is a specific need for
+throttling the number of active work items, specifying '0' is
+recommended.
+
+Some users depend on the strict execution ordering of ST wq.  The
+combination of @max_active of 1 and WQ_UNBOUND is used to achieve this
+behavior.  Work items on such wq are always queued to the unbound gcwq
+and only one work item can be active at any given time thus achieving
+the same ordering property as ST wq.
+
+
+5. Example Execution Scenarios
+
+The following example execution scenarios try to illustrate how cmwq
+behave under different configurations.
+
+ Work items w0, w1, w2 are queued to a bound wq q0 on the same CPU.
+ w0 burns CPU for 5ms then sleeps for 10ms then burns CPU for 5ms
+ again before finishing.  w1 and w2 burn CPU for 5ms then sleep for
+ 10ms.
+
+Ignoring all other tasks, works and processing overhead, and assuming
+simple FIFO scheduling, the following is one highly simplified version
+of possible sequences of events with the original wq.
+
+ TIME IN MSECS EVENT
+ 0             w0 starts and burns CPU
+ 5             w0 sleeps
+ 15            w0 wakes up and burns CPU
+ 20            w0 finishes
+ 20            w1 starts and burns CPU
+ 25            w1 sleeps
+ 35            w1 wakes up and finishes
+ 35            w2 starts and burns CPU
+ 40            w2 sleeps
+ 50            w2 wakes up and finishes
+
+And with cmwq with @max_active >= 3,
+
+ TIME IN MSECS EVENT
+ 0             w0 starts and burns CPU
+ 5             w0 sleeps
+ 5             w1 starts and burns CPU
+ 10            w1 sleeps
+ 10            w2 starts and burns CPU
+ 15            w2 sleeps
+ 15            w0 wakes up and burns CPU
+ 20            w0 finishes
+ 20            w1 wakes up and finishes
+ 25            w2 wakes up and finishes
+
+If @max_active == 2,
+
+ TIME IN MSECS EVENT
+ 0             w0 starts and burns CPU
+ 5             w0 sleeps
+ 5             w1 starts and burns CPU
+ 10            w1 sleeps
+ 15            w0 wakes up and burns CPU
+ 20            w0 finishes
+ 20            w1 wakes up and finishes
+ 20            w2 starts and burns CPU
+ 25            w2 sleeps
+ 35            w2 wakes up and finishes
+
+Now, let's assume w1 and w2 are queued to a different wq q1 which has
+WQ_HIGHPRI set,
+
+ TIME IN MSECS EVENT
+ 0             w1 and w2 start and burn CPU
+ 5             w1 sleeps
+ 10            w2 sleeps
+ 10            w0 starts and burns CPU
+ 15            w0 sleeps
+ 15            w1 wakes up and finishes
+ 20            w2 wakes up and finishes
+ 25            w0 wakes up and burns CPU
+ 30            w0 finishes
+
+If q1 has WQ_CPU_INTENSIVE set,
+
+ TIME IN MSECS EVENT
+ 0             w0 starts and burns CPU
+ 5             w0 sleeps
+ 5             w1 and w2 start and burn CPU
+ 10            w1 sleeps
+ 15            w2 sleeps
+ 15            w0 wakes up and burns CPU
+ 20            w0 finishes
+ 20            w1 wakes up and finishes
+ 25            w2 wakes up and finishes
+
+
+6. Guidelines
+
+* Do not forget to use WQ_RESCUER if a wq may process work items which
+  are used during memory reclaim.  Each wq with WQ_RESCUER set has one
+  rescuer thread reserved for it.  If there is dependency among
+  multiple work items used during memory reclaim, they should be
+  queued to separate wq each with WQ_RESCUER.
+
+* Unless strict ordering is required, there is no need to use ST wq.
+
+* Unless there is a specific need, using 0 for @max_active is
+  recommended.  In most use cases, concurrency level usually stays
+  well under the default limit.
+
+* A wq serves as a domain for forward progress guarantee (WQ_RESCUER),
+  flush and work item attributes.  Work items which are not involved
+  in memory reclaim and don't need to be flushed as a part of a group
+  of work items, and don't require any special attribute, can use one
+  of the system wq.  There is no difference in execution
+  characteristics between using a dedicated wq and a system wq.
+
+* Unless work items are expected to consume a huge amount of CPU
+  cycles, using a bound wq is usually beneficial due to the increased
+  level of locality in wq operations and work item execution.
index e7c528ff1013048cd4c6dadc0dbfc23f11204685..8395f2eeb7822628ad0649754f6952446a6360c7 100644 (file)
@@ -962,6 +962,23 @@ W: http://www.fluff.org/ben/linux/
 S:     Maintained
 F:     arch/arm/mach-s3c6410/
 
+ARM/S5P ARM ARCHITECTURES
+M:     Kukjin Kim <kgene.kim@samsung.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-s5p*/
+
+ARM/SAMSUNG S5P SERIES FIMC SUPPORT
+M:     Kyungmin Park <kyungmin.park@samsung.com>
+M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
+L:     linux-arm-kernel@lists.infradead.org
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     arch/arm/plat-s5p/dev-fimc*
+F:     arch/arm/plat-samsung/include/plat/*fimc*
+F:     drivers/media/video/s5p-fimc/
+
 ARM/SHMOBILE ARM ARCHITECTURE
 M:     Paul Mundt <lethal@linux-sh.org>
 M:     Magnus Damm <magnus.damm@gmail.com>
@@ -973,11 +990,23 @@ S:        Supported
 F:     arch/arm/mach-shmobile/
 F:     drivers/sh/
 
+ARM/TELECHIPS ARM ARCHITECTURE
+M:     "Hans J. Koch" <hjk@linutronix.de>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/plat-tcc/
+F:     arch/arm/mach-tcc8k/
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/TETON BGA MACHINE SUPPORT
+M:     Mark F. Brown <mark.brown314@gmail.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+
 ARM/THECUS N2100 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1135,7 +1164,7 @@ ATLX ETHERNET DRIVERS
 M:     Jay Cliburn <jcliburn@gmail.com>
 M:     Chris Snook <chris.snook@gmail.com>
 M:     Jie Yang <jie.yang@atheros.com>
-L:     atl1-devel@lists.sourceforge.net
+L:     netdev@vger.kernel.org
 W:     http://sourceforge.net/projects/atl1
 W:     http://atl1.sourceforge.net
 S:     Maintained
@@ -1220,7 +1249,7 @@ F:        drivers/auxdisplay/
 F:     include/linux/cfag12864b.h
 
 AVR32 ARCHITECTURE
-M:     Haavard Skinnemoen <hskinnemoen@atmel.com>
+M:     Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
 W:     http://www.atmel.com/products/AVR32/
 W:     http://avr32linux.org/
 W:     http://avrfreaks.net/
@@ -1228,7 +1257,7 @@ S:        Supported
 F:     arch/avr32/
 
 AVR32/AT32AP MACHINE SUPPORT
-M:     Haavard Skinnemoen <hskinnemoen@atmel.com>
+M:     Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
 S:     Supported
 F:     arch/avr32/mach-at32ap/
 
@@ -2199,6 +2228,12 @@ W:       http://acpi4asus.sf.net
 S:     Maintained
 F:     drivers/platform/x86/eeepc-laptop.c
 
+EFIFB FRAMEBUFFER DRIVER
+L:     linux-fbdev@vger.kernel.org
+M:     Peter Jones <pjones@redhat.com>
+S:     Maintained
+F:     drivers/video/efifb.c
+
 EFS FILESYSTEM
 W:     http://aeschi.ch.eu.org/efs/
 S:     Orphan
@@ -2522,7 +2557,7 @@ S:        Supported
 F:     drivers/scsi/gdt*
 
 GENERIC GPIO I2C DRIVER
-M:     Haavard Skinnemoen <hskinnemoen@atmel.com>
+M:     Haavard Skinnemoen <hskinnemoen@gmail.com>
 S:     Supported
 F:     drivers/i2c/busses/i2c-gpio.c
 F:     include/linux/i2c-gpio.h
@@ -2657,9 +2692,14 @@ S:       Maintained
 F:     drivers/media/video/gspca/
 
 HARDWARE MONITORING
+M:     Jean Delvare <khali@linux-fr.org>
+M:     Guenter Roeck <guenter.roeck@ericsson.com>
 L:     lm-sensors@lm-sensors.org
 W:     http://www.lm-sensors.org/
-S:     Orphan
+T:     quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/
+T:     quilt kernel.org/pub/linux/kernel/people/groeck/linux-staging/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
+S:     Maintained
 F:     Documentation/hwmon/
 F:     drivers/hwmon/
 F:     include/linux/hwmon*.h
@@ -3045,16 +3085,27 @@ L:      netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ixp2000/
 
-INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe)
+INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
 M:     Jeff Kirsher <jeffrey.t.kirsher@intel.com>
 M:     Jesse Brandeburg <jesse.brandeburg@intel.com>
 M:     Bruce Allan <bruce.w.allan@intel.com>
-M:     Alex Duyck <alexander.h.duyck@intel.com>
+M:     Carolyn Wyborny <carolyn.wyborny@intel.com>
+M:     Don Skidmore <donald.c.skidmore@intel.com>
+M:     Greg Rose <gregory.v.rose@intel.com>
 M:     PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
+M:     Alex Duyck <alexander.h.duyck@intel.com>
 M:     John Ronciak <john.ronciak@intel.com>
 L:     e1000-devel@lists.sourceforge.net
 W:     http://e1000.sourceforge.net/
 S:     Supported
+F:     Documentation/networking/e100.txt
+F:     Documentation/networking/e1000.txt
+F:     Documentation/networking/e1000e.txt
+F:     Documentation/networking/igb.txt
+F:     Documentation/networking/igbvf.txt
+F:     Documentation/networking/ixgb.txt
+F:     Documentation/networking/ixgbe.txt
+F:     Documentation/networking/ixgbevf.txt
 F:     drivers/net/e100.c
 F:     drivers/net/e1000/
 F:     drivers/net/e1000e/
@@ -3062,6 +3113,7 @@ F:        drivers/net/igb/
 F:     drivers/net/igbvf/
 F:     drivers/net/ixgb/
 F:     drivers/net/ixgbe/
+F:     drivers/net/ixgbevf/
 
 INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
 L:     linux-wireless@vger.kernel.org
@@ -3770,9 +3822,8 @@ W:        http://www.syskonnect.com
 S:     Supported
 
 MATROX FRAMEBUFFER DRIVER
-M:     Petr Vandrovec <vandrove@vc.cvut.cz>
 L:     linux-fbdev@vger.kernel.org
-S:     Maintained
+S:     Orphan
 F:     drivers/video/matrox/matroxfb_*
 F:     include/linux/matroxfb.h
 
@@ -3896,10 +3947,8 @@ F:       Documentation/serial/moxa-smartio
 F:     drivers/char/mxser.*
 
 MSI LAPTOP SUPPORT
-M:     Lennart Poettering <mzxreary@0pointer.de>
+M:     Lee, Chun-Yi <jlee@novell.com>
 L:     platform-driver-x86@vger.kernel.org
-W:     https://tango.0pointer.de/mailman/listinfo/s270-linux
-W:     http://0pointer.de/lennart/tchibo.html
 S:     Maintained
 F:     drivers/platform/x86/msi-laptop.c
 
@@ -3916,8 +3965,10 @@ S:       Supported
 F:     drivers/mfd/
 
 MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
-S:     Orphan
+M:     Chris Ball <cjb@laptop.org>
 L:     linux-mmc@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git
+S:     Maintained
 F:     drivers/mmc/
 F:     include/linux/mmc/
 
@@ -3939,7 +3990,7 @@ F:        drivers/char/isicom.c
 F:     include/linux/isicom.h
 
 MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
-M:     Felipe Balbi <felipe.balbi@nokia.com>
+M:     Felipe Balbi <balbi@ti.com>
 L:     linux-usb@vger.kernel.org
 T:     git git://gitorious.org/usb/usb.git
 S:     Maintained
@@ -3959,8 +4010,8 @@ S:        Maintained
 F:     drivers/net/natsemi.c
 
 NCP FILESYSTEM
-M:     Petr Vandrovec <vandrove@vc.cvut.cz>
-S:     Maintained
+M:     Petr Vandrovec <petr@vandrovec.name>
+S:     Odd Fixes
 F:     fs/ncpfs/
 
 NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
@@ -4237,7 +4288,7 @@ S:        Maintained
 F:     drivers/char/hw_random/omap-rng.c
 
 OMAP USB SUPPORT
-M:     Felipe Balbi <felipe.balbi@nokia.com>
+M:     Felipe Balbi <balbi@ti.com>
 M:     David Brownell <dbrownell@users.sourceforge.net>
 L:     linux-usb@vger.kernel.org
 L:     linux-omap@vger.kernel.org
@@ -4991,6 +5042,12 @@ F:       drivers/media/common/saa7146*
 F:     drivers/media/video/*7146*
 F:     include/media/*7146*
 
+SAMSUNG AUDIO (ASoC) DRIVERS
+M:     Jassi Brar <jassi.brar@samsung.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Supported
+F:     sound/soc/s3c24xx
+
 TLG2300 VIDEO4LINUX-2 DRIVER
 M:     Huang Shijie <shijie8@gmail.com>
 M:     Kang Yong <kangyong@telegent.com>
@@ -5088,8 +5145,10 @@ S:       Maintained
 F:     drivers/mmc/host/sdricoh_cs.c
 
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
-S:     Orphan
+M:     Chris Ball <cjb@laptop.org>
 L:     linux-mmc@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git
+S:     Maintained
 F:     drivers/mmc/host/sdhci.*
 
 SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
@@ -6431,8 +6490,10 @@ F:       include/linux/wm97xx.h
 WOLFSON MICROELECTRONICS DRIVERS
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
 M:     Ian Lartey <ian@opensource.wolfsonmicro.com>
+M:     Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+T:     git git://opensource.wolfsonmicro.com/linux-2.6-asoc
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
-W:     http://opensource.wolfsonmicro.com/node/8
+W:     http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
 S:     Supported
 F:     Documentation/hwmon/wm83??
 F:     drivers/leds/leds-wm83*.c
index 92ab33f16cf0a31256b754cf4f1f46fafb83d3a8..7583116e5d9a2e4cdcd33d33bc1fb9da43c2fcb4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 36
-EXTRAVERSION = -rc4
-NAME = Sheep on Meth
+EXTRAVERSION = -rc8
+NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 4877a8c8ee1697599289f35107824f95ba8daf84..fe48fc7a3ebaf85c9bf8c56391bf20d9c9b90bbf 100644 (file)
@@ -32,8 +32,9 @@ config HAVE_OPROFILE
 
 config KPROBES
        bool "Kprobes"
-       depends on KALLSYMS && MODULES
+       depends on MODULES
        depends on HAVE_KPROBES
+       select KALLSYMS
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
@@ -45,7 +46,6 @@ config OPTPROBES
        def_bool y
        depends on KPROBES && HAVE_OPTPROBES
        depends on !PREEMPT
-       select KALLSYMS_ALL
 
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
        bool
index 01d71e1c8a9eb6df57fe8bc13e1f94f634a8eaf7..012f1243b1c1a0024af9cffe0afdfc204f4dcf11 100644 (file)
@@ -43,6 +43,8 @@ extern void smp_imb(void);
 /* ??? Ought to use this in arch/alpha/kernel/signal.c too.  */
 
 #ifndef CONFIG_SMP
+#include <linux/sched.h>
+
 extern void __load_new_mm_context(struct mm_struct *);
 static inline void
 flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
index 804e5311c84188fbc14a62b7afb97bc35a232003..058937bf5a77718983126f2ab3813a023cb8c1d0 100644 (file)
 #define __NR_pwritev                   491
 #define __NR_rt_tgsigqueueinfo         492
 #define __NR_perf_event_open           493
+#define __NR_fanotify_init             494
+#define __NR_fanotify_mark             495
+#define __NR_prlimit64                 496
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS                    494
+#define NR_SYSCALLS                    497
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
 /* "Conditional" syscalls.  What we want is
 
index b45d913a51c368881b4311d1f1887566829b09a8..6d159cee5f2f43a48bc9aac8355069a3e588ef7f 100644 (file)
@@ -73,8 +73,6 @@
        ldq     $20, HAE_REG($19);      \
        stq     $21, HAE_CACHE($19);    \
        stq     $21, 0($20);            \
-       ldq     $0, 0($sp);             \
-       ldq     $1, 8($sp);             \
 99:;                                   \
        ldq     $19, 72($sp);           \
        ldq     $20, 80($sp);           \
@@ -316,19 +314,24 @@ ret_from_sys_call:
        cmovne  $26, 0, $19             /* $19 = 0 => non-restartable */
        ldq     $0, SP_OFF($sp)
        and     $0, 8, $0
-       beq     $0, restore_all
-ret_from_reschedule:
+       beq     $0, ret_to_kernel
+ret_to_user:
        /* Make sure need_resched and sigpending don't change between
                sampling and the rti.  */
        lda     $16, 7
        call_pal PAL_swpipl
        ldl     $5, TI_FLAGS($8)
        and     $5, _TIF_WORK_MASK, $2
-       bne     $5, work_pending
+       bne     $2, work_pending
 restore_all:
        RESTORE_ALL
        call_pal PAL_rti
 
+ret_to_kernel:
+       lda     $16, 7
+       call_pal PAL_swpipl
+       br restore_all
+
        .align 3
 $syscall_error:
        /*
@@ -363,7 +366,7 @@ $ret_success:
  *       $8: current.
  *      $19: The old syscall number, or zero if this is not a return
  *           from a syscall that errored and is possibly restartable.
- *      $20: Error indication.
+ *      $20: The old a3 value
  */
 
        .align  4
@@ -392,12 +395,18 @@ $work_resched:
 
 $work_notifysig:
        mov     $sp, $16
-       b     $1, do_switch_stack
+       bsr     $1, do_switch_stack
        mov     $sp, $17
        mov     $5, $18
+       mov     $19, $9         /* save old syscall number */
+       mov     $20, $10        /* save old a3 */
+       and     $5, _TIF_SIGPENDING, $2
+       cmovne  $2, 0, $9       /* we don't want double syscall restarts */
        jsr     $26, do_notify_resume
+       mov     $9, $19
+       mov     $10, $20
        bsr     $1, undo_switch_stack
-       br      restore_all
+       br      ret_to_user
 .end work_pending
 
 /*
@@ -430,6 +439,7 @@ strace:
        beq     $1, 1f
        ldq     $27, 0($2)
 1:     jsr     $26, ($27), sys_gettimeofday
+ret_from_straced:
        ldgp    $gp, 0($26)
 
        /* check return.. */
@@ -650,7 +660,7 @@ kernel_thread:
        /* We don't actually care for a3 success widgetry in the kernel.
           Not for positive errno values.  */
        stq     $0, 0($sp)              /* $0 */
-       br      restore_all
+       br      ret_to_kernel
 .end kernel_thread
 
 /*
@@ -757,11 +767,15 @@ sys_vfork:
        .ent    sys_sigreturn
 sys_sigreturn:
        .prologue 0
+       lda     $9, ret_from_straced
+       cmpult  $26, $9, $9
        mov     $sp, $17
        lda     $18, -SWITCH_STACK_SIZE($sp)
        lda     $sp, -SWITCH_STACK_SIZE($sp)
        jsr     $26, do_sigreturn
-       br      $1, undo_switch_stack
+       bne     $9, 1f
+       jsr     $26, syscall_trace
+1:     br      $1, undo_switch_stack
        br      ret_from_sys_call
 .end sys_sigreturn
 
@@ -770,46 +784,18 @@ sys_sigreturn:
        .ent    sys_rt_sigreturn
 sys_rt_sigreturn:
        .prologue 0
+       lda     $9, ret_from_straced
+       cmpult  $26, $9, $9
        mov     $sp, $17
        lda     $18, -SWITCH_STACK_SIZE($sp)
        lda     $sp, -SWITCH_STACK_SIZE($sp)
        jsr     $26, do_rt_sigreturn
-       br      $1, undo_switch_stack
+       bne     $9, 1f
+       jsr     $26, syscall_trace
+1:     br      $1, undo_switch_stack
        br      ret_from_sys_call
 .end sys_rt_sigreturn
 
-       .align  4
-       .globl  sys_sigsuspend
-       .ent    sys_sigsuspend
-sys_sigsuspend:
-       .prologue 0
-       mov     $sp, $17
-       br      $1, do_switch_stack
-       mov     $sp, $18
-       subq    $sp, 16, $sp
-       stq     $26, 0($sp)
-       jsr     $26, do_sigsuspend
-       ldq     $26, 0($sp)
-       lda     $sp, SWITCH_STACK_SIZE+16($sp)
-       ret
-.end sys_sigsuspend
-
-       .align  4
-       .globl  sys_rt_sigsuspend
-       .ent    sys_rt_sigsuspend
-sys_rt_sigsuspend:
-       .prologue 0
-       mov     $sp, $18
-       br      $1, do_switch_stack
-       mov     $sp, $19
-       subq    $sp, 16, $sp
-       stq     $26, 0($sp)
-       jsr     $26, do_rt_sigsuspend
-       ldq     $26, 0($sp)
-       lda     $sp, SWITCH_STACK_SIZE+16($sp)
-       ret
-.end sys_rt_sigsuspend
-
        .align  4
        .globl  sys_sethae
        .ent    sys_sethae
@@ -928,15 +914,6 @@ sys_execve:
        jmp     $31, do_sys_execve
 .end sys_execve
 
-       .align  4
-       .globl  osf_sigprocmask
-       .ent    osf_sigprocmask
-osf_sigprocmask:
-       .prologue 0
-       mov     $sp, $18
-       jmp     $31, sys_osf_sigprocmask
-.end osf_sigprocmask
-
        .align  4
        .globl  alpha_ni_syscall
        .ent    alpha_ni_syscall
index 8ca6345bf13167842d3c0fb60637e51e18e3db93..253cf1a87481e815ad9a724dde1fef51b5616d09 100644 (file)
@@ -90,11 +90,13 @@ static int
 ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, 
               u64 c_stat, u64 c_sts, int print)
 {
-       char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN",
-                              "MEMORY", "BCACHE", "DCACHE", 
-                              "BCACHE PROBE", "BCACHE PROBE" };
-       char *streamname[] = { "D", "I" };
-       char *bitsname[] = { "SINGLE", "DOUBLE" };
+       static const char * const sourcename[] = {
+               "UNKNOWN", "UNKNOWN", "UNKNOWN",
+               "MEMORY", "BCACHE", "DCACHE",
+               "BCACHE PROBE", "BCACHE PROBE"
+       };
+       static const char * const streamname[] = { "D", "I" };
+       static const char * const bitsname[] = { "SINGLE", "DOUBLE" };
        int status = MCHK_DISPOSITION_REPORT;
        int source = -1, stream = -1, bits = -1;
 
index 5c905aaaeccd82861ea62d9186517475f0d7019c..648ae88aeb8ae0cce7dcedbe215bf56417e5eebc 100644 (file)
@@ -589,22 +589,23 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt)
 static void
 marvel_print_pox_trans_sum(u64 trans_sum)
 {
-       char *pcix_cmd[] = { "Interrupt Acknowledge",
-                            "Special Cycle",
-                            "I/O Read",
-                            "I/O Write",
-                            "Reserved",
-                            "Reserved / Device ID Message",
-                            "Memory Read",
-                            "Memory Write",
-                            "Reserved / Alias to Memory Read Block",
-                            "Reserved / Alias to Memory Write Block",
-                            "Configuration Read",
-                            "Configuration Write",
-                            "Memory Read Multiple / Split Completion",
-                            "Dual Address Cycle",
-                            "Memory Read Line / Memory Read Block",
-                            "Memory Write and Invalidate / Memory Write Block"
+       static const char * const pcix_cmd[] = {
+               "Interrupt Acknowledge",
+               "Special Cycle",
+               "I/O Read",
+               "I/O Write",
+               "Reserved",
+               "Reserved / Device ID Message",
+               "Memory Read",
+               "Memory Write",
+               "Reserved / Alias to Memory Read Block",
+               "Reserved / Alias to Memory Write Block",
+               "Configuration Read",
+               "Configuration Write",
+               "Memory Read Multiple / Split Completion",
+               "Dual Address Cycle",
+               "Memory Read Line / Memory Read Block",
+               "Memory Write and Invalidate / Memory Write Block"
        };
 
 #define IO7__POX_TRANSUM__PCI_ADDR__S          (0)
index f7ed97ce0dfd72458dde026292b89702be518477..c3b3781a03de01045ebd270319173ae2b5d347ee 100644 (file)
@@ -75,8 +75,12 @@ titan_parse_p_serror(int which, u64 serror, int print)
        int status = MCHK_DISPOSITION_REPORT;
 
 #ifdef CONFIG_VERBOSE_MCHECK
-       char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"};
-       char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"};
+       static const char * const serror_src[] = {
+               "GPCI", "APCI", "AGP HP", "AGP LP"
+       };
+       static const char * const serror_cmd[] = {
+               "DMA Read", "DMA RMW", "SGTE Read", "Reserved"
+       };
 #endif /* CONFIG_VERBOSE_MCHECK */
 
 #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0)
@@ -140,14 +144,15 @@ titan_parse_p_perror(int which, int port, u64 perror, int print)
        int status = MCHK_DISPOSITION_REPORT;
 
 #ifdef CONFIG_VERBOSE_MCHECK
-       char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle",
-                              "I/O Read",              "I/O Write",
-                              "Reserved",              "Reserved",
-                              "Memory Read",           "Memory Write",
-                              "Reserved",              "Reserved",
-                              "Configuration Read",    "Configuration Write",
-                              "Memory Read Multiple",  "Dual Address Cycle",
-                              "Memory Read Line","Memory Write and Invalidate"
+       static const char * const perror_cmd[] = {
+               "Interrupt Acknowledge", "Special Cycle",
+               "I/O Read",             "I/O Write",
+               "Reserved",             "Reserved",
+               "Memory Read",          "Memory Write",
+               "Reserved",             "Reserved",
+               "Configuration Read",   "Configuration Write",
+               "Memory Read Multiple", "Dual Address Cycle",
+               "Memory Read Line",     "Memory Write and Invalidate"
        };
 #endif /* CONFIG_VERBOSE_MCHECK */
 
@@ -273,11 +278,11 @@ titan_parse_p_agperror(int which, u64 agperror, int print)
        int cmd, len;
        unsigned long addr;
 
-       char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)",
-                                "Write (low-priority)",
-                                "Write (high-priority)",
-                                "Reserved",            "Reserved",
-                                "Flush",               "Fence"
+       static const char * const agperror_cmd[] = {
+               "Read (low-priority)",  "Read (high-priority)",
+               "Write (low-priority)", "Write (high-priority)",
+               "Reserved",             "Reserved",
+               "Flush",                "Fence"
        };
 #endif /* CONFIG_VERBOSE_MCHECK */
 
index 5d1e6d6ce6843b136fb7810e74c86df16d86daf4..547e8b84b2f794ab546aca3b1927c80bdc1104bf 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
@@ -69,7 +68,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start,
 {
        struct mm_struct *mm;
 
-       lock_kernel();
        mm = current->mm;
        mm->end_code = bss_start + bss_len;
        mm->start_brk = bss_start + bss_len;
@@ -78,7 +76,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start,
        printk("set_program_attributes(%lx %lx %lx %lx)\n",
                text_start, text_len, bss_start, bss_len);
 #endif
-       unlock_kernel();
        return 0;
 }
 
@@ -517,7 +514,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code,
        long error;
        int __user *min_buf_size_ptr;
 
-       lock_kernel();
        switch (code) {
        case PL_SET:
                if (get_user(error, &args->set.nbytes))
@@ -547,7 +543,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code,
                error = -EOPNOTSUPP;
                break;
        };
-       unlock_kernel();
        return error;
 }
 
@@ -594,7 +589,7 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss,
 
 SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
 {
-       char *sysinfo_table[] = {
+       const char *sysinfo_table[] = {
                utsname()->sysname,
                utsname()->nodename,
                utsname()->release,
@@ -606,7 +601,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
                "dummy",        /* secure RPC domain */
        };
        unsigned long offset;
-       char *res;
+       const char *res;
        long len, err = -EINVAL;
 
        offset = command-1;
index 738fc824e2ea373f85b3ae04fb7eb1346ecacdac..b899e95f79fdb424ea9b07d31153edb0e824ac8e 100644 (file)
@@ -66,7 +66,7 @@ static int pci_mmap_resource(struct kobject *kobj,
 {
        struct pci_dev *pdev = to_pci_dev(container_of(kobj,
                                                       struct device, kobj));
-       struct resource *res = (struct resource *)attr->private;
+       struct resource *res = attr->private;
        enum pci_mmap_state mmap_type;
        struct pci_bus_region bar;
        int i;
index 842dba308eab3065510857e50312496c674c1097..3ec35066f1dc51c09367c32bea106453a109953d 100644 (file)
@@ -356,7 +356,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti)
        dest[27] = pt->r27;
        dest[28] = pt->r28;
        dest[29] = pt->gp;
-       dest[30] = rdusp();
+       dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp;
        dest[31] = pt->pc;
 
        /* Once upon a time this was the PS value.  Which is stupid
index 0932dbb1ef8eff444943645e15b0802b1d4cf5d5..6f7feb5db27193f33e24e962e4d1be257d8464ef 100644 (file)
@@ -41,46 +41,20 @@ static void do_signal(struct pt_regs *, struct switch_stack *,
 /*
  * The OSF/1 sigprocmask calling sequence is different from the
  * C sigprocmask() sequence..
- *
- * how:
- * 1 - SIG_BLOCK
- * 2 - SIG_UNBLOCK
- * 3 - SIG_SETMASK
- *
- * We change the range to -1 .. 1 in order to let gcc easily
- * use the conditional move instructions.
- *
- * Note that we don't need to acquire the kernel lock for SMP
- * operation, as all of this is local to this thread.
  */
-SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask,
-               struct pt_regs *, regs)
+SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
 {
-       unsigned long oldmask = -EINVAL;
-
-       if ((unsigned long)how-1 <= 2) {
-               long sign = how-2;              /* -1 .. 1 */
-               unsigned long block, unblock;
-
-               newmask &= _BLOCKABLE;
-               spin_lock_irq(&current->sighand->siglock);
-               oldmask = current->blocked.sig[0];
-
-               unblock = oldmask & ~newmask;
-               block = oldmask | newmask;
-               if (!sign)
-                       block = unblock;
-               if (sign <= 0)
-                       newmask = block;
-               if (_NSIG_WORDS > 1 && sign > 0)
-                       sigemptyset(&current->blocked);
-               current->blocked.sig[0] = newmask;
-               recalc_sigpending();
-               spin_unlock_irq(&current->sighand->siglock);
-
-               regs->r0 = 0;           /* special no error return */
+       sigset_t oldmask;
+       sigset_t mask;
+       unsigned long res;
+
+       siginitset(&mask, newmask & _BLOCKABLE);
+       res = sigprocmask(how, &mask, &oldmask);
+       if (!res) {
+               force_successful_syscall_return();
+               res = oldmask.sig[0];
        }
-       return oldmask;
+       return res;
 }
 
 SYSCALL_DEFINE3(osf_sigaction, int, sig,
@@ -94,9 +68,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig,
                old_sigset_t mask;
                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-                   __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+                   __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+                   __get_user(mask, &act->sa_mask))
                        return -EFAULT;
-               __get_user(mask, &act->sa_mask);
                siginitset(&new_ka.sa.sa_mask, mask);
                new_ka.ka_restorer = NULL;
        }
@@ -106,9 +80,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig,
        if (!ret && oact) {
                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+                   __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+                   __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
                        return -EFAULT;
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
        }
 
        return ret;
@@ -144,8 +118,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-asmlinkage int
-do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
+SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
 {
        mask &= _BLOCKABLE;
        spin_lock_irq(&current->sighand->siglock);
@@ -154,41 +127,6 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       /* Indicate EINTR on return from any possible signal handler,
-          which will not come back through here, but via sigreturn.  */
-       regs->r0 = EINTR;
-       regs->r19 = 1;
-
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       set_thread_flag(TIF_RESTORE_SIGMASK);
-       return -ERESTARTNOHAND;
-}
-
-asmlinkage int
-do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
-                struct pt_regs *regs, struct switch_stack *sw)
-{
-       sigset_t set;
-
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
-       if (copy_from_user(&set, uset, sizeof(set)))
-               return -EFAULT;
-
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       /* Indicate EINTR on return from any possible signal handler,
-          which will not come back through here, but via sigreturn.  */
-       regs->r0 = EINTR;
-       regs->r19 = 1;
-
        current->state = TASK_INTERRUPTIBLE;
        schedule();
        set_thread_flag(TIF_RESTORE_SIGMASK);
@@ -239,6 +177,8 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        unsigned long usp;
        long i, err = __get_user(regs->pc, &sc->sc_pc);
 
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
        sw->r26 = (unsigned long) ret_from_sys_call;
 
        err |= __get_user(regs->r0, sc->sc_regs+0);
@@ -591,7 +531,6 @@ syscall_restart(unsigned long r0, unsigned long r19,
                regs->pc -= 4;
                break;
        case ERESTART_RESTARTBLOCK:
-               current_thread_info()->restart_block.fn = do_no_restart_syscall;
                regs->r0 = EINTR;
                break;
        }
index 4afc1a1e2e5a055ccda3d11a7d2f1b96c3670235..f0df3fbd84025eff9bf304fd179bed8785e865dc 100644 (file)
@@ -87,7 +87,7 @@ static int srm_env_proc_show(struct seq_file *m, void *v)
        srm_env_t       *entry;
        char            *page;
 
-       entry = (srm_env_t *)m->private;
+       entry = m->private;
        page = (char *)__get_free_page(GFP_USER);
        if (!page)
                return -ENOMEM;
index 09acb786e72b0d665d3aa9e38346148adbdb08c5..a6a1de9db16fd6e57d96c4e0b1f76db70f27147f 100644 (file)
@@ -58,7 +58,7 @@ sys_call_table:
        .quad sys_open                          /* 45 */
        .quad alpha_ni_syscall
        .quad sys_getxgid
-       .quad osf_sigprocmask
+       .quad sys_osf_sigprocmask
        .quad alpha_ni_syscall
        .quad alpha_ni_syscall                  /* 50 */
        .quad sys_acct
@@ -512,6 +512,9 @@ sys_call_table:
        .quad sys_pwritev
        .quad sys_rt_tgsigqueueinfo
        .quad sys_perf_event_open
+       .quad sys_fanotify_init
+       .quad sys_fanotify_mark                         /* 495 */
+       .quad sys_prlimit64
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index eacceb26d9c8aa8bd250b409e821c277a9b51c73..396af1799ea44e3a80bd758226f31f0c3bced799 100644 (file)
@@ -191,16 +191,16 @@ irqreturn_t timer_interrupt(int irq, void *dev)
 
        write_sequnlock(&xtime_lock);
 
-#ifndef CONFIG_SMP
-       while (nticks--)
-               update_process_times(user_mode(get_irq_regs()));
-#endif
-
        if (test_perf_event_pending()) {
                clear_perf_event_pending();
                perf_event_do_pending();
        }
 
+#ifndef CONFIG_SMP
+       while (nticks--)
+               update_process_times(user_mode(get_irq_regs()));
+#endif
+
        return IRQ_HANDLED;
 }
 
index b14f015008ada5e90d580b0589d4ff5144a1602e..0414e021a91c3ba8756674dea873f0dabd6c0abd 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/delay.h>
-#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
@@ -623,7 +622,6 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
                return;
        }
 
-       lock_kernel();
        printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
                pc, va, opcode, reg);
        do_exit(SIGSEGV);
@@ -646,7 +644,6 @@ got_exception:
         * Yikes!  No one to forward the exception to.
         * Since the registers are in a weird format, dump them ourselves.
         */
-       lock_kernel();
 
        printk("%s(%d): unhandled unaligned exception\n",
               current->comm, task_pid_nr(current));
index 553b7cf17bfb0bac057eaedf0402a0bca2aa47e8..b27f8abf163c5bc9aa2f87df4e290f47eb6e4ebd 100644 (file)
@@ -271,7 +271,6 @@ config ARCH_AT91
        bool "Atmel AT91"
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
-       select ARCH_USES_GETTIMEOFFSET
        help
          This enables support for systems based on the Atmel AT91RM9200,
          AT91SAM9 and AT91CAP9 processors.
@@ -511,6 +510,7 @@ config ARCH_MMP
        select GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        select PLAT_PXA
+       select SPARSE_IRQ
        help
          Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
 
@@ -588,6 +588,7 @@ config ARCH_PXA
        select GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        select PLAT_PXA
+       select SPARSE_IRQ
        help
          Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
 
@@ -679,8 +680,8 @@ config ARCH_S3C64XX
        help
          Samsung S3C64XX series based systems
 
-config ARCH_S5P6440
-       bool "Samsung S5P6440"
+config ARCH_S5P64X0
+       bool "Samsung S5P6440 S5P6450"
        select CPU_V6
        select GENERIC_GPIO
        select HAVE_CLK
@@ -689,7 +690,8 @@ config ARCH_S5P6440
        select HAVE_S3C2410_I2C
        select HAVE_S3C_RTC
        help
-         Samsung S5P6440 CPU based systems
+         Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
+         SMDK6450.
 
 config ARCH_S5P6442
        bool "Samsung S5P6442"
@@ -748,6 +750,15 @@ config ARCH_SHARK
          Support for the StrongARM based Digital DNARD machine, also known
          as "Shark" (<http://www.shark-linux.de/shark.html>).
 
+config ARCH_TCC_926
+       bool "Telechips TCC ARM926-based systems"
+       select CPU_ARM926T
+       select HAVE_CLK
+       select COMMON_CLKDEV
+       select GENERIC_CLOCKEVENTS
+       help
+         Support for Telechips TCC ARM926-based systems.
+
 config ARCH_LH7A40X
        bool "Sharp LH7A40X"
        select CPU_ARM922T
@@ -916,6 +927,8 @@ source "arch/arm/plat-s5p/Kconfig"
 
 source "arch/arm/plat-spear/Kconfig"
 
+source "arch/arm/plat-tcc/Kconfig"
+
 if ARCH_S3C2410
 source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
@@ -929,7 +942,7 @@ if ARCH_S3C64XX
 source "arch/arm/mach-s3c64xx/Kconfig"
 endif
 
-source "arch/arm/mach-s5p6440/Kconfig"
+source "arch/arm/mach-s5p64x0/Kconfig"
 
 source "arch/arm/mach-s5p6442/Kconfig"
 
@@ -1051,6 +1064,32 @@ config ARM_ERRATA_460075
          ACTLR register. Note that setting specific bits in the ACTLR register
          may not be available in non-secure mode.
 
+config ARM_ERRATA_742230
+       bool "ARM errata: DMB operation may be faulty"
+       depends on CPU_V7 && SMP
+       help
+         This option enables the workaround for the 742230 Cortex-A9
+         (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction
+         between two write operations may not ensure the correct visibility
+         ordering of the two writes. This workaround sets a specific bit in
+         the diagnostic register of the Cortex-A9 which causes the DMB
+         instruction to behave as a DSB, ensuring the correct behaviour of
+         the two writes.
+
+config ARM_ERRATA_742231
+       bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption"
+       depends on CPU_V7 && SMP
+       help
+         This option enables the workaround for the 742231 Cortex-A9
+         (r2p0..r2p2) erratum. Under certain conditions, specific to the
+         Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode,
+         accessing some data located in the same cache line, may get corrupted
+         data due to bad handling of the address hazard when the line gets
+         replaced from one of the CPUs at the same time as another CPU is
+         accessing it. This workaround sets specific bits in the diagnostic
+         register of the Cortex-A9 which reduces the linefill issuing
+         capabilities of the processor.
+
 config PL310_ERRATA_588369
        bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
        depends on CACHE_L2X0 && ARCH_OMAP4
@@ -1076,6 +1115,20 @@ config ARM_ERRATA_720789
          invalidated are not, resulting in an incoherency in the system page
          tables. The workaround changes the TLB flushing routines to invalidate
          entries regardless of the ASID.
+
+config ARM_ERRATA_743622
+       bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
+       depends on CPU_V7
+       help
+         This option enables the workaround for the 743622 Cortex-A9
+         (r2p0..r2p2) erratum. Under very rare conditions, a faulty
+         optimisation in the Cortex-A9 Store Buffer may lead to data
+         corruption. This workaround sets a specific bit in the diagnostic
+         register of the Cortex-A9 which disables the Store Buffer
+         optimisation, preventing the defect from occurring. This has no
+         visible impact on the overall performance or power consumption of the
+         processor.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1232,7 +1285,7 @@ source kernel/Kconfig.preempt
 
 config HZ
        int
-       default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || \
+       default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
                ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310
        default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
        default AT91_TIMER_HZ if ARCH_AT91
@@ -1438,6 +1491,20 @@ config UACCESS_WITH_MEMCPY
          However, if the CPU data cache is using a write-allocate mode,
          this option is unlikely to provide any performance gain.
 
+config SECCOMP
+       bool
+       prompt "Enable seccomp to safely compute untrusted bytecode"
+       ---help---
+         This kernel feature is useful for number crunching applications
+         that may need to compute untrusted bytecode during their
+         execution. By using pipes or other transports made available to
+         the process as file descriptors supporting the read/write
+         syscalls, it's possible to isolate those applications in
+         their own address space using seccomp. Once seccomp is
+         enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+         and the task is only allowed to execute a few safe syscalls
+         defined by each seccomp mode.
+
 config CC_STACKPROTECTOR
        bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
        help
index 91344af75f39694f89d1b4e16529184816f42965..c29fb382aeee306a80959db5e135c1fe2a6c1187 100644 (file)
@@ -2,6 +2,20 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+config STRICT_DEVMEM
+       bool "Filter access to /dev/mem"
+       depends on MMU
+       ---help---
+         If this option is disabled, you allow userspace (root) access to all
+         of memory, including kernel and userspace memory. Accidental
+         access to this is obviously disastrous, but specific access can
+         be used by people debugging the kernel.
+
+         If this option is switched on, the /dev/mem file only allows
+         userspace access to memory mapped peripherals.
+
+          If in doubt, say Y.
+
 # RMK wants arm kernels compiled with frame pointers or stack unwinding.
 # If you know what you are doing and are willing to live without stack
 # traces, you can get a slightly smaller kernel by setting this option to
index 59c1ce858fc8b18d4ec613e6dd2bfe62ed06047e..b87aed028eeff2dc50bb4b7c1005f9daadac26a8 100644 (file)
@@ -173,7 +173,7 @@ machine-$(CONFIG_ARCH_RPC)          := rpc
 machine-$(CONFIG_ARCH_S3C2410)         := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
 machine-$(CONFIG_ARCH_S3C24A0)         := s3c24a0
 machine-$(CONFIG_ARCH_S3C64XX)         := s3c64xx
-machine-$(CONFIG_ARCH_S5P6440)         := s5p6440
+machine-$(CONFIG_ARCH_S5P64X0)         := s5p64x0
 machine-$(CONFIG_ARCH_S5P6442)         := s5p6442
 machine-$(CONFIG_ARCH_S5PC100)         := s5pc100
 machine-$(CONFIG_ARCH_S5PV210)         := s5pv210
@@ -183,6 +183,7 @@ machine-$(CONFIG_ARCH_SHARK)                := shark
 machine-$(CONFIG_ARCH_SHMOBILE)        := shmobile
 machine-$(CONFIG_ARCH_STMP378X)                := stmp378x
 machine-$(CONFIG_ARCH_STMP37XX)                := stmp37xx
+machine-$(CONFIG_ARCH_TCC8K)           := tcc8k
 machine-$(CONFIG_ARCH_TEGRA)           := tegra
 machine-$(CONFIG_ARCH_U300)            := u300
 machine-$(CONFIG_ARCH_U8500)           := ux500
@@ -202,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC)             := mxc
 plat-$(CONFIG_ARCH_OMAP)       := omap
 plat-$(CONFIG_ARCH_S3C64XX)    := samsung
 plat-$(CONFIG_ARCH_STMP3XXX)   := stmp3xxx
+plat-$(CONFIG_ARCH_TCC_926)    := tcc
 plat-$(CONFIG_PLAT_IOP)                := iop
 plat-$(CONFIG_PLAT_NOMADIK)    := nomadik
 plat-$(CONFIG_PLAT_ORION)      := orion
@@ -245,13 +247,14 @@ ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
 FASTFPE_OBJ    :=$(FASTFPE)/
 endif
 
-# If we have a machine-specific directory, then include it in the build.
-core-y                         += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
-core-y                         += $(machdirs) $(platdirs)
 core-$(CONFIG_FPE_NWFPE)       += arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)     += $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)             += arch/arm/vfp/
 
+# If we have a machine-specific directory, then include it in the build.
+core-y                         += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y                         += $(machdirs) $(platdirs)
+
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 
 libs-y                         := arch/arm/lib/ $(libs-y)
index b23f6bc46cfa1dd1029bb53dc7009c3c790f1088..65a7c1c588a94ab4623be0ddfe02a691fb2954c6 100644 (file)
@@ -116,5 +116,5 @@ CFLAGS_font.o := -Dstatic=
 $(obj)/font.c: $(FONTC)
        $(call cmd,shipped)
 
-$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
+$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
        @sed "$(SEDFLAGS)" < $< > $@
index 7dfa9a85bc0c875b11567025f68e92bd768d7419..ada6359160ebef12614e9cd725449e5353a7a85b 100644 (file)
@@ -67,25 +67,11 @@ static inline unsigned int gic_irq(unsigned int irq)
 
 /*
  * Routines to acknowledge, disable and enable interrupts
- *
- * Linux assumes that when we're done with an interrupt we need to
- * unmask it, in the same way we need to unmask an interrupt when
- * we first enable it.
- *
- * The GIC has a separate notion of "end of interrupt" to re-enable
- * an interrupt after handling, in order to support hardware
- * prioritisation.
- *
- * We can make the GIC behave in the way that Linux expects by making
- * our "acknowledge" routine disable the interrupt, then mark it as
- * complete.
  */
 static void gic_ack_irq(unsigned int irq)
 {
-       u32 mask = 1 << (irq % 32);
 
        spin_lock(&irq_controller_lock);
-       writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
        writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
        spin_unlock(&irq_controller_lock);
 }
index 7974baacafcea74ec055a46ee0f6cea496f24e6f..1bec96e851967101df7a796745b84d24bd320ab8 100644 (file)
@@ -271,6 +271,14 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
                ((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
 }
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+       if (mask >= PHYS_OFFSET + SZ_64M - 1)
+               return 0;
+
+       return -EIO;
+}
+
 int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
 {
        it8152_io.start = IT8152_IO_BASE + 0x12000;
index f1bac70d6ce95f7ae364dd6eb8d4e745dea19fdf..9e90e6d792973042ec81faf2f78433e416a2752d 100644 (file)
@@ -13,6 +13,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9G20=y
 CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_AEABI=y
index ccc9c9959b82baf75d0faa04769a85e79ac23d51..2f7042813765f783fd139d4a7680b880bf9574e5 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_MACH_MV88F6281GTW_GE=y
 CONFIG_MACH_SHEEVAPLUG=y
 CONFIG_MACH_ESATA_SHEEVAPLUG=y
 CONFIG_MACH_GURUPLUG=y
+CONFIG_MACH_DOCKSTAR=y
 CONFIG_MACH_TS219=y
 CONFIG_MACH_TS41X=y
 CONFIG_MACH_OPENRD_BASE=y
similarity index 97%
rename from arch/arm/configs/s5p6440_defconfig
rename to arch/arm/configs/s5p64x0_defconfig
index 0b0266c6d3269592ed882fc664dee73dd045d5e1..2993ecd35145265d0cf2566bbf227158cd07a5c5 100644 (file)
@@ -5,10 +5,11 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S5P6440=y
+CONFIG_ARCH_S5P64X0=y
 CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=1
 CONFIG_MACH_SMDK6440=y
+CONFIG_MACH_SMDK6450=y
 CONFIG_CPU_32v6K=y
 CONFIG_AEABI=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
index 5747a8baa4135b44c25711197799255c9f5f61ff..8bb66bca2e3eb8a8561f2c63d9334e8991ebb728 100644 (file)
@@ -127,4 +127,8 @@ struct mm_struct;
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
+extern int vectors_user_mapping(void);
+#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+
 #endif
index 1261b1f928d95a9ac1cf374148208415c4dc248d..815efa2d4e07b5087e31965a06fc05c1fdfd9fa0 100644 (file)
@@ -294,6 +294,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
 #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
 extern int valid_phys_addr_range(unsigned long addr, size_t size);
 extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+extern int devmem_is_allowed(unsigned long pfn);
 #endif
 
 /*
index a0b3cac0547c0a9949c30cc919adcf5e08fcf500..71605d9f8e421ad36a058992c032ad5459114929 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/proc-fns.h>
-#include <asm-generic/mm_hooks.h>
 
 void __check_kvm_seq(struct mm_struct *mm);
 
@@ -134,4 +133,32 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
 #define deactivate_mm(tsk,mm)  do { } while (0)
 #define activate_mm(prev,next) switch_mm(prev, next, NULL)
 
+/*
+ * We are inserting a "fake" vma for the user-accessible vector page so
+ * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
+ * But we also want to remove it before the generic code gets to see it
+ * during process exit or the unmapping of it would  cause total havoc.
+ * (the macro is used as remove_vma() is static to mm/mmap.c)
+ */
+#define arch_exit_mmap(mm) \
+do { \
+       struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
+       if (high_vma) { \
+               BUG_ON(high_vma->vm_next);  /* it should be last */ \
+               if (high_vma->vm_prev) \
+                       high_vma->vm_prev->vm_next = NULL; \
+               else \
+                       mm->mmap = NULL; \
+               rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
+               mm->mmap_cache = NULL; \
+               mm->map_count--; \
+               remove_vma(high_vma); \
+       } \
+} while (0)
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+                                struct mm_struct *mm)
+{
+}
+
 #endif
index ab68cf1ef80fe7ccad28bfdd5d5084bb6f1b61dc..e90b167ea8484002fffb0121e7a2d61726851fe6 100644 (file)
@@ -317,6 +317,10 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+                                    unsigned long size, pgprot_t vma_prot);
 #else
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h
new file mode 100644 (file)
index 0000000..52b156b
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ASM_ARM_SECCOMP_H
+#define _ASM_ARM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_ARM_SECCOMP_H */
index 763e29fa85300b23180221a0c832c71b71b3e382..7b5cc8dae06e6e99b1dfc18edf6cef748629f25f 100644 (file)
@@ -144,6 +144,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_FREEZE             19
 #define TIF_RESTORE_SIGMASK    20
+#define TIF_SECCOMP            21
 
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
@@ -153,6 +154,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
 #define _TIF_USING_IWMMXT      (1 << TIF_USING_IWMMXT)
 #define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 
 /*
  * Change these and you break ASM code in entry-common.S
index f05a35a59694dc7af54a76ffb899e02f8b849875..0385a8207b6730c9e09dfb71a34ebd34eee474ef 100644 (file)
@@ -48,6 +48,8 @@ work_pending:
        beq     no_work_pending
        mov     r0, sp                          @ 'regs'
        mov     r2, why                         @ 'syscall'
+       tst     r1, #_TIF_SIGPENDING            @ delivering a signal?
+       movne   why, #0                         @ prevent further restarts
        bl      do_notify_resume
        b       ret_slow_syscall                @ Check work again
 
@@ -293,7 +295,6 @@ ENTRY(vector_swi)
 
        get_thread_info tsk
        adr     tbl, sys_call_table             @ load syscall table pointer
-       ldr     ip, [tsk, #TI_FLAGS]            @ check for syscall tracing
 
 #if defined(CONFIG_OABI_COMPAT)
        /*
@@ -310,8 +311,20 @@ ENTRY(vector_swi)
        eor     scno, scno, #__NR_SYSCALL_BASE  @ check OS number
 #endif
 
+       ldr     r10, [tsk, #TI_FLAGS]           @ check for syscall tracing
        stmdb   sp!, {r4, r5}                   @ push fifth and sixth args
-       tst     ip, #_TIF_SYSCALL_TRACE         @ are we tracing syscalls?
+
+#ifdef CONFIG_SECCOMP
+       tst     r10, #_TIF_SECCOMP
+       beq     1f
+       mov     r0, scno
+       bl      __secure_computing      
+       add     r0, sp, #S_R0 + S_OFF           @ pointer to regs
+       ldmia   r0, {r0 - r3}                   @ have to reload r0 - r3
+1:
+#endif
+
+       tst     r10, #_TIF_SYSCALL_TRACE                @ are we tracing syscalls?
        bne     __sys_trace
 
        cmp     scno, #NR_syscalls              @ check upper syscall limit
@@ -418,11 +431,13 @@ ENDPROC(sys_clone_wrapper)
 
 sys_sigreturn_wrapper:
                add     r0, sp, #S_OFF
+               mov     why, #0         @ prevent syscall restart handling
                b       sys_sigreturn
 ENDPROC(sys_sigreturn_wrapper)
 
 sys_rt_sigreturn_wrapper:
                add     r0, sp, #S_OFF
+               mov     why, #0         @ prevent syscall restart handling
                b       sys_rt_sigreturn
 ENDPROC(sys_rt_sigreturn_wrapper)
 
index 8bccbfa693ffc359dc55d6004837d2a149e2c5cd..2c1f0050c9c4d9fd74ac08b1c0a9c193e16df4de 100644 (file)
@@ -1162,11 +1162,12 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
        /*
         * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
-        * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx
+        * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx
         * ALU op with S bit and Rd == 15 :
         *         cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
         */
-       if ((insn & 0x0f900000) == 0x03200000 ||        /* MSR & Undef */
+       if ((insn & 0x0fb00000) == 0x03200000 ||        /* MSR */
+           (insn & 0x0ff00000) == 0x03400000 ||        /* Undef */
            (insn & 0x0e10f000) == 0x0210f000)          /* ALU s-bit, R15  */
                return INSN_REJECTED;
 
@@ -1177,7 +1178,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
         * *S (bit 20) updates condition codes
         * ADC/SBC/RSC reads the C flag
         */
-       insn &= 0xfff00fff;     /* Rn = r0, Rd = r0 */
+       insn &= 0xffff0fff;     /* Rd = r0 */
        asi->insn[0] = insn;
        asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
                        emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
index 401e38be1f787c16e7b36d6429406a05229d83da..66ac9c926200adf44da29173197206b95ac8cd85 100644 (file)
@@ -458,3 +458,24 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
        unsigned long range_end = mm->brk + 0x02000000;
        return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
 }
+
+/*
+ * The vectors page is always readable from user space for the
+ * atomic helpers and the signal restart code.  Let's declare a mapping
+ * for it so it is visible through ptrace and /proc/<pid>/mem.
+ */
+
+int vectors_user_mapping(void)
+{
+       struct mm_struct *mm = current->mm;
+       return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
+                                      VM_READ | VM_EXEC |
+                                      VM_MAYREAD | VM_MAYEXEC |
+                                      VM_ALWAYSDUMP | VM_RESERVED,
+                                      NULL);
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
+}
index 551f68f666bf0273bb465272887cedfbe7244b94..cff4e0a996ce992953780bc1af4f11d72aff34f3 100644 (file)
@@ -11,6 +11,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END            (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END            0xd0000000
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 939bccd70569846987c6ddb304cd22c7de730bf7..bbd5efa65099a4efcd790c464b2c72c9cbb591be 100644 (file)
@@ -33,6 +33,7 @@ config ARCH_AT91SAM9260
        select HAVE_AT91_USART3
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
+       select HAVE_NET_MACB
 
 config ARCH_AT91SAM9261
        bool "AT91SAM9261"
@@ -51,6 +52,7 @@ config ARCH_AT91SAM9263
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
+       select HAVE_NET_MACB
 
 config ARCH_AT91SAM9RL
        bool "AT91SAM9RL"
@@ -66,6 +68,7 @@ config ARCH_AT91SAM9G20
        select HAVE_AT91_USART3
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
+       select HAVE_NET_MACB
 
 config ARCH_AT91SAM9G45
        bool "AT91SAM9G45"
@@ -73,6 +76,7 @@ config ARCH_AT91SAM9G45
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
+       select HAVE_NET_MACB
 
 config ARCH_AT91CAP9
        bool "AT91CAP9"
@@ -338,6 +342,7 @@ config MACH_AT91SAM9G20EK
          that embeds only one SD/MMC slot.
 
 config MACH_AT91SAM9G20EK_2MMC
+       depends on MACH_AT91SAM9G20EK
        bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
        select HAVE_NAND_ATMEL_BUSWIDTH_16
        help
@@ -383,8 +388,8 @@ if ARCH_AT91SAM9G45
 
 comment "AT91SAM9G45 Board Type"
 
-config MACH_AT91SAM9G45EKES
-       bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
+config MACH_AT91SAM9M10G45EK
+       bool "Atmel AT91SAM9M10G45-EK Evaluation Kits"
        select HAVE_NAND_ATMEL_BUSWIDTH_16
        help
          Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
index ca2ac003f41f5666fb8da8c1e23b34ab3e363ea6..3a07a36964417b3fb921cc36b66fc3947acca189 100644 (file)
@@ -61,7 +61,6 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK)       += board-sam9rlek.o
 
 # AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
-obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
 obj-$(CONFIG_MACH_CPU9G20)     += board-cpu9krea.o
 obj-$(CONFIG_MACH_STAMP9G20)   += board-stamp9g20.o
 obj-$(CONFIG_MACH_PORTUXG20)   += board-stamp9g20.o
@@ -70,7 +69,7 @@ obj-$(CONFIG_MACH_PORTUXG20)  += board-stamp9g20.o
 obj-$(CONFIG_MACH_SNAPPER_9260)        += board-snapper9260.o
 
 # AT91SAM9G45 board-specific support
-obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
+obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
 
 # AT91CAP9 board-specific support
 obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
index 5e71ccd5e7d381ca211d1f73653351bdca814c6b..1276babf84d540ad253d06eb089f29d57beab1a7 100644 (file)
@@ -426,7 +426,7 @@ static struct i2c_gpio_platform_data pdata_i2c0 = {
        .sda_is_open_drain      = 1,
        .scl_pin                = AT91_PIN_PA21,
        .scl_is_open_drain      = 1,
-       .udelay                 = 2,            /* ~100 kHz */
+       .udelay                 = 5,            /* ~100 kHz */
 };
 
 static struct platform_device at91sam9g45_twi0_device = {
@@ -440,7 +440,7 @@ static struct i2c_gpio_platform_data pdata_i2c1 = {
        .sda_is_open_drain      = 1,
        .scl_pin                = AT91_PIN_PB11,
        .scl_is_open_drain      = 1,
-       .udelay                 = 2,            /* ~100 kHz */
+       .udelay                 = 5,            /* ~100 kHz */
 };
 
 static struct platform_device at91sam9g45_twi1_device = {
index 5daff277f53e0deaccfc8665d75613440ba7bbfa..46651623f20885e3739deb55e0be6b8885f9c187 100644 (file)
@@ -216,7 +216,7 @@ static struct atmel_nand_data __initdata eb_nand_data = {
 /*     .rdy_pin        = AT91_PIN_PC16, */
        .enable_pin     = AT91_PIN_PA15,
        .partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
        .bus_width_16   = 1,
 #else
        .bus_width_16   = 0,
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
deleted file mode 100644 (file)
index c49f5c0..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- *  Copyright (C) 2005 SAN People
- *  Copyright (C) 2008 Atmel
- *  Copyright (C) 2009 Rob Emanuele
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/at73c213.h>
-#include <linux/clk.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/consumer.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91sam9_smc.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init ek_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91sam9260_initialize(18432000);
-
-       /* DGBU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-                          | ATMEL_UART_RI);
-
-       /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
-       at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init ek_init_irq(void)
-{
-       at91sam9260_init_interrupts(NULL);
-}
-
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata ek_usbh_data = {
-       .ports          = 2,
-};
-
-/*
- * USB Device port
- */
-static struct at91_udc_data __initdata ek_udc_data = {
-       .vbus_pin       = AT91_PIN_PC5,
-       .pullup_pin     = 0,            /* pull-up driven by UDC */
-};
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info ek_spi_devices[] = {
-#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
-       {       /* DataFlash chip */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 1,
-               .max_speed_hz   = 15 * 1000 * 1000,
-               .bus_num        = 0,
-       },
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-               .bus_num        = 0,
-       },
-#endif
-#endif
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct at91_eth_data __initdata ek_macb_data = {
-       .phy_irq_pin    = AT91_PIN_PB0,
-       .is_rmii        = 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata ek_nand_partition[] = {
-       {
-               .name   = "Bootstrap",
-               .offset = 0,
-               .size   = 4 * SZ_1M,
-       },
-       {
-               .name   = "Partition 1",
-               .offset = MTDPART_OFS_NXTBLK,
-               .size   = 60 * SZ_1M,
-       },
-       {
-               .name   = "Partition 2",
-               .offset = MTDPART_OFS_NXTBLK,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
-/* det_pin is not connected */
-static struct atmel_nand_data __initdata ek_nand_data = {
-       .ale            = 21,
-       .cle            = 22,
-       .rdy_pin        = AT91_PIN_PC13,
-       .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-       .bus_width_16   = 1,
-#else
-       .bus_width_16   = 0,
-#endif
-};
-
-static struct sam9_smc_config __initdata ek_nand_smc_config = {
-       .ncs_read_setup         = 0,
-       .nrd_setup              = 2,
-       .ncs_write_setup        = 0,
-       .nwe_setup              = 2,
-
-       .ncs_read_pulse         = 4,
-       .nrd_pulse              = 4,
-       .ncs_write_pulse        = 4,
-       .nwe_pulse              = 4,
-
-       .read_cycle             = 7,
-       .write_cycle            = 7,
-
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
-       .tdf_cycles             = 3,
-};
-
-static void __init ek_add_device_nand(void)
-{
-       /* setup bus-width (8 or 16) */
-       if (ek_nand_data.bus_width_16)
-               ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
-       else
-               ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
-       /* configure chip-select 3 (NAND) */
-       sam9_smc_configure(3, &ek_nand_smc_config);
-
-       at91_add_device_nand(&ek_nand_data);
-}
-
-
-/*
- * MCI (SD/MMC)
- * wp_pin is not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata ek_mmc_data = {
-       .slot[0] = {
-               .bus_width      = 4,
-               .detect_pin     = AT91_PIN_PC2,
-               .wp_pin         = -ENODEV,
-       },
-       .slot[1] = {
-               .bus_width      = 4,
-               .detect_pin     = AT91_PIN_PC9,
-               .wp_pin         = -ENODEV,
-       },
-
-};
-#else
-static struct at91_mmc_data __initdata ek_mmc_data = {
-       .slot_b         = 1,    /* Only one slot so use slot B */
-       .wire4          = 1,
-       .det_pin        = AT91_PIN_PC9,
-};
-#endif
-
-/*
- * LEDs
- */
-static struct gpio_led ek_leds[] = {
-       {       /* "bottom" led, green, userled1 to be defined */
-               .name                   = "ds5",
-               .gpio                   = AT91_PIN_PB8,
-               .active_low             = 1,
-               .default_trigger        = "none",
-       },
-       {       /* "power" led, yellow */
-               .name                   = "ds1",
-               .gpio                   = AT91_PIN_PB9,
-               .default_trigger        = "heartbeat",
-       }
-};
-
-#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
-static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
-       REGULATOR_SUPPLY("AVDD", "0-001b"),
-       REGULATOR_SUPPLY("HPVDD", "0-001b"),
-       REGULATOR_SUPPLY("DBVDD", "0-001b"),
-       REGULATOR_SUPPLY("DCVDD", "0-001b"),
-};
-
-static struct regulator_init_data ek_avdd_reg_init_data = {
-       .constraints    = {
-               .name   = "3V3",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-       },
-       .consumer_supplies = ek_audio_consumer_supplies,
-       .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
-};
-
-static struct fixed_voltage_config ek_vdd_pdata = {
-       .supply_name    = "board-3V3",
-       .microvolts     = 3300000,
-       .gpio           = -EINVAL,
-       .enabled_at_boot = 0,
-       .init_data      = &ek_avdd_reg_init_data,
-};
-static struct platform_device ek_voltage_regulator = {
-       .name           = "reg-fixed-voltage",
-       .id             = -1,
-       .num_resources  = 0,
-       .dev            = {
-               .platform_data  = &ek_vdd_pdata,
-       },
-};
-static void __init ek_add_regulators(void)
-{
-       platform_device_register(&ek_voltage_regulator);
-}
-#else
-static void __init ek_add_regulators(void) {}
-#endif
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("24c512", 0x50),
-       },
-};
-
-
-static void __init ek_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* USB Host */
-       at91_add_device_usbh(&ek_usbh_data);
-       /* USB Device */
-       at91_add_device_udc(&ek_udc_data);
-       /* SPI */
-       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
-       /* NAND */
-       ek_add_device_nand();
-       /* Ethernet */
-       at91_add_device_eth(&ek_macb_data);
-       /* Regulators */
-       ek_add_regulators();
-       /* MMC */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-       at91_add_device_mci(0, &ek_mmc_data);
-#else
-       at91_add_device_mmc(0, &ek_mmc_data);
-#endif
-       /* I2C */
-       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
-       /* LEDs */
-       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-       /* PCK0 provides MCLK to the WM8731 */
-       at91_set_B_periph(AT91_PIN_PC1, 0);
-       /* SSC (for WM8731) */
-       at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
-}
-
-MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
-       /* Maintainer: Rob Emanuele */
-       .phys_io        = AT91_BASE_SYS,
-       .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
-       .boot_params    = AT91_SDRAM_BASE + 0x100,
-       .timer          = &at91sam926x_timer,
-       .map_io         = ek_map_io,
-       .init_irq       = ek_init_irq,
-       .init_machine   = ek_board_init,
-MACHINE_END
index 6ea9808b8868d53a0c7cefd1926f921eadd82633..b463e340c4a091a6d20692245efe76568e6ddebf 100644 (file)
 #include "sam9_smc.h"
 #include "generic.h"
 
+/*
+ * board revision encoding
+ * bit 0:
+ *     0 => 1 sd/mmc slot
+ *     1 => 2 sd/mmc slots connectors (board from revision C)
+ */
+#define HAVE_2MMC      (1 << 0)
+static int inline ek_have_2mmc(void)
+{
+       return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC);
+}
+
 
 static void __init ek_map_io(void)
 {
@@ -94,7 +106,7 @@ static struct at91_udc_data __initdata ek_udc_data = {
  * SPI devices.
  */
 static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_AT91)
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
        {       /* DataFlash chip */
                .modalias       = "mtd_dataflash",
                .chip_select    = 1,
@@ -121,6 +133,13 @@ static struct at91_eth_data __initdata ek_macb_data = {
        .is_rmii        = 1,
 };
 
+static void __init ek_add_device_macb(void)
+{
+       if (ek_have_2mmc())
+               ek_macb_data.phy_irq_pin = AT91_PIN_PB0;
+
+       at91_add_device_eth(&ek_macb_data);
+}
 
 /*
  * NAND flash
@@ -198,13 +217,36 @@ static void __init ek_add_device_nand(void)
 
 /*
  * MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
+ * wp_pin and vcc_pin are not connected
  */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata ek_mmc_data = {
+       .slot[1] = {
+               .bus_width      = 4,
+               .detect_pin     = AT91_PIN_PC9,
+       },
+
+};
+#else
 static struct at91_mmc_data __initdata ek_mmc_data = {
-       .slot_b         = 1,
+       .slot_b         = 1,    /* Only one slot so use slot B */
        .wire4          = 1,
+       .det_pin        = AT91_PIN_PC9,
 };
+#endif
 
+static void __init ek_add_device_mmc(void)
+{
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+       if (ek_have_2mmc()) {
+               ek_mmc_data.slot[0].bus_width = 4;
+               ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2;
+       }
+       at91_add_device_mci(0, &ek_mmc_data);
+#else
+       at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+}
 
 /*
  * LEDs
@@ -223,6 +265,15 @@ static struct gpio_led ek_leds[] = {
        }
 };
 
+static void __init ek_add_device_gpio_leds(void)
+{
+       if (ek_have_2mmc()) {
+               ek_leds[0].gpio = AT91_PIN_PB8;
+               ek_leds[1].gpio = AT91_PIN_PB9;
+       }
+
+       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
 
 /*
  * GPIO Buttons
@@ -336,15 +387,15 @@ static void __init ek_board_init(void)
        /* NAND */
        ek_add_device_nand();
        /* Ethernet */
-       at91_add_device_eth(&ek_macb_data);
+       ek_add_device_macb();
        /* Regulators */
        ek_add_regulators();
        /* MMC */
-       at91_add_device_mmc(0, &ek_mmc_data);
+       ek_add_device_mmc();
        /* I2C */
        at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
        /* LEDs */
-       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+       ek_add_device_gpio_leds();
        /* Push Buttons */
        ek_add_device_buttons();
        /* PCK0 provides MCLK to the WM8731 */
@@ -363,3 +414,14 @@ MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
        .init_irq       = ek_init_irq,
        .init_machine   = ek_board_init,
 MACHINE_END
+
+MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
+       /* Maintainer: Atmel */
+       .phys_io        = AT91_BASE_SYS,
+       .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91sam926x_timer,
+       .map_io         = ek_map_io,
+       .init_irq       = ek_init_irq,
+       .init_machine   = ek_board_init,
+MACHINE_END
index ee800595594d3fa790f6d4737f59d3c9c4b8c473..ae0e0843e5f550f2a94b900a251b1e3052654dda 100644 (file)
@@ -135,7 +135,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .rdy_pin        = AT91_PIN_PC8,
        .enable_pin     = AT91_PIN_PC14,
        .partition_info = nand_partitions,
-#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
        .bus_width_16   = 1,
 #else
        .bus_width_16   = 0,
@@ -399,7 +399,7 @@ static void __init ek_board_init(void)
        at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
 }
 
-MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
+MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
        /* Maintainer: Atmel */
        .phys_io        = AT91_BASE_SYS,
        .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
index d34cdb8abdca652dfcc64523e089361ed3ff2c0e..063ac44a020423119b52749dc3c866b6dd7eb965 100644 (file)
 #define AT91_DBGU_CIDR (AT91_SF + 0)   /* CIDR in PS segment */
 #define AT91_DBGU_EXID (AT91_SF + 4)   /* EXID in PS segment */
 
+/*
+ * Support defines for the simple Power Controller module.
+ */
+#define        AT91_PS_CR      (AT91_PS + 0)   /* PS Control register */
+#define        AT91_PS_CR_CPU  (1 << 0)        /* CPU clock disable bit */
+
 #endif /* AT91X40_H */
index c80e090b36708706671d8c66ff1a67a1c0106d61..36af14bc13bbbbc88aad80487b6d3cc85b924f0b 100644 (file)
 
 static inline void arch_idle(void)
 {
-#ifndef CONFIG_DEBUG_KERNEL
        /*
         * Disable the processor clock.  The processor will be automatically
         * re-enabled by an interrupt or by a reset.
         */
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#ifdef AT91_PS
+       at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
 #else
+       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#endif
+#ifndef CONFIG_CPU_ARM920T
        /*
         * Set the processor (CP15) into 'Wait for Interrupt' mode.
-        * Unlike disabling the processor clock via the PMC (above)
-        *  this allows the processor to be woken via JTAG.
+        * Post-RM9200 processors need this in conjunction with the above
+        * to save power when idle.
         */
        cpu_do_idle();
 #endif
index 35e2ead8395c5f05447bca5efeebd7c4e8d9cafe..3db3a09fd3986e7ee452997e75a13180a38475b1 100644 (file)
@@ -22,4 +22,4 @@
  * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
  * larger physical memory designs better.
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END       0xf0000000
index ea6cc7beff287939e117cbc57beed7f3ffa5e155..30b3a287ed8865d897adccbfb2f318cfa4212e9b 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
index 3d996b659ff41e43d794d93c167b409afb90c355..9be261beae7ddb2a72e2e9a76d9dbf2e2bf51316 100644 (file)
@@ -769,8 +769,7 @@ static struct map_desc dm355_io_desc[] = {
                .virtual        = SRAM_VIRT,
                .pfn            = __phys_to_pfn(0x00010000),
                .length         = SZ_32K,
-               /* MT_MEMORY_NONCACHED requires supersection alignment */
-               .type           = MT_DEVICE,
+               .type           = MT_MEMORY_NONCACHED,
        },
 };
 
index 6b6f4c643709c7d14a4b2baf168464ad772be4ce..7781e35daec3d0a7cf9e956aceb7e717f48c7c44 100644 (file)
@@ -969,8 +969,7 @@ static struct map_desc dm365_io_desc[] = {
                .virtual        = SRAM_VIRT,
                .pfn            = __phys_to_pfn(0x00010000),
                .length         = SZ_32K,
-               /* MT_MEMORY_NONCACHED requires supersection alignment */
-               .type           = MT_DEVICE,
+               .type           = MT_MEMORY_NONCACHED,
        },
 };
 
index 40fec315c99a192826d7530d43c6406726ecbcff..5e5b0a7831fbf2b7af156ba76bf4af0b6be26489 100644 (file)
@@ -653,8 +653,7 @@ static struct map_desc dm644x_io_desc[] = {
                .virtual        = SRAM_VIRT,
                .pfn            = __phys_to_pfn(0x00008000),
                .length         = SZ_16K,
-               /* MT_MEMORY_NONCACHED requires supersection alignment */
-               .type           = MT_DEVICE,
+               .type           = MT_MEMORY_NONCACHED,
        },
 };
 
index e4a3df1872aca89404899034ebbe920d453e7f66..26e8a9c7f50b4393f1e716575950fff967658b9a 100644 (file)
@@ -737,8 +737,7 @@ static struct map_desc dm646x_io_desc[] = {
                .virtual        = SRAM_VIRT,
                .pfn            = __phys_to_pfn(0x00010000),
                .length         = SZ_32K,
-               /* MT_MEMORY_NONCACHED requires supersection alignment */
-               .type           = MT_DEVICE,
+               .type           = MT_MEMORY_NONCACHED,
        },
 };
 
index 3b3e4721ce2ea0fb9236803e566d4c67b0d5638e..eb4936ff90ad9c42b283fc6c354eae1f01c6c4c7 100644 (file)
@@ -13,8 +13,8 @@
 
 #define IO_SPACE_LIMIT         0xffffffff
 
-#define __io(a)  ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\
-                                  DOVE_PCIE0_IO_VIRT_BASE))
-#define __mem_pci(a)           (a)
+#define __io(a)        ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \
+                                                DOVE_PCIE0_IO_VIRT_BASE))
+#define __mem_pci(a)   (a)
 
 #endif
index 9b44c19e95ec5167af7b5607ae5ff05a58e7e4f9..60bde56fba4cf3e4ef90cea65ceb2bf8e2db3111 100644 (file)
@@ -7,4 +7,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x1f000000)
+#define VMALLOC_END       0xdf000000
index 8904ca4e2e24fc9a4984bd0b88ce9d3eab52e7ea..a696d354b1f82598649586e6478be6334a91f978 100644 (file)
@@ -276,7 +276,7 @@ static void channel_disable(struct m2p_channel *ch)
        v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN);
        m2p_set_control(ch, v);
 
-       while (m2p_channel_state(ch) == STATE_ON)
+       while (m2p_channel_state(ch) >= STATE_ON)
                cpu_relax();
 
        m2p_set_control(ch, 0x0);
index d0958d860a3cb52f16f9464cf625c13498f3ec73..0ffbb7c85e59e738ce5d1966788ae72f52252ffe 100644 (file)
@@ -7,4 +7,4 @@
  */
 
 
-#define VMALLOC_END       (PAGE_OFFSET + 0x30000000)
+#define VMALLOC_END       0xf0000000
index ff1460d6841ba9c76f85e54d11d0709c4de801a3..a45915b88756d4e8e786e653bba677c5e36488b0 100644 (file)
@@ -5,6 +5,6 @@
 #ifndef __ARCH_ARM_VMALLOC_H
 #define __ARCH_ARM_VMALLOC_H
 
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
 
 #endif
index 28f73a1c79f7c24c1f17d7e71a307dc7e1eb0fd7..a1681fc9d9b066a3a5f274264af605ef1a2e5373 100644 (file)
@@ -258,7 +258,7 @@ static void __init eukrea_cpuimx27_init(void)
        i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
                                ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
 
-       imx27_add_imx_i2c(1, &cpuimx27_i2c1_data);
+       imx27_add_imx_i2c(0, &cpuimx27_i2c1_data);
 
        imx27_add_fec(NULL);
        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
index e87ab0b37bddb353810f97bd25461a536cf167c1..e056e7cf5645f8c936f4144f8d584f2772ae9bf2 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
index 61cd4d64b98596c7507dcaf67d069dbe22508e50..24498a932ba65b8054de5ba8229ef0e0c838dd71 100644 (file)
@@ -503,6 +503,14 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
        return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
 }
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+       if (mask >= SZ_64M - 1)
+               return 0;
+
+       return -EIO;
+}
+
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
 
index f91ca6d4fbe8a2820758d2252091a761caac377c..8138371c406e6584b8990803079c7a093cbe1964 100644 (file)
@@ -26,6 +26,8 @@
 #define PCIBIOS_MAX_MEM                0x4BFFFFFF
 #endif
 
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
+
 #define pcibios_assign_all_busses()    1
 
 /* Register locations and bits */
index cc25501b57fa8edf270752e0a719f2564965f44a..34106335c728f31527dc59dbc05d5978165ae365 100644 (file)
@@ -58,6 +58,12 @@ config MACH_TS41X
          QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
          devices.
 
+config MACH_DOCKSTAR
+       bool "Seagate FreeAgent DockStar"
+       help
+         Say 'Y' here if you want your kernel to support the
+         Seagate FreeAgent DockStar.
+
 config MACH_OPENRD
         bool
 
@@ -100,6 +106,12 @@ config MACH_NETSPACE_MAX_V2
          Say 'Y' here if you want your kernel to support the
          LaCie Network Space Max v2 NAS.
 
+config MACH_D2NET_V2
+       bool "LaCie d2 Network v2 NAS Board"
+       help
+         Say 'Y' here if you want your kernel to support the
+         LaCie d2 Network v2 NAS.
+
 config MACH_NET2BIG_V2
        bool "LaCie 2Big Network v2 NAS Board"
        help
index 295d7baa6ae11150956e004330259859ef3c4ec6..5dcaa81a2ec39f0f6b60a13438651ab381fc6eb4 100644 (file)
@@ -7,14 +7,16 @@ obj-$(CONFIG_MACH_MV88F6281GTW_GE)    += mv88f6281gtw_ge-setup.o
 obj-$(CONFIG_MACH_SHEEVAPLUG)          += sheevaplug-setup.o
 obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG)    += sheevaplug-setup.o
 obj-$(CONFIG_MACH_GURUPLUG)            += guruplug-setup.o
+obj-$(CONFIG_MACH_DOCKSTAR)            += dockstar-setup.o
 obj-$(CONFIG_MACH_TS219)               += ts219-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_TS41X)               += ts41x-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_OPENRD)              += openrd-setup.o
-obj-$(CONFIG_MACH_NETSPACE_V2)         += netspace_v2-setup.o
-obj-$(CONFIG_MACH_INETSPACE_V2)                += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NETSPACE_MAX_V2)     += netspace_v2-setup.o
-obj-$(CONFIG_MACH_NET2BIG_V2)          += netxbig_v2-setup.o
-obj-$(CONFIG_MACH_NET5BIG_V2)          += netxbig_v2-setup.o
+obj-$(CONFIG_MACH_NETSPACE_V2)         += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_INETSPACE_V2)                += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NETSPACE_MAX_V2)     += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_D2NET_V2)            += d2net_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET2BIG_V2)          += netxbig_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET5BIG_V2)          += netxbig_v2-setup.o lacie_v2-common.o
 obj-$(CONFIG_MACH_T5325)               += t5325-setup.o
 
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c
new file mode 100644 (file)
index 0000000..cd62d0f
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * arch/arm/mach-kirkwood/d2net_v2-setup.c
+ *
+ * LaCie d2 Network Space v2 Board Setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-ns2.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_v2_ge00_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_v2_sata_data = {
+       .n_ports        = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_PUSH_BUTTON          34
+#define D2NET_V2_GPIO_POWER_SWITCH_ON      13
+#define D2NET_V2_GPIO_POWER_SWITCH_OFF     15
+
+#define D2NET_V2_SWITCH_POWER_ON           0x1
+#define D2NET_V2_SWITCH_POWER_OFF          0x2
+
+static struct gpio_keys_button d2net_v2_buttons[] = {
+       [0] = {
+               .type           = EV_SW,
+               .code           = D2NET_V2_SWITCH_POWER_ON,
+               .gpio           = D2NET_V2_GPIO_POWER_SWITCH_ON,
+               .desc           = "Back power switch (on|auto)",
+               .active_low     = 0,
+       },
+       [1] = {
+               .type           = EV_SW,
+               .code           = D2NET_V2_SWITCH_POWER_OFF,
+               .gpio           = D2NET_V2_GPIO_POWER_SWITCH_OFF,
+               .desc           = "Back power switch (auto|off)",
+               .active_low     = 0,
+       },
+       [2] = {
+               .code           = KEY_POWER,
+               .gpio           = D2NET_V2_GPIO_PUSH_BUTTON,
+               .desc           = "Front Push Button",
+               .active_low     = 1,
+       },
+};
+
+static struct gpio_keys_platform_data d2net_v2_button_data = {
+       .buttons        = d2net_v2_buttons,
+       .nbuttons       = ARRAY_SIZE(d2net_v2_buttons),
+};
+
+static struct platform_device d2net_v2_gpio_buttons = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &d2net_v2_button_data,
+       },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_RED_LED          12
+
+static struct gpio_led d2net_v2_gpio_led_pins[] = {
+       {
+               .name   = "d2net_v2:red:fail",
+               .gpio   = D2NET_V2_GPIO_RED_LED,
+       },
+};
+
+static struct gpio_led_platform_data d2net_v2_gpio_leds_data = {
+       .num_leds       = ARRAY_SIZE(d2net_v2_gpio_led_pins),
+       .leds           = d2net_v2_gpio_led_pins,
+};
+
+static struct platform_device d2net_v2_gpio_leds = {
+       .name           = "leds-gpio",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &d2net_v2_gpio_leds_data,
+       },
+};
+
+/*****************************************************************************
+ * Dual-GPIO CPLD LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_BLUE_LED_SLOW    29
+#define D2NET_V2_GPIO_BLUE_LED_CMD     30
+
+static struct ns2_led d2net_v2_led_pins[] = {
+       {
+               .name   = "d2net_v2:blue:sata",
+               .cmd    = D2NET_V2_GPIO_BLUE_LED_CMD,
+               .slow   = D2NET_V2_GPIO_BLUE_LED_SLOW,
+       },
+};
+
+static struct ns2_led_platform_data d2net_v2_leds_data = {
+       .num_leds       = ARRAY_SIZE(d2net_v2_led_pins),
+       .leds           = d2net_v2_led_pins,
+};
+
+static struct platform_device d2net_v2_leds = {
+       .name           = "leds-ns2",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &d2net_v2_leds_data,
+       },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int d2net_v2_mpp_config[] __initdata = {
+       MPP0_SPI_SCn,
+       MPP1_SPI_MOSI,
+       MPP2_SPI_SCK,
+       MPP3_SPI_MISO,
+       MPP6_SYSRST_OUTn,
+       MPP7_GPO,               /* Request power-off */
+       MPP8_TW0_SDA,
+       MPP9_TW0_SCK,
+       MPP10_UART0_TXD,
+       MPP11_UART0_RXD,
+       MPP12_GPO,              /* Red led */
+       MPP13_GPIO,             /* Rear power switch (on|auto) */
+       MPP14_GPIO,             /* USB fuse */
+       MPP15_GPIO,             /* Rear power switch (auto|off) */
+       MPP16_GPIO,             /* SATA 0 power */
+       MPP21_SATA0_ACTn,
+       MPP24_GPIO,             /* USB mode select */
+       MPP26_GPIO,             /* USB device vbus */
+       MPP28_GPIO,             /* USB enable host vbus */
+       MPP29_GPIO,             /* Blue led (slow register) */
+       MPP30_GPIO,             /* Blue led (command register) */
+       MPP34_GPIO,             /* Power button (1 = Released, 0 = Pushed) */
+       MPP35_GPIO,             /* Inhibit power-off */
+       0
+};
+
+#define D2NET_V2_GPIO_POWER_OFF                7
+
+static void d2net_v2_power_off(void)
+{
+       gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init d2net_v2_init(void)
+{
+       /*
+        * Basic setup. Needs to be called early.
+        */
+       kirkwood_init();
+       kirkwood_mpp_conf(d2net_v2_mpp_config);
+
+       lacie_v2_hdd_power_init(1);
+
+       kirkwood_ehci_init();
+       kirkwood_ge00_init(&d2net_v2_ge00_data);
+       kirkwood_sata_init(&d2net_v2_sata_data);
+       kirkwood_uart0_init();
+       lacie_v2_register_flash();
+       lacie_v2_register_i2c_devices();
+
+       platform_device_register(&d2net_v2_leds);
+       platform_device_register(&d2net_v2_gpio_leds);
+       platform_device_register(&d2net_v2_gpio_buttons);
+
+       if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+           gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0)
+               pm_power_off = d2net_v2_power_off;
+       else
+               pr_err("d2net_v2: failed to configure power-off GPIO\n");
+}
+
+MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
+       .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
+       .io_pg_offst    = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = d2net_v2_init,
+       .map_io         = kirkwood_map_io,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &lacie_v2_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c
new file mode 100644 (file)
index 0000000..a90475d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * arch/arm/mach-kirkwood/dockstar-setup.c
+ *
+ * Seagate FreeAgent DockStar Setup
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition dockstar_nand_parts[] = {
+       {
+               .name = "u-boot",
+               .offset = 0,
+               .size = SZ_1M
+       }, {
+               .name = "uImage",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size = SZ_4M
+       }, {
+               .name = "root",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size = MTDPART_SIZ_FULL
+       },
+};
+
+static struct mv643xx_eth_platform_data dockstar_ge00_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct gpio_led dockstar_led_pins[] = {
+       {
+               .name                   = "dockstar:green:health",
+               .default_trigger        = "default-on",
+               .gpio                   = 46,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "dockstar:orange:misc",
+               .default_trigger        = "none",
+               .gpio                   = 47,
+               .active_low             = 1,
+       },
+};
+
+static struct gpio_led_platform_data dockstar_led_data = {
+       .leds           = dockstar_led_pins,
+       .num_leds       = ARRAY_SIZE(dockstar_led_pins),
+};
+
+static struct platform_device dockstar_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &dockstar_led_data,
+       }
+};
+
+static unsigned int dockstar_mpp_config[] __initdata = {
+       MPP29_GPIO,     /* USB Power Enable */
+       MPP46_GPIO,     /* LED green */
+       MPP47_GPIO,     /* LED orange */
+       0
+};
+
+static void __init dockstar_init(void)
+{
+       /*
+        * Basic setup. Needs to be called early.
+        */
+       kirkwood_init();
+
+       /* setup gpio pin select */
+       kirkwood_mpp_conf(dockstar_mpp_config);
+
+       kirkwood_uart0_init();
+       kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25);
+
+       if (gpio_request(29, "USB Power Enable") != 0 ||
+           gpio_direction_output(29, 1) != 0)
+               printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+       kirkwood_ehci_init();
+
+       kirkwood_ge00_init(&dockstar_ge00_data);
+
+       platform_device_register(&dockstar_leds);
+}
+
+MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar")
+       .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
+       .io_pg_offst    = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = dockstar_init,
+       .map_io         = kirkwood_map_io,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &kirkwood_timer,
+MACHINE_END
index 93fc2ec95e7687b30b6144f2116adb0664266a4d..6e924b398919e822ca4f2bddd294358bf4008ede 100644 (file)
@@ -38,7 +38,7 @@
 
 #define KIRKWOOD_PCIE1_IO_PHYS_BASE    0xf3000000
 #define KIRKWOOD_PCIE1_IO_VIRT_BASE    0xfef00000
-#define KIRKWOOD_PCIE1_IO_BUS_BASE     0x00000000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE     0x00100000
 #define KIRKWOOD_PCIE1_IO_SIZE         SZ_1M
 
 #define KIRKWOOD_PCIE_IO_PHYS_BASE     0xf2000000
diff --git a/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
new file mode 100644 (file)
index 0000000..24b536e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
+ *
+ * Platform data structure for netxbig LED driver
+ *
+ * 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.
+ */
+
+#ifndef __MACH_LEDS_NETXBIG_H
+#define __MACH_LEDS_NETXBIG_H
+
+struct netxbig_gpio_ext {
+       unsigned        *addr;
+       int             num_addr;
+       unsigned        *data;
+       int             num_data;
+       unsigned        enable;
+};
+
+enum netxbig_led_mode {
+       NETXBIG_LED_OFF,
+       NETXBIG_LED_ON,
+       NETXBIG_LED_SATA,
+       NETXBIG_LED_TIMER1,
+       NETXBIG_LED_TIMER2,
+       NETXBIG_LED_MODE_NUM,
+};
+
+#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
+
+struct netxbig_led_timer {
+       unsigned long           delay_on;
+       unsigned long           delay_off;
+       enum netxbig_led_mode   mode;
+};
+
+struct netxbig_led {
+       const char      *name;
+       const char      *default_trigger;
+       int             mode_addr;
+       int             *mode_val;
+       int             bright_addr;
+};
+
+struct netxbig_led_platform_data {
+       struct netxbig_gpio_ext *gpio_ext;
+       struct netxbig_led_timer *timer;
+       int                     num_timer;
+       struct netxbig_led      *leds;
+       int                     num_leds;
+};
+
+#endif /* __MACH_LEDS_NETXBIG_H */
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c
new file mode 100644 (file)
index 0000000..d3ea1b6
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.c
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <mach/irqs.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition lacie_v2_flash_parts[] = {
+       {
+               .name = "u-boot",
+               .size = MTDPART_SIZ_FULL,
+               .offset = 0,
+               .mask_flags = MTD_WRITEABLE, /* force read-only */
+       },
+};
+
+static const struct flash_platform_data lacie_v2_flash = {
+       .type           = "mx25l4005a",
+       .name           = "spi_flash",
+       .parts          = lacie_v2_flash_parts,
+       .nr_parts       = ARRAY_SIZE(lacie_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = {
+       {
+               .modalias       = "m25p80",
+               .platform_data  = &lacie_v2_flash,
+               .irq            = -1,
+               .max_speed_hz   = 20000000,
+               .bus_num        = 0,
+               .chip_select    = 0,
+       },
+};
+
+void __init lacie_v2_register_flash(void)
+{
+       spi_register_board_info(lacie_v2_spi_slave_info,
+                               ARRAY_SIZE(lacie_v2_spi_slave_info));
+       kirkwood_spi_init();
+}
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+       .byte_len       = SZ_4K / 8,
+       .page_size      = 16,
+};
+
+/*
+ * i2c addr | chip         | description
+ * 0x50     | HT24LC04     | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata lacie_v2_i2c_info[] = {
+       {
+               I2C_BOARD_INFO("24c04", 0x50),
+               .platform_data  = &at24c04,
+       }
+};
+
+void __init lacie_v2_register_i2c_devices(void)
+{
+       kirkwood_i2c_init();
+       i2c_register_board_info(0, lacie_v2_i2c_info,
+                               ARRAY_SIZE(lacie_v2_i2c_info));
+}
+
+/*****************************************************************************
+ * Hard Disk power
+ ****************************************************************************/
+
+static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
+
+void __init lacie_v2_hdd_power_init(int hdd_num)
+{
+       int i;
+       int err;
+
+       /* Power up all hard disks. */
+       for (i = 0; i < hdd_num; i++) {
+               err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL);
+               if (err == 0) {
+                       err = gpio_direction_output(
+                                       lacie_v2_gpio_hdd_power[i], 1);
+                       /* Free the HDD power GPIOs. This allow user-space to
+                        * configure them via the gpiolib sysfs interface. */
+                       gpio_free(lacie_v2_gpio_hdd_power[i]);
+               }
+               if (err)
+                       pr_err("Failed to power up HDD%d\n", i + 1);
+       }
+}
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void lacie_v2_timer_init(void)
+{
+       kirkwood_tclk = 166666667;
+       orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer lacie_v2_timer = {
+       .init = lacie_v2_timer_init,
+};
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h
new file mode 100644 (file)
index 0000000..af52131
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.h
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+
+void lacie_v2_register_flash(void);
+void lacie_v2_register_i2c_devices(void);
+void lacie_v2_hdd_power_init(int hdd_num);
+
+extern struct sys_timer lacie_v2_timer;
+
+#endif
index d26bf324738bde48e5be8b5c5cf13978a9f03730..fed264d28f4a17272230ae96a95c29fda8ef9ccb 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/leds.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
 #include <mach/kirkwood.h>
 #include <mach/leds-ns2.h>
-#include <plat/time.h>
 #include "common.h"
 #include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netspace_v2_flash_parts[] = {
-       {
-               .name = "u-boot",
-               .size = MTDPART_SIZ_FULL,
-               .offset = 0,
-               .mask_flags = MTD_WRITEABLE, /* force read-only */
-       },
-};
-
-static const struct flash_platform_data netspace_v2_flash = {
-       .type           = "mx25l4005a",
-       .name           = "spi_flash",
-       .parts          = netspace_v2_flash_parts,
-       .nr_parts       = ARRAY_SIZE(netspace_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = {
-       {
-               .modalias       = "m25p80",
-               .platform_data  = &netspace_v2_flash,
-               .irq            = -1,
-               .max_speed_hz   = 20000000,
-               .bus_num        = 0,
-               .chip_select    = 0,
-       },
-};
+#include "lacie_v2-common.h"
 
 /*****************************************************************************
  * Ethernet
@@ -83,27 +46,6 @@ static struct mv643xx_eth_platform_data netspace_v2_ge00_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
-/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
-       .byte_len       = SZ_4K / 8,
-       .page_size      = 16,
-};
-
-/*
- * i2c addr | chip         | description
- * 0x50     | HT24LC04     | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netspace_v2_i2c_info[] = {
-       {
-               I2C_BOARD_INFO("24c04", 0x50),
-               .platform_data  = &at24c04,
-       }
-};
-
 /*****************************************************************************
  * SATA
  ****************************************************************************/
@@ -112,35 +54,6 @@ static struct mv_sata_platform_data netspace_v2_sata_data = {
        .n_ports        = 2,
 };
 
-#define NETSPACE_V2_GPIO_SATA0_POWER   16
-#define NETSPACE_V2_GPIO_SATA1_POWER   17
-
-static void __init netspace_v2_sata_power_init(void)
-{
-       int err;
-
-       err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power");
-       if (err == 0) {
-               err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1);
-               if (err)
-                       gpio_free(NETSPACE_V2_GPIO_SATA0_POWER);
-       }
-       if (err)
-               pr_err("netspace_v2: failed to setup SATA0 power\n");
-
-       if (machine_is_netspace_max_v2()) {
-               err = gpio_request(NETSPACE_V2_GPIO_SATA1_POWER, "SATA1 power");
-               if (err == 0) {
-                       err = gpio_direction_output(
-                                       NETSPACE_V2_GPIO_SATA1_POWER, 1);
-                       if (err)
-                               gpio_free(NETSPACE_V2_GPIO_SATA1_POWER);
-               }
-               if (err)
-                       pr_err("netspace_v2: failed to setup SATA1 power\n");
-       }
-}
-
 /*****************************************************************************
  * GPIO keys
  ****************************************************************************/
@@ -223,20 +136,6 @@ static struct platform_device netspace_v2_leds = {
        },
 };
 
-/*****************************************************************************
- * Timer
- ****************************************************************************/
-
-static void netspace_v2_timer_init(void)
-{
-       kirkwood_tclk = 166666667;
-       orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
-
-struct sys_timer netspace_v2_timer = {
-       .init = netspace_v2_timer_init,
-};
-
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
@@ -291,18 +190,17 @@ static void __init netspace_v2_init(void)
        kirkwood_init();
        kirkwood_mpp_conf(netspace_v2_mpp_config);
 
-       netspace_v2_sata_power_init();
+       if (machine_is_netspace_max_v2())
+               lacie_v2_hdd_power_init(2);
+       else
+               lacie_v2_hdd_power_init(1);
 
        kirkwood_ehci_init();
        kirkwood_ge00_init(&netspace_v2_ge00_data);
        kirkwood_sata_init(&netspace_v2_sata_data);
        kirkwood_uart0_init();
-       spi_register_board_info(netspace_v2_spi_slave_info,
-                               ARRAY_SIZE(netspace_v2_spi_slave_info));
-       kirkwood_spi_init();
-       kirkwood_i2c_init();
-       i2c_register_board_info(0, netspace_v2_i2c_info,
-                               ARRAY_SIZE(netspace_v2_i2c_info));
+       lacie_v2_register_flash();
+       lacie_v2_register_i2c_devices();
 
        platform_device_register(&netspace_v2_leds);
        platform_device_register(&netspace_v2_gpio_leds);
@@ -323,7 +221,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &netspace_v2_timer,
+       .timer          = &lacie_v2_timer,
 MACHINE_END
 #endif
 
@@ -335,7 +233,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &netspace_v2_timer,
+       .timer          = &lacie_v2_timer,
 MACHINE_END
 #endif
 
@@ -347,6 +245,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &netspace_v2_timer,
+       .timer          = &lacie_v2_timer,
 MACHINE_END
 #endif
index 2bd14c5079de7c0e7379439523aed3422173f383..d970e1eee37d9b556fda46438742c1f5612cbe8a 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/leds.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
 #include <mach/kirkwood.h>
-#include <plat/time.h>
+#include <mach/leds-netxbig.h>
 #include "common.h"
 #include "mpp.h"
-
-/*****************************************************************************
- * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
- ****************************************************************************/
-
-static struct mtd_partition netxbig_v2_flash_parts[] = {
-       {
-               .name = "u-boot",
-               .size = MTDPART_SIZ_FULL,
-               .offset = 0,
-               .mask_flags = MTD_WRITEABLE, /* force read-only */
-       },
-};
-
-static const struct flash_platform_data netxbig_v2_flash = {
-       .type           = "mx25l4005a",
-       .name           = "spi_flash",
-       .parts          = netxbig_v2_flash_parts,
-       .nr_parts       = ARRAY_SIZE(netxbig_v2_flash_parts),
-};
-
-static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = {
-       {
-               .modalias       = "m25p80",
-               .platform_data  = &netxbig_v2_flash,
-               .irq            = -1,
-               .max_speed_hz   = 20000000,
-               .bus_num        = 0,
-               .chip_select    = 0,
-       },
-};
+#include "lacie_v2-common.h"
 
 /*****************************************************************************
  * Ethernet
@@ -85,27 +49,6 @@ static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
 };
 
-/*****************************************************************************
- * I2C devices
- ****************************************************************************/
-
-static struct at24_platform_data at24c04 = {
-       .byte_len       = SZ_4K / 8,
-       .page_size      = 16,
-};
-
-/*
- * i2c addr | chip         | description
- * 0x50     | HT24LC04     | eeprom (512B)
- */
-
-static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = {
-       {
-               I2C_BOARD_INFO("24c04", 0x50),
-               .platform_data  = &at24c04,
-       }
-};
-
 /*****************************************************************************
  * SATA
  ****************************************************************************/
@@ -114,34 +57,6 @@ static struct mv_sata_platform_data netxbig_v2_sata_data = {
        .n_ports        = 2,
 };
 
-static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
-
-static void __init netxbig_v2_sata_power_init(void)
-{
-       int i;
-       int err;
-       int hdd_nb;
-
-       if (machine_is_net2big_v2())
-               hdd_nb = 2;
-       else
-               hdd_nb = 5;
-
-       /* Power up all hard disks. */
-       for (i = 0; i < hdd_nb; i++) {
-               err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL);
-               if (err == 0) {
-                       err = gpio_direction_output(
-                                       netxbig_v2_gpio_hdd_power[i], 1);
-                       /* Free the HDD power GPIOs. This allow user-space to
-                        * configure them via the gpiolib sysfs interface. */
-                       gpio_free(netxbig_v2_gpio_hdd_power[i]);
-               }
-               if (err)
-                       pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1);
-       }
-}
-
 /*****************************************************************************
  * GPIO keys
  ****************************************************************************/
@@ -190,7 +105,7 @@ static struct platform_device netxbig_v2_gpio_buttons = {
 };
 
 /*****************************************************************************
- * GPIO LEDs
+ * GPIO extension LEDs
  ****************************************************************************/
 
 /*
@@ -200,19 +115,32 @@ static struct platform_device netxbig_v2_gpio_buttons = {
  * - address register : bit [0-2] -> GPIO [47-49]
  * - data register    : bit [0-2] -> GPIO [44-46]
  * - enable register  : GPIO 29
- *
+ */
+
+static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
+static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
+
+static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
+       .addr           = netxbig_v2_gpio_ext_addr,
+       .num_addr       = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
+       .data           = netxbig_v2_gpio_ext_data,
+       .num_data       = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
+       .enable         = 29,
+};
+
+/*
  * Address register selection:
  *
  * addr | register
  * ----------------------------
  *   0  | front LED
  *   1  | front LED brightness
- *   2  | HDD LED brightness
- *   3  | HDD1 LED
- *   4  | HDD2 LED
- *   5  | HDD3 LED
- *   6  | HDD4 LED
- *   7  | HDD5 LED
+ *   2  | SATA LED brightness
+ *   3  | SATA0 LED
+ *   4  | SATA1 LED
+ *   5  | SATA2 LED
+ *   6  | SATA3 LED
+ *   7  | SATA4 LED
  *
  * Data register configuration:
  *
@@ -233,30 +161,107 @@ static struct platform_device netxbig_v2_gpio_buttons = {
  *   6  | blink blue on=1 sec and red on=1 sec
  *   7  | blink blue on=0.5 sec and blue off=2.5 sec
  *
- * data | HDD LED mode
+ * data | SATA LED mode
  * -------------------------------------------------
- *   0  | fix blue on
+ *   0  | fix off
  *   1  | SATA activity blink
  *   2  | fix red on
  *   3  | blink blue on=1 sec and blue off=1 sec
  *   4  | blink red on=1 sec and red off=1 sec
  *   5  | blink blue on=2.5 sec and red on=0.5 sec
  *   6  | blink blue on=1 sec and red on=1 sec
- *   7  | blink blue on=0.5 sec and blue off=2.5 sec
+ *   7  | fix blue on
  */
 
-/*****************************************************************************
- * Timer
- ****************************************************************************/
+static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
+       [NETXBIG_LED_OFF]       = 0,
+       [NETXBIG_LED_ON]        = 2,
+       [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
+       [NETXBIG_LED_TIMER1]    = 4,
+       [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
+};
 
-static void netxbig_v2_timer_init(void)
-{
-       kirkwood_tclk = 166666667;
-       orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
+static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
+       [NETXBIG_LED_OFF]       = 0,
+       [NETXBIG_LED_ON]        = 1,
+       [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
+       [NETXBIG_LED_TIMER1]    = 3,
+       [NETXBIG_LED_TIMER2]    = 7,
+};
+
+static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
+       [NETXBIG_LED_OFF]       = 0,
+       [NETXBIG_LED_ON]        = 7,
+       [NETXBIG_LED_SATA]      = 1,
+       [NETXBIG_LED_TIMER1]    = 3,
+       [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
+};
+
+static struct netxbig_led_timer netxbig_v2_led_timer[] = {
+       [0] = {
+               .delay_on       = 500,
+               .delay_off      = 500,
+               .mode           = NETXBIG_LED_TIMER1,
+       },
+       [1] = {
+               .delay_on       = 500,
+               .delay_off      = 1000,
+               .mode           = NETXBIG_LED_TIMER2,
+       },
+};
+
+#define NETXBIG_LED(_name, maddr, mval, baddr)                 \
+       { .name         = _name,                                \
+         .mode_addr    = maddr,                                \
+         .mode_val     = mval,                                 \
+         .bright_addr  = baddr }
+
+static struct netxbig_led net2big_v2_leds_ctrl[] = {
+       NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
+       NETXBIG_LED("net2big-v2:red:power",  0, netxbig_v2_red_mled,       1),
+       NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net2big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
+       NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net2big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
+};
+
+static struct netxbig_led_platform_data net2big_v2_leds_data = {
+       .gpio_ext       = &netxbig_v2_gpio_ext,
+       .timer          = netxbig_v2_led_timer,
+       .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
+       .leds           = net2big_v2_leds_ctrl,
+       .num_leds       = ARRAY_SIZE(net2big_v2_leds_ctrl),
+};
+
+static struct netxbig_led net5big_v2_leds_ctrl[] = {
+       NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
+       NETXBIG_LED("net5big-v2:red:power",  0, netxbig_v2_red_mled,       1),
+       NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net5big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
+       NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net5big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
+       NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net5big-v2:red:sata2",  5, netxbig_v2_red_mled,       2),
+       NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net5big-v2:red:sata3",  6, netxbig_v2_red_mled,       2),
+       NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
+       NETXBIG_LED("net5big-v2:red:sata5",  7, netxbig_v2_red_mled,       2),
+};
 
-struct sys_timer netxbig_v2_timer = {
-       .init = netxbig_v2_timer_init,
+static struct netxbig_led_platform_data net5big_v2_leds_data = {
+       .gpio_ext       = &netxbig_v2_gpio_ext,
+       .timer          = netxbig_v2_led_timer,
+       .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
+       .leds           = net5big_v2_leds_ctrl,
+       .num_leds       = ARRAY_SIZE(net5big_v2_leds_ctrl),
+};
+
+static struct platform_device netxbig_v2_leds = {
+       .name           = "leds-netxbig",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &net2big_v2_leds_data,
+       },
 };
 
 /*****************************************************************************
@@ -284,18 +289,18 @@ static unsigned int net2big_v2_mpp_config[] __initdata = {
        MPP24_GPIO,             /* USB mode select */
        MPP26_GPIO,             /* USB device vbus */
        MPP28_GPIO,             /* USB enable host vbus */
-       MPP29_GPIO,             /* CPLD extension ALE */
+       MPP29_GPIO,             /* GPIO extension ALE */
        MPP34_GPIO,             /* Rear Push button */
        MPP35_GPIO,             /* Inhibit switch power-off */
        MPP36_GPIO,             /* SATA HDD1 presence */
        MPP37_GPIO,             /* SATA HDD2 presence */
        MPP40_GPIO,             /* eSATA presence */
-       MPP44_GPIO,             /* CPLD extension (data 0) */
-       MPP45_GPIO,             /* CPLD extension (data 1) */
-       MPP46_GPIO,             /* CPLD extension (data 2) */
-       MPP47_GPIO,             /* CPLD extension (addr 0) */
-       MPP48_GPIO,             /* CPLD extension (addr 1) */
-       MPP49_GPIO,             /* CPLD extension (addr 2) */
+       MPP44_GPIO,             /* GPIO extension (data 0) */
+       MPP45_GPIO,             /* GPIO extension (data 1) */
+       MPP46_GPIO,             /* GPIO extension (data 2) */
+       MPP47_GPIO,             /* GPIO extension (addr 0) */
+       MPP48_GPIO,             /* GPIO extension (addr 1) */
+       MPP49_GPIO,             /* GPIO extension (addr 2) */
        0
 };
 
@@ -324,7 +329,7 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
        MPP26_GE1_RXD2,
        MPP27_GE1_RXD3,
        MPP28_GPIO,             /* USB enable host vbus */
-       MPP29_GPIO,             /* CPLD extension ALE */
+       MPP29_GPIO,             /* GPIO extension ALE */
        MPP30_GE1_RXCTL,
        MPP31_GE1_RXCLK,
        MPP32_GE1_TCLKOUT,
@@ -339,12 +344,12 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
        MPP41_GPIO,             /* SATA HDD3 power */
        MPP42_GPIO,             /* SATA HDD4 power */
        MPP43_GPIO,             /* SATA HDD5 power */
-       MPP44_GPIO,             /* CPLD extension (data 0) */
-       MPP45_GPIO,             /* CPLD extension (data 1) */
-       MPP46_GPIO,             /* CPLD extension (data 2) */
-       MPP47_GPIO,             /* CPLD extension (addr 0) */
-       MPP48_GPIO,             /* CPLD extension (addr 1) */
-       MPP49_GPIO,             /* CPLD extension (addr 2) */
+       MPP44_GPIO,             /* GPIO extension (data 0) */
+       MPP45_GPIO,             /* GPIO extension (data 1) */
+       MPP46_GPIO,             /* GPIO extension (data 2) */
+       MPP47_GPIO,             /* GPIO extension (addr 0) */
+       MPP48_GPIO,             /* GPIO extension (addr 1) */
+       MPP49_GPIO,             /* GPIO extension (addr 2) */
        0
 };
 
@@ -366,7 +371,10 @@ static void __init netxbig_v2_init(void)
        else
                kirkwood_mpp_conf(net5big_v2_mpp_config);
 
-       netxbig_v2_sata_power_init();
+       if (machine_is_net2big_v2())
+               lacie_v2_hdd_power_init(2);
+       else
+               lacie_v2_hdd_power_init(5);
 
        kirkwood_ehci_init();
        kirkwood_ge00_init(&netxbig_v2_ge00_data);
@@ -374,13 +382,12 @@ static void __init netxbig_v2_init(void)
                kirkwood_ge01_init(&netxbig_v2_ge01_data);
        kirkwood_sata_init(&netxbig_v2_sata_data);
        kirkwood_uart0_init();
-       spi_register_board_info(netxbig_v2_spi_slave_info,
-                               ARRAY_SIZE(netxbig_v2_spi_slave_info));
-       kirkwood_spi_init();
-       kirkwood_i2c_init();
-       i2c_register_board_info(0, netxbig_v2_i2c_info,
-                               ARRAY_SIZE(netxbig_v2_i2c_info));
+       lacie_v2_register_flash();
+       lacie_v2_register_i2c_devices();
 
+       if (machine_is_net5big_v2())
+               netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
+       platform_device_register(&netxbig_v2_leds);
        platform_device_register(&netxbig_v2_gpio_buttons);
 
        if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
@@ -398,7 +405,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
        .init_machine   = netxbig_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &netxbig_v2_timer,
+       .timer          = &lacie_v2_timer,
 MACHINE_END
 #endif
 
@@ -410,6 +417,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
        .init_machine   = netxbig_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &netxbig_v2_timer,
+       .timer          = &lacie_v2_timer,
 MACHINE_END
 #endif
index fd06be6188159da478ba8311dbec6f6b167e3df9..38017c8ac43fc2f1a25523f1770b0ec212c498e8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/i2c.h>
+#include <linux/gpio.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
@@ -57,7 +58,22 @@ static struct mvsdio_platform_data openrd_mvsdio_data = {
 };
 
 static unsigned int openrd_mpp_config[] __initdata = {
+       MPP12_SD_CLK,
+       MPP13_SD_CMD,
+       MPP14_SD_D0,
+       MPP15_SD_D1,
+       MPP16_SD_D2,
+       MPP17_SD_D3,
+       MPP28_GPIO,
        MPP29_GPIO,
+       MPP34_GPIO,
+       0
+};
+
+/* Configure MPP for UART1 */
+static unsigned int openrd_uart1_mpp_config[] __initdata = {
+       MPP13_UART1_TXD,
+       MPP14_UART1_RXD,
        0
 };
 
@@ -67,6 +83,68 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
        },
 };
 
+static int __initdata uart1;
+
+static int __init sd_uart_selection(char *str)
+{
+       uart1 = -EINVAL;
+
+       /* Default is SD. Change if required, for UART */
+       if (!str)
+               return 0;
+
+       if (!strncmp(str, "232", 3)) {
+               uart1 = 232;
+       } else if (!strncmp(str, "485", 3)) {
+               /* OpenRD-Base doesn't have RS485. Treat is as an
+                * unknown argument & just have default setting -
+                * which is SD */
+               if (machine_is_openrd_base()) {
+                       uart1 = -ENODEV;
+                       return 1;
+               }
+
+               uart1 = 485;
+       }
+       return 1;
+}
+/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */
+__setup("kw_openrd_init_uart1=", sd_uart_selection);
+
+static int __init uart1_mpp_config(void)
+{
+       kirkwood_mpp_conf(openrd_uart1_mpp_config);
+
+       if (gpio_request(34, "SD_UART1_SEL")) {
+               printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
+                               ", gpio: 34\n");
+               return -EIO;
+       }
+
+       if (gpio_request(28, "RS232_RS485_SEL")) {
+               printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
+                               ", gpio# 28\n");
+               gpio_free(34);
+               return -EIO;
+       }
+
+       /* Select UART1
+        * Pin # 34: 0 => UART1, 1 => SD */
+       gpio_direction_output(34, 0);
+
+       /* Select RS232 OR RS485
+        * Pin # 28: 0 => RS232, 1 => RS485 */
+       if (uart1 == 232)
+               gpio_direction_output(28, 0);
+       else
+               gpio_direction_output(28, 1);
+
+       gpio_free(34);
+       gpio_free(28);
+
+       return 0;
+}
+
 static void __init openrd_init(void)
 {
        /*
@@ -90,7 +168,6 @@ static void __init openrd_init(void)
                kirkwood_ge01_init(&openrd_ge01_data);
 
        kirkwood_sata_init(&openrd_sata_data);
-       kirkwood_sdio_init(&openrd_mvsdio_data);
 
        kirkwood_i2c_init();
 
@@ -99,6 +176,28 @@ static void __init openrd_init(void)
                        ARRAY_SIZE(i2c_board_info));
                kirkwood_audio_init();
        }
+
+       if (uart1 <= 0) {
+               if (uart1 < 0)
+                       printk(KERN_ERR "Invalid kernel parameter to select "
+                               "UART1. Defaulting to SD. ERROR CODE: %d\n",
+                               uart1);
+
+               /* Select SD
+                * Pin # 34: 0 => UART1, 1 => SD */
+               if (gpio_request(34, "SD_UART1_SEL")) {
+                       printk(KERN_ERR "GPIO request failed for SD/UART1 "
+                                       "selection, gpio: 34\n");
+               } else {
+
+                       gpio_direction_output(34, 1);
+                       gpio_free(34);
+                       kirkwood_sdio_init(&openrd_mvsdio_data);
+               }
+       } else {
+               if (!uart1_mpp_config())
+                       kirkwood_uart1_init();
+       }
 }
 
 static int __init openrd_pci_init(void)
index 55e7f00836b7cdba68a9662729119e977904a2dd..513ad3102d7c192d2fdc00229b6cdb527b002d87 100644 (file)
@@ -117,7 +117,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp)
         * IORESOURCE_IO
         */
        pp->res[0].name = "PCIe 0 I/O Space";
-       pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+       pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
        pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
        pp->res[0].flags = IORESOURCE_IO;
 
@@ -139,7 +139,7 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
         * IORESOURCE_IO
         */
        pp->res[0].name = "PCIe 1 I/O Space";
-       pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE;
+       pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE;
        pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
        pp->res[0].flags = IORESOURCE_IO;
 
index 6ab843eaa35b507b5df31773ecc6fe5a60200b23..0711d3b620ad2286ea5aaabd035fbc1e19627e81 100644 (file)
@@ -57,6 +57,13 @@ config MACH_MARVELL_JASPER
          PXA910-based development board. Since MMP2 is compatible to
          ARMv6 architecture.
 
+config MACH_TETON_BGA
+       bool "Marvell's PXA168 Teton BGA Development Board"
+       select CPU_PXA168
+       help
+         Say 'Y' here if you want to support the Marvell PXA168-based
+         Teton BGA Development Board.
+
 endmenu
 
 config CPU_PXA168
index 8b66d06739c4d9c02ea1c03e98b1d23548894e8d..751cdbf733c852c5970e77e32013d28931b0113e 100644 (file)
@@ -17,3 +17,4 @@ obj-$(CONFIG_MACH_TAVOREVB)   += tavorevb.o
 obj-$(CONFIG_MACH_TTC_DKB)     += ttc_dkb.o
 obj-$(CONFIG_MACH_FLINT)       += flint.o
 obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
+obj-$(CONFIG_MACH_TETON_BGA)   += teton_bga.o
index 0629394a5fb9ad3dce6b73f0298a9ae56f52310f..4681bedbe788f9f4f920e5576c9ced6ed24f96b3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -23,6 +24,9 @@
 #include <mach/mfp-pxa168.h>
 #include <mach/pxa168.h>
 #include <mach/gpio.h>
+#include <video/pxa168fb.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
 
 #include "common.h"
 
@@ -66,6 +70,43 @@ static unsigned long common_pin_config[] __initdata = {
        GPIO115_I2S_BCLK,
        GPIO116_I2S_RXD,
        GPIO117_I2S_TXD,
+
+       /* LCD */
+       GPIO56_LCD_FCLK_RD,
+       GPIO57_LCD_LCLK_A0,
+       GPIO58_LCD_PCLK_WR,
+       GPIO59_LCD_DENA_BIAS,
+       GPIO60_LCD_DD0,
+       GPIO61_LCD_DD1,
+       GPIO62_LCD_DD2,
+       GPIO63_LCD_DD3,
+       GPIO64_LCD_DD4,
+       GPIO65_LCD_DD5,
+       GPIO66_LCD_DD6,
+       GPIO67_LCD_DD7,
+       GPIO68_LCD_DD8,
+       GPIO69_LCD_DD9,
+       GPIO70_LCD_DD10,
+       GPIO71_LCD_DD11,
+       GPIO72_LCD_DD12,
+       GPIO73_LCD_DD13,
+       GPIO74_LCD_DD14,
+       GPIO75_LCD_DD15,
+       GPIO76_LCD_DD16,
+       GPIO77_LCD_DD17,
+       GPIO78_LCD_DD18,
+       GPIO79_LCD_DD19,
+       GPIO80_LCD_DD20,
+       GPIO81_LCD_DD21,
+       GPIO82_LCD_DD22,
+       GPIO83_LCD_DD23,
+
+       /* Keypad */
+       GPIO109_KP_MKIN1,
+       GPIO110_KP_MKIN0,
+       GPIO111_KP_MKOUT7,
+       GPIO112_KP_MKOUT6,
+       GPIO121_KP_MKIN4,
 };
 
 static struct smc91x_platdata smc91x_info = {
@@ -134,6 +175,51 @@ static struct i2c_board_info aspenite_i2c_info[] __initdata = {
        { I2C_BOARD_INFO("wm8753", 0x1b), },
 };
 
+static struct fb_videomode video_modes[] = {
+       [0] = {
+               .pixclock       = 30120,
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .hsync_len      = 1,
+               .left_margin    = 215,
+               .right_margin   = 40,
+               .vsync_len      = 1,
+               .upper_margin   = 34,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+       },
+};
+
+struct pxa168fb_mach_info aspenite_lcd_info = {
+       .id                     = "Graphic Frame",
+       .modes                  = video_modes,
+       .num_modes              = ARRAY_SIZE(video_modes),
+       .pix_fmt                = PIX_FMT_RGB565,
+       .io_pin_allocation_mode = PIN_MODE_DUMB_24,
+       .dumb_mode              = DUMB_MODE_RGB888,
+       .active                 = 1,
+       .panel_rbswap           = 0,
+       .invert_pixclock        = 0,
+};
+
+static unsigned int aspenite_matrix_key_map[] = {
+       KEY(0, 6, KEY_UP),      /* SW 4 */
+       KEY(0, 7, KEY_DOWN),    /* SW 5 */
+       KEY(1, 6, KEY_LEFT),    /* SW 6 */
+       KEY(1, 7, KEY_RIGHT),   /* SW 7 */
+       KEY(4, 6, KEY_ENTER),   /* SW 8 */
+       KEY(4, 7, KEY_ESC),     /* SW 9 */
+};
+
+static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
+       .matrix_key_rows        = 5,
+       .matrix_key_cols        = 8,
+       .matrix_key_map         = aspenite_matrix_key_map,
+       .matrix_key_map_size    = ARRAY_SIZE(aspenite_matrix_key_map),
+       .debounce_interval      = 30,
+};
+
 static void __init common_init(void)
 {
        mfp_config(ARRAY_AND_SIZE(common_pin_config));
@@ -143,6 +229,8 @@ static void __init common_init(void)
        pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
        pxa168_add_ssp(1);
        pxa168_add_nand(&aspenite_nand_info);
+       pxa168_add_fb(&aspenite_lcd_info);
+       pxa168_add_keypad(&aspenite_keypad_info);
 
        /* off-chip devices */
        platform_device_register(&smc91x_device);
@@ -152,6 +240,7 @@ MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
        .phys_io        = APB_PHYS_BASE,
        .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
        .map_io         = mmp_map_io,
+       .nr_irqs        = IRQ_BOARD_START,
        .init_irq       = pxa168_init_irq,
        .timer          = &pxa168_timer,
        .init_machine   = common_init,
@@ -161,6 +250,7 @@ MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
        .phys_io        = APB_PHYS_BASE,
        .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
        .map_io         = mmp_map_io,
+       .nr_irqs        = IRQ_BOARD_START,
        .init_irq       = pxa168_init_irq,
        .timer          = &pxa168_timer,
        .init_machine   = common_init,
index 3b29fa7e9b084c1c3891aea452d1e5cda5c35a03..0ec0ca80bb3ed4e87300030484ee21fa9ac6177a 100644 (file)
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/mach/map.h>
 #include <mach/addr-map.h>
+#include <mach/cputype.h>
 
 #include "common.h"
 
+#define MMP_CHIPID     (AXI_VIRT_BASE + 0x82c00)
+
+unsigned int mmp_chip_id;
+EXPORT_SYMBOL(mmp_chip_id);
+
 static struct map_desc standard_io_desc[] __initdata = {
        {
                .pfn            = __phys_to_pfn(APB_PHYS_BASE),
@@ -34,4 +41,7 @@ static struct map_desc standard_io_desc[] __initdata = {
 void __init mmp_map_io(void)
 {
        iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+
+       /* this is early, initialize mmp_chip_id here */
+       mmp_chip_id = __raw_readl(MMP_CHIPID);
 }
index e4312d238eae3ec4e3a4b9a93564a5a265619549..c558425c36138698edf346e92e6d44015040954b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/smc91x.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -25,6 +26,8 @@
 
 #include "common.h"
 
+#define FLINT_NR_IRQS  (IRQ_BOARD_START + 48)
+
 static unsigned long flint_pin_config[] __initdata = {
        /* UART1 */
        GPIO45_UART1_RXD,
@@ -116,6 +119,7 @@ MACHINE_START(FLINT, "Flint Development Platform")
        .phys_io        = APB_PHYS_BASE,
        .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
        .map_io         = mmp_map_io,
+       .nr_irqs        = FLINT_NR_IRQS,
        .init_irq       = mmp2_init_irq,
        .timer          = &mmp2_timer,
        .init_machine   = flint_init,
index 83b18721d93305f6c9f47b0989e21b3e2006b0e5..f43a68b213f111a200e0395638e3cc538e442b3e 100644 (file)
@@ -4,36 +4,51 @@
 #include <asm/cputype.h>
 
 /*
- *  CPU   Stepping   OLD_ID       CPU_ID      CHIP_ID
+ *  CPU   Stepping   CPU_ID      CHIP_ID
  *
- * PXA168    A0    0x41159263   0x56158400   0x00A0A333
- * PXA910    Y0    0x41159262   0x56158000   0x00F0C910
- * MMP2             Z0                 0x560f5811
+ * PXA168    S0    0x56158400   0x0000C910
+ * PXA168    A0    0x56158400   0x00A0A168
+ * PXA910    Y1    0x56158400   0x00F2C920
+ * PXA910    A0    0x56158400   0x00F2C910
+ * PXA910    A1    0x56158400   0x00A0C910
+ * PXA920    Y0    0x56158400   0x00F2C920
+ * PXA920    A0    0x56158400   0x00A0C920
+ * PXA920    A1    0x56158400   0x00A1C920
+ * MMP2             Z0    0x560f5811   0x00F00410
+ * MMP2      Z1    0x560f5811   0x00E00410
+ * MMP2      A0    0x560f5811   0x00A0A610
  */
 
+extern unsigned int mmp_chip_id;
+
 #ifdef CONFIG_CPU_PXA168
-#  define __cpu_is_pxa168(id)  \
-       ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
+static inline int cpu_is_pxa168(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+               ((mmp_chip_id & 0xfff) == 0x168);
+}
 #else
-#  define __cpu_is_pxa168(id)  (0)
+#define cpu_is_pxa168()        (0)
 #endif
 
+/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
 #ifdef CONFIG_CPU_PXA910
-#  define __cpu_is_pxa910(id)  \
-       ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; })
+static inline int cpu_is_pxa910(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+               (((mmp_chip_id & 0xfff) == 0x910) ||
+                ((mmp_chip_id & 0xfff) == 0x920));
+}
 #else
-#  define __cpu_is_pxa910(id)  (0)
+#define cpu_is_pxa910()        (0)
 #endif
 
 #ifdef CONFIG_CPU_MMP2
-#  define __cpu_is_mmp2(id)    \
-       ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; })
+static inline int cpu_is_mmp2(void)
+{
+       return (((cpu_readid_id() >> 8) & 0xff) == 0x58);
 #else
-#  define __cpu_is_mmp2(id)    (0)
+#define cpu_is_mmp2()  (0)
 #endif
 
-#define cpu_is_pxa168()                ({ __cpu_is_pxa168(read_cpuid_id()); })
-#define cpu_is_pxa910()                ({ __cpu_is_pxa910(read_cpuid_id()); })
-#define cpu_is_mmp2()          ({ __cpu_is_mmp2(read_cpuid_id()); })
-
 #endif /* __ASM_MACH_CPUTYPE_H */
index b379cdec4d38410d9caeedf927b6d8cbae4c9ef6..a09d328e2ddd02087cdd7d08c68d6950b0ff6250 100644 (file)
 #define IRQ_GPIO_NUM                   192
 #define IRQ_GPIO(x)                    (IRQ_GPIO_START + (x))
 
-/* Board IRQ - 64 by default, increase if not enough */
 #define IRQ_BOARD_START                        (IRQ_GPIO_START + IRQ_GPIO_NUM)
-#define IRQ_BOARD_END                  (IRQ_BOARD_START + 64)
 
-#define NR_IRQS                                (IRQ_BOARD_END)
+#define NR_IRQS                                (IRQ_BOARD_START)
 
 #endif /* __ASM_MACH_IRQS_H */
index ded43c455ec39870dab17e0da05d2c36d5a91329..4621067c7720f457b311faff80e19dddc87ecd3e 100644 (file)
 #define GPIO86_PWM1_OUT                MFP_CFG(GPIO86, AF2)
 #define GPIO86_PWM2_OUT                MFP_CFG(GPIO86, AF3)
 
+/* Keypad */
+#define GPIO109_KP_MKIN1        MFP_CFG(GPIO109, AF7)
+#define GPIO110_KP_MKIN0        MFP_CFG(GPIO110, AF7)
+#define GPIO111_KP_MKOUT7       MFP_CFG(GPIO111, AF7)
+#define GPIO112_KP_MKOUT6       MFP_CFG(GPIO112, AF7)
+#define GPIO121_KP_MKIN4        MFP_CFG(GPIO121, AF7)
+
 #endif /* __ASM_MACH_MFP_PXA168_H */
index 27e1bc758623808cb30ed6471ca2d45fb2b40dbd..1801e420623259a6a4004dd0f8f9ba280997fc0a 100644 (file)
@@ -5,11 +5,15 @@ struct sys_timer;
 
 extern struct sys_timer pxa168_timer;
 extern void __init pxa168_init_irq(void);
+extern void pxa168_clear_keypad_wakeup(void);
 
 #include <linux/i2c.h>
 #include <mach/devices.h>
 #include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
+#include <video/pxa168fb.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/cputype.h>
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -25,6 +29,8 @@ extern struct pxa_device_desc pxa168_device_ssp3;
 extern struct pxa_device_desc pxa168_device_ssp4;
 extern struct pxa_device_desc pxa168_device_ssp5;
 extern struct pxa_device_desc pxa168_device_nand;
+extern struct pxa_device_desc pxa168_device_fb;
+extern struct pxa_device_desc pxa168_device_keypad;
 
 static inline int pxa168_add_uart(int id)
 {
@@ -97,4 +103,18 @@ static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
 {
        return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
 }
+
+static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
+{
+       return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
+}
+
+static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
+{
+       if (cpu_is_pxa168())
+               data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
+
+       return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
+}
+
 #endif /* __ASM_MACH_PXA168_H */
index 9190305141201cf5d99aead14375420c38b7d4ca..ac4702357a6e5b026d8939bdd93fdad9c2ed2c6d 100644 (file)
 #define APMU_FNRST_DIS (1 << 1)
 #define APMU_AXIRST_DIS        (1 << 0)
 
+/* Wake Clear Register */
+#define APMU_WAKE_CLR  APMU_REG(0x07c)
+
+#define APMU_PXA168_KP_WAKE_CLR                (1 << 7)
+#define APMU_PXA168_CFI_WAKE_CLR       (1 << 6)
+#define APMU_PXA168_XD_WAKE_CLR                (1 << 5)
+#define APMU_PXA168_MSP_WAKE_CLR       (1 << 4)
+#define APMU_PXA168_SD4_WAKE_CLR       (1 << 3)
+#define APMU_PXA168_SD3_WAKE_CLR       (1 << 2)
+#define APMU_PXA168_SD2_WAKE_CLR       (1 << 1)
+#define APMU_PXA168_SD1_WAKE_CLR       (1 << 0)
+
 #endif /* __ASM_MACH_REGS_APMU_H */
index 4f5b0e0ce6cf8f87e0e843b82ce2f8b0b4cbc34c..1a8a25edb1b422ace6925e07171953390b51bc11 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef __ASM_MACH_SYSTEM_H
 #define __ASM_MACH_SYSTEM_H
 
+#include <mach/cputype.h>
+
 static inline void arch_idle(void)
 {
        cpu_do_idle();
@@ -16,6 +18,9 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode, const char *cmd)
 {
-       cpu_reset(0);
+       if (cpu_is_pxa168())
+               cpu_reset(0xffff0000);
+       else
+               cpu_reset(0);
 }
 #endif /* __ASM_MACH_SYSTEM_H */
diff --git a/arch/arm/mach-mmp/include/mach/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h
new file mode 100644 (file)
index 0000000..61a539b
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  linux/arch/arm/mach-mmp/include/mach/teton_bga.h
+ *
+ *  Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_TETON_BGA_H
+#define __ASM_MACH_TETON_BGA_H
+
+/* GPIOs */
+#define MMC_PWENA_GPIO         27
+#define USBHPENB_GPIO          55
+#define RTC_INT_GPIO           78
+#define LCD_VBLK_EN_GPIO       79
+#define LCD_DVDD_EN_GPIO       80
+#define RST_WIFI_GPIO          81
+#define CF_PWEN_GPIO           82
+#define USB_OC_GPIO            83
+#define PWM_GPIO               84
+#define USBHPENA_GPIO          85
+#define TS_INT_GPIO            86
+#define CIR_GPIO               108
+
+#endif /* __ASM_MACH_TETON_BGA_H */
index 80c3e7ab1e1700c2aa96bdb9270b0e5a57004b3f..940ee03e3682909449c3dd4fa36b839144276c08 100644 (file)
 #include <linux/regulator/machine.h>
 #include <linux/regulator/max8649.h>
 #include <linux/mfd/max8925.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/addr-map.h>
 #include <mach/mfp-mmp2.h>
 #include <mach/mmp2.h>
-#include <mach/irqs.h>
 
 #include "common.h"
 
+#define JASPER_NR_IRQS         (IRQ_BOARD_START + 48)
+
 static unsigned long jasper_pin_config[] __initdata = {
        /* UART1 */
        GPIO29_UART1_RXD,
@@ -137,6 +139,7 @@ MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
        .phys_io        = APB_PHYS_BASE,
        .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
        .map_io         = mmp_map_io,
+       .nr_irqs        = JASPER_NR_IRQS,
        .init_irq       = mmp2_init_irq,
        .timer          = &mmp2_timer,
        .init_machine   = jasper_init,
index 652ae660634c5fcd8409972994bd3f97d20acba2..72b4e76315830e91b9dad19dfdedcdf829021559 100644 (file)
@@ -77,8 +77,10 @@ static APBC_CLK(ssp2, PXA168_SSP2, 4, 0);
 static APBC_CLK(ssp3, PXA168_SSP3, 4, 0);
 static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
 static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
+static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
 
 static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(lcd, LCD, 0x7f, 312000000);
 
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
@@ -96,6 +98,8 @@ static struct clk_lookup pxa168_clkregs[] = {
        INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
        INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+       INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
+       INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
 };
 
 static int __init pxa168_init(void)
@@ -132,6 +136,16 @@ struct sys_timer pxa168_timer = {
        .init   = pxa168_timer_init,
 };
 
+void pxa168_clear_keypad_wakeup(void)
+{
+       uint32_t val;
+       uint32_t mask = APMU_PXA168_KP_WAKE_CLR;
+
+       /* wake event clear is needed in order to clear keypad interrupt */
+       val = __raw_readl(APMU_WAKE_CLR);
+       __raw_writel(val |  mask, APMU_WAKE_CLR);
+}
+
 /* on-chip devices */
 PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
 PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
@@ -147,3 +161,5 @@ PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55);
 PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57);
 PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
 PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
+PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
+PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
new file mode 100644 (file)
index 0000000..a4a375c
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  linux/arch/arm/mach-mmp/teton_bga.c
+ *
+ *  Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ *  Author: Mark F. Brown <mark.brown314@gmail.com>
+ *
+ *  This code is based on aspenite.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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/teton_bga.h>
+
+#include "common.h"
+
+static unsigned long teton_bga_pin_config[] __initdata = {
+       /* UART1 */
+       GPIO107_UART1_TXD,
+       GPIO108_UART1_RXD,
+
+       /* Keypad */
+       GPIO109_KP_MKIN1,
+       GPIO110_KP_MKIN0,
+       GPIO111_KP_MKOUT7,
+       GPIO112_KP_MKOUT6,
+
+       /* I2C Bus */
+       GPIO105_CI2C_SDA,
+       GPIO106_CI2C_SCL,
+
+       /* RTC */
+       GPIO78_GPIO,
+};
+
+static unsigned int teton_bga_matrix_key_map[] = {
+       KEY(0, 6, KEY_ESC),
+       KEY(0, 7, KEY_ENTER),
+       KEY(1, 6, KEY_LEFT),
+       KEY(1, 7, KEY_RIGHT),
+};
+
+static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
+       .matrix_key_rows        = 2,
+       .matrix_key_cols        = 8,
+       .matrix_key_map         = teton_bga_matrix_key_map,
+       .matrix_key_map_size    = ARRAY_SIZE(teton_bga_matrix_key_map),
+       .debounce_interval      = 30,
+};
+
+static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
+       {
+               I2C_BOARD_INFO("ds1337", 0x68),
+               .irq = gpio_to_irq(RTC_INT_GPIO)
+       },
+};
+
+static void __init teton_bga_init(void)
+{
+       mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config));
+
+       /* on-chip devices */
+       pxa168_add_uart(1);
+       pxa168_add_keypad(&teton_bga_keypad_info);
+       pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+}
+
+MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
+       .phys_io        = APB_PHYS_BASE,
+       .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
+       .map_io         = mmp_map_io,
+       .nr_irqs        = IRQ_BOARD_START,
+       .init_irq       = pxa168_init_irq,
+       .timer          = &pxa168_timer,
+       .init_machine   = teton_bga_init,
+MACHINE_END
index ee65e05f0cf15e0118461ce4a7b277e5038a77c2..54571139dc4b7e737ddfe4d95fd4cadeafe663b9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/onenand.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -24,6 +25,8 @@
 
 #include "common.h"
 
+#define TTCDKB_NR_IRQS         (IRQ_BOARD_START + 24)
+
 static unsigned long ttc_dkb_pin_config[] __initdata = {
        /* UART2 */
        GPIO47_UART2_RXD,
@@ -125,6 +128,7 @@ MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
        .phys_io        = APB_PHYS_BASE,
        .io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
        .map_io         = mmp_map_io,
+       .nr_irqs        = TTCDKB_NR_IRQS,
        .init_irq       = pxa910_init_irq,
        .timer          = &pxa910_timer,
        .init_machine   = ttc_dkb_init,
index 47264a76eeb31d52602ca9386960d4cbf0a012fb..3115a29dec4ea58b867cfa0dab424833ecbf7e5f 100644 (file)
@@ -10,6 +10,8 @@ config ARCH_MSM7X00A
        select MSM_SMD
        select MSM_SMD_PKG3
        select CPU_V6
+       select MSM_PROC_COMM
+       select HAS_MSM_DEBUG_UART_PHYS
 
 config ARCH_MSM7X30
        bool "MSM7x30"
@@ -18,6 +20,9 @@ config ARCH_MSM7X30
        select MSM_VIC
        select CPU_V7
        select MSM_REMOTE_SPINLOCK_DEKKERS
+       select MSM_GPIOMUX
+       select MSM_PROC_COMM
+       select HAS_MSM_DEBUG_UART_PHYS
 
 config ARCH_QSD8X50
        bool "QSD8X50"
@@ -26,6 +31,19 @@ config ARCH_QSD8X50
        select MSM_VIC
        select CPU_V7
        select MSM_REMOTE_SPINLOCK_LDREX
+       select MSM_GPIOMUX
+       select MSM_PROC_COMM
+       select HAS_MSM_DEBUG_UART_PHYS
+
+config ARCH_MSM8X60
+       bool "MSM8X60"
+       select ARM_GIC
+       select CPU_V7
+       select MSM_V2_TLMM
+       select MSM_GPIOMUX
+       select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
+                                 && !MACH_MSM8X60_FFA)
+
 endchoice
 
 config MSM_SOC_REV_A
@@ -36,6 +54,9 @@ config  ARCH_MSM_ARM11
 config  ARCH_MSM_SCORPION
        bool
 
+config HAS_MSM_DEBUG_UART_PHYS
+       bool
+
 config  MSM_VIC
        bool
 
@@ -74,6 +95,30 @@ config MACH_QSD8X50A_ST1_5
        help
          Support for the Qualcomm ST1.5.
 
+config MACH_MSM8X60_RUMI3
+       depends on ARCH_MSM8X60
+       bool "MSM8x60 RUMI3"
+       help
+         Support for the Qualcomm MSM8x60 RUMI3 emulator.
+
+config MACH_MSM8X60_SURF
+       depends on ARCH_MSM8X60
+       bool "MSM8x60 SURF"
+       help
+         Support for the Qualcomm MSM8x60 SURF eval board.
+
+config MACH_MSM8X60_SIM
+       depends on ARCH_MSM8X60
+       bool "MSM8x60 Simulator"
+       help
+         Support for the Qualcomm MSM8x60 simulator.
+
+config MACH_MSM8X60_FFA
+       depends on ARCH_MSM8X60
+       bool "MSM8x60 FFA"
+       help
+         Support for the Qualcomm MSM8x60 FFA eval board.
+
 endmenu
 
 config MSM_DEBUG_UART
@@ -82,6 +127,7 @@ config MSM_DEBUG_UART
        default 2 if MSM_DEBUG_UART2
        default 3 if MSM_DEBUG_UART3
 
+if HAS_MSM_DEBUG_UART_PHYS
 choice
        prompt "Debug UART"
 
@@ -99,11 +145,20 @@ choice
        config MSM_DEBUG_UART3
                bool "UART3"
 endchoice
+endif
 
 config MSM_SMD_PKG3
        bool
 
+config MSM_PROC_COMM
+       bool
+
 config MSM_SMD
        bool
 
+config MSM_GPIOMUX
+       bool
+
+config MSM_V2_TLMM
+       bool
 endif
index 704610648a255870d5b959899d1f1f0b3a8259d4..b5a7b07a44f53c9652048d10157f7a24745c53a2 100644 (file)
@@ -1,16 +1,20 @@
-obj-y += proc_comm.o
-obj-y += io.o idle.o timer.o dma.o
-obj-y += vreg.o
+obj-y += io.o idle.o timer.o
+ifndef CONFIG_ARCH_MSM8X60
 obj-y += acpuclock-arm11.o
-obj-y += clock.o clock-pcom.o
-obj-y += gpio.o
+obj-y += dma.o
+endif
 
 ifdef CONFIG_MSM_VIC
 obj-y += irq-vic.o
 else
+ifndef CONFIG_ARCH_MSM8X60
 obj-y += irq.o
 endif
+endif
 
+obj-$(CONFIG_ARCH_MSM8X60) += clock-dummy.o iommu.o iommu_dev.o devices-msm8x60-iommu.o
+obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
+obj-$(CONFIG_MSM_PROC_COMM) += clock.o
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
 obj-$(CONFIG_MSM_SMD) += last_radio_log.o
@@ -19,4 +23,11 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o d
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
+obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
 
+obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+ifndef CONFIG_MSM_V2_TLMM
+obj-y  += gpio.o
+endif
index e32981928c7701e2032414d69ef099fd6a1bd9db..76d5a22a6984ada8cc9d2f99ee7d2d2a995e8c5c 100644 (file)
 
 extern struct sys_timer msm_timer;
 
-#ifdef CONFIG_SERIAL_MSM_CONSOLE
-static struct msm_gpio uart2_config_data[] = {
-       { GPIO_CFG(49, 2, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"},
-       { GPIO_CFG(50, 2, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"},
-       { GPIO_CFG(51, 2, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
-       { GPIO_CFG(52, 2, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
-};
-
-static void msm7x30_init_uart2(void)
-{
-       msm_gpios_request_enable(uart2_config_data,
-                       ARRAY_SIZE(uart2_config_data));
-
-}
-#endif
-
 static struct platform_device *devices[] __initdata = {
 #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
         &msm_device_uart2,
 #endif
-
+       &msm_device_smd,
 };
 
 static void __init msm7x30_init_irq(void)
@@ -70,10 +54,6 @@ static void __init msm7x30_init_irq(void)
 static void __init msm7x30_init(void)
 {
        platform_add_devices(devices, ARRAY_SIZE(devices));
-#ifdef CONFIG_SERIAL_MSM_CONSOLE
-       msm7x30_init_uart2();
-#endif
-
 }
 
 static void __init msm7x30_map_io(void)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
new file mode 100644 (file)
index 0000000..7486a68
--- /dev/null
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+void __iomem *gic_cpu_base_addr;
+
+unsigned long clk_get_max_axi_khz(void)
+{
+       return 0;
+}
+
+static void __init msm8x60_map_io(void)
+{
+       msm_map_msm8x60_io();
+}
+
+static void __init msm8x60_init_irq(void)
+{
+       unsigned int i;
+
+       gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START);
+       gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE;
+       gic_cpu_init(0, MSM_QGIC_CPU_BASE);
+
+       /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+       writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+       /* RUMI does not adhere to GIC spec by enabling STIs by default.
+        * Enable/clear is supposed to be RO for STIs, but is RW on RUMI.
+        */
+       if (!machine_is_msm8x60_sim())
+               writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+
+       /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+        * as they are configured as level, which does not play nice with
+        * handle_percpu_irq.
+        */
+       for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+               if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+                       set_irq_handler(i, handle_percpu_irq);
+       }
+}
+
+static void __init msm8x60_init(void)
+{
+}
+
+MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+       .map_io = msm8x60_map_io,
+       .init_irq = msm8x60_init_irq,
+       .init_machine = msm8x60_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+       .map_io = msm8x60_map_io,
+       .init_irq = msm8x60_init_irq,
+       .init_machine = msm8x60_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+       .map_io = msm8x60_map_io,
+       .init_irq = msm8x60_init_irq,
+       .init_machine = msm8x60_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+       .map_io = msm8x60_map_io,
+       .init_irq = msm8x60_init_irq,
+       .init_machine = msm8x60_init,
+       .timer = &msm_timer,
+MACHINE_END
index e3cc80792d6c2bafbcb9bb68ce9505434d71c176..d5d5e441a52d8a8437c39f535bcf4d0023724a21 100644 (file)
 
 extern struct sys_timer msm_timer;
 
-static struct msm_gpio uart3_config_data[] = {
-       { GPIO_CFG(86, 1, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
-       { GPIO_CFG(87, 1, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
+static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300;
+static const unsigned        qsd8x50_surf_smc91x_gpio __initdata = 156;
+
+/* Leave smc91x resources empty here, as we'll fill them in
+ * at run-time: they vary from board to board, and the true
+ * configuration won't be known until boot.
+ */
+static struct resource smc91x_resources[] __initdata = {
+       [0] = {
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .flags = IORESOURCE_IRQ,
+       },
 };
 
-static struct platform_device *devices[] __initdata = {
-       &msm_device_uart3,
+static struct platform_device smc91x_device __initdata = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
 };
 
-static void msm8x50_init_uart3(void)
+static int __init msm_init_smc91x(void)
 {
-       msm_gpios_request_enable(uart3_config_data,
-                               ARRAY_SIZE(uart3_config_data));
+       if (machine_is_qsd8x50_surf()) {
+               smc91x_resources[0].start = qsd8x50_surf_smc91x_base;
+               smc91x_resources[0].end   = qsd8x50_surf_smc91x_base + 0xff;
+               smc91x_resources[1].start =
+                       gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+               smc91x_resources[1].end   =
+                       gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+               platform_device_register(&smc91x_device);
+       }
+
+       return 0;
 }
+module_init(msm_init_smc91x);
+
+static struct platform_device *devices[] __initdata = {
+       &msm_device_uart3,
+       &msm_device_smd,
+};
 
 static void __init qsd8x50_map_io(void)
 {
@@ -64,7 +93,6 @@ static void __init qsd8x50_init_irq(void)
 
 static void __init qsd8x50_init(void)
 {
-       msm8x50_init_uart3();
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
new file mode 100644 (file)
index 0000000..1250d22
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+       return -ENOENT;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       return -ENOENT;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
index b449e8ad2904c36905043e5bf951510052d89790..7fcf2e3b7698d5ef329a6483eefc29b7be432075 100644 (file)
@@ -51,6 +51,11 @@ struct platform_device msm_device_uart2 = {
        .resource       = resources_uart2,
 };
 
+struct platform_device msm_device_smd = {
+       .name   = "msm_smd",
+       .id     = -1,
+};
+
 struct clk msm_clocks_7x30[] = {
        CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
        CLK_PCOM("adsp_clk",    ADSP_CLK,       NULL, 0),
diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c
new file mode 100644 (file)
index 0000000..89b9d44
--- /dev/null
@@ -0,0 +1,883 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+
+#include <mach/msm_iomap-8x60.h>
+#include <mach/irqs-8x60.h>
+#include <mach/iommu.h>
+
+static struct resource msm_iommu_jpegd_resources[] = {
+       {
+               .start = MSM_IOMMU_JPEGD_PHYS,
+               .end   = MSM_IOMMU_JPEGD_PHYS + MSM_IOMMU_JPEGD_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+               .end   = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_vpe_resources[] = {
+       {
+               .start = MSM_IOMMU_VPE_PHYS,
+               .end   = MSM_IOMMU_VPE_PHYS + MSM_IOMMU_VPE_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_VPE_CB_SC_SECURE_IRQ,
+               .end   = SMMU_VPE_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_mdp0_resources[] = {
+       {
+               .start = MSM_IOMMU_MDP0_PHYS,
+               .end   = MSM_IOMMU_MDP0_PHYS + MSM_IOMMU_MDP0_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_MDP0_CB_SC_SECURE_IRQ,
+               .end   = SMMU_MDP0_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_mdp1_resources[] = {
+       {
+               .start = MSM_IOMMU_MDP1_PHYS,
+               .end   = MSM_IOMMU_MDP1_PHYS + MSM_IOMMU_MDP1_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_MDP1_CB_SC_SECURE_IRQ,
+               .end   = SMMU_MDP1_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_rot_resources[] = {
+       {
+               .start = MSM_IOMMU_ROT_PHYS,
+               .end   = MSM_IOMMU_ROT_PHYS + MSM_IOMMU_ROT_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_ROT_CB_SC_SECURE_IRQ,
+               .end   = SMMU_ROT_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_ijpeg_resources[] = {
+       {
+               .start = MSM_IOMMU_IJPEG_PHYS,
+               .end   = MSM_IOMMU_IJPEG_PHYS + MSM_IOMMU_IJPEG_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+               .end   = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_vfe_resources[] = {
+       {
+               .start = MSM_IOMMU_VFE_PHYS,
+               .end   = MSM_IOMMU_VFE_PHYS + MSM_IOMMU_VFE_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_VFE_CB_SC_SECURE_IRQ,
+               .end   = SMMU_VFE_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_vcodec_a_resources[] = {
+       {
+               .start = MSM_IOMMU_VCODEC_A_PHYS,
+               .end   = MSM_IOMMU_VCODEC_A_PHYS + MSM_IOMMU_VCODEC_A_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+               .end   = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_vcodec_b_resources[] = {
+       {
+               .start = MSM_IOMMU_VCODEC_B_PHYS,
+               .end   = MSM_IOMMU_VCODEC_B_PHYS + MSM_IOMMU_VCODEC_B_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+               .end   = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_gfx3d_resources[] = {
+       {
+               .start = MSM_IOMMU_GFX3D_PHYS,
+               .end   = MSM_IOMMU_GFX3D_PHYS + MSM_IOMMU_GFX3D_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+               .end   = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource msm_iommu_gfx2d0_resources[] = {
+       {
+               .start = MSM_IOMMU_GFX2D0_PHYS,
+               .end   = MSM_IOMMU_GFX2D0_PHYS + MSM_IOMMU_GFX2D0_SIZE - 1,
+               .name  = "physbase",
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name = "nonsecure_irq",
+               .start = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+               .end   = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .name = "secure_irq",
+               .start = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+               .end   = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device msm_root_iommu_dev = {
+       .name = "msm_iommu",
+       .id = -1,
+};
+
+static struct msm_iommu_dev jpegd_smmu = {
+       .name = "jpegd",
+       .clk_rate = -1
+};
+
+static struct msm_iommu_dev vpe_smmu = {
+       .name = "vpe"
+};
+
+static struct msm_iommu_dev mdp0_smmu = {
+       .name = "mdp0"
+};
+
+static struct msm_iommu_dev mdp1_smmu = {
+       .name = "mdp1"
+};
+
+static struct msm_iommu_dev rot_smmu = {
+       .name = "rot"
+};
+
+static struct msm_iommu_dev ijpeg_smmu = {
+       .name = "ijpeg"
+};
+
+static struct msm_iommu_dev vfe_smmu = {
+       .name = "vfe",
+       .clk_rate = -1
+};
+
+static struct msm_iommu_dev vcodec_a_smmu = {
+       .name = "vcodec_a"
+};
+
+static struct msm_iommu_dev vcodec_b_smmu = {
+       .name = "vcodec_b"
+};
+
+static struct msm_iommu_dev gfx3d_smmu = {
+       .name = "gfx3d",
+       .clk_rate = 27000000
+};
+
+static struct msm_iommu_dev gfx2d0_smmu = {
+       .name = "gfx2d0",
+       .clk_rate = 27000000
+};
+
+static struct platform_device msm_device_smmu_jpegd = {
+       .name = "msm_iommu",
+       .id = 0,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources),
+       .resource = msm_iommu_jpegd_resources,
+};
+
+static struct platform_device msm_device_smmu_vpe = {
+       .name = "msm_iommu",
+       .id = 1,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_vpe_resources),
+       .resource = msm_iommu_vpe_resources,
+};
+
+static struct platform_device msm_device_smmu_mdp0 = {
+       .name = "msm_iommu",
+       .id = 2,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources),
+       .resource = msm_iommu_mdp0_resources,
+};
+
+static struct platform_device msm_device_smmu_mdp1 = {
+       .name = "msm_iommu",
+       .id = 3,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources),
+       .resource = msm_iommu_mdp1_resources,
+};
+
+static struct platform_device msm_device_smmu_rot = {
+       .name = "msm_iommu",
+       .id = 4,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_rot_resources),
+       .resource = msm_iommu_rot_resources,
+};
+
+static struct platform_device msm_device_smmu_ijpeg = {
+       .name = "msm_iommu",
+       .id = 5,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources),
+       .resource = msm_iommu_ijpeg_resources,
+};
+
+static struct platform_device msm_device_smmu_vfe = {
+       .name = "msm_iommu",
+       .id = 6,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_vfe_resources),
+       .resource = msm_iommu_vfe_resources,
+};
+
+static struct platform_device msm_device_smmu_vcodec_a = {
+       .name = "msm_iommu",
+       .id = 7,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources),
+       .resource = msm_iommu_vcodec_a_resources,
+};
+
+static struct platform_device msm_device_smmu_vcodec_b = {
+       .name = "msm_iommu",
+       .id = 8,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources),
+       .resource = msm_iommu_vcodec_b_resources,
+};
+
+static struct platform_device msm_device_smmu_gfx3d = {
+       .name = "msm_iommu",
+       .id = 9,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources),
+       .resource = msm_iommu_gfx3d_resources,
+};
+
+static struct platform_device msm_device_smmu_gfx2d0 = {
+       .name = "msm_iommu",
+       .id = 10,
+       .dev = {
+               .parent = &msm_root_iommu_dev.dev,
+       },
+       .num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources),
+       .resource = msm_iommu_gfx2d0_resources,
+};
+
+static struct msm_iommu_ctx_dev jpegd_src_ctx = {
+       .name = "jpegd_src",
+       .num = 0,
+       .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev jpegd_dst_ctx = {
+       .name = "jpegd_dst",
+       .num = 1,
+       .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_src_ctx = {
+       .name = "vpe_src",
+       .num = 0,
+       .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_dst_ctx = {
+       .name = "vpe_dst",
+       .num = 1,
+       .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
+       .name = "mdp_vg1",
+       .num = 0,
+       .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
+       .name = "mdp_rgb1",
+       .num = 1,
+       .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
+       .name = "mdp_vg2",
+       .num = 0,
+       .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
+       .name = "mdp_rgb2",
+       .num = 1,
+       .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_src_ctx = {
+       .name = "rot_src",
+       .num = 0,
+       .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_dst_ctx = {
+       .name = "rot_dst",
+       .num = 1,
+       .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_src_ctx = {
+       .name = "ijpeg_src",
+       .num = 0,
+       .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_dst_ctx = {
+       .name = "ijpeg_dst",
+       .num = 1,
+       .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_imgwr_ctx = {
+       .name = "vfe_imgwr",
+       .num = 0,
+       .mids = {2, 3, 4, 5, 6, 7, 8, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_misc_ctx = {
+       .name = "vfe_misc",
+       .num = 1,
+       .mids = {0, 1, 9, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = {
+       .name = "vcodec_a_stream",
+       .num = 0,
+       .mids = {2, 5, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = {
+       .name = "vcodec_a_mm1",
+       .num = 1,
+       .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
+       .name = "vcodec_b_mm2",
+       .num = 0,
+       .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = {
+       .name = "gfx3d_rbpa",
+       .num = 0,
+       .mids = {-1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = {
+       .name = "gfx3d_cpvgttc",
+       .num = 1,
+       .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = {
+       .name = "gfx3d_smmu",
+       .num = 2,
+       .mids = {8, 9, 10, 11, 12, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = {
+       .name = "gfx2d0_pixv1_smmu",
+       .num = 0,
+       .mids = {0, 3, 4, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = {
+       .name = "gfx2d0_texv3_smmu",
+       .num = 1,
+       .mids = {1, 6, 7, -1}
+};
+
+static struct platform_device msm_device_jpegd_src_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 0,
+       .dev = {
+               .parent = &msm_device_smmu_jpegd.dev,
+       },
+};
+
+static struct platform_device msm_device_jpegd_dst_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 1,
+       .dev = {
+               .parent = &msm_device_smmu_jpegd.dev,
+       },
+};
+
+static struct platform_device msm_device_vpe_src_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 2,
+       .dev = {
+               .parent = &msm_device_smmu_vpe.dev,
+       },
+};
+
+static struct platform_device msm_device_vpe_dst_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 3,
+       .dev = {
+               .parent = &msm_device_smmu_vpe.dev,
+       },
+};
+
+static struct platform_device msm_device_mdp_vg1_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 4,
+       .dev = {
+               .parent = &msm_device_smmu_mdp0.dev,
+       },
+};
+
+static struct platform_device msm_device_mdp_rgb1_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 5,
+       .dev = {
+               .parent = &msm_device_smmu_mdp0.dev,
+       },
+};
+
+static struct platform_device msm_device_mdp_vg2_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 6,
+       .dev = {
+               .parent = &msm_device_smmu_mdp1.dev,
+       },
+};
+
+static struct platform_device msm_device_mdp_rgb2_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 7,
+       .dev = {
+               .parent = &msm_device_smmu_mdp1.dev,
+       },
+};
+
+static struct platform_device msm_device_rot_src_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 8,
+       .dev = {
+               .parent = &msm_device_smmu_rot.dev,
+       },
+};
+
+static struct platform_device msm_device_rot_dst_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 9,
+       .dev = {
+               .parent = &msm_device_smmu_rot.dev,
+       },
+};
+
+static struct platform_device msm_device_ijpeg_src_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 10,
+       .dev = {
+               .parent = &msm_device_smmu_ijpeg.dev,
+       },
+};
+
+static struct platform_device msm_device_ijpeg_dst_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 11,
+       .dev = {
+               .parent = &msm_device_smmu_ijpeg.dev,
+       },
+};
+
+static struct platform_device msm_device_vfe_imgwr_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 12,
+       .dev = {
+               .parent = &msm_device_smmu_vfe.dev,
+       },
+};
+
+static struct platform_device msm_device_vfe_misc_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 13,
+       .dev = {
+               .parent = &msm_device_smmu_vfe.dev,
+       },
+};
+
+static struct platform_device msm_device_vcodec_a_stream_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 14,
+       .dev = {
+               .parent = &msm_device_smmu_vcodec_a.dev,
+       },
+};
+
+static struct platform_device msm_device_vcodec_a_mm1_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 15,
+       .dev = {
+               .parent = &msm_device_smmu_vcodec_a.dev,
+       },
+};
+
+static struct platform_device msm_device_vcodec_b_mm2_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 16,
+       .dev = {
+               .parent = &msm_device_smmu_vcodec_b.dev,
+       },
+};
+
+static struct platform_device msm_device_gfx3d_rbpa_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 17,
+       .dev = {
+               .parent = &msm_device_smmu_gfx3d.dev,
+       },
+};
+
+static struct platform_device msm_device_gfx3d_cpvgttc_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 18,
+       .dev = {
+               .parent = &msm_device_smmu_gfx3d.dev,
+       },
+};
+
+static struct platform_device msm_device_gfx3d_smmu_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 19,
+       .dev = {
+               .parent = &msm_device_smmu_gfx3d.dev,
+       },
+};
+
+static struct platform_device msm_device_gfx2d0_pixv1_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 20,
+       .dev = {
+               .parent = &msm_device_smmu_gfx2d0.dev,
+       },
+};
+
+static struct platform_device msm_device_gfx2d0_texv3_ctx = {
+       .name = "msm_iommu_ctx",
+       .id = 21,
+       .dev = {
+               .parent = &msm_device_smmu_gfx2d0.dev,
+       },
+};
+
+static struct platform_device *msm_iommu_devs[] = {
+       &msm_device_smmu_jpegd,
+       &msm_device_smmu_vpe,
+       &msm_device_smmu_mdp0,
+       &msm_device_smmu_mdp1,
+       &msm_device_smmu_rot,
+       &msm_device_smmu_ijpeg,
+       &msm_device_smmu_vfe,
+       &msm_device_smmu_vcodec_a,
+       &msm_device_smmu_vcodec_b,
+       &msm_device_smmu_gfx3d,
+       &msm_device_smmu_gfx2d0,
+};
+
+static struct msm_iommu_dev *msm_iommu_data[] = {
+       &jpegd_smmu,
+       &vpe_smmu,
+       &mdp0_smmu,
+       &mdp1_smmu,
+       &rot_smmu,
+       &ijpeg_smmu,
+       &vfe_smmu,
+       &vcodec_a_smmu,
+       &vcodec_b_smmu,
+       &gfx3d_smmu,
+       &gfx2d0_smmu,
+};
+
+static struct platform_device *msm_iommu_ctx_devs[] = {
+       &msm_device_jpegd_src_ctx,
+       &msm_device_jpegd_dst_ctx,
+       &msm_device_vpe_src_ctx,
+       &msm_device_vpe_dst_ctx,
+       &msm_device_mdp_vg1_ctx,
+       &msm_device_mdp_rgb1_ctx,
+       &msm_device_mdp_vg2_ctx,
+       &msm_device_mdp_rgb2_ctx,
+       &msm_device_rot_src_ctx,
+       &msm_device_rot_dst_ctx,
+       &msm_device_ijpeg_src_ctx,
+       &msm_device_ijpeg_dst_ctx,
+       &msm_device_vfe_imgwr_ctx,
+       &msm_device_vfe_misc_ctx,
+       &msm_device_vcodec_a_stream_ctx,
+       &msm_device_vcodec_a_mm1_ctx,
+       &msm_device_vcodec_b_mm2_ctx,
+       &msm_device_gfx3d_rbpa_ctx,
+       &msm_device_gfx3d_cpvgttc_ctx,
+       &msm_device_gfx3d_smmu_ctx,
+       &msm_device_gfx2d0_pixv1_ctx,
+       &msm_device_gfx2d0_texv3_ctx,
+};
+
+static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
+       &jpegd_src_ctx,
+       &jpegd_dst_ctx,
+       &vpe_src_ctx,
+       &vpe_dst_ctx,
+       &mdp_vg1_ctx,
+       &mdp_rgb1_ctx,
+       &mdp_vg2_ctx,
+       &mdp_rgb2_ctx,
+       &rot_src_ctx,
+       &rot_dst_ctx,
+       &ijpeg_src_ctx,
+       &ijpeg_dst_ctx,
+       &vfe_imgwr_ctx,
+       &vfe_misc_ctx,
+       &vcodec_a_stream_ctx,
+       &vcodec_a_mm1_ctx,
+       &vcodec_b_mm2_ctx,
+       &gfx3d_rbpa_ctx,
+       &gfx3d_cpvgttc_ctx,
+       &gfx3d_smmu_ctx,
+       &gfx2d0_pixv1_ctx,
+       &gfx2d0_texv3_ctx,
+};
+
+static int msm8x60_iommu_init(void)
+{
+       int ret, i;
+
+       ret = platform_device_register(&msm_root_iommu_dev);
+       if (ret != 0) {
+               pr_err("Failed to register root IOMMU device!\n");
+               goto failure;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
+               ret = platform_device_add_data(msm_iommu_devs[i],
+                                              msm_iommu_data[i],
+                                              sizeof(struct msm_iommu_dev));
+               if (ret != 0) {
+                       pr_err("platform_device_add_data failed, "
+                              "i = %d\n", i);
+                       goto failure_unwind;
+               }
+
+               ret = platform_device_register(msm_iommu_devs[i]);
+
+               if (ret != 0) {
+                       pr_err("platform_device_register smmu failed, "
+                              "i = %d\n", i);
+                       goto failure_unwind;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) {
+               ret = platform_device_add_data(msm_iommu_ctx_devs[i],
+                                              msm_iommu_ctx_data[i],
+                                              sizeof(*msm_iommu_ctx_devs[i]));
+               if (ret != 0) {
+                       pr_err("platform_device_add_data smmu failed, "
+                              "i = %d\n", i);
+                       goto failure_unwind2;
+               }
+
+               ret = platform_device_register(msm_iommu_ctx_devs[i]);
+               if (ret != 0) {
+                       pr_err("platform_device_register ctx failed, "
+                              "i = %d\n", i);
+                       goto failure_unwind2;
+               }
+       }
+       return 0;
+
+failure_unwind2:
+       while (--i >= 0)
+               platform_device_unregister(msm_iommu_ctx_devs[i]);
+failure_unwind:
+       while (--i >= 0)
+               platform_device_unregister(msm_iommu_devs[i]);
+
+       platform_device_unregister(&msm_root_iommu_dev);
+failure:
+       return ret;
+}
+
+static void msm8x60_iommu_exit(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
+               platform_device_unregister(msm_iommu_ctx_devs[i]);
+
+       for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
+               platform_device_unregister(msm_iommu_devs[i]);
+
+       platform_device_unregister(&msm_root_iommu_dev);
+}
+
+subsys_initcall(msm8x60_iommu_init);
+module_exit(msm8x60_iommu_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
index 4d4a50785e344914ffee947cf64fae3664125a56..6fe67c5d1ae0aa3e7286f659b67acb8d11dd12fb 100644 (file)
@@ -48,6 +48,11 @@ struct platform_device msm_device_uart3 = {
        .resource       = resources_uart3,
 };
 
+struct platform_device msm_device_smd = {
+       .name   = "msm_smd",
+       .id     = -1,
+};
+
 struct clk msm_clocks_8x50[] = {
        CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
        CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, CLK_MIN),
index bc32c845c7b0e4f777e3366fd4f418daa44c700e..33051b509e88a18679876840a6a5a4a12a4bfdc1 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/gpio.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
  *
  * 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/bitops.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/module.h>
-#include <mach/gpio.h>
-#include "proc_comm.h"
-
-int gpio_tlmm_config(unsigned config, unsigned disable)
-{
-       return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
-}
-EXPORT_SYMBOL(gpio_tlmm_config);
-
-int msm_gpios_enable(const struct msm_gpio *table, int size)
-{
-       int rc;
-       int i;
-       const struct msm_gpio *g;
-       for (i = 0; i < size; i++) {
-               g = table + i;
-               rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
-               if (rc) {
-                       pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)"
-                              " <%s> failed: %d\n",
-                              g->gpio_cfg, g->label ?: "?", rc);
-                       pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
-                              GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
-                              GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
-                              GPIO_DRVSTR(g->gpio_cfg));
-                       goto err;
-               }
+#include "gpio_hw.h"
+#include "gpiomux.h"
+
+#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
+
+#define MSM_GPIO_BANK(bank, first, last)                               \
+       {                                                               \
+               .regs = {                                               \
+                       .out =         MSM_GPIO_OUT_##bank,             \
+                       .in =          MSM_GPIO_IN_##bank,              \
+                       .int_status =  MSM_GPIO_INT_STATUS_##bank,      \
+                       .int_clear =   MSM_GPIO_INT_CLEAR_##bank,       \
+                       .int_en =      MSM_GPIO_INT_EN_##bank,          \
+                       .int_edge =    MSM_GPIO_INT_EDGE_##bank,        \
+                       .int_pos =     MSM_GPIO_INT_POS_##bank,         \
+                       .oe =          MSM_GPIO_OE_##bank,              \
+               },                                                      \
+               .chip = {                                               \
+                       .base = (first),                                \
+                       .ngpio = (last) - (first) + 1,                  \
+                       .get = msm_gpio_get,                            \
+                       .set = msm_gpio_set,                            \
+                       .direction_input = msm_gpio_direction_input,    \
+                       .direction_output = msm_gpio_direction_output,  \
+                       .to_irq = msm_gpio_to_irq,                      \
+                       .request = msm_gpio_request,                    \
+                       .free = msm_gpio_free,                          \
+               }                                                       \
        }
+
+#define MSM_GPIO_BROKEN_INT_CLEAR 1
+
+struct msm_gpio_regs {
+       void __iomem *out;
+       void __iomem *in;
+       void __iomem *int_status;
+       void __iomem *int_clear;
+       void __iomem *int_en;
+       void __iomem *int_edge;
+       void __iomem *int_pos;
+       void __iomem *oe;
+};
+
+struct msm_gpio_chip {
+       spinlock_t              lock;
+       struct gpio_chip        chip;
+       struct msm_gpio_regs    regs;
+#if MSM_GPIO_BROKEN_INT_CLEAR
+       unsigned                int_status_copy;
+#endif
+       unsigned int            both_edge_detect;
+       unsigned int            int_enable[2]; /* 0: awake, 1: sleep */
+};
+
+static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
+                         unsigned offset, unsigned on)
+{
+       unsigned mask = BIT(offset);
+       unsigned val;
+
+       val = readl(msm_chip->regs.out);
+       if (on)
+               writel(val | mask, msm_chip->regs.out);
+       else
+               writel(val & ~mask, msm_chip->regs.out);
        return 0;
-err:
-       msm_gpios_disable(table, i);
-       return rc;
-}
-EXPORT_SYMBOL(msm_gpios_enable);
-
-void msm_gpios_disable(const struct msm_gpio *table, int size)
-{
-       int rc;
-       int i;
-       const struct msm_gpio *g;
-       for (i = size-1; i >= 0; i--) {
-               g = table + i;
-               rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE);
-               if (rc) {
-                       pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)"
-                              " <%s> failed: %d\n",
-                              g->gpio_cfg, g->label ?: "?", rc);
-                       pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
-                              GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
-                              GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
-                              GPIO_DRVSTR(g->gpio_cfg));
-               }
+}
+
+static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
+{
+       int loop_limit = 100;
+       unsigned pol, val, val2, intstat;
+       do {
+               val = readl(msm_chip->regs.in);
+               pol = readl(msm_chip->regs.int_pos);
+               pol = (pol & ~msm_chip->both_edge_detect) |
+                     (~val & msm_chip->both_edge_detect);
+               writel(pol, msm_chip->regs.int_pos);
+               intstat = readl(msm_chip->regs.int_status);
+               val2 = readl(msm_chip->regs.in);
+               if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
+                       return;
+       } while (loop_limit-- > 0);
+       printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
+              "failed to reach stable state %x != %x\n", val, val2);
+}
+
+static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
+                                       unsigned offset)
+{
+       unsigned bit = BIT(offset);
+
+#if MSM_GPIO_BROKEN_INT_CLEAR
+       /* Save interrupts that already triggered before we loose them. */
+       /* Any interrupt that triggers between the read of int_status */
+       /* and the write to int_clear will still be lost though. */
+       msm_chip->int_status_copy |= readl(msm_chip->regs.int_status);
+       msm_chip->int_status_copy &= ~bit;
+#endif
+       writel(bit, msm_chip->regs.int_clear);
+       msm_gpio_update_both_edge_detect(msm_chip);
+       return 0;
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct msm_gpio_chip *msm_chip;
+       unsigned long irq_flags;
+
+       msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe);
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+       return 0;
+}
+
+static int
+msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct msm_gpio_chip *msm_chip;
+       unsigned long irq_flags;
+
+       msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       msm_gpio_write(msm_chip, offset, value);
+       writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe);
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+       return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct msm_gpio_chip *msm_chip;
+
+       msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+       return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0;
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct msm_gpio_chip *msm_chip;
+       unsigned long irq_flags;
+
+       msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       msm_gpio_write(msm_chip, offset, value);
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+#ifdef CONFIG_MSM_GPIOMUX
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       msm_gpiomux_put(chip->base + offset);
+}
+#else
+#define msm_gpio_request NULL
+#define msm_gpio_free NULL
+#endif
+
+struct msm_gpio_chip msm_gpio_chips[] = {
+#if defined(CONFIG_ARCH_MSM7X00A)
+       MSM_GPIO_BANK(0,   0,  15),
+       MSM_GPIO_BANK(1,  16,  42),
+       MSM_GPIO_BANK(2,  43,  67),
+       MSM_GPIO_BANK(3,  68,  94),
+       MSM_GPIO_BANK(4,  95, 106),
+       MSM_GPIO_BANK(5, 107, 121),
+#elif defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X27)
+       MSM_GPIO_BANK(0,   0,  15),
+       MSM_GPIO_BANK(1,  16,  42),
+       MSM_GPIO_BANK(2,  43,  67),
+       MSM_GPIO_BANK(3,  68,  94),
+       MSM_GPIO_BANK(4,  95, 106),
+       MSM_GPIO_BANK(5, 107, 132),
+#elif defined(CONFIG_ARCH_MSM7X30)
+       MSM_GPIO_BANK(0,   0,  15),
+       MSM_GPIO_BANK(1,  16,  43),
+       MSM_GPIO_BANK(2,  44,  67),
+       MSM_GPIO_BANK(3,  68,  94),
+       MSM_GPIO_BANK(4,  95, 106),
+       MSM_GPIO_BANK(5, 107, 133),
+       MSM_GPIO_BANK(6, 134, 150),
+       MSM_GPIO_BANK(7, 151, 181),
+#elif defined(CONFIG_ARCH_QSD8X50)
+       MSM_GPIO_BANK(0,   0,  15),
+       MSM_GPIO_BANK(1,  16,  42),
+       MSM_GPIO_BANK(2,  43,  67),
+       MSM_GPIO_BANK(3,  68,  94),
+       MSM_GPIO_BANK(4,  95, 103),
+       MSM_GPIO_BANK(5, 104, 121),
+       MSM_GPIO_BANK(6, 122, 152),
+       MSM_GPIO_BANK(7, 153, 164),
+#endif
+};
+
+static void msm_gpio_irq_ack(unsigned int irq)
+{
+       unsigned long irq_flags;
+       struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       msm_gpio_clear_detect_status(msm_chip,
+                                    irq - gpio_to_irq(msm_chip->chip.base));
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+       unsigned long irq_flags;
+       struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+       unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       /* level triggered interrupts are also latched */
+       if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+               msm_gpio_clear_detect_status(msm_chip, offset);
+       msm_chip->int_enable[0] &= ~BIT(offset);
+       writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+       unsigned long irq_flags;
+       struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+       unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       /* level triggered interrupts are also latched */
+       if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+               msm_gpio_clear_detect_status(msm_chip, offset);
+       msm_chip->int_enable[0] |= BIT(offset);
+       writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+       unsigned long irq_flags;
+       struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+       unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+
+       if (on)
+               msm_chip->int_enable[1] |= BIT(offset);
+       else
+               msm_chip->int_enable[1] &= ~BIT(offset);
+
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+       return 0;
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+       unsigned long irq_flags;
+       struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq);
+       unsigned offset = irq - gpio_to_irq(msm_chip->chip.base);
+       unsigned val, mask = BIT(offset);
+
+       spin_lock_irqsave(&msm_chip->lock, irq_flags);
+       val = readl(msm_chip->regs.int_edge);
+       if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+               writel(val | mask, msm_chip->regs.int_edge);
+               irq_desc[irq].handle_irq = handle_edge_irq;
+       } else {
+               writel(val & ~mask, msm_chip->regs.int_edge);
+               irq_desc[irq].handle_irq = handle_level_irq;
+       }
+       if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+               msm_chip->both_edge_detect |= mask;
+               msm_gpio_update_both_edge_detect(msm_chip);
+       } else {
+               msm_chip->both_edge_detect &= ~mask;
+               val = readl(msm_chip->regs.int_pos);
+               if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+                       writel(val | mask, msm_chip->regs.int_pos);
+               else
+                       writel(val & ~mask, msm_chip->regs.int_pos);
        }
+       spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+       return 0;
 }
-EXPORT_SYMBOL(msm_gpios_disable);
 
-int msm_gpios_request_enable(const struct msm_gpio *table, int size)
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-       int rc = msm_gpios_enable(table, size);
-       return rc;
+       int i, j, mask;
+       unsigned val;
+
+       for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+               struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
+               val = readl(msm_chip->regs.int_status);
+               val &= msm_chip->int_enable[0];
+               while (val) {
+                       mask = val & -val;
+                       j = fls(mask) - 1;
+                       /* printk("%s %08x %08x bit %d gpio %d irq %d\n",
+                               __func__, v, m, j, msm_chip->chip.start + j,
+                               FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
+                       val &= ~mask;
+                       generic_handle_irq(FIRST_GPIO_IRQ +
+                                          msm_chip->chip.base + j);
+               }
+       }
+       desc->chip->ack(irq);
 }
-EXPORT_SYMBOL(msm_gpios_request_enable);
 
-void msm_gpios_disable_free(const struct msm_gpio *table, int size)
+static struct irq_chip msm_gpio_irq_chip = {
+       .name      = "msmgpio",
+       .ack       = msm_gpio_irq_ack,
+       .mask      = msm_gpio_irq_mask,
+       .unmask    = msm_gpio_irq_unmask,
+       .set_wake  = msm_gpio_irq_set_wake,
+       .set_type  = msm_gpio_irq_set_type,
+};
+
+static int __init msm_init_gpio(void)
 {
-       msm_gpios_disable(table, size);
+       int i, j = 0;
+
+       for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
+               if (i - FIRST_GPIO_IRQ >=
+                       msm_gpio_chips[j].chip.base +
+                       msm_gpio_chips[j].chip.ngpio)
+                       j++;
+               set_irq_chip_data(i, &msm_gpio_chips[j]);
+               set_irq_chip(i, &msm_gpio_irq_chip);
+               set_irq_handler(i, handle_edge_irq);
+               set_irq_flags(i, IRQF_VALID);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+               spin_lock_init(&msm_gpio_chips[i].lock);
+               writel(0, msm_gpio_chips[i].regs.int_en);
+               gpiochip_add(&msm_gpio_chips[i].chip);
+       }
+
+       set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+       set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+       set_irq_wake(INT_GPIO_GROUP1, 1);
+       set_irq_wake(INT_GPIO_GROUP2, 2);
+       return 0;
 }
-EXPORT_SYMBOL(msm_gpios_disable_free);
+
+postcore_initcall(msm_init_gpio);
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644 (file)
index 0000000..6b50660
--- /dev/null
@@ -0,0 +1,278 @@
+/* arch/arm/mach-msm/gpio_hw.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+/* see 80-VA736-2 Rev C pp 695-751
+**
+** These are actually the *shadow* gpio registers, since the
+** real ones (which allow full access) are only available to the
+** ARM9 side of the world.
+**
+** Since the _BASE need to be page-aligned when we're mapping them
+** to virtual addresses, adjust for the additional offset in these
+** macros.
+*/
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X25) ||\
+    defined(CONFIG_ARCH_MSM7X27)
+
+/* output value */
+#define MSM_GPIO_OUT_0         MSM_GPIO1_REG(0x00)  /* gpio  15-0  */
+#define MSM_GPIO_OUT_1         MSM_GPIO2_REG(0x00)  /* gpio  42-16 */
+#define MSM_GPIO_OUT_2         MSM_GPIO1_REG(0x04)  /* gpio  67-43 */
+#define MSM_GPIO_OUT_3         MSM_GPIO1_REG(0x08)  /* gpio  94-68 */
+#define MSM_GPIO_OUT_4         MSM_GPIO1_REG(0x0C)  /* gpio 106-95 */
+#define MSM_GPIO_OUT_5         MSM_GPIO1_REG(0x50)  /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0          MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1          MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2          MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3          MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4          MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5          MSM_GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0          MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1          MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2          MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3          MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4          MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5          MSM_GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0    MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1    MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2    MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3    MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4    MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5    MSM_GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0     MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1     MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2     MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3     MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4     MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5     MSM_GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0      MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1      MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2      MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3      MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4      MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5      MSM_GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0   MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1   MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2   MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3   MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4   MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5   MSM_GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0  MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1  MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2  MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3  MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4  MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5  MSM_GPIO1_REG(0xB0)
+
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+/* output value */
+#define MSM_GPIO_OUT_0         MSM_GPIO1_REG(0x00)  /* gpio  15-0   */
+#define MSM_GPIO_OUT_1         MSM_GPIO2_REG(0x00)  /* gpio  42-16  */
+#define MSM_GPIO_OUT_2         MSM_GPIO1_REG(0x04)  /* gpio  67-43  */
+#define MSM_GPIO_OUT_3         MSM_GPIO1_REG(0x08)  /* gpio  94-68  */
+#define MSM_GPIO_OUT_4         MSM_GPIO1_REG(0x0C)  /* gpio 103-95  */
+#define MSM_GPIO_OUT_5         MSM_GPIO1_REG(0x10)  /* gpio 121-104 */
+#define MSM_GPIO_OUT_6         MSM_GPIO1_REG(0x14)  /* gpio 152-122 */
+#define MSM_GPIO_OUT_7         MSM_GPIO1_REG(0x18)  /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0          MSM_GPIO1_REG(0x20)
+#define MSM_GPIO_OE_1          MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2          MSM_GPIO1_REG(0x24)
+#define MSM_GPIO_OE_3          MSM_GPIO1_REG(0x28)
+#define MSM_GPIO_OE_4          MSM_GPIO1_REG(0x2C)
+#define MSM_GPIO_OE_5          MSM_GPIO1_REG(0x30)
+#define MSM_GPIO_OE_6          MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_OE_7          MSM_GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0          MSM_GPIO1_REG(0x50)
+#define MSM_GPIO_IN_1          MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2          MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_IN_3          MSM_GPIO1_REG(0x58)
+#define MSM_GPIO_IN_4          MSM_GPIO1_REG(0x5C)
+#define MSM_GPIO_IN_5          MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_IN_6          MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_IN_7          MSM_GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0    MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_EDGE_1    MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2    MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_EDGE_3    MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_EDGE_4    MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_EDGE_5    MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EDGE_6    MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EDGE_7    MSM_GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0     MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_POS_1     MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2     MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_POS_3     MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_POS_4     MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_POS_5     MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_POS_6     MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_POS_7     MSM_GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0      MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_EN_1      MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2      MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_EN_3      MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_4      MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_EN_5      MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EN_6      MSM_GPIO1_REG(0xC4)
+#define MSM_GPIO_INT_EN_7      MSM_GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0   MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_CLEAR_1   MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2   MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_CLEAR_3   MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_CLEAR_4   MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_5   MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_CLEAR_6   MSM_GPIO1_REG(0xE4)
+#define MSM_GPIO_INT_CLEAR_7   MSM_GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0  MSM_GPIO1_REG(0xF0)
+#define MSM_GPIO_INT_STATUS_1  MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2  MSM_GPIO1_REG(0xF4)
+#define MSM_GPIO_INT_STATUS_3  MSM_GPIO1_REG(0xF8)
+#define MSM_GPIO_INT_STATUS_4  MSM_GPIO1_REG(0xFC)
+#define MSM_GPIO_INT_STATUS_5  MSM_GPIO1_REG(0x100)
+#define MSM_GPIO_INT_STATUS_6  MSM_GPIO1_REG(0x104)
+#define MSM_GPIO_INT_STATUS_7  MSM_GPIO1_REG(0x108)
+
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+
+/* output value */
+#define MSM_GPIO_OUT_0         MSM_GPIO1_REG(0x00)   /* gpio  15-0   */
+#define MSM_GPIO_OUT_1         MSM_GPIO2_REG(0x00)   /* gpio  43-16  */
+#define MSM_GPIO_OUT_2         MSM_GPIO1_REG(0x04)   /* gpio  67-44  */
+#define MSM_GPIO_OUT_3         MSM_GPIO1_REG(0x08)   /* gpio  94-68  */
+#define MSM_GPIO_OUT_4         MSM_GPIO1_REG(0x0C)   /* gpio 106-95  */
+#define MSM_GPIO_OUT_5         MSM_GPIO1_REG(0x50)   /* gpio 133-107 */
+#define MSM_GPIO_OUT_6         MSM_GPIO1_REG(0xC4)   /* gpio 150-134 */
+#define MSM_GPIO_OUT_7         MSM_GPIO1_REG(0x214)  /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0          MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1          MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2          MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3          MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4          MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5          MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_OE_6          MSM_GPIO1_REG(0xC8)
+#define MSM_GPIO_OE_7          MSM_GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0          MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1          MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2          MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3          MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4          MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5          MSM_GPIO1_REG(0x44)
+#define MSM_GPIO_IN_6          MSM_GPIO1_REG(0xCC)
+#define MSM_GPIO_IN_7          MSM_GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0    MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1    MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2    MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3    MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4    MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5    MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EDGE_6    MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_EDGE_7    MSM_GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0     MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1     MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2     MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3     MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4     MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5     MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_POS_6     MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_POS_7     MSM_GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0      MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1      MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2      MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3      MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4      MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5      MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_6      MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_EN_7      MSM_GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0   MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1   MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2   MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3   MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4   MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5   MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_CLEAR_6   MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_7   MSM_GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0  MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1  MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2  MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3  MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4  MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5  MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_STATUS_6  MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_STATUS_7  MSM_GPIO1_REG(0x234)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c
new file mode 100644 (file)
index 0000000..6ce41c5
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+#ifdef CONFIG_SERIAL_MSM_CONSOLE
+       [49] = { /* UART2 RFR */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+       },
+       [50] = { /* UART2 CTS */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+       },
+       [51] = { /* UART2 RX */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+       },
+       [52] = { /* UART2 TX */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+       },
+#endif
+};
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
new file mode 100644 (file)
index 0000000..4406e0f
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+       [86] = { /* UART3 RX */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+       },
+       [87] = { /* UART3 TX */
+               .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+                            GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+       },
+};
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
new file mode 100644 (file)
index 0000000..7b380b3
--- /dev/null
@@ -0,0 +1,19 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
new file mode 100644 (file)
index 0000000..27de2ab
--- /dev/null
@@ -0,0 +1,33 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/kernel.h>
+#include "gpiomux.h"
+#include "proc_comm.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+       unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
+                               ((gpio & 0x3ff) << 4);
+       unsigned tlmm_disable = 0;
+       int rc;
+
+       rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+                          &tlmm_config, &tlmm_disable);
+       if (rc)
+               pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
+                      __func__, rc, tlmm_config, tlmm_disable);
+}
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
new file mode 100644 (file)
index 0000000..71d86fe
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIOMUX_NGPIOS 182
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define GPIOMUX_NGPIOS 165
+#else
+#define GPIOMUX_NGPIOS 133
+#endif
+
+typedef u32 gpiomux_config_t;
+
+enum {
+       GPIOMUX_DRV_2MA  = 0UL << 17,
+       GPIOMUX_DRV_4MA  = 1UL << 17,
+       GPIOMUX_DRV_6MA  = 2UL << 17,
+       GPIOMUX_DRV_8MA  = 3UL << 17,
+       GPIOMUX_DRV_10MA = 4UL << 17,
+       GPIOMUX_DRV_12MA = 5UL << 17,
+       GPIOMUX_DRV_14MA = 6UL << 17,
+       GPIOMUX_DRV_16MA = 7UL << 17,
+};
+
+enum {
+       GPIOMUX_FUNC_GPIO = 0UL,
+       GPIOMUX_FUNC_1    = 1UL,
+       GPIOMUX_FUNC_2    = 2UL,
+       GPIOMUX_FUNC_3    = 3UL,
+       GPIOMUX_FUNC_4    = 4UL,
+       GPIOMUX_FUNC_5    = 5UL,
+       GPIOMUX_FUNC_6    = 6UL,
+       GPIOMUX_FUNC_7    = 7UL,
+       GPIOMUX_FUNC_8    = 8UL,
+       GPIOMUX_FUNC_9    = 9UL,
+       GPIOMUX_FUNC_A    = 10UL,
+       GPIOMUX_FUNC_B    = 11UL,
+       GPIOMUX_FUNC_C    = 12UL,
+       GPIOMUX_FUNC_D    = 13UL,
+       GPIOMUX_FUNC_E    = 14UL,
+       GPIOMUX_FUNC_F    = 15UL,
+};
+
+enum {
+       GPIOMUX_PULL_NONE   = 0UL << 15,
+       GPIOMUX_PULL_DOWN   = 1UL << 15,
+       GPIOMUX_PULL_KEEPER = 2UL << 15,
+       GPIOMUX_PULL_UP     = 3UL << 15,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
new file mode 100644 (file)
index 0000000..273396d
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/io.h>
+#include <mach/msm_iomap.h>
+#include "gpiomux.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+       writel(val & ~GPIOMUX_CTL_MASK,
+              MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
+}
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
new file mode 100644 (file)
index 0000000..3bf10e7
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+
+#define GPIOMUX_NGPIOS 173
+
+typedef u16 gpiomux_config_t;
+
+enum {
+       GPIOMUX_DRV_2MA  = 0UL << 6,
+       GPIOMUX_DRV_4MA  = 1UL << 6,
+       GPIOMUX_DRV_6MA  = 2UL << 6,
+       GPIOMUX_DRV_8MA  = 3UL << 6,
+       GPIOMUX_DRV_10MA = 4UL << 6,
+       GPIOMUX_DRV_12MA = 5UL << 6,
+       GPIOMUX_DRV_14MA = 6UL << 6,
+       GPIOMUX_DRV_16MA = 7UL << 6,
+};
+
+enum {
+       GPIOMUX_FUNC_GPIO = 0UL  << 2,
+       GPIOMUX_FUNC_1    = 1UL  << 2,
+       GPIOMUX_FUNC_2    = 2UL  << 2,
+       GPIOMUX_FUNC_3    = 3UL  << 2,
+       GPIOMUX_FUNC_4    = 4UL  << 2,
+       GPIOMUX_FUNC_5    = 5UL  << 2,
+       GPIOMUX_FUNC_6    = 6UL  << 2,
+       GPIOMUX_FUNC_7    = 7UL  << 2,
+       GPIOMUX_FUNC_8    = 8UL  << 2,
+       GPIOMUX_FUNC_9    = 9UL  << 2,
+       GPIOMUX_FUNC_A    = 10UL << 2,
+       GPIOMUX_FUNC_B    = 11UL << 2,
+       GPIOMUX_FUNC_C    = 12UL << 2,
+       GPIOMUX_FUNC_D    = 13UL << 2,
+       GPIOMUX_FUNC_E    = 14UL << 2,
+       GPIOMUX_FUNC_F    = 15UL << 2,
+};
+
+enum {
+       GPIOMUX_PULL_NONE   = 0UL,
+       GPIOMUX_PULL_DOWN   = 1UL,
+       GPIOMUX_PULL_KEEPER = 2UL,
+       GPIOMUX_PULL_UP     = 3UL,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
new file mode 100644 (file)
index 0000000..53af21a
--- /dev/null
@@ -0,0 +1,96 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include "gpiomux.h"
+
+static DEFINE_SPINLOCK(gpiomux_lock);
+
+int msm_gpiomux_write(unsigned gpio,
+                     gpiomux_config_t active,
+                     gpiomux_config_t suspended)
+{
+       struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+       unsigned long irq_flags;
+       gpiomux_config_t setting;
+
+       if (gpio >= GPIOMUX_NGPIOS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&gpiomux_lock, irq_flags);
+
+       if (active & GPIOMUX_VALID)
+               cfg->active = active;
+
+       if (suspended & GPIOMUX_VALID)
+               cfg->suspended = suspended;
+
+       setting = cfg->ref ? active : suspended;
+       if (setting & GPIOMUX_VALID)
+               __msm_gpiomux_write(gpio, setting);
+
+       spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+       return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_write);
+
+int msm_gpiomux_get(unsigned gpio)
+{
+       struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+       unsigned long irq_flags;
+
+       if (gpio >= GPIOMUX_NGPIOS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&gpiomux_lock, irq_flags);
+       if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
+               __msm_gpiomux_write(gpio, cfg->active);
+       spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+       return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_get);
+
+int msm_gpiomux_put(unsigned gpio)
+{
+       struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+       unsigned long irq_flags;
+
+       if (gpio >= GPIOMUX_NGPIOS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&gpiomux_lock, irq_flags);
+       BUG_ON(cfg->ref == 0);
+       if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
+               __msm_gpiomux_write(gpio, cfg->suspended);
+       spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+       return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_put);
+
+static int __init gpiomux_init(void)
+{
+       unsigned n;
+
+       for (n = 0; n < GPIOMUX_NGPIOS; ++n) {
+               msm_gpiomux_configs[n].ref = 0;
+               if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID))
+                       continue;
+               __msm_gpiomux_write(n, msm_gpiomux_configs[n].suspended);
+       }
+       return 0;
+}
+postcore_initcall(gpiomux_init);
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
new file mode 100644 (file)
index 0000000..b178d9c
--- /dev/null
@@ -0,0 +1,114 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_H
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+
+#if defined(CONFIG_MSM_V2_TLMM)
+#include "gpiomux-v2.h"
+#else
+#include "gpiomux-v1.h"
+#endif
+
+/**
+ * struct msm_gpiomux_config: gpiomux settings for one gpio line.
+ *
+ * A complete gpiomux config is the bitwise-or of a drive-strength,
+ * function, and pull.  For functions other than GPIO, the OE
+ * is hard-wired according to the function.  For GPIO mode,
+ * OE is controlled by gpiolib.
+ *
+ * Available settings differ by target; see the gpiomux header
+ * specific to your target arch for available configurations.
+ *
+ * @active: The configuration to be installed when the line is
+ * active, or its reference count is > 0.
+ * @suspended: The configuration to be installed when the line
+ * is suspended, or its reference count is 0.
+ * @ref: The reference count of the line.  For internal use of
+ * the gpiomux framework only.
+ */
+struct msm_gpiomux_config {
+       gpiomux_config_t active;
+       gpiomux_config_t suspended;
+       unsigned         ref;
+};
+
+/**
+ * @GPIOMUX_VALID:     If set, the config field contains 'good data'.
+ *                      The absence of this bit will prevent the gpiomux
+ *                     system from applying the configuration under all
+ *                     circumstances.
+ */
+enum {
+       GPIOMUX_VALID    = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
+       GPIOMUX_CTL_MASK = GPIOMUX_VALID,
+};
+
+#ifdef CONFIG_MSM_GPIOMUX
+
+/* Each architecture must provide its own instance of this table.
+ * To avoid having gpiomux manage any given gpio, one or both of
+ * the entries can avoid setting GPIOMUX_VALID - the absence
+ * of that flag will prevent the configuration from being applied
+ * during state transitions.
+ */
+extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
+
+/* Increment a gpio's reference count, possibly activating the line. */
+int __must_check msm_gpiomux_get(unsigned gpio);
+
+/* Decrement a gpio's reference count, possibly suspending the line. */
+int msm_gpiomux_put(unsigned gpio);
+
+/* Install a new configuration to the gpio line.  To avoid overwriting
+ * a configuration, leave the VALID bit out.
+ */
+int msm_gpiomux_write(unsigned gpio,
+                     gpiomux_config_t active,
+                     gpiomux_config_t suspended);
+
+/* Architecture-internal function for use by the framework only.
+ * This function can assume the following:
+ * - the gpio value has passed a bounds-check
+ * - the gpiomux spinlock has been obtained
+ *
+ * This function is not for public consumption.  External users
+ * should use msm_gpiomux_write.
+ */
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
+#else
+static inline int __must_check msm_gpiomux_get(unsigned gpio)
+{
+       return -ENOSYS;
+}
+
+static inline int msm_gpiomux_put(unsigned gpio)
+{
+       return -ENOSYS;
+}
+
+static inline int msm_gpiomux_write(unsigned gpio,
+                                   gpiomux_config_t active,
+                                   gpiomux_config_t suspended)
+{
+       return -ENOSYS;
+}
+#endif
+#endif
index 5a79bcf5041367894d876ece1a86f20f5948bb97..6abf4a6eadc19be578b7888c21bfd3ec534291f6 100644 (file)
@@ -33,6 +33,8 @@ struct msm_acpu_clock_platform_data
 
 struct clk;
 
+extern struct sys_timer msm_timer;
+
 /* common init routines for use by arch/arm/mach-msm/board-*.c */
 
 void __init msm_add_devices(void);
index 528750f307e9428433c97101153be1933d495ba8..238c4f132cdb954d451addcb00e904cfd6131805 100644 (file)
@@ -19,7 +19,7 @@
 #include <mach/hardware.h>
 #include <mach/msm_iomap.h>
 
-#ifdef CONFIG_MSM_DEBUG_UART
+#ifdef CONFIG_HAS_MSM_DEBUG_UART_PHYS
        .macro  addruart, rx, tmp
        @ see if the MMU is enabled and select appropriate base address
        mrc     p15, 0, \rx, c1, c0
index 00f9bbfadbe6052972e5c5a183e312f7b800c233..05583f569524449ed2b61ea52ecd42544a959416 100644 (file)
@@ -32,10 +32,18 @@ struct msm_dmov_cmd {
        void *data;
 };
 
+#ifndef CONFIG_ARCH_MSM8X60
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
 void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
 int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-
+#else
+static inline
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
+static inline
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
+static inline
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
+#endif
 
 
 #define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
new file mode 100644 (file)
index 0000000..4dc99aa
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Low-level IRQ helper macros
+ *
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * 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 <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       ldr     \base, =gic_cpu_base_addr
+       ldr     \base, [\base]
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       /*
+        * The interrupt numbering scheme is defined in the
+        * interrupt controller spec.  To wit:
+        *
+        * Migrated the code from ARM MP port to be more consistant
+        * with interrupt processing , the following still holds true
+        * however, all interrupts are treated the same regardless of
+        * if they are local IPI or PPI
+        *
+        * Interrupts 0-15 are IPI
+        * 16-31 are PPI
+        *   (16-18 are the timers)
+        * 32-1020 are global
+        * 1021-1022 are reserved
+        * 1023 is "spurious" (no interrupt)
+        *
+        * A simple read from the controller will tell us the number of the
+        * highest priority enabled interrupt.  We then just need to check
+        * whether it is in the valid range for an IRQ (0-1020 inclusive).
+        *
+        * Base ARM code assumes that the local (private) peripheral interrupts
+        * are not valid, we treat them differently, in that the privates are
+        * handled like normal shared interrupts with the exception that only
+        * one processor can register the interrupt and the handler must be
+        * the same for all processors.
+        */
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+       ldr  \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU,
+                                                  9-0 =int # */
+
+       bic     \irqnr, \irqstat, #0x1c00       @mask src
+       cmp     \irqnr, #15
+       ldr             \tmp, =1021
+       cmpcc   \irqnr, \irqnr
+       cmpne   \irqnr, \tmp
+       cmpcs   \irqnr, \irqnr
+
+       .endm
+
+       /* We assume that irqstat (the raw value of the IRQ acknowledge
+        * register) is preserved from the macro above.
+        * If there is an IPI, we immediately signal end of interrupt on the
+        * controller, since this requires the original irqstat value which
+        * we won't easily be able to recreate later.
+        */
+       .macro test_for_ipi, irqnr, irqstat, base, tmp
+    bic \irqnr, \irqstat, #0x1c00
+    cmp \irqnr, #16
+    strcc   \irqstat, [\base, #GIC_CPU_EOI]
+    cmpcs   \irqnr, \irqnr
+       .endm
+
+       /* As above, this assumes that irqstat and base are preserved.. */
+
+       .macro test_for_ltirq, irqnr, irqstat, base, tmp
+    bic \irqnr, \irqstat, #0x1c00
+    mov     \tmp, #0
+    cmp \irqnr, #16
+    moveq   \tmp, #1
+    streq   \irqstat, [\base, #GIC_CPU_EOI]
+    cmp \tmp, #0
+       .endm
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-vic.S b/arch/arm/mach-msm/include/mach/entry-macro-vic.S
new file mode 100644 (file)
index 0000000..70563ed
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <mach/msm_iomap.h>
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       @ enable imprecise aborts
+       cpsie   a
+       mov     \base, #MSM_VIC_BASE
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       @ 0xD0 has irq# or old irq# if the irq has been handled
+       @ 0xD4 has irq# or -1 if none pending *but* if you just
+       @ read 0xD4 you never get the first irq for some reason
+       ldr     \irqnr, [\base, #0xD0]
+       ldr     \irqnr, [\base, #0xD4]
+       cmp     \irqnr, #0xffffffff
+       .endm
index d2259486bcb1588175df8a9f5fcdd76c5efe4aae..b16f082eeb6f7c092f8a041f3ba302fae5fcf163 100644 (file)
@@ -1,38 +1,23 @@
-/* arch/arm/mach-msm7200/include/mach/entry-macro.S
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
- * Copyright (C) 2007 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
  */
 
-#include <mach/msm_iomap.h>
-
-       .macro  disable_fiq
-       .endm
-
-       .macro  get_irqnr_preamble, base, tmp
-       @ enable imprecise aborts
-       cpsie   a
-       mov     \base, #MSM_VIC_BASE
-       .endm
-
-       .macro  arch_ret_to_user, tmp1, tmp2
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       @ 0xD0 has irq# or old irq# if the irq has been handled
-       @ 0xD4 has irq# or -1 if none pending *but* if you just
-       @ read 0xD4 you never get the first irq for some reason
-       ldr     \irqnr, [\base, #0xD0]
-       ldr     \irqnr, [\base, #0xD4]
-       cmp     \irqnr, #0xffffffff
-       .endm
+#if defined(CONFIG_ARM_GIC)
+#include <mach/entry-macro-qgic.S>
+#else
+#include <mach/entry-macro-vic.S>
+#endif
index 83e47c0d5c2e451de5f459653053684beb786ee8..36ad50d3bfaa8e03e9f0333c05ed655d9ebf4adb 100644 (file)
 #define gpio_cansleep   __gpio_cansleep
 #define gpio_to_irq     __gpio_to_irq
 
-/**
- * struct msm_gpio - GPIO pin description
- * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
- * @label - textual label
- *
- * Usually, GPIO's are operated by sets.
- * This struct accumulate all GPIO information in single source
- * and facilitete group operations provided by msm_gpios_xxx()
- */
-struct msm_gpio {
-       u32 gpio_cfg;
-       const char *label;
-};
-
-/**
- * msm_gpios_request_enable() - request and enable set of GPIOs
- *
- * Request and configure set of GPIO's
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-int msm_gpios_request_enable(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_disable_free() - disable and free set of GPIOs
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-void msm_gpios_disable_free(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_request() - request set of GPIOs
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-int msm_gpios_request(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_free() - free set of GPIOs
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-void msm_gpios_free(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_enable() - enable set of GPIOs
- * In case of error, all operations rolled back.
- * Return error code.
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-int msm_gpios_enable(const struct msm_gpio *table, int size);
-
-/**
- * msm_gpios_disable() - disable set of GPIOs
- *
- * @table: GPIO table
- * @size:  number of entries in @table
- */
-void msm_gpios_disable(const struct msm_gpio *table, int size);
-
-/* GPIO TLMM (Top Level Multiplexing) Definitions */
-
-/* GPIO TLMM: Function -- GPIO specific */
-
-/* GPIO TLMM: Direction */
-enum {
-       GPIO_INPUT,
-       GPIO_OUTPUT,
-};
-
-/* GPIO TLMM: Pullup/Pulldown */
-enum {
-       GPIO_NO_PULL,
-       GPIO_PULL_DOWN,
-       GPIO_KEEPER,
-       GPIO_PULL_UP,
-};
-
-/* GPIO TLMM: Drive Strength */
-enum {
-       GPIO_2MA,
-       GPIO_4MA,
-       GPIO_6MA,
-       GPIO_8MA,
-       GPIO_10MA,
-       GPIO_12MA,
-       GPIO_14MA,
-       GPIO_16MA,
-};
-
-enum {
-       GPIO_ENABLE,
-       GPIO_DISABLE,
-};
-
-#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
-       ((((gpio) & 0x3FF) << 4)        |         \
-        ((func) & 0xf)                  |        \
-        (((dir) & 0x1) << 14)           |        \
-        (((pull) & 0x3) << 15)          |        \
-        (((drvstr) & 0xF) << 17))
-
-/**
- * extract GPIO pin from bit-field used for gpio_tlmm_config
- */
-#define GPIO_PIN(gpio_cfg)    (((gpio_cfg) >>  4) & 0x3ff)
-#define GPIO_FUNC(gpio_cfg)   (((gpio_cfg) >>  0) & 0xf)
-#define GPIO_DIR(gpio_cfg)    (((gpio_cfg) >> 14) & 0x1)
-#define GPIO_PULL(gpio_cfg)   (((gpio_cfg) >> 15) & 0x3)
-#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
-
-int gpio_tlmm_config(unsigned config, unsigned disable);
-
 #endif /* __ASM_ARCH_MSM_GPIO_H */
index c35b29f9ac0fb615180344f7edb0bb3440bc1b7b..7386e732baad9d380914fd923404cb7a5e2e1931 100644 (file)
@@ -28,6 +28,7 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m
 
 void msm_map_qsd8x50_io(void);
 void msm_map_msm7x30_io(void);
+void msm_map_msm8x60_io(void);
 
 extern unsigned int msm_shared_ram_phys;
 
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
new file mode 100644 (file)
index 0000000..218ef57
--- /dev/null
@@ -0,0 +1,103 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef MSM_IOMMU_H
+#define MSM_IOMMU_H
+
+#include <linux/interrupt.h>
+
+/* Maximum number of Machine IDs that we are allowing to be mapped to the same
+ * context bank. The number of MIDs mapped to the same CB does not affect
+ * performance, but there is a practical limit on how many distinct MIDs may
+ * be present. These mappings are typically determined at design time and are
+ * not expected to change at run time.
+ */
+#define MAX_NUM_MIDS   16
+
+/**
+ * struct msm_iommu_dev - a single IOMMU hardware instance
+ * name                Human-readable name given to this IOMMU HW instance
+ * clk_rate    Rate to set for this IOMMU's clock, if applicable to this
+ *             particular IOMMU. 0 means don't set a rate.
+ *             -1 means it is an AXI clock with no valid rate
+ *
+ */
+struct msm_iommu_dev {
+       const char *name;
+       int clk_rate;
+};
+
+/**
+ * struct msm_iommu_ctx_dev - an IOMMU context bank instance
+ * name                Human-readable name given to this context bank
+ * num         Index of this context bank within the hardware
+ * mids                List of Machine IDs that are to be mapped into this context
+ *             bank, terminated by -1. The MID is a set of signals on the
+ *             AXI bus that identifies the function associated with a specific
+ *             memory request. (See ARM spec).
+ */
+struct msm_iommu_ctx_dev {
+       const char *name;
+       int num;
+       int mids[MAX_NUM_MIDS];
+};
+
+
+/**
+ * struct msm_iommu_drvdata - A single IOMMU hardware instance
+ * @base:      IOMMU config port base address (VA)
+ * @irq:       Interrupt number
+  *
+ * A msm_iommu_drvdata holds the global driver data about a single piece
+ * of an IOMMU hardware instance.
+ */
+struct msm_iommu_drvdata {
+       void __iomem *base;
+       int irq;
+};
+
+/**
+ * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
+ * @num:               Hardware context number of this context
+ * @pdev:              Platform device associated wit this HW instance
+ * @attached_elm:      List element for domains to track which devices are
+ *                     attached to them
+ *
+ * A msm_iommu_ctx_drvdata holds the driver data for a single context bank
+ * within each IOMMU hardware instance
+ */
+struct msm_iommu_ctx_drvdata {
+       int num;
+       struct platform_device *pdev;
+       struct list_head attached_elm;
+};
+
+/*
+ * Look up an IOMMU context device by its context name. NULL if none found.
+ * Useful for testing and drivers that do not yet fully have IOMMU stuff in
+ * their platform devices.
+ */
+struct device *msm_iommu_get_ctx(const char *ctx_name);
+
+/*
+ * Interrupt handler for the IOMMU context fault interrupt. Hooking the
+ * interrupt is not supported in the API yet, but this will print an error
+ * message and dump useful IOMMU registers.
+ */
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
new file mode 100644 (file)
index 0000000..f9386d3
--- /dev/null
@@ -0,0 +1,1871 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+
+#define CTX_SHIFT 12
+
+#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg)))
+#define GET_CTX_REG(reg, base, ctx) \
+                               (readl((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+#define SET_GLOBAL_REG(reg, base, val) writel((val), ((base) + (reg)))
+
+#define SET_CTX_REG(reg, base, ctx, val) \
+                       writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+/* Wrappers for numbered registers */
+#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
+#define GET_GLOBAL_REG_N(b, n, r)    GET_GLOBAL_REG(b, ((r) + (n << 2)))
+
+/* Field wrappers */
+#define GET_GLOBAL_FIELD(b, r, F)    GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT)
+#define GET_CONTEXT_FIELD(b, c, r, F)  \
+       GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT)
+
+#define SET_GLOBAL_FIELD(b, r, F, v) \
+       SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v))
+#define SET_CONTEXT_FIELD(b, c, r, F, v)       \
+       SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))
+
+#define GET_FIELD(addr, mask, shift)  ((readl(addr) >> (shift)) & (mask))
+
+#define SET_FIELD(addr, mask, shift, v) \
+do { \
+       int t = readl(addr); \
+       writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\
+} while (0)
+
+
+#define NUM_FL_PTE     4096
+#define NUM_SL_PTE     256
+
+/* First-level page table bits */
+#define FL_BASE_MASK           0xFFFFFC00
+#define FL_TYPE_TABLE          (1 << 0)
+#define FL_TYPE_SECT           (2 << 0)
+#define FL_SUPERSECTION                (1 << 18)
+#define FL_AP_WRITE            (1 << 10)
+#define FL_AP_READ             (1 << 11)
+#define FL_SHARED              (1 << 16)
+#define FL_OFFSET(va)          (((va) & 0xFFF00000) >> 20)
+
+/* Second-level page table bits */
+#define SL_BASE_MASK_LARGE     0xFFFF0000
+#define SL_BASE_MASK_SMALL     0xFFFFF000
+#define SL_TYPE_LARGE          (1 << 0)
+#define SL_TYPE_SMALL          (2 << 0)
+#define SL_AP0                 (1 << 4)
+#define SL_AP1                 (2 << 4)
+#define SL_SHARED              (1 << 10)
+#define SL_OFFSET(va)          (((va) & 0xFF000) >> 12)
+
+/* Global register setters / getters */
+#define SET_M2VCBR_N(b, N, v)   SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
+#define SET_CBACR_N(b, N, v)    SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
+#define SET_TLBRSW(b, v)        SET_GLOBAL_REG(TLBRSW, (b), (v))
+#define SET_TLBTR0(b, v)        SET_GLOBAL_REG(TLBTR0, (b), (v))
+#define SET_TLBTR1(b, v)        SET_GLOBAL_REG(TLBTR1, (b), (v))
+#define SET_TLBTR2(b, v)        SET_GLOBAL_REG(TLBTR2, (b), (v))
+#define SET_TESTBUSCR(b, v)     SET_GLOBAL_REG(TESTBUSCR, (b), (v))
+#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v))
+#define SET_TLBIVMID(b, v)      SET_GLOBAL_REG(TLBIVMID, (b), (v))
+#define SET_CR(b, v)            SET_GLOBAL_REG(CR, (b), (v))
+#define SET_EAR(b, v)           SET_GLOBAL_REG(EAR, (b), (v))
+#define SET_ESR(b, v)           SET_GLOBAL_REG(ESR, (b), (v))
+#define SET_ESRRESTORE(b, v)    SET_GLOBAL_REG(ESRRESTORE, (b), (v))
+#define SET_ESYNR0(b, v)        SET_GLOBAL_REG(ESYNR0, (b), (v))
+#define SET_ESYNR1(b, v)        SET_GLOBAL_REG(ESYNR1, (b), (v))
+#define SET_RPU_ACR(b, v)       SET_GLOBAL_REG(RPU_ACR, (b), (v))
+
+#define GET_M2VCBR_N(b, N)      GET_GLOBAL_REG_N(M2VCBR_N, N, (b))
+#define GET_CBACR_N(b, N)       GET_GLOBAL_REG_N(CBACR_N, N, (b))
+#define GET_TLBTR0(b)           GET_GLOBAL_REG(TLBTR0, (b))
+#define GET_TLBTR1(b)           GET_GLOBAL_REG(TLBTR1, (b))
+#define GET_TLBTR2(b)           GET_GLOBAL_REG(TLBTR2, (b))
+#define GET_TESTBUSCR(b)        GET_GLOBAL_REG(TESTBUSCR, (b))
+#define GET_GLOBAL_TLBIALL(b)   GET_GLOBAL_REG(GLOBAL_TLBIALL, (b))
+#define GET_TLBIVMID(b)                 GET_GLOBAL_REG(TLBIVMID, (b))
+#define GET_CR(b)               GET_GLOBAL_REG(CR, (b))
+#define GET_EAR(b)              GET_GLOBAL_REG(EAR, (b))
+#define GET_ESR(b)              GET_GLOBAL_REG(ESR, (b))
+#define GET_ESRRESTORE(b)       GET_GLOBAL_REG(ESRRESTORE, (b))
+#define GET_ESYNR0(b)           GET_GLOBAL_REG(ESYNR0, (b))
+#define GET_ESYNR1(b)           GET_GLOBAL_REG(ESYNR1, (b))
+#define GET_REV(b)              GET_GLOBAL_REG(REV, (b))
+#define GET_IDR(b)              GET_GLOBAL_REG(IDR, (b))
+#define GET_RPU_ACR(b)          GET_GLOBAL_REG(RPU_ACR, (b))
+
+
+/* Context register setters/getters */
+#define SET_SCTLR(b, c, v)      SET_CTX_REG(SCTLR, (b), (c), (v))
+#define SET_ACTLR(b, c, v)      SET_CTX_REG(ACTLR, (b), (c), (v))
+#define SET_CONTEXTIDR(b, c, v)         SET_CTX_REG(CONTEXTIDR, (b), (c), (v))
+#define SET_TTBR0(b, c, v)      SET_CTX_REG(TTBR0, (b), (c), (v))
+#define SET_TTBR1(b, c, v)      SET_CTX_REG(TTBR1, (b), (c), (v))
+#define SET_TTBCR(b, c, v)      SET_CTX_REG(TTBCR, (b), (c), (v))
+#define SET_PAR(b, c, v)        SET_CTX_REG(PAR, (b), (c), (v))
+#define SET_FSR(b, c, v)        SET_CTX_REG(FSR, (b), (c), (v))
+#define SET_FSRRESTORE(b, c, v)         SET_CTX_REG(FSRRESTORE, (b), (c), (v))
+#define SET_FAR(b, c, v)        SET_CTX_REG(FAR, (b), (c), (v))
+#define SET_FSYNR0(b, c, v)     SET_CTX_REG(FSYNR0, (b), (c), (v))
+#define SET_FSYNR1(b, c, v)     SET_CTX_REG(FSYNR1, (b), (c), (v))
+#define SET_PRRR(b, c, v)       SET_CTX_REG(PRRR, (b), (c), (v))
+#define SET_NMRR(b, c, v)       SET_CTX_REG(NMRR, (b), (c), (v))
+#define SET_TLBLKCR(b, c, v)    SET_CTX_REG(TLBLCKR, (b), (c), (v))
+#define SET_V2PSR(b, c, v)      SET_CTX_REG(V2PSR, (b), (c), (v))
+#define SET_TLBFLPTER(b, c, v)  SET_CTX_REG(TLBFLPTER, (b), (c), (v))
+#define SET_TLBSLPTER(b, c, v)  SET_CTX_REG(TLBSLPTER, (b), (c), (v))
+#define SET_BFBCR(b, c, v)      SET_CTX_REG(BFBCR, (b), (c), (v))
+#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v))
+#define SET_TLBIASID(b, c, v)   SET_CTX_REG(TLBIASID, (b), (c), (v))
+#define SET_TLBIVA(b, c, v)     SET_CTX_REG(TLBIVA, (b), (c), (v))
+#define SET_TLBIVAA(b, c, v)    SET_CTX_REG(TLBIVAA, (b), (c), (v))
+#define SET_V2PPR(b, c, v)      SET_CTX_REG(V2PPR, (b), (c), (v))
+#define SET_V2PPW(b, c, v)      SET_CTX_REG(V2PPW, (b), (c), (v))
+#define SET_V2PUR(b, c, v)      SET_CTX_REG(V2PUR, (b), (c), (v))
+#define SET_V2PUW(b, c, v)      SET_CTX_REG(V2PUW, (b), (c), (v))
+#define SET_RESUME(b, c, v)     SET_CTX_REG(RESUME, (b), (c), (v))
+
+#define GET_SCTLR(b, c)                 GET_CTX_REG(SCTLR, (b), (c))
+#define GET_ACTLR(b, c)                 GET_CTX_REG(ACTLR, (b), (c))
+#define GET_CONTEXTIDR(b, c)    GET_CTX_REG(CONTEXTIDR, (b), (c))
+#define GET_TTBR0(b, c)                 GET_CTX_REG(TTBR0, (b), (c))
+#define GET_TTBR1(b, c)                 GET_CTX_REG(TTBR1, (b), (c))
+#define GET_TTBCR(b, c)                 GET_CTX_REG(TTBCR, (b), (c))
+#define GET_PAR(b, c)           GET_CTX_REG(PAR, (b), (c))
+#define GET_FSR(b, c)           GET_CTX_REG(FSR, (b), (c))
+#define GET_FSRRESTORE(b, c)    GET_CTX_REG(FSRRESTORE, (b), (c))
+#define GET_FAR(b, c)           GET_CTX_REG(FAR, (b), (c))
+#define GET_FSYNR0(b, c)        GET_CTX_REG(FSYNR0, (b), (c))
+#define GET_FSYNR1(b, c)        GET_CTX_REG(FSYNR1, (b), (c))
+#define GET_PRRR(b, c)          GET_CTX_REG(PRRR, (b), (c))
+#define GET_NMRR(b, c)          GET_CTX_REG(NMRR, (b), (c))
+#define GET_TLBLCKR(b, c)       GET_CTX_REG(TLBLCKR, (b), (c))
+#define GET_V2PSR(b, c)                 GET_CTX_REG(V2PSR, (b), (c))
+#define GET_TLBFLPTER(b, c)     GET_CTX_REG(TLBFLPTER, (b), (c))
+#define GET_TLBSLPTER(b, c)     GET_CTX_REG(TLBSLPTER, (b), (c))
+#define GET_BFBCR(b, c)                 GET_CTX_REG(BFBCR, (b), (c))
+#define GET_CTX_TLBIALL(b, c)   GET_CTX_REG(CTX_TLBIALL, (b), (c))
+#define GET_TLBIASID(b, c)      GET_CTX_REG(TLBIASID, (b), (c))
+#define GET_TLBIVA(b, c)        GET_CTX_REG(TLBIVA, (b), (c))
+#define GET_TLBIVAA(b, c)       GET_CTX_REG(TLBIVAA, (b), (c))
+#define GET_V2PPR(b, c)                 GET_CTX_REG(V2PPR, (b), (c))
+#define GET_V2PPW(b, c)                 GET_CTX_REG(V2PPW, (b), (c))
+#define GET_V2PUR(b, c)                 GET_CTX_REG(V2PUR, (b), (c))
+#define GET_V2PUW(b, c)                 GET_CTX_REG(V2PUW, (b), (c))
+#define GET_RESUME(b, c)        GET_CTX_REG(RESUME, (b), (c))
+
+
+/* Global field setters / getters */
+/* Global Field Setters: */
+/* CBACR_N */
+#define SET_RWVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v)
+#define SET_RWE(b, n, v)      SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v)
+#define SET_RWGE(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v)
+#define SET_CBVMID(b, n, v)   SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v)
+#define SET_IRPTNDX(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v)
+
+
+/* M2VCBR_N */
+#define SET_VMID(b, n, v)     SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v)
+#define SET_CBNDX(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v)
+#define SET_BYPASSD(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v)
+#define SET_BPRCOSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v)
+#define SET_BPRCISH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v)
+#define SET_BPRCNSH(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v)
+#define SET_BPSHCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v)
+#define SET_NSCFG(b, n, v)    SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v)
+#define SET_BPMTCFG(b, n, v)  SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v)
+#define SET_BPMEMTYPE(b, n, v) \
+       SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v)
+
+
+/* CR */
+#define SET_RPUE(b, v)          SET_GLOBAL_FIELD(b, CR, RPUE, v)
+#define SET_RPUERE(b, v)        SET_GLOBAL_FIELD(b, CR, RPUERE, v)
+#define SET_RPUEIE(b, v)        SET_GLOBAL_FIELD(b, CR, RPUEIE, v)
+#define SET_DCDEE(b, v)                 SET_GLOBAL_FIELD(b, CR, DCDEE, v)
+#define SET_CLIENTPD(b, v)       SET_GLOBAL_FIELD(b, CR, CLIENTPD, v)
+#define SET_STALLD(b, v)        SET_GLOBAL_FIELD(b, CR, STALLD, v)
+#define SET_TLBLKCRWE(b, v)      SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v)
+#define SET_CR_TLBIALLCFG(b, v)  SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v)
+#define SET_TLBIVMIDCFG(b, v)    SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v)
+#define SET_CR_HUME(b, v)        SET_GLOBAL_FIELD(b, CR, CR_HUME, v)
+
+
+/* ESR */
+#define SET_CFG(b, v)           SET_GLOBAL_FIELD(b, ESR, CFG, v)
+#define SET_BYPASS(b, v)        SET_GLOBAL_FIELD(b, ESR, BYPASS, v)
+#define SET_ESR_MULTI(b, v)      SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v)
+
+
+/* ESYNR0 */
+#define SET_ESYNR0_AMID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v)
+#define SET_ESYNR0_APID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v)
+#define SET_ESYNR0_ABID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v)
+#define SET_ESYNR0_AVMID(b, v)   SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v)
+#define SET_ESYNR0_ATID(b, v)    SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v)
+
+
+/* ESYNR1 */
+#define SET_ESYNR1_AMEMTYPE(b, v) \
+                       SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v)
+#define SET_ESYNR1_ASHARED(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v)
+#define SET_ESYNR1_AINNERSHARED(b, v) \
+                       SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v)
+#define SET_ESYNR1_APRIV(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v)
+#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v)
+#define SET_ESYNR1_AINST(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v)
+#define SET_ESYNR1_AWRITE(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v)
+#define SET_ESYNR1_ABURST(b, v)  SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v)
+#define SET_ESYNR1_ALEN(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v)
+#define SET_ESYNR1_ASIZE(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v)
+#define SET_ESYNR1_ALOCK(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v)
+#define SET_ESYNR1_AOOO(b, v)    SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v)
+#define SET_ESYNR1_AFULL(b, v)   SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v)
+#define SET_ESYNR1_AC(b, v)      SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v)
+#define SET_ESYNR1_DCD(b, v)     SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v)
+
+
+/* TESTBUSCR */
+#define SET_TBE(b, v)           SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v)
+#define SET_SPDMBE(b, v)        SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v)
+#define SET_WGSEL(b, v)                 SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v)
+#define SET_TBLSEL(b, v)        SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v)
+#define SET_TBHSEL(b, v)        SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v)
+#define SET_SPDM0SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v)
+#define SET_SPDM1SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v)
+#define SET_SPDM2SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v)
+#define SET_SPDM3SEL(b, v)       SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v)
+
+
+/* TLBIVMID */
+#define SET_TLBIVMID_VMID(b, v)  SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v)
+
+
+/* TLBRSW */
+#define SET_TLBRSW_INDEX(b, v)   SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v)
+#define SET_TLBBFBS(b, v)       SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v)
+
+
+/* TLBTR0 */
+#define SET_PR(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, PR, v)
+#define SET_PW(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, PW, v)
+#define SET_UR(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, UR, v)
+#define SET_UW(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, UW, v)
+#define SET_XN(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, XN, v)
+#define SET_NSDESC(b, v)        SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v)
+#define SET_ISH(b, v)           SET_GLOBAL_FIELD(b, TLBTR0, ISH, v)
+#define SET_SH(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, SH, v)
+#define SET_MT(b, v)            SET_GLOBAL_FIELD(b, TLBTR0, MT, v)
+#define SET_DPSIZR(b, v)        SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v)
+#define SET_DPSIZC(b, v)        SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v)
+
+
+/* TLBTR1 */
+#define SET_TLBTR1_VMID(b, v)    SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v)
+#define SET_TLBTR1_PA(b, v)      SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v)
+
+
+/* TLBTR2 */
+#define SET_TLBTR2_ASID(b, v)    SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v)
+#define SET_TLBTR2_V(b, v)       SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v)
+#define SET_TLBTR2_NSTID(b, v)   SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v)
+#define SET_TLBTR2_NV(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v)
+#define SET_TLBTR2_VA(b, v)      SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v)
+
+
+/* Global Field Getters */
+/* CBACR_N */
+#define GET_RWVMID(b, n)        GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID)
+#define GET_RWE(b, n)           GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE)
+#define GET_RWGE(b, n)          GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE)
+#define GET_CBVMID(b, n)        GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID)
+#define GET_IRPTNDX(b, n)       GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX)
+
+
+/* M2VCBR_N */
+#define GET_VMID(b, n)       GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID)
+#define GET_CBNDX(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX)
+#define GET_BYPASSD(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD)
+#define GET_BPRCOSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH)
+#define GET_BPRCISH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH)
+#define GET_BPRCNSH(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH)
+#define GET_BPSHCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG)
+#define GET_NSCFG(b, n)      GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG)
+#define GET_BPMTCFG(b, n)    GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG)
+#define GET_BPMEMTYPE(b, n)  GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE)
+
+
+/* CR */
+#define GET_RPUE(b)             GET_GLOBAL_FIELD(b, CR, RPUE)
+#define GET_RPUERE(b)           GET_GLOBAL_FIELD(b, CR, RPUERE)
+#define GET_RPUEIE(b)           GET_GLOBAL_FIELD(b, CR, RPUEIE)
+#define GET_DCDEE(b)            GET_GLOBAL_FIELD(b, CR, DCDEE)
+#define GET_CLIENTPD(b)                 GET_GLOBAL_FIELD(b, CR, CLIENTPD)
+#define GET_STALLD(b)           GET_GLOBAL_FIELD(b, CR, STALLD)
+#define GET_TLBLKCRWE(b)        GET_GLOBAL_FIELD(b, CR, TLBLKCRWE)
+#define GET_CR_TLBIALLCFG(b)    GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG)
+#define GET_TLBIVMIDCFG(b)      GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG)
+#define GET_CR_HUME(b)          GET_GLOBAL_FIELD(b, CR, CR_HUME)
+
+
+/* ESR */
+#define GET_CFG(b)              GET_GLOBAL_FIELD(b, ESR, CFG)
+#define GET_BYPASS(b)           GET_GLOBAL_FIELD(b, ESR, BYPASS)
+#define GET_ESR_MULTI(b)        GET_GLOBAL_FIELD(b, ESR, ESR_MULTI)
+
+
+/* ESYNR0 */
+#define GET_ESYNR0_AMID(b)      GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID)
+#define GET_ESYNR0_APID(b)      GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID)
+#define GET_ESYNR0_ABID(b)      GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID)
+#define GET_ESYNR0_AVMID(b)     GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID)
+#define GET_ESYNR0_ATID(b)      GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID)
+
+
+/* ESYNR1 */
+#define GET_ESYNR1_AMEMTYPE(b)   GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE)
+#define GET_ESYNR1_ASHARED(b)    GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED)
+#define GET_ESYNR1_AINNERSHARED(b) \
+                       GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED)
+#define GET_ESYNR1_APRIV(b)      GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV)
+#define GET_ESYNR1_APROTNS(b)   GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS)
+#define GET_ESYNR1_AINST(b)     GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST)
+#define GET_ESYNR1_AWRITE(b)    GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE)
+#define GET_ESYNR1_ABURST(b)    GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST)
+#define GET_ESYNR1_ALEN(b)      GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN)
+#define GET_ESYNR1_ASIZE(b)     GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE)
+#define GET_ESYNR1_ALOCK(b)     GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK)
+#define GET_ESYNR1_AOOO(b)      GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO)
+#define GET_ESYNR1_AFULL(b)     GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL)
+#define GET_ESYNR1_AC(b)        GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC)
+#define GET_ESYNR1_DCD(b)       GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD)
+
+
+/* IDR */
+#define GET_NM2VCBMT(b)                 GET_GLOBAL_FIELD(b, IDR, NM2VCBMT)
+#define GET_HTW(b)              GET_GLOBAL_FIELD(b, IDR, HTW)
+#define GET_HUM(b)              GET_GLOBAL_FIELD(b, IDR, HUM)
+#define GET_TLBSIZE(b)          GET_GLOBAL_FIELD(b, IDR, TLBSIZE)
+#define GET_NCB(b)              GET_GLOBAL_FIELD(b, IDR, NCB)
+#define GET_NIRPT(b)            GET_GLOBAL_FIELD(b, IDR, NIRPT)
+
+
+/* REV */
+#define GET_MAJOR(b)            GET_GLOBAL_FIELD(b, REV, MAJOR)
+#define GET_MINOR(b)            GET_GLOBAL_FIELD(b, REV, MINOR)
+
+
+/* TESTBUSCR */
+#define GET_TBE(b)              GET_GLOBAL_FIELD(b, TESTBUSCR, TBE)
+#define GET_SPDMBE(b)           GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE)
+#define GET_WGSEL(b)            GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL)
+#define GET_TBLSEL(b)           GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL)
+#define GET_TBHSEL(b)           GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL)
+#define GET_SPDM0SEL(b)                 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL)
+#define GET_SPDM1SEL(b)                 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL)
+#define GET_SPDM2SEL(b)                 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL)
+#define GET_SPDM3SEL(b)                 GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL)
+
+
+/* TLBIVMID */
+#define GET_TLBIVMID_VMID(b)    GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID)
+
+
+/* TLBTR0 */
+#define GET_PR(b)               GET_GLOBAL_FIELD(b, TLBTR0, PR)
+#define GET_PW(b)               GET_GLOBAL_FIELD(b, TLBTR0, PW)
+#define GET_UR(b)               GET_GLOBAL_FIELD(b, TLBTR0, UR)
+#define GET_UW(b)               GET_GLOBAL_FIELD(b, TLBTR0, UW)
+#define GET_XN(b)               GET_GLOBAL_FIELD(b, TLBTR0, XN)
+#define GET_NSDESC(b)           GET_GLOBAL_FIELD(b, TLBTR0, NSDESC)
+#define GET_ISH(b)              GET_GLOBAL_FIELD(b, TLBTR0, ISH)
+#define GET_SH(b)               GET_GLOBAL_FIELD(b, TLBTR0, SH)
+#define GET_MT(b)               GET_GLOBAL_FIELD(b, TLBTR0, MT)
+#define GET_DPSIZR(b)           GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR)
+#define GET_DPSIZC(b)           GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC)
+
+
+/* TLBTR1 */
+#define GET_TLBTR1_VMID(b)      GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID)
+#define GET_TLBTR1_PA(b)        GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA)
+
+
+/* TLBTR2 */
+#define GET_TLBTR2_ASID(b)      GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID)
+#define GET_TLBTR2_V(b)                 GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V)
+#define GET_TLBTR2_NSTID(b)     GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID)
+#define GET_TLBTR2_NV(b)        GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV)
+#define GET_TLBTR2_VA(b)        GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA)
+
+
+/* Context Register setters / getters */
+/* Context Register setters */
+/* ACTLR */
+#define SET_CFERE(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v)
+#define SET_CFEIE(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v)
+#define SET_PTSHCFG(b, c, v)    SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v)
+#define SET_RCOSH(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v)
+#define SET_RCISH(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v)
+#define SET_RCNSH(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v)
+#define SET_PRIVCFG(b, c, v)    SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v)
+#define SET_DNA(b, c, v)        SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v)
+#define SET_DNLV2PA(b, c, v)    SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v)
+#define SET_TLBMCFG(b, c, v)    SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v)
+#define SET_CFCFG(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v)
+#define SET_TIPCF(b, c, v)      SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v)
+#define SET_V2PCFG(b, c, v)     SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v)
+#define SET_HUME(b, c, v)       SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v)
+#define SET_PTMTCFG(b, c, v)    SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v)
+#define SET_PTMEMTYPE(b, c, v)  SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v)
+
+
+/* BFBCR */
+#define SET_BFBDFE(b, c, v)     SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v)
+#define SET_BFBSFE(b, c, v)     SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v)
+#define SET_SFVS(b, c, v)       SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v)
+#define SET_FLVIC(b, c, v)      SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v)
+#define SET_SLVIC(b, c, v)      SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v)
+
+
+/* CONTEXTIDR */
+#define SET_CONTEXTIDR_ASID(b, c, v)   \
+               SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v)
+#define SET_CONTEXTIDR_PROCID(b, c, v) \
+               SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v)
+
+
+/* FSR */
+#define SET_TF(b, c, v)                 SET_CONTEXT_FIELD(b, c, FSR, TF, v)
+#define SET_AFF(b, c, v)        SET_CONTEXT_FIELD(b, c, FSR, AFF, v)
+#define SET_APF(b, c, v)        SET_CONTEXT_FIELD(b, c, FSR, APF, v)
+#define SET_TLBMF(b, c, v)      SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v)
+#define SET_HTWDEEF(b, c, v)    SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v)
+#define SET_HTWSEEF(b, c, v)    SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v)
+#define SET_MHF(b, c, v)        SET_CONTEXT_FIELD(b, c, FSR, MHF, v)
+#define SET_SL(b, c, v)                 SET_CONTEXT_FIELD(b, c, FSR, SL, v)
+#define SET_SS(b, c, v)                 SET_CONTEXT_FIELD(b, c, FSR, SS, v)
+#define SET_MULTI(b, c, v)      SET_CONTEXT_FIELD(b, c, FSR, MULTI, v)
+
+
+/* FSYNR0 */
+#define SET_AMID(b, c, v)       SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v)
+#define SET_APID(b, c, v)       SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v)
+#define SET_ABID(b, c, v)       SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v)
+#define SET_ATID(b, c, v)       SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v)
+
+
+/* FSYNR1 */
+#define SET_AMEMTYPE(b, c, v)   SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v)
+#define SET_ASHARED(b, c, v)    SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v)
+#define SET_AINNERSHARED(b, c, v)  \
+                               SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v)
+#define SET_APRIV(b, c, v)      SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v)
+#define SET_APROTNS(b, c, v)    SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v)
+#define SET_AINST(b, c, v)      SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v)
+#define SET_AWRITE(b, c, v)     SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v)
+#define SET_ABURST(b, c, v)     SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v)
+#define SET_ALEN(b, c, v)       SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v)
+#define SET_FSYNR1_ASIZE(b, c, v) \
+                               SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v)
+#define SET_ALOCK(b, c, v)      SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v)
+#define SET_AFULL(b, c, v)      SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v)
+
+
+/* NMRR */
+#define SET_ICPC0(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v)
+#define SET_ICPC1(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v)
+#define SET_ICPC2(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v)
+#define SET_ICPC3(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v)
+#define SET_ICPC4(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v)
+#define SET_ICPC5(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v)
+#define SET_ICPC6(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v)
+#define SET_ICPC7(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v)
+#define SET_OCPC0(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v)
+#define SET_OCPC1(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v)
+#define SET_OCPC2(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v)
+#define SET_OCPC3(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v)
+#define SET_OCPC4(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v)
+#define SET_OCPC5(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v)
+#define SET_OCPC6(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v)
+#define SET_OCPC7(b, c, v)      SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v)
+
+
+/* PAR */
+#define SET_FAULT(b, c, v)      SET_CONTEXT_FIELD(b, c, PAR, FAULT, v)
+
+#define SET_FAULT_TF(b, c, v)   SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v)
+#define SET_FAULT_AFF(b, c, v)  SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v)
+#define SET_FAULT_APF(b, c, v)  SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v)
+#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v)
+#define SET_FAULT_HTWDEEF(b, c, v) \
+                               SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v)
+#define SET_FAULT_HTWSEEF(b, c, v) \
+                               SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v)
+#define SET_FAULT_MHF(b, c, v)  SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v)
+#define SET_FAULT_SL(b, c, v)   SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v)
+#define SET_FAULT_SS(b, c, v)   SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v)
+
+#define SET_NOFAULT_SS(b, c, v)         SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v)
+#define SET_NOFAULT_MT(b, c, v)         SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v)
+#define SET_NOFAULT_SH(b, c, v)         SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v)
+#define SET_NOFAULT_NS(b, c, v)         SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v)
+#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v)
+#define SET_NPFAULT_PA(b, c, v)         SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v)
+
+
+/* PRRR */
+#define SET_MTC0(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v)
+#define SET_MTC1(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v)
+#define SET_MTC2(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v)
+#define SET_MTC3(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v)
+#define SET_MTC4(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v)
+#define SET_MTC5(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v)
+#define SET_MTC6(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v)
+#define SET_MTC7(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v)
+#define SET_SHDSH0(b, c, v)     SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v)
+#define SET_SHDSH1(b, c, v)     SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v)
+#define SET_SHNMSH0(b, c, v)    SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v)
+#define SET_SHNMSH1(b, c, v)     SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v)
+#define SET_NOS0(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v)
+#define SET_NOS1(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v)
+#define SET_NOS2(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v)
+#define SET_NOS3(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v)
+#define SET_NOS4(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v)
+#define SET_NOS5(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v)
+#define SET_NOS6(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v)
+#define SET_NOS7(b, c, v)       SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v)
+
+
+/* RESUME */
+#define SET_TNR(b, c, v)        SET_CONTEXT_FIELD(b, c, RESUME, TNR, v)
+
+
+/* SCTLR */
+#define SET_M(b, c, v)          SET_CONTEXT_FIELD(b, c, SCTLR, M, v)
+#define SET_TRE(b, c, v)        SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v)
+#define SET_AFE(b, c, v)        SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v)
+#define SET_HAF(b, c, v)        SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v)
+#define SET_BE(b, c, v)                 SET_CONTEXT_FIELD(b, c, SCTLR, BE, v)
+#define SET_AFFD(b, c, v)       SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v)
+
+
+/* TLBLKCR */
+#define SET_LKE(b, c, v)          SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v)
+#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \
+                       SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v)
+#define SET_TLBIASIDCFG(b, c, v) \
+                       SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v)
+#define SET_TLBIVAACFG(b, c, v)        SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v)
+#define SET_FLOOR(b, c, v)     SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v)
+#define SET_VICTIM(b, c, v)    SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v)
+
+
+/* TTBCR */
+#define SET_N(b, c, v)          SET_CONTEXT_FIELD(b, c, TTBCR, N, v)
+#define SET_PD0(b, c, v)        SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v)
+#define SET_PD1(b, c, v)        SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v)
+
+
+/* TTBR0 */
+#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v)
+#define SET_TTBR0_SH(b, c, v)   SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v)
+#define SET_TTBR0_ORGN(b, c, v)         SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v)
+#define SET_TTBR0_NOS(b, c, v)  SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v)
+#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v)
+#define SET_TTBR0_PA(b, c, v)   SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v)
+
+
+/* TTBR1 */
+#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v)
+#define SET_TTBR1_SH(b, c, v)   SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v)
+#define SET_TTBR1_ORGN(b, c, v)         SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v)
+#define SET_TTBR1_NOS(b, c, v)  SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v)
+#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v)
+#define SET_TTBR1_PA(b, c, v)   SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v)
+
+
+/* V2PSR */
+#define SET_HIT(b, c, v)        SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v)
+#define SET_INDEX(b, c, v)      SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v)
+
+
+/* V2Pxx UW UR PW PR */
+#define SET_V2PUW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX, v)
+#define SET_V2PUW_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA, v)
+
+#define SET_V2PUR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX, v)
+#define SET_V2PUR_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA, v)
+
+#define SET_V2PPW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX, v)
+#define SET_V2PPW_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA, v)
+
+#define SET_V2PPR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX, v)
+#define SET_V2PPR_VA(b, c, v)   SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA, v)
+
+
+/* Context Register getters */
+/* ACTLR */
+#define GET_CFERE(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, CFERE)
+#define GET_CFEIE(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE)
+#define GET_PTSHCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG)
+#define GET_RCOSH(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH)
+#define GET_RCISH(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, RCISH)
+#define GET_RCNSH(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH)
+#define GET_PRIVCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG)
+#define GET_DNA(b, c)          GET_CONTEXT_FIELD(b, c, ACTLR, DNA)
+#define GET_DNLV2PA(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA)
+#define GET_TLBMCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG)
+#define GET_CFCFG(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG)
+#define GET_TIPCF(b, c)                GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF)
+#define GET_V2PCFG(b, c)        GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG)
+#define GET_HUME(b, c)         GET_CONTEXT_FIELD(b, c, ACTLR, HUME)
+#define GET_PTMTCFG(b, c)       GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG)
+#define GET_PTMEMTYPE(b, c)     GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE)
+
+/* BFBCR */
+#define GET_BFBDFE(b, c)       GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE)
+#define GET_BFBSFE(b, c)       GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE)
+#define GET_SFVS(b, c)         GET_CONTEXT_FIELD(b, c, BFBCR, SFVS)
+#define GET_FLVIC(b, c)                GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC)
+#define GET_SLVIC(b, c)                GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC)
+
+
+/* CONTEXTIDR */
+#define GET_CONTEXTIDR_ASID(b, c) \
+                       GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID)
+#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID)
+
+
+/* FSR */
+#define GET_TF(b, c)           GET_CONTEXT_FIELD(b, c, FSR, TF)
+#define GET_AFF(b, c)          GET_CONTEXT_FIELD(b, c, FSR, AFF)
+#define GET_APF(b, c)          GET_CONTEXT_FIELD(b, c, FSR, APF)
+#define GET_TLBMF(b, c)                GET_CONTEXT_FIELD(b, c, FSR, TLBMF)
+#define GET_HTWDEEF(b, c)      GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF)
+#define GET_HTWSEEF(b, c)      GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF)
+#define GET_MHF(b, c)          GET_CONTEXT_FIELD(b, c, FSR, MHF)
+#define GET_SL(b, c)           GET_CONTEXT_FIELD(b, c, FSR, SL)
+#define GET_SS(b, c)           GET_CONTEXT_FIELD(b, c, FSR, SS)
+#define GET_MULTI(b, c)                GET_CONTEXT_FIELD(b, c, FSR, MULTI)
+
+
+/* FSYNR0 */
+#define GET_AMID(b, c)         GET_CONTEXT_FIELD(b, c, FSYNR0, AMID)
+#define GET_APID(b, c)         GET_CONTEXT_FIELD(b, c, FSYNR0, APID)
+#define GET_ABID(b, c)         GET_CONTEXT_FIELD(b, c, FSYNR0, ABID)
+#define GET_ATID(b, c)         GET_CONTEXT_FIELD(b, c, FSYNR0, ATID)
+
+
+/* FSYNR1 */
+#define GET_AMEMTYPE(b, c)     GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE)
+#define GET_ASHARED(b, c)      GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED)
+#define GET_AINNERSHARED(b, c)  GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED)
+#define GET_APRIV(b, c)                GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV)
+#define GET_APROTNS(b, c)      GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS)
+#define GET_AINST(b, c)                GET_CONTEXT_FIELD(b, c, FSYNR1, AINST)
+#define GET_AWRITE(b, c)       GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE)
+#define GET_ABURST(b, c)       GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST)
+#define GET_ALEN(b, c)         GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN)
+#define GET_FSYNR1_ASIZE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE)
+#define GET_ALOCK(b, c)                GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK)
+#define GET_AFULL(b, c)                GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL)
+
+
+/* NMRR */
+#define GET_ICPC0(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC0)
+#define GET_ICPC1(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC1)
+#define GET_ICPC2(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC2)
+#define GET_ICPC3(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC3)
+#define GET_ICPC4(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC4)
+#define GET_ICPC5(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC5)
+#define GET_ICPC6(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC6)
+#define GET_ICPC7(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, ICPC7)
+#define GET_OCPC0(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC0)
+#define GET_OCPC1(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC1)
+#define GET_OCPC2(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC2)
+#define GET_OCPC3(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC3)
+#define GET_OCPC4(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC4)
+#define GET_OCPC5(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
+#define GET_OCPC6(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
+#define GET_OCPC7(b, c)                GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
+
+
+/* PAR */
+#define GET_FAULT(b, c)                GET_CONTEXT_FIELD(b, c, PAR, FAULT)
+
+#define GET_FAULT_TF(b, c)     GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF)
+#define GET_FAULT_AFF(b, c)    GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF)
+#define GET_FAULT_APF(b, c)    GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF)
+#define GET_FAULT_TLBMF(b, c)   GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF)
+#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF)
+#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF)
+#define GET_FAULT_MHF(b, c)    GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF)
+#define GET_FAULT_SL(b, c)     GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL)
+#define GET_FAULT_SS(b, c)     GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS)
+
+#define GET_NOFAULT_SS(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS)
+#define GET_NOFAULT_MT(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT)
+#define GET_NOFAULT_SH(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH)
+#define GET_NOFAULT_NS(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS)
+#define GET_NOFAULT_NOS(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS)
+#define GET_NPFAULT_PA(b, c)   GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA)
+
+
+/* PRRR */
+#define GET_MTC0(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC0)
+#define GET_MTC1(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC1)
+#define GET_MTC2(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC2)
+#define GET_MTC3(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC3)
+#define GET_MTC4(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC4)
+#define GET_MTC5(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC5)
+#define GET_MTC6(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC6)
+#define GET_MTC7(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, MTC7)
+#define GET_SHDSH0(b, c)       GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0)
+#define GET_SHDSH1(b, c)       GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1)
+#define GET_SHNMSH0(b, c)      GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0)
+#define GET_SHNMSH1(b, c)      GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1)
+#define GET_NOS0(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS0)
+#define GET_NOS1(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS1)
+#define GET_NOS2(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS2)
+#define GET_NOS3(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS3)
+#define GET_NOS4(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS4)
+#define GET_NOS5(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
+#define GET_NOS6(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
+#define GET_NOS7(b, c)         GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
+
+
+/* RESUME */
+#define GET_TNR(b, c)          GET_CONTEXT_FIELD(b, c, RESUME, TNR)
+
+
+/* SCTLR */
+#define GET_M(b, c)            GET_CONTEXT_FIELD(b, c, SCTLR, M)
+#define GET_TRE(b, c)          GET_CONTEXT_FIELD(b, c, SCTLR, TRE)
+#define GET_AFE(b, c)          GET_CONTEXT_FIELD(b, c, SCTLR, AFE)
+#define GET_HAF(b, c)          GET_CONTEXT_FIELD(b, c, SCTLR, HAF)
+#define GET_BE(b, c)           GET_CONTEXT_FIELD(b, c, SCTLR, BE)
+#define GET_AFFD(b, c)         GET_CONTEXT_FIELD(b, c, SCTLR, AFFD)
+
+
+/* TLBLKCR */
+#define GET_LKE(b, c)          GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE)
+#define GET_TLBLCKR_TLBIALLCFG(b, c) \
+                       GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG)
+#define GET_TLBIASIDCFG(b, c)   GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG)
+#define GET_TLBIVAACFG(b, c)   GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG)
+#define GET_FLOOR(b, c)                GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR)
+#define GET_VICTIM(b, c)       GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM)
+
+
+/* TTBCR */
+#define GET_N(b, c)            GET_CONTEXT_FIELD(b, c, TTBCR, N)
+#define GET_PD0(b, c)          GET_CONTEXT_FIELD(b, c, TTBCR, PD0)
+#define GET_PD1(b, c)          GET_CONTEXT_FIELD(b, c, TTBCR, PD1)
+
+
+/* TTBR0 */
+#define GET_TTBR0_IRGNH(b, c)  GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH)
+#define GET_TTBR0_SH(b, c)     GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH)
+#define GET_TTBR0_ORGN(b, c)   GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN)
+#define GET_TTBR0_NOS(b, c)    GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS)
+#define GET_TTBR0_IRGNL(b, c)  GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL)
+#define GET_TTBR0_PA(b, c)     GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA)
+
+
+/* TTBR1 */
+#define GET_TTBR1_IRGNH(b, c)  GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH)
+#define GET_TTBR1_SH(b, c)     GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH)
+#define GET_TTBR1_ORGN(b, c)   GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN)
+#define GET_TTBR1_NOS(b, c)    GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS)
+#define GET_TTBR1_IRGNL(b, c)  GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL)
+#define GET_TTBR1_PA(b, c)     GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA)
+
+
+/* V2PSR */
+#define GET_HIT(b, c)          GET_CONTEXT_FIELD(b, c, V2PSR, HIT)
+#define GET_INDEX(b, c)                GET_CONTEXT_FIELD(b, c, V2PSR, INDEX)
+
+
+/* V2Pxx UW UR PW PR */
+#define GET_V2PUW_INDEX(b, c)  GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX)
+#define GET_V2PUW_VA(b, c)     GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA)
+
+#define GET_V2PUR_INDEX(b, c)  GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX)
+#define GET_V2PUR_VA(b, c)     GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA)
+
+#define GET_V2PPW_INDEX(b, c)  GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX)
+#define GET_V2PPW_VA(b, c)     GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA)
+
+#define GET_V2PPR_INDEX(b, c)  GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX)
+#define GET_V2PPR_VA(b, c)     GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA)
+
+
+/* Global Registers */
+#define M2VCBR_N       (0xFF000)
+#define CBACR_N                (0xFF800)
+#define TLBRSW         (0xFFE00)
+#define TLBTR0         (0xFFE80)
+#define TLBTR1         (0xFFE84)
+#define TLBTR2         (0xFFE88)
+#define TESTBUSCR      (0xFFE8C)
+#define GLOBAL_TLBIALL (0xFFF00)
+#define TLBIVMID       (0xFFF04)
+#define CR             (0xFFF80)
+#define EAR            (0xFFF84)
+#define ESR            (0xFFF88)
+#define ESRRESTORE     (0xFFF8C)
+#define ESYNR0         (0xFFF90)
+#define ESYNR1         (0xFFF94)
+#define REV            (0xFFFF4)
+#define IDR            (0xFFFF8)
+#define RPU_ACR                (0xFFFFC)
+
+
+/* Context Bank Registers */
+#define SCTLR          (0x000)
+#define ACTLR          (0x004)
+#define CONTEXTIDR     (0x008)
+#define TTBR0          (0x010)
+#define TTBR1          (0x014)
+#define TTBCR          (0x018)
+#define PAR            (0x01C)
+#define FSR            (0x020)
+#define FSRRESTORE     (0x024)
+#define FAR            (0x028)
+#define FSYNR0         (0x02C)
+#define FSYNR1         (0x030)
+#define PRRR           (0x034)
+#define NMRR           (0x038)
+#define TLBLCKR                (0x03C)
+#define V2PSR          (0x040)
+#define TLBFLPTER      (0x044)
+#define TLBSLPTER      (0x048)
+#define BFBCR          (0x04C)
+#define CTX_TLBIALL    (0x800)
+#define TLBIASID       (0x804)
+#define TLBIVA         (0x808)
+#define TLBIVAA                (0x80C)
+#define V2PPR          (0x810)
+#define V2PPW          (0x814)
+#define V2PUR          (0x818)
+#define V2PUW          (0x81C)
+#define RESUME         (0x820)
+
+
+/* Global Register Fields */
+/* CBACRn */
+#define RWVMID        (RWVMID_MASK       << RWVMID_SHIFT)
+#define RWE           (RWE_MASK          << RWE_SHIFT)
+#define RWGE          (RWGE_MASK         << RWGE_SHIFT)
+#define CBVMID        (CBVMID_MASK       << CBVMID_SHIFT)
+#define IRPTNDX       (IRPTNDX_MASK      << IRPTNDX_SHIFT)
+
+
+/* CR */
+#define RPUE          (RPUE_MASK          << RPUE_SHIFT)
+#define RPUERE        (RPUERE_MASK        << RPUERE_SHIFT)
+#define RPUEIE        (RPUEIE_MASK        << RPUEIE_SHIFT)
+#define DCDEE         (DCDEE_MASK         << DCDEE_SHIFT)
+#define CLIENTPD      (CLIENTPD_MASK      << CLIENTPD_SHIFT)
+#define STALLD        (STALLD_MASK        << STALLD_SHIFT)
+#define TLBLKCRWE     (TLBLKCRWE_MASK     << TLBLKCRWE_SHIFT)
+#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT)
+#define TLBIVMIDCFG   (TLBIVMIDCFG_MASK   << TLBIVMIDCFG_SHIFT)
+#define CR_HUME       (CR_HUME_MASK       << CR_HUME_SHIFT)
+
+
+/* ESR */
+#define CFG           (CFG_MASK          << CFG_SHIFT)
+#define BYPASS        (BYPASS_MASK       << BYPASS_SHIFT)
+#define ESR_MULTI     (ESR_MULTI_MASK    << ESR_MULTI_SHIFT)
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID   (ESYNR0_AMID_MASK  << ESYNR0_AMID_SHIFT)
+#define ESYNR0_APID   (ESYNR0_APID_MASK  << ESYNR0_APID_SHIFT)
+#define ESYNR0_ABID   (ESYNR0_ABID_MASK  << ESYNR0_ABID_SHIFT)
+#define ESYNR0_AVMID  (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT)
+#define ESYNR0_ATID   (ESYNR0_ATID_MASK  << ESYNR0_ATID_SHIFT)
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE      (ESYNR1_AMEMTYPE_MASK    << ESYNR1_AMEMTYPE_SHIFT)
+#define ESYNR1_ASHARED       (ESYNR1_ASHARED_MASK     << ESYNR1_ASHARED_SHIFT)
+#define ESYNR1_AINNERSHARED  (ESYNR1_AINNERSHARED_MASK<< \
+                                               ESYNR1_AINNERSHARED_SHIFT)
+#define ESYNR1_APRIV         (ESYNR1_APRIV_MASK       << ESYNR1_APRIV_SHIFT)
+#define ESYNR1_APROTNS       (ESYNR1_APROTNS_MASK     << ESYNR1_APROTNS_SHIFT)
+#define ESYNR1_AINST         (ESYNR1_AINST_MASK       << ESYNR1_AINST_SHIFT)
+#define ESYNR1_AWRITE        (ESYNR1_AWRITE_MASK      << ESYNR1_AWRITE_SHIFT)
+#define ESYNR1_ABURST        (ESYNR1_ABURST_MASK      << ESYNR1_ABURST_SHIFT)
+#define ESYNR1_ALEN          (ESYNR1_ALEN_MASK        << ESYNR1_ALEN_SHIFT)
+#define ESYNR1_ASIZE         (ESYNR1_ASIZE_MASK       << ESYNR1_ASIZE_SHIFT)
+#define ESYNR1_ALOCK         (ESYNR1_ALOCK_MASK       << ESYNR1_ALOCK_SHIFT)
+#define ESYNR1_AOOO          (ESYNR1_AOOO_MASK        << ESYNR1_AOOO_SHIFT)
+#define ESYNR1_AFULL         (ESYNR1_AFULL_MASK       << ESYNR1_AFULL_SHIFT)
+#define ESYNR1_AC            (ESYNR1_AC_MASK          << ESYNR1_AC_SHIFT)
+#define ESYNR1_DCD           (ESYNR1_DCD_MASK         << ESYNR1_DCD_SHIFT)
+
+
+/* IDR */
+#define NM2VCBMT      (NM2VCBMT_MASK     << NM2VCBMT_SHIFT)
+#define HTW           (HTW_MASK          << HTW_SHIFT)
+#define HUM           (HUM_MASK          << HUM_SHIFT)
+#define TLBSIZE       (TLBSIZE_MASK      << TLBSIZE_SHIFT)
+#define NCB           (NCB_MASK          << NCB_SHIFT)
+#define NIRPT         (NIRPT_MASK        << NIRPT_SHIFT)
+
+
+/* M2VCBRn */
+#define VMID          (VMID_MASK         << VMID_SHIFT)
+#define CBNDX         (CBNDX_MASK        << CBNDX_SHIFT)
+#define BYPASSD       (BYPASSD_MASK      << BYPASSD_SHIFT)
+#define BPRCOSH       (BPRCOSH_MASK      << BPRCOSH_SHIFT)
+#define BPRCISH       (BPRCISH_MASK      << BPRCISH_SHIFT)
+#define BPRCNSH       (BPRCNSH_MASK      << BPRCNSH_SHIFT)
+#define BPSHCFG       (BPSHCFG_MASK      << BPSHCFG_SHIFT)
+#define NSCFG         (NSCFG_MASK        << NSCFG_SHIFT)
+#define BPMTCFG       (BPMTCFG_MASK      << BPMTCFG_SHIFT)
+#define BPMEMTYPE     (BPMEMTYPE_MASK    << BPMEMTYPE_SHIFT)
+
+
+/* REV */
+#define IDR_MINOR     (MINOR_MASK        << MINOR_SHIFT)
+#define IDR_MAJOR     (MAJOR_MASK        << MAJOR_SHIFT)
+
+
+/* TESTBUSCR */
+#define TBE           (TBE_MASK          << TBE_SHIFT)
+#define SPDMBE        (SPDMBE_MASK       << SPDMBE_SHIFT)
+#define WGSEL         (WGSEL_MASK        << WGSEL_SHIFT)
+#define TBLSEL        (TBLSEL_MASK       << TBLSEL_SHIFT)
+#define TBHSEL        (TBHSEL_MASK       << TBHSEL_SHIFT)
+#define SPDM0SEL      (SPDM0SEL_MASK     << SPDM0SEL_SHIFT)
+#define SPDM1SEL      (SPDM1SEL_MASK     << SPDM1SEL_SHIFT)
+#define SPDM2SEL      (SPDM2SEL_MASK     << SPDM2SEL_SHIFT)
+#define SPDM3SEL      (SPDM3SEL_MASK     << SPDM3SEL_SHIFT)
+
+
+/* TLBIVMID */
+#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX  (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT)
+#define TLBBFBS       (TLBBFBS_MASK      << TLBBFBS_SHIFT)
+
+
+/* TLBTR0 */
+#define PR            (PR_MASK           << PR_SHIFT)
+#define PW            (PW_MASK           << PW_SHIFT)
+#define UR            (UR_MASK           << UR_SHIFT)
+#define UW            (UW_MASK           << UW_SHIFT)
+#define XN            (XN_MASK           << XN_SHIFT)
+#define NSDESC        (NSDESC_MASK       << NSDESC_SHIFT)
+#define ISH           (ISH_MASK          << ISH_SHIFT)
+#define SH            (SH_MASK           << SH_SHIFT)
+#define MT            (MT_MASK           << MT_SHIFT)
+#define DPSIZR        (DPSIZR_MASK       << DPSIZR_SHIFT)
+#define DPSIZC        (DPSIZC_MASK       << DPSIZC_SHIFT)
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID   (TLBTR1_VMID_MASK  << TLBTR1_VMID_SHIFT)
+#define TLBTR1_PA     (TLBTR1_PA_MASK    << TLBTR1_PA_SHIFT)
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID   (TLBTR2_ASID_MASK  << TLBTR2_ASID_SHIFT)
+#define TLBTR2_V      (TLBTR2_V_MASK     << TLBTR2_V_SHIFT)
+#define TLBTR2_NSTID  (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT)
+#define TLBTR2_NV     (TLBTR2_NV_MASK    << TLBTR2_NV_SHIFT)
+#define TLBTR2_VA     (TLBTR2_VA_MASK    << TLBTR2_VA_SHIFT)
+
+
+/* Context Register Fields */
+/* ACTLR */
+#define CFERE              (CFERE_MASK              << CFERE_SHIFT)
+#define CFEIE              (CFEIE_MASK              << CFEIE_SHIFT)
+#define PTSHCFG            (PTSHCFG_MASK            << PTSHCFG_SHIFT)
+#define RCOSH              (RCOSH_MASK              << RCOSH_SHIFT)
+#define RCISH              (RCISH_MASK              << RCISH_SHIFT)
+#define RCNSH              (RCNSH_MASK              << RCNSH_SHIFT)
+#define PRIVCFG            (PRIVCFG_MASK            << PRIVCFG_SHIFT)
+#define DNA                (DNA_MASK                << DNA_SHIFT)
+#define DNLV2PA            (DNLV2PA_MASK            << DNLV2PA_SHIFT)
+#define TLBMCFG            (TLBMCFG_MASK            << TLBMCFG_SHIFT)
+#define CFCFG              (CFCFG_MASK              << CFCFG_SHIFT)
+#define TIPCF              (TIPCF_MASK              << TIPCF_SHIFT)
+#define V2PCFG             (V2PCFG_MASK             << V2PCFG_SHIFT)
+#define HUME               (HUME_MASK               << HUME_SHIFT)
+#define PTMTCFG            (PTMTCFG_MASK            << PTMTCFG_SHIFT)
+#define PTMEMTYPE          (PTMEMTYPE_MASK          << PTMEMTYPE_SHIFT)
+
+
+/* BFBCR */
+#define BFBDFE             (BFBDFE_MASK             << BFBDFE_SHIFT)
+#define BFBSFE             (BFBSFE_MASK             << BFBSFE_SHIFT)
+#define SFVS               (SFVS_MASK               << SFVS_SHIFT)
+#define FLVIC              (FLVIC_MASK              << FLVIC_SHIFT)
+#define SLVIC              (SLVIC_MASK              << SLVIC_SHIFT)
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID    (CONTEXTIDR_ASID_MASK    << CONTEXTIDR_ASID_SHIFT)
+#define PROCID             (PROCID_MASK             << PROCID_SHIFT)
+
+
+/* FSR */
+#define TF                 (TF_MASK                 << TF_SHIFT)
+#define AFF                (AFF_MASK                << AFF_SHIFT)
+#define APF                (APF_MASK                << APF_SHIFT)
+#define TLBMF              (TLBMF_MASK              << TLBMF_SHIFT)
+#define HTWDEEF            (HTWDEEF_MASK            << HTWDEEF_SHIFT)
+#define HTWSEEF            (HTWSEEF_MASK            << HTWSEEF_SHIFT)
+#define MHF                (MHF_MASK                << MHF_SHIFT)
+#define SL                 (SL_MASK                 << SL_SHIFT)
+#define SS                 (SS_MASK                 << SS_SHIFT)
+#define MULTI              (MULTI_MASK              << MULTI_SHIFT)
+
+
+/* FSYNR0 */
+#define AMID               (AMID_MASK               << AMID_SHIFT)
+#define APID               (APID_MASK               << APID_SHIFT)
+#define ABID               (ABID_MASK               << ABID_SHIFT)
+#define ATID               (ATID_MASK               << ATID_SHIFT)
+
+
+/* FSYNR1 */
+#define AMEMTYPE           (AMEMTYPE_MASK           << AMEMTYPE_SHIFT)
+#define ASHARED            (ASHARED_MASK            << ASHARED_SHIFT)
+#define AINNERSHARED       (AINNERSHARED_MASK       << AINNERSHARED_SHIFT)
+#define APRIV              (APRIV_MASK              << APRIV_SHIFT)
+#define APROTNS            (APROTNS_MASK            << APROTNS_SHIFT)
+#define AINST              (AINST_MASK              << AINST_SHIFT)
+#define AWRITE             (AWRITE_MASK             << AWRITE_SHIFT)
+#define ABURST             (ABURST_MASK             << ABURST_SHIFT)
+#define ALEN               (ALEN_MASK               << ALEN_SHIFT)
+#define FSYNR1_ASIZE       (FSYNR1_ASIZE_MASK       << FSYNR1_ASIZE_SHIFT)
+#define ALOCK              (ALOCK_MASK              << ALOCK_SHIFT)
+#define AFULL              (AFULL_MASK              << AFULL_SHIFT)
+
+
+/* NMRR */
+#define ICPC0              (ICPC0_MASK              << ICPC0_SHIFT)
+#define ICPC1              (ICPC1_MASK              << ICPC1_SHIFT)
+#define ICPC2              (ICPC2_MASK              << ICPC2_SHIFT)
+#define ICPC3              (ICPC3_MASK              << ICPC3_SHIFT)
+#define ICPC4              (ICPC4_MASK              << ICPC4_SHIFT)
+#define ICPC5              (ICPC5_MASK              << ICPC5_SHIFT)
+#define ICPC6              (ICPC6_MASK              << ICPC6_SHIFT)
+#define ICPC7              (ICPC7_MASK              << ICPC7_SHIFT)
+#define OCPC0              (OCPC0_MASK              << OCPC0_SHIFT)
+#define OCPC1              (OCPC1_MASK              << OCPC1_SHIFT)
+#define OCPC2              (OCPC2_MASK              << OCPC2_SHIFT)
+#define OCPC3              (OCPC3_MASK              << OCPC3_SHIFT)
+#define OCPC4              (OCPC4_MASK              << OCPC4_SHIFT)
+#define OCPC5              (OCPC5_MASK              << OCPC5_SHIFT)
+#define OCPC6              (OCPC6_MASK              << OCPC6_SHIFT)
+#define OCPC7              (OCPC7_MASK              << OCPC7_SHIFT)
+
+
+/* PAR */
+#define FAULT              (FAULT_MASK              << FAULT_SHIFT)
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF           (FAULT_TF_MASK           << FAULT_TF_SHIFT)
+#define FAULT_AFF          (FAULT_AFF_MASK          << FAULT_AFF_SHIFT)
+#define FAULT_APF          (FAULT_APF_MASK          << FAULT_APF_SHIFT)
+#define FAULT_TLBMF        (FAULT_TLBMF_MASK        << FAULT_TLBMF_SHIFT)
+#define FAULT_HTWDEEF      (FAULT_HTWDEEF_MASK      << FAULT_HTWDEEF_SHIFT)
+#define FAULT_HTWSEEF      (FAULT_HTWSEEF_MASK      << FAULT_HTWSEEF_SHIFT)
+#define FAULT_MHF          (FAULT_MHF_MASK          << FAULT_MHF_SHIFT)
+#define FAULT_SL           (FAULT_SL_MASK           << FAULT_SL_SHIFT)
+#define FAULT_SS           (FAULT_SS_MASK           << FAULT_SS_SHIFT)
+
+/* If NO fault is present, the following fields are in effect */
+/* (FAULT remains as before) */
+#define PAR_NOFAULT_SS     (PAR_NOFAULT_SS_MASK     << PAR_NOFAULT_SS_SHIFT)
+#define PAR_NOFAULT_MT     (PAR_NOFAULT_MT_MASK     << PAR_NOFAULT_MT_SHIFT)
+#define PAR_NOFAULT_SH     (PAR_NOFAULT_SH_MASK     << PAR_NOFAULT_SH_SHIFT)
+#define PAR_NOFAULT_NS     (PAR_NOFAULT_NS_MASK     << PAR_NOFAULT_NS_SHIFT)
+#define PAR_NOFAULT_NOS    (PAR_NOFAULT_NOS_MASK    << PAR_NOFAULT_NOS_SHIFT)
+#define PAR_NPFAULT_PA     (PAR_NPFAULT_PA_MASK     << PAR_NPFAULT_PA_SHIFT)
+
+
+/* PRRR */
+#define MTC0               (MTC0_MASK               << MTC0_SHIFT)
+#define MTC1               (MTC1_MASK               << MTC1_SHIFT)
+#define MTC2               (MTC2_MASK               << MTC2_SHIFT)
+#define MTC3               (MTC3_MASK               << MTC3_SHIFT)
+#define MTC4               (MTC4_MASK               << MTC4_SHIFT)
+#define MTC5               (MTC5_MASK               << MTC5_SHIFT)
+#define MTC6               (MTC6_MASK               << MTC6_SHIFT)
+#define MTC7               (MTC7_MASK               << MTC7_SHIFT)
+#define SHDSH0             (SHDSH0_MASK             << SHDSH0_SHIFT)
+#define SHDSH1             (SHDSH1_MASK             << SHDSH1_SHIFT)
+#define SHNMSH0            (SHNMSH0_MASK            << SHNMSH0_SHIFT)
+#define SHNMSH1            (SHNMSH1_MASK            << SHNMSH1_SHIFT)
+#define NOS0               (NOS0_MASK               << NOS0_SHIFT)
+#define NOS1               (NOS1_MASK               << NOS1_SHIFT)
+#define NOS2               (NOS2_MASK               << NOS2_SHIFT)
+#define NOS3               (NOS3_MASK               << NOS3_SHIFT)
+#define NOS4               (NOS4_MASK               << NOS4_SHIFT)
+#define NOS5               (NOS5_MASK               << NOS5_SHIFT)
+#define NOS6               (NOS6_MASK               << NOS6_SHIFT)
+#define NOS7               (NOS7_MASK               << NOS7_SHIFT)
+
+
+/* RESUME */
+#define TNR                (TNR_MASK                << TNR_SHIFT)
+
+
+/* SCTLR */
+#define M                  (M_MASK                  << M_SHIFT)
+#define TRE                (TRE_MASK                << TRE_SHIFT)
+#define AFE                (AFE_MASK                << AFE_SHIFT)
+#define HAF                (HAF_MASK                << HAF_SHIFT)
+#define BE                 (BE_MASK                 << BE_SHIFT)
+#define AFFD               (AFFD_MASK               << AFFD_SHIFT)
+
+
+/* TLBIASID */
+#define TLBIASID_ASID      (TLBIASID_ASID_MASK      << TLBIASID_ASID_SHIFT)
+
+
+/* TLBIVA */
+#define TLBIVA_ASID        (TLBIVA_ASID_MASK        << TLBIVA_ASID_SHIFT)
+#define TLBIVA_VA          (TLBIVA_VA_MASK          << TLBIVA_VA_SHIFT)
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA         (TLBIVAA_VA_MASK         << TLBIVAA_VA_SHIFT)
+
+
+/* TLBLCKR */
+#define LKE                (LKE_MASK                << LKE_SHIFT)
+#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT)
+#define TLBIASIDCFG        (TLBIASIDCFG_MASK        << TLBIASIDCFG_SHIFT)
+#define TLBIVAACFG         (TLBIVAACFG_MASK         << TLBIVAACFG_SHIFT)
+#define FLOOR              (FLOOR_MASK              << FLOOR_SHIFT)
+#define VICTIM             (VICTIM_MASK             << VICTIM_SHIFT)
+
+
+/* TTBCR */
+#define N                  (N_MASK                  << N_SHIFT)
+#define PD0                (PD0_MASK                << PD0_SHIFT)
+#define PD1                (PD1_MASK                << PD1_SHIFT)
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH        (TTBR0_IRGNH_MASK        << TTBR0_IRGNH_SHIFT)
+#define TTBR0_SH           (TTBR0_SH_MASK           << TTBR0_SH_SHIFT)
+#define TTBR0_ORGN         (TTBR0_ORGN_MASK         << TTBR0_ORGN_SHIFT)
+#define TTBR0_NOS          (TTBR0_NOS_MASK          << TTBR0_NOS_SHIFT)
+#define TTBR0_IRGNL        (TTBR0_IRGNL_MASK        << TTBR0_IRGNL_SHIFT)
+#define TTBR0_PA           (TTBR0_PA_MASK           << TTBR0_PA_SHIFT)
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH        (TTBR1_IRGNH_MASK        << TTBR1_IRGNH_SHIFT)
+#define TTBR1_SH           (TTBR1_SH_MASK           << TTBR1_SH_SHIFT)
+#define TTBR1_ORGN         (TTBR1_ORGN_MASK         << TTBR1_ORGN_SHIFT)
+#define TTBR1_NOS          (TTBR1_NOS_MASK          << TTBR1_NOS_SHIFT)
+#define TTBR1_IRGNL        (TTBR1_IRGNL_MASK        << TTBR1_IRGNL_SHIFT)
+#define TTBR1_PA           (TTBR1_PA_MASK           << TTBR1_PA_SHIFT)
+
+
+/* V2PSR */
+#define HIT                (HIT_MASK                << HIT_SHIFT)
+#define INDEX              (INDEX_MASK              << INDEX_SHIFT)
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX        (V2Pxx_INDEX_MASK        << V2Pxx_INDEX_SHIFT)
+#define V2Pxx_VA           (V2Pxx_VA_MASK           << V2Pxx_VA_SHIFT)
+
+
+/* Global Register Masks */
+/* CBACRn */
+#define RWVMID_MASK               0x1F
+#define RWE_MASK                  0x01
+#define RWGE_MASK                 0x01
+#define CBVMID_MASK               0x1F
+#define IRPTNDX_MASK              0xFF
+
+
+/* CR */
+#define RPUE_MASK                 0x01
+#define RPUERE_MASK               0x01
+#define RPUEIE_MASK               0x01
+#define DCDEE_MASK                0x01
+#define CLIENTPD_MASK             0x01
+#define STALLD_MASK               0x01
+#define TLBLKCRWE_MASK            0x01
+#define CR_TLBIALLCFG_MASK        0x01
+#define TLBIVMIDCFG_MASK          0x01
+#define CR_HUME_MASK              0x01
+
+
+/* ESR */
+#define CFG_MASK                  0x01
+#define BYPASS_MASK               0x01
+#define ESR_MULTI_MASK            0x01
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_MASK          0xFF
+#define ESYNR0_APID_MASK          0x1F
+#define ESYNR0_ABID_MASK          0x07
+#define ESYNR0_AVMID_MASK         0x1F
+#define ESYNR0_ATID_MASK          0xFF
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_MASK             0x07
+#define ESYNR1_ASHARED_MASK              0x01
+#define ESYNR1_AINNERSHARED_MASK         0x01
+#define ESYNR1_APRIV_MASK                0x01
+#define ESYNR1_APROTNS_MASK              0x01
+#define ESYNR1_AINST_MASK                0x01
+#define ESYNR1_AWRITE_MASK               0x01
+#define ESYNR1_ABURST_MASK               0x01
+#define ESYNR1_ALEN_MASK                 0x0F
+#define ESYNR1_ASIZE_MASK                0x01
+#define ESYNR1_ALOCK_MASK                0x03
+#define ESYNR1_AOOO_MASK                 0x01
+#define ESYNR1_AFULL_MASK                0x01
+#define ESYNR1_AC_MASK                   0x01
+#define ESYNR1_DCD_MASK                  0x01
+
+
+/* IDR */
+#define NM2VCBMT_MASK             0x1FF
+#define HTW_MASK                  0x01
+#define HUM_MASK                  0x01
+#define TLBSIZE_MASK              0x0F
+#define NCB_MASK                  0xFF
+#define NIRPT_MASK                0xFF
+
+
+/* M2VCBRn */
+#define VMID_MASK                 0x1F
+#define CBNDX_MASK                0xFF
+#define BYPASSD_MASK              0x01
+#define BPRCOSH_MASK              0x01
+#define BPRCISH_MASK              0x01
+#define BPRCNSH_MASK              0x01
+#define BPSHCFG_MASK              0x03
+#define NSCFG_MASK                0x03
+#define BPMTCFG_MASK              0x01
+#define BPMEMTYPE_MASK            0x07
+
+
+/* REV */
+#define MINOR_MASK                0x0F
+#define MAJOR_MASK                0x0F
+
+
+/* TESTBUSCR */
+#define TBE_MASK                  0x01
+#define SPDMBE_MASK               0x01
+#define WGSEL_MASK                0x03
+#define TBLSEL_MASK               0x03
+#define TBHSEL_MASK               0x03
+#define SPDM0SEL_MASK             0x0F
+#define SPDM1SEL_MASK             0x0F
+#define SPDM2SEL_MASK             0x0F
+#define SPDM3SEL_MASK             0x0F
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_MASK        0x1F
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_MASK         0xFF
+#define TLBBFBS_MASK              0x03
+
+
+/* TLBTR0 */
+#define PR_MASK                   0x01
+#define PW_MASK                   0x01
+#define UR_MASK                   0x01
+#define UW_MASK                   0x01
+#define XN_MASK                   0x01
+#define NSDESC_MASK               0x01
+#define ISH_MASK                  0x01
+#define SH_MASK                   0x01
+#define MT_MASK                   0x07
+#define DPSIZR_MASK               0x07
+#define DPSIZC_MASK               0x07
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_MASK          0x1F
+#define TLBTR1_PA_MASK            0x000FFFFF
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_MASK          0xFF
+#define TLBTR2_V_MASK             0x01
+#define TLBTR2_NSTID_MASK         0x01
+#define TLBTR2_NV_MASK            0x01
+#define TLBTR2_VA_MASK            0x000FFFFF
+
+
+/* Global Register Shifts */
+/* CBACRn */
+#define RWVMID_SHIFT             0
+#define RWE_SHIFT                8
+#define RWGE_SHIFT               9
+#define CBVMID_SHIFT             16
+#define IRPTNDX_SHIFT            24
+
+
+/* CR */
+#define RPUE_SHIFT               0
+#define RPUERE_SHIFT             1
+#define RPUEIE_SHIFT             2
+#define DCDEE_SHIFT              3
+#define CLIENTPD_SHIFT           4
+#define STALLD_SHIFT             5
+#define TLBLKCRWE_SHIFT          6
+#define CR_TLBIALLCFG_SHIFT      7
+#define TLBIVMIDCFG_SHIFT        8
+#define CR_HUME_SHIFT            9
+
+
+/* ESR */
+#define CFG_SHIFT                0
+#define BYPASS_SHIFT             1
+#define ESR_MULTI_SHIFT          31
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_SHIFT        0
+#define ESYNR0_APID_SHIFT        8
+#define ESYNR0_ABID_SHIFT        13
+#define ESYNR0_AVMID_SHIFT       16
+#define ESYNR0_ATID_SHIFT        24
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_SHIFT           0
+#define ESYNR1_ASHARED_SHIFT            3
+#define ESYNR1_AINNERSHARED_SHIFT       4
+#define ESYNR1_APRIV_SHIFT              5
+#define ESYNR1_APROTNS_SHIFT            6
+#define ESYNR1_AINST_SHIFT              7
+#define ESYNR1_AWRITE_SHIFT             8
+#define ESYNR1_ABURST_SHIFT             10
+#define ESYNR1_ALEN_SHIFT               12
+#define ESYNR1_ASIZE_SHIFT              16
+#define ESYNR1_ALOCK_SHIFT              20
+#define ESYNR1_AOOO_SHIFT               22
+#define ESYNR1_AFULL_SHIFT              24
+#define ESYNR1_AC_SHIFT                 30
+#define ESYNR1_DCD_SHIFT                31
+
+
+/* IDR */
+#define NM2VCBMT_SHIFT           0
+#define HTW_SHIFT                9
+#define HUM_SHIFT                10
+#define TLBSIZE_SHIFT            12
+#define NCB_SHIFT                16
+#define NIRPT_SHIFT              24
+
+
+/* M2VCBRn */
+#define VMID_SHIFT               0
+#define CBNDX_SHIFT              8
+#define BYPASSD_SHIFT            16
+#define BPRCOSH_SHIFT            17
+#define BPRCISH_SHIFT            18
+#define BPRCNSH_SHIFT            19
+#define BPSHCFG_SHIFT            20
+#define NSCFG_SHIFT              22
+#define BPMTCFG_SHIFT            24
+#define BPMEMTYPE_SHIFT          25
+
+
+/* REV */
+#define MINOR_SHIFT              0
+#define MAJOR_SHIFT              4
+
+
+/* TESTBUSCR */
+#define TBE_SHIFT                0
+#define SPDMBE_SHIFT             1
+#define WGSEL_SHIFT              8
+#define TBLSEL_SHIFT             12
+#define TBHSEL_SHIFT             14
+#define SPDM0SEL_SHIFT           16
+#define SPDM1SEL_SHIFT           20
+#define SPDM2SEL_SHIFT           24
+#define SPDM3SEL_SHIFT           28
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_SHIFT      0
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_SHIFT       0
+#define TLBBFBS_SHIFT            8
+
+
+/* TLBTR0 */
+#define PR_SHIFT                 0
+#define PW_SHIFT                 1
+#define UR_SHIFT                 2
+#define UW_SHIFT                 3
+#define XN_SHIFT                 4
+#define NSDESC_SHIFT             6
+#define ISH_SHIFT                7
+#define SH_SHIFT                 8
+#define MT_SHIFT                 9
+#define DPSIZR_SHIFT             16
+#define DPSIZC_SHIFT             20
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_SHIFT        0
+#define TLBTR1_PA_SHIFT          12
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_SHIFT        0
+#define TLBTR2_V_SHIFT           8
+#define TLBTR2_NSTID_SHIFT       9
+#define TLBTR2_NV_SHIFT          10
+#define TLBTR2_VA_SHIFT          12
+
+
+/* Context Register Masks */
+/* ACTLR */
+#define CFERE_MASK                       0x01
+#define CFEIE_MASK                       0x01
+#define PTSHCFG_MASK                     0x03
+#define RCOSH_MASK                       0x01
+#define RCISH_MASK                       0x01
+#define RCNSH_MASK                       0x01
+#define PRIVCFG_MASK                     0x03
+#define DNA_MASK                         0x01
+#define DNLV2PA_MASK                     0x01
+#define TLBMCFG_MASK                     0x03
+#define CFCFG_MASK                       0x01
+#define TIPCF_MASK                       0x01
+#define V2PCFG_MASK                      0x03
+#define HUME_MASK                        0x01
+#define PTMTCFG_MASK                     0x01
+#define PTMEMTYPE_MASK                   0x07
+
+
+/* BFBCR */
+#define BFBDFE_MASK                      0x01
+#define BFBSFE_MASK                      0x01
+#define SFVS_MASK                        0x01
+#define FLVIC_MASK                       0x0F
+#define SLVIC_MASK                       0x0F
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_MASK             0xFF
+#define PROCID_MASK                      0x00FFFFFF
+
+
+/* FSR */
+#define TF_MASK                          0x01
+#define AFF_MASK                         0x01
+#define APF_MASK                         0x01
+#define TLBMF_MASK                       0x01
+#define HTWDEEF_MASK                     0x01
+#define HTWSEEF_MASK                     0x01
+#define MHF_MASK                         0x01
+#define SL_MASK                          0x01
+#define SS_MASK                          0x01
+#define MULTI_MASK                       0x01
+
+
+/* FSYNR0 */
+#define AMID_MASK                        0xFF
+#define APID_MASK                        0x1F
+#define ABID_MASK                        0x07
+#define ATID_MASK                        0xFF
+
+
+/* FSYNR1 */
+#define AMEMTYPE_MASK                    0x07
+#define ASHARED_MASK                     0x01
+#define AINNERSHARED_MASK                0x01
+#define APRIV_MASK                       0x01
+#define APROTNS_MASK                     0x01
+#define AINST_MASK                       0x01
+#define AWRITE_MASK                      0x01
+#define ABURST_MASK                      0x01
+#define ALEN_MASK                        0x0F
+#define FSYNR1_ASIZE_MASK                0x07
+#define ALOCK_MASK                       0x03
+#define AFULL_MASK                       0x01
+
+
+/* NMRR */
+#define ICPC0_MASK                       0x03
+#define ICPC1_MASK                       0x03
+#define ICPC2_MASK                       0x03
+#define ICPC3_MASK                       0x03
+#define ICPC4_MASK                       0x03
+#define ICPC5_MASK                       0x03
+#define ICPC6_MASK                       0x03
+#define ICPC7_MASK                       0x03
+#define OCPC0_MASK                       0x03
+#define OCPC1_MASK                       0x03
+#define OCPC2_MASK                       0x03
+#define OCPC3_MASK                       0x03
+#define OCPC4_MASK                       0x03
+#define OCPC5_MASK                       0x03
+#define OCPC6_MASK                       0x03
+#define OCPC7_MASK                       0x03
+
+
+/* PAR */
+#define FAULT_MASK                       0x01
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_MASK                    0x01
+#define FAULT_AFF_MASK                   0x01
+#define FAULT_APF_MASK                   0x01
+#define FAULT_TLBMF_MASK                 0x01
+#define FAULT_HTWDEEF_MASK               0x01
+#define FAULT_HTWSEEF_MASK               0x01
+#define FAULT_MHF_MASK                   0x01
+#define FAULT_SL_MASK                    0x01
+#define FAULT_SS_MASK                    0x01
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_MASK              0x01
+#define PAR_NOFAULT_MT_MASK              0x07
+#define PAR_NOFAULT_SH_MASK              0x01
+#define PAR_NOFAULT_NS_MASK              0x01
+#define PAR_NOFAULT_NOS_MASK             0x01
+#define PAR_NPFAULT_PA_MASK              0x000FFFFF
+
+
+/* PRRR */
+#define MTC0_MASK                        0x03
+#define MTC1_MASK                        0x03
+#define MTC2_MASK                        0x03
+#define MTC3_MASK                        0x03
+#define MTC4_MASK                        0x03
+#define MTC5_MASK                        0x03
+#define MTC6_MASK                        0x03
+#define MTC7_MASK                        0x03
+#define SHDSH0_MASK                      0x01
+#define SHDSH1_MASK                      0x01
+#define SHNMSH0_MASK                     0x01
+#define SHNMSH1_MASK                     0x01
+#define NOS0_MASK                        0x01
+#define NOS1_MASK                        0x01
+#define NOS2_MASK                        0x01
+#define NOS3_MASK                        0x01
+#define NOS4_MASK                        0x01
+#define NOS5_MASK                        0x01
+#define NOS6_MASK                        0x01
+#define NOS7_MASK                        0x01
+
+
+/* RESUME */
+#define TNR_MASK                         0x01
+
+
+/* SCTLR */
+#define M_MASK                           0x01
+#define TRE_MASK                         0x01
+#define AFE_MASK                         0x01
+#define HAF_MASK                         0x01
+#define BE_MASK                          0x01
+#define AFFD_MASK                        0x01
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_MASK               0xFF
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_MASK                 0xFF
+#define TLBIVA_VA_MASK                   0x000FFFFF
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_MASK                  0x000FFFFF
+
+
+/* TLBLCKR */
+#define LKE_MASK                         0x01
+#define TLBLCKR_TLBIALLCFG_MASK          0x01
+#define TLBIASIDCFG_MASK                 0x01
+#define TLBIVAACFG_MASK                  0x01
+#define FLOOR_MASK                       0xFF
+#define VICTIM_MASK                      0xFF
+
+
+/* TTBCR */
+#define N_MASK                           0x07
+#define PD0_MASK                         0x01
+#define PD1_MASK                         0x01
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_MASK                 0x01
+#define TTBR0_SH_MASK                    0x01
+#define TTBR0_ORGN_MASK                  0x03
+#define TTBR0_NOS_MASK                   0x01
+#define TTBR0_IRGNL_MASK                 0x01
+#define TTBR0_PA_MASK                    0x0003FFFF
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_MASK                 0x01
+#define TTBR1_SH_MASK                    0x01
+#define TTBR1_ORGN_MASK                  0x03
+#define TTBR1_NOS_MASK                   0x01
+#define TTBR1_IRGNL_MASK                 0x01
+#define TTBR1_PA_MASK                    0x0003FFFF
+
+
+/* V2PSR */
+#define HIT_MASK                         0x01
+#define INDEX_MASK                       0xFF
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_MASK                 0xFF
+#define V2Pxx_VA_MASK                    0x000FFFFF
+
+
+/* Context Register Shifts */
+/* ACTLR */
+#define CFERE_SHIFT                    0
+#define CFEIE_SHIFT                    1
+#define PTSHCFG_SHIFT                  2
+#define RCOSH_SHIFT                    4
+#define RCISH_SHIFT                    5
+#define RCNSH_SHIFT                    6
+#define PRIVCFG_SHIFT                  8
+#define DNA_SHIFT                      10
+#define DNLV2PA_SHIFT                  11
+#define TLBMCFG_SHIFT                  12
+#define CFCFG_SHIFT                    14
+#define TIPCF_SHIFT                    15
+#define V2PCFG_SHIFT                   16
+#define HUME_SHIFT                     18
+#define PTMTCFG_SHIFT                  20
+#define PTMEMTYPE_SHIFT                21
+
+
+/* BFBCR */
+#define BFBDFE_SHIFT                   0
+#define BFBSFE_SHIFT                   1
+#define SFVS_SHIFT                     2
+#define FLVIC_SHIFT                    4
+#define SLVIC_SHIFT                    8
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_SHIFT          0
+#define PROCID_SHIFT                   8
+
+
+/* FSR */
+#define TF_SHIFT                       1
+#define AFF_SHIFT                      2
+#define APF_SHIFT                      3
+#define TLBMF_SHIFT                    4
+#define HTWDEEF_SHIFT                  5
+#define HTWSEEF_SHIFT                  6
+#define MHF_SHIFT                      7
+#define SL_SHIFT                       16
+#define SS_SHIFT                       30
+#define MULTI_SHIFT                    31
+
+
+/* FSYNR0 */
+#define AMID_SHIFT                     0
+#define APID_SHIFT                     8
+#define ABID_SHIFT                     13
+#define ATID_SHIFT                     24
+
+
+/* FSYNR1 */
+#define AMEMTYPE_SHIFT                 0
+#define ASHARED_SHIFT                  3
+#define AINNERSHARED_SHIFT             4
+#define APRIV_SHIFT                    5
+#define APROTNS_SHIFT                  6
+#define AINST_SHIFT                    7
+#define AWRITE_SHIFT                   8
+#define ABURST_SHIFT                   10
+#define ALEN_SHIFT                     12
+#define FSYNR1_ASIZE_SHIFT             16
+#define ALOCK_SHIFT                    20
+#define AFULL_SHIFT                    24
+
+
+/* NMRR */
+#define ICPC0_SHIFT                    0
+#define ICPC1_SHIFT                    2
+#define ICPC2_SHIFT                    4
+#define ICPC3_SHIFT                    6
+#define ICPC4_SHIFT                    8
+#define ICPC5_SHIFT                    10
+#define ICPC6_SHIFT                    12
+#define ICPC7_SHIFT                    14
+#define OCPC0_SHIFT                    16
+#define OCPC1_SHIFT                    18
+#define OCPC2_SHIFT                    20
+#define OCPC3_SHIFT                    22
+#define OCPC4_SHIFT                    24
+#define OCPC5_SHIFT                    26
+#define OCPC6_SHIFT                    28
+#define OCPC7_SHIFT                    30
+
+
+/* PAR */
+#define FAULT_SHIFT                    0
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_SHIFT                 1
+#define FAULT_AFF_SHIFT                2
+#define FAULT_APF_SHIFT                3
+#define FAULT_TLBMF_SHIFT              4
+#define FAULT_HTWDEEF_SHIFT            5
+#define FAULT_HTWSEEF_SHIFT            6
+#define FAULT_MHF_SHIFT                7
+#define FAULT_SL_SHIFT                 16
+#define FAULT_SS_SHIFT                 30
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_SHIFT           1
+#define PAR_NOFAULT_MT_SHIFT           4
+#define PAR_NOFAULT_SH_SHIFT           7
+#define PAR_NOFAULT_NS_SHIFT           9
+#define PAR_NOFAULT_NOS_SHIFT          10
+#define PAR_NPFAULT_PA_SHIFT           12
+
+
+/* PRRR */
+#define MTC0_SHIFT                     0
+#define MTC1_SHIFT                     2
+#define MTC2_SHIFT                     4
+#define MTC3_SHIFT                     6
+#define MTC4_SHIFT                     8
+#define MTC5_SHIFT                     10
+#define MTC6_SHIFT                     12
+#define MTC7_SHIFT                     14
+#define SHDSH0_SHIFT                   16
+#define SHDSH1_SHIFT                   17
+#define SHNMSH0_SHIFT                  18
+#define SHNMSH1_SHIFT                  19
+#define NOS0_SHIFT                     24
+#define NOS1_SHIFT                     25
+#define NOS2_SHIFT                     26
+#define NOS3_SHIFT                     27
+#define NOS4_SHIFT                     28
+#define NOS5_SHIFT                     29
+#define NOS6_SHIFT                     30
+#define NOS7_SHIFT                     31
+
+
+/* RESUME */
+#define TNR_SHIFT                      0
+
+
+/* SCTLR */
+#define M_SHIFT                        0
+#define TRE_SHIFT                      1
+#define AFE_SHIFT                      2
+#define HAF_SHIFT                      3
+#define BE_SHIFT                       4
+#define AFFD_SHIFT                     5
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_SHIFT            0
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_SHIFT              0
+#define TLBIVA_VA_SHIFT                12
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_SHIFT               12
+
+
+/* TLBLCKR */
+#define LKE_SHIFT                      0
+#define TLBLCKR_TLBIALLCFG_SHIFT       1
+#define TLBIASIDCFG_SHIFT              2
+#define TLBIVAACFG_SHIFT               3
+#define FLOOR_SHIFT                    8
+#define VICTIM_SHIFT                   8
+
+
+/* TTBCR */
+#define N_SHIFT                        3
+#define PD0_SHIFT                      4
+#define PD1_SHIFT                      5
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_SHIFT              0
+#define TTBR0_SH_SHIFT                 1
+#define TTBR0_ORGN_SHIFT               3
+#define TTBR0_NOS_SHIFT                5
+#define TTBR0_IRGNL_SHIFT              6
+#define TTBR0_PA_SHIFT                 14
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_SHIFT              0
+#define TTBR1_SH_SHIFT                 1
+#define TTBR1_ORGN_SHIFT               3
+#define TTBR1_NOS_SHIFT                5
+#define TTBR1_IRGNL_SHIFT              6
+#define TTBR1_PA_SHIFT                 14
+
+
+/* V2PSR */
+#define HIT_SHIFT                      0
+#define INDEX_SHIFT                    8
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_SHIFT              0
+#define V2Pxx_VA_SHIFT                 12
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
new file mode 100644 (file)
index 0000000..36074cf
--- /dev/null
@@ -0,0 +1,253 @@
+/* Copyright (c) 2010 Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ASM_ARCH_MSM_IRQS_8X60_H
+#define __ASM_ARCH_MSM_IRQS_8X60_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15:  STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+:   SPI (shared peripheral interrupts)
+ */
+
+#define GIC_PPI_START 16
+#define GIC_SPI_START 32
+
+#define INT_DEBUG_TIMER_EXP                    (GIC_PPI_START + 0)
+#define INT_GP_TIMER_EXP                       (GIC_PPI_START + 1)
+#define INT_GP_TIMER2_EXP                      (GIC_PPI_START + 2)
+#define WDT0_ACCSCSSNBARK_INT                  (GIC_PPI_START + 3)
+#define WDT1_ACCSCSSNBARK_INT                  (GIC_PPI_START + 4)
+#define AVS_SVICINT                            (GIC_PPI_START + 5)
+#define AVS_SVICINTSWDONE                      (GIC_PPI_START + 6)
+#define CPU_DBGCPUXCOMMRXFULL                  (GIC_PPI_START + 7)
+#define CPU_DBGCPUXCOMMTXEMPTY                 (GIC_PPI_START + 8)
+#define CPU_SICCPUXPERFMONIRPTREQ              (GIC_PPI_START + 9)
+#define SC_AVSCPUXDOWN                         (GIC_PPI_START + 10)
+#define SC_AVSCPUXUP                           (GIC_PPI_START + 11)
+#define SC_SICCPUXACGIRPTREQ                   (GIC_PPI_START + 12)
+/* PPI 13 to 15 are unused */
+
+
+#define SC_SICMPUIRPTREQ                       (GIC_SPI_START + 0)
+#define SC_SICL2IRPTREQ                                (GIC_SPI_START + 1)
+#define SC_SICL2ACGIRPTREQ                     (GIC_SPI_START + 2)
+#define NC                                     (GIC_SPI_START + 3)
+#define TLMM_SCSS_DIR_CONN_IRQ_0               (GIC_SPI_START + 4)
+#define TLMM_SCSS_DIR_CONN_IRQ_1               (GIC_SPI_START + 5)
+#define TLMM_SCSS_DIR_CONN_IRQ_2               (GIC_SPI_START + 6)
+#define TLMM_SCSS_DIR_CONN_IRQ_3               (GIC_SPI_START + 7)
+#define TLMM_SCSS_DIR_CONN_IRQ_4               (GIC_SPI_START + 8)
+#define TLMM_SCSS_DIR_CONN_IRQ_5               (GIC_SPI_START + 9)
+#define TLMM_SCSS_DIR_CONN_IRQ_6               (GIC_SPI_START + 10)
+#define TLMM_SCSS_DIR_CONN_IRQ_7               (GIC_SPI_START + 11)
+#define TLMM_SCSS_DIR_CONN_IRQ_8               (GIC_SPI_START + 12)
+#define TLMM_SCSS_DIR_CONN_IRQ_9               (GIC_SPI_START + 13)
+#define PM8058_SEC_IRQ_N                       (GIC_SPI_START + 14)
+#define PM8901_SEC_IRQ_N                       (GIC_SPI_START + 15)
+#define TLMM_SCSS_SUMMARY_IRQ                  (GIC_SPI_START + 16)
+#define SPDM_RT_1_IRQ                          (GIC_SPI_START + 17)
+#define SPDM_DIAG_IRQ                          (GIC_SPI_START + 18)
+#define RPM_SCSS_CPU0_GP_HIGH_IRQ              (GIC_SPI_START + 19)
+#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ            (GIC_SPI_START + 20)
+#define RPM_SCSS_CPU0_GP_LOW_IRQ               (GIC_SPI_START + 21)
+#define RPM_SCSS_CPU0_WAKE_UP_IRQ              (GIC_SPI_START + 22)
+#define RPM_SCSS_CPU1_GP_HIGH_IRQ              (GIC_SPI_START + 23)
+#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ            (GIC_SPI_START + 24)
+#define RPM_SCSS_CPU1_GP_LOW_IRQ               (GIC_SPI_START + 25)
+#define RPM_SCSS_CPU1_WAKE_UP_IRQ              (GIC_SPI_START + 26)
+#define SSBI2_2_SC_CPU0_SECURE_INT             (GIC_SPI_START + 27)
+#define SSBI2_2_SC_CPU0_NON_SECURE_INT         (GIC_SPI_START + 28)
+#define SSBI2_1_SC_CPU0_SECURE_INT             (GIC_SPI_START + 29)
+#define SSBI2_1_SC_CPU0_NON_SECURE_INT         (GIC_SPI_START + 30)
+#define MSMC_SC_SEC_CE_IRQ                     (GIC_SPI_START + 31)
+#define MSMC_SC_PRI_CE_IRQ                     (GIC_SPI_START + 32)
+#define MARM_FIQ                               (GIC_SPI_START + 33)
+#define MARM_IRQ                               (GIC_SPI_START + 34)
+#define MARM_L2CC_IRQ                          (GIC_SPI_START + 35)
+#define MARM_WDOG_EXPIRED                      (GIC_SPI_START + 36)
+#define MARM_SCSS_GP_IRQ_0                     (GIC_SPI_START + 37)
+#define MARM_SCSS_GP_IRQ_1                     (GIC_SPI_START + 38)
+#define MARM_SCSS_GP_IRQ_2                     (GIC_SPI_START + 39)
+#define MARM_SCSS_GP_IRQ_3                     (GIC_SPI_START + 40)
+#define MARM_SCSS_GP_IRQ_4                     (GIC_SPI_START + 41)
+#define MARM_SCSS_GP_IRQ_5                     (GIC_SPI_START + 42)
+#define MARM_SCSS_GP_IRQ_6                     (GIC_SPI_START + 43)
+#define MARM_SCSS_GP_IRQ_7                     (GIC_SPI_START + 44)
+#define MARM_SCSS_GP_IRQ_8                     (GIC_SPI_START + 45)
+#define MARM_SCSS_GP_IRQ_9                     (GIC_SPI_START + 46)
+#define VPE_IRQ                                        (GIC_SPI_START + 47)
+#define VFE_IRQ                                        (GIC_SPI_START + 48)
+#define VCODEC_IRQ                             (GIC_SPI_START + 49)
+#define TV_ENC_IRQ                             (GIC_SPI_START + 50)
+#define SMMU_VPE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 51)
+#define SMMU_VPE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 52)
+#define SMMU_VFE_CB_SC_SECURE_IRQ              (GIC_SPI_START + 53)
+#define SMMU_VFE_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 54)
+#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ         (GIC_SPI_START + 55)
+#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 56)
+#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ         (GIC_SPI_START + 57)
+#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ     (GIC_SPI_START + 58)
+#define SMMU_ROT_CB_SC_SECURE_IRQ              (GIC_SPI_START + 59)
+#define SMMU_ROT_CB_SC_NON_SECURE_IRQ          (GIC_SPI_START + 60)
+#define SMMU_MDP1_CB_SC_SECURE_IRQ             (GIC_SPI_START + 61)
+#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 62)
+#define SMMU_MDP0_CB_SC_SECURE_IRQ             (GIC_SPI_START + 63)
+#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ         (GIC_SPI_START + 64)
+#define SMMU_JPEGD_CB_SC_SECURE_IRQ            (GIC_SPI_START + 65)
+#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 66)
+#define SMMU_IJPEG_CB_SC_SECURE_IRQ            (GIC_SPI_START + 67)
+#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 68)
+#define SMMU_GFX3D_CB_SC_SECURE_IRQ            (GIC_SPI_START + 69)
+#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ                (GIC_SPI_START + 70)
+#define SMMU_GFX2D0_CB_SC_SECURE_IRQ           (GIC_SPI_START + 71)
+#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ       (GIC_SPI_START + 72)
+#define ROT_IRQ                                        (GIC_SPI_START + 73)
+#define MMSS_FABRIC_IRQ                                (GIC_SPI_START + 74)
+#define MDP_IRQ                                        (GIC_SPI_START + 75)
+#define JPEGD_IRQ                              (GIC_SPI_START + 76)
+#define JPEG_IRQ                               (GIC_SPI_START + 77)
+#define MMSS_IMEM_IRQ                          (GIC_SPI_START + 78)
+#define HDMI_IRQ                               (GIC_SPI_START + 79)
+#define GFX3D_IRQ                              (GIC_SPI_START + 80)
+#define GFX2D0_IRQ                             (GIC_SPI_START + 81)
+#define DSI_IRQ                                        (GIC_SPI_START + 82)
+#define CSI_1_IRQ                              (GIC_SPI_START + 83)
+#define CSI_0_IRQ                              (GIC_SPI_START + 84)
+#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ           (GIC_SPI_START + 85)
+#define LPASS_SCSS_MIDI_IRQ                    (GIC_SPI_START + 86)
+#define LPASS_Q6SS_WDOG_EXPIRED                        (GIC_SPI_START + 87)
+#define LPASS_SCSS_GP_LOW_IRQ                  (GIC_SPI_START + 88)
+#define LPASS_SCSS_GP_MEDIUM_IRQ               (GIC_SPI_START + 89)
+#define LPASS_SCSS_GP_HIGH_IRQ                 (GIC_SPI_START + 90)
+#define TOP_IMEM_IRQ                           (GIC_SPI_START + 91)
+#define FABRIC_SYS_IRQ                         (GIC_SPI_START + 92)
+#define FABRIC_APPS_IRQ                                (GIC_SPI_START + 93)
+#define USB1_HS_BAM_IRQ                                (GIC_SPI_START + 94)
+#define SDC4_BAM_IRQ                           (GIC_SPI_START + 95)
+#define SDC3_BAM_IRQ                           (GIC_SPI_START + 96)
+#define SDC2_BAM_IRQ                           (GIC_SPI_START + 97)
+#define SDC1_BAM_IRQ                           (GIC_SPI_START + 98)
+#define FABRIC_SPS_IRQ                         (GIC_SPI_START + 99)
+#define USB1_HS_IRQ                            (GIC_SPI_START + 100)
+#define SDC4_IRQ_0                             (GIC_SPI_START + 101)
+#define SDC3_IRQ_0                             (GIC_SPI_START + 102)
+#define SDC2_IRQ_0                             (GIC_SPI_START + 103)
+#define SDC1_IRQ_0                             (GIC_SPI_START + 104)
+#define SPS_BAM_DMA_IRQ                                (GIC_SPI_START + 105)
+#define SPS_SEC_VIOL_IRQ                       (GIC_SPI_START + 106)
+#define SPS_MTI_0                              (GIC_SPI_START + 107)
+#define SPS_MTI_1                              (GIC_SPI_START + 108)
+#define SPS_MTI_2                              (GIC_SPI_START + 109)
+#define SPS_MTI_3                              (GIC_SPI_START + 110)
+#define SPS_MTI_4                              (GIC_SPI_START + 111)
+#define SPS_MTI_5                              (GIC_SPI_START + 112)
+#define SPS_MTI_6                              (GIC_SPI_START + 113)
+#define SPS_MTI_7                              (GIC_SPI_START + 114)
+#define SPS_MTI_8                              (GIC_SPI_START + 115)
+#define SPS_MTI_9                              (GIC_SPI_START + 116)
+#define SPS_MTI_10                             (GIC_SPI_START + 117)
+#define SPS_MTI_11                             (GIC_SPI_START + 118)
+#define SPS_MTI_12                             (GIC_SPI_START + 119)
+#define SPS_MTI_13                             (GIC_SPI_START + 120)
+#define SPS_MTI_14                             (GIC_SPI_START + 121)
+#define SPS_MTI_15                             (GIC_SPI_START + 122)
+#define SPS_MTI_16                             (GIC_SPI_START + 123)
+#define SPS_MTI_17                             (GIC_SPI_START + 124)
+#define SPS_MTI_18                             (GIC_SPI_START + 125)
+#define SPS_MTI_19                             (GIC_SPI_START + 126)
+#define SPS_MTI_20                             (GIC_SPI_START + 127)
+#define SPS_MTI_21                             (GIC_SPI_START + 128)
+#define SPS_MTI_22                             (GIC_SPI_START + 129)
+#define SPS_MTI_23                             (GIC_SPI_START + 130)
+#define SPS_MTI_24                             (GIC_SPI_START + 131)
+#define SPS_MTI_25                             (GIC_SPI_START + 132)
+#define SPS_MTI_26                             (GIC_SPI_START + 133)
+#define SPS_MTI_27                             (GIC_SPI_START + 134)
+#define SPS_MTI_28                             (GIC_SPI_START + 135)
+#define SPS_MTI_29                             (GIC_SPI_START + 136)
+#define SPS_MTI_30                             (GIC_SPI_START + 137)
+#define SPS_MTI_31                             (GIC_SPI_START + 138)
+#define UXMC_EBI2_WR_ER_DONE_IRQ               (GIC_SPI_START + 139)
+#define UXMC_EBI2_OP_DONE_IRQ                  (GIC_SPI_START + 140)
+#define USB2_IRQ                               (GIC_SPI_START + 141)
+#define USB1_IRQ                               (GIC_SPI_START + 142)
+#define TSSC_SSBI_IRQ                          (GIC_SPI_START + 143)
+#define TSSC_SAMPLE_IRQ                                (GIC_SPI_START + 144)
+#define TSSC_PENUP_IRQ                         (GIC_SPI_START + 145)
+#define INT_UART1DM_IRQ                                (GIC_SPI_START + 146)
+#define GSBI1_QUP_IRQ                          (GIC_SPI_START + 147)
+#define INT_UART2DM_IRQ                                (GIC_SPI_START + 148)
+#define GSBI2_QUP_IRQ                          (GIC_SPI_START + 149)
+#define INT_UART3DM_IRQ                                (GIC_SPI_START + 150)
+#define GSBI3_QUP_IRQ                          (GIC_SPI_START + 151)
+#define INT_UART4DM_IRQ                                (GIC_SPI_START + 152)
+#define GSBI4_QUP_IRQ                          (GIC_SPI_START + 153)
+#define INT_UART5DM_IRQ                                (GIC_SPI_START + 154)
+#define GSBI5_QUP_IRQ                          (GIC_SPI_START + 155)
+#define INT_UART6DM_IRQ                                (GIC_SPI_START + 156)
+#define GSBI6_QUP_IRQ                          (GIC_SPI_START + 157)
+#define INT_UART7DM_IRQ                                (GIC_SPI_START + 158)
+#define GSBI7_QUP_IRQ                          (GIC_SPI_START + 159)
+#define INT_UART8DM_IRQ                                (GIC_SPI_START + 160)
+#define GSBI8_QUP_IRQ                          (GIC_SPI_START + 161)
+#define TSIF_TSPP_IRQ                          (GIC_SPI_START + 162)
+#define TSIF_BAM_IRQ                           (GIC_SPI_START + 163)
+#define TSIF2_IRQ                              (GIC_SPI_START + 164)
+#define TSIF1_IRQ                              (GIC_SPI_START + 165)
+#define INT_ADM1_MASTER                                (GIC_SPI_START + 166)
+#define INT_ADM1_AARM                          (GIC_SPI_START + 167)
+#define INT_ADM1_SD2                           (GIC_SPI_START + 168)
+#define INT_ADM1_SD3                           (GIC_SPI_START + 169)
+#define INT_ADM0_MASTER                                (GIC_SPI_START + 170)
+#define INT_ADM0_AARM                          (GIC_SPI_START + 171)
+#define INT_ADM0_SD2                           (GIC_SPI_START + 172)
+#define INT_ADM0_SD3                           (GIC_SPI_START + 173)
+#define CC_SCSS_WDT1CPU1BITEEXPIRED            (GIC_SPI_START + 174)
+#define CC_SCSS_WDT1CPU0BITEEXPIRED            (GIC_SPI_START + 175)
+#define CC_SCSS_WDT0CPU1BITEEXPIRED            (GIC_SPI_START + 176)
+#define CC_SCSS_WDT0CPU0BITEEXPIRED            (GIC_SPI_START + 177)
+#define TSENS_UPPER_LOWER_INT                  (GIC_SPI_START + 178)
+#define SSBI2_2_SC_CPU1_SECURE_INT             (GIC_SPI_START + 179)
+#define SSBI2_2_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 180)
+#define SSBI2_1_SC_CPU1_SECURE_INT             (GIC_SPI_START + 181)
+#define SSBI2_1_SC_CPU1_NON_SECURE_INT         (GIC_SPI_START + 182)
+#define XPU_SUMMARY_IRQ                                (GIC_SPI_START + 183)
+#define BUS_EXCEPTION_SUMMARY_IRQ              (GIC_SPI_START + 184)
+#define HSDDRX_SMICH0_IRQ                      (GIC_SPI_START + 185)
+#define HSDDRX_EBI1_IRQ                                (GIC_SPI_START + 186)
+#define SDC5_BAM_IRQ                           (GIC_SPI_START + 187)
+#define SDC5_IRQ_0                             (GIC_SPI_START + 188)
+#define INT_UART9DM_IRQ                                (GIC_SPI_START + 189)
+#define GSBI9_QUP_IRQ                          (GIC_SPI_START + 190)
+#define INT_UART10DM_IRQ                       (GIC_SPI_START + 191)
+#define GSBI10_QUP_IRQ                         (GIC_SPI_START + 192)
+#define INT_UART11DM_IRQ                       (GIC_SPI_START + 193)
+#define GSBI11_QUP_IRQ                         (GIC_SPI_START + 194)
+#define INT_UART12DM_IRQ                       (GIC_SPI_START + 195)
+#define GSBI12_QUP_IRQ                         (GIC_SPI_START + 196)
+/*SPI 197 to 216 arent used in 8x60*/
+#define SMPSS_SPARE_1                          (GIC_SPI_START + 217)
+#define SMPSS_SPARE_2                          (GIC_SPI_START + 218)
+#define SMPSS_SPARE_3                          (GIC_SPI_START + 219)
+#define SMPSS_SPARE_4                          (GIC_SPI_START + 220)
+#define SMPSS_SPARE_5                          (GIC_SPI_START + 221)
+#define SMPSS_SPARE_6                          (GIC_SPI_START + 222)
+#define SMPSS_SPARE_7                          (GIC_SPI_START + 223)
+
+#define NR_GPIO_IRQS 173
+#define NR_MSM_IRQS 256
+#define NR_BOARD_IRQS 0
+
+#endif
index 164d355c96ea99d5a9b884de18b201f4461054f4..8679a45647447c213902c297efd953aabba7ecba 100644 (file)
@@ -24,6 +24,8 @@
 #elif defined(CONFIG_ARCH_QSD8X50)
 #include "irqs-8x50.h"
 #include "sirc.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "irqs-8x60.h"
 #elif defined(CONFIG_ARCH_MSM_ARM11)
 #include "irqs-7x00.h"
 #else
index 50c7847e6002d3311b265c514f471ee39ad371ce..070e17d237f1926916391a56822d2cc6b8c3d444 100644 (file)
@@ -23,6 +23,8 @@
 #define PHYS_OFFSET            UL(0x20000000)
 #elif defined(CONFIG_ARCH_MSM7X30)
 #define PHYS_OFFSET            UL(0x00200000)
+#elif defined(CONFIG_ARCH_MSM8X60)
+#define PHYS_OFFSET            UL(0x40200000)
 #else
 #define PHYS_OFFSET            UL(0x10000000)
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
new file mode 100644 (file)
index 0000000..45bab50
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough.  Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8X60_H
+#define __ASM_ARCH_MSM_IOMAP_8X60_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_QGIC_DIST_BASE     IOMEM(0xF0000000)
+#define MSM_QGIC_DIST_PHYS     0x02080000
+#define MSM_QGIC_DIST_SIZE     SZ_4K
+
+#define MSM_QGIC_CPU_BASE      IOMEM(0xF0001000)
+#define MSM_QGIC_CPU_PHYS      0x02081000
+#define MSM_QGIC_CPU_SIZE      SZ_4K
+
+#define MSM_ACC_BASE           IOMEM(0xF0002000)
+#define MSM_ACC_PHYS           0x02001000
+#define MSM_ACC_SIZE           SZ_4K
+
+#define MSM_GCC_BASE           IOMEM(0xF0003000)
+#define MSM_GCC_PHYS           0x02082000
+#define MSM_GCC_SIZE           SZ_4K
+
+#define MSM_TLMM_BASE          IOMEM(0xF0004000)
+#define MSM_TLMM_PHYS          0x00800000
+#define MSM_TLMM_SIZE          SZ_16K
+
+#define MSM_SHARED_RAM_BASE    IOMEM(0xF0100000)
+#define MSM_SHARED_RAM_SIZE    SZ_1M
+
+#define MSM_TMR_BASE           IOMEM(0xF0200000)
+#define MSM_TMR_PHYS           0x02000000
+#define MSM_TMR_SIZE           (SZ_1M)
+
+#define MSM_GPT_BASE           (MSM_TMR_BASE + 0x4)
+#define MSM_DGT_BASE           (MSM_TMR_BASE + 0x24)
+
+#define MSM_IOMMU_JPEGD_PHYS   0x07300000
+#define MSM_IOMMU_JPEGD_SIZE   SZ_1M
+
+#define MSM_IOMMU_VPE_PHYS     0x07400000
+#define MSM_IOMMU_VPE_SIZE     SZ_1M
+
+#define MSM_IOMMU_MDP0_PHYS    0x07500000
+#define MSM_IOMMU_MDP0_SIZE    SZ_1M
+
+#define MSM_IOMMU_MDP1_PHYS    0x07600000
+#define MSM_IOMMU_MDP1_SIZE    SZ_1M
+
+#define MSM_IOMMU_ROT_PHYS     0x07700000
+#define MSM_IOMMU_ROT_SIZE     SZ_1M
+
+#define MSM_IOMMU_IJPEG_PHYS   0x07800000
+#define MSM_IOMMU_IJPEG_SIZE   SZ_1M
+
+#define MSM_IOMMU_VFE_PHYS     0x07900000
+#define MSM_IOMMU_VFE_SIZE     SZ_1M
+
+#define MSM_IOMMU_VCODEC_A_PHYS        0x07A00000
+#define MSM_IOMMU_VCODEC_A_SIZE        SZ_1M
+
+#define MSM_IOMMU_VCODEC_B_PHYS        0x07B00000
+#define MSM_IOMMU_VCODEC_B_SIZE        SZ_1M
+
+#define MSM_IOMMU_GFX3D_PHYS   0x07C00000
+#define MSM_IOMMU_GFX3D_SIZE   SZ_1M
+
+#define MSM_IOMMU_GFX2D0_PHYS  0x07D00000
+#define MSM_IOMMU_GFX2D0_SIZE  SZ_1M
+
+#endif
index e6b1821cc4ea130e0266d83191e95195694ee9d4..8e24dd8121397871de5bc3f8ee4a5d5769bca8f6 100644 (file)
 #include "msm_iomap-7x30.h"
 #elif defined(CONFIG_ARCH_QSD8X50)
 #include "msm_iomap-8x50.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "msm_iomap-8x60.h"
 #else
 #include "msm_iomap-7x00.h"
 #endif
 
+
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h
new file mode 100644 (file)
index 0000000..3ff7bf5
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Code Aurora nor
+ *       the names of its contributors may be used to endorse or promote
+ *       products derived from this software without specific prior written
+ *       permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMP_H
+#define __ASM_ARCH_MSM_SMP_H
+
+#include <asm/hardware/gic.h>
+
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+       gic_raise_softirq(mask, 1);
+}
+
+#endif
index 05f81fd8623c2534a680a2be78bf824e3673e43b..31a32ad062dcd7eee3c280aa91e63c55ea11cf64 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef __ASM_ARCH_MSM_VMALLOC_H
 #define __ASM_ARCH_MSM_VMALLOC_H
 
-#define VMALLOC_END      (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END      0xd0000000
 
 #endif
 
index 1c05060b5f3b40545dce99453d97f55500c69f6d..d36b61074146eb35aa862f9c0ff46c619840c9bf 100644 (file)
@@ -100,6 +100,21 @@ void __init msm_map_qsd8x50_io(void)
 }
 #endif /* CONFIG_ARCH_QSD8X50 */
 
+#ifdef CONFIG_ARCH_MSM8X60
+static struct map_desc msm8x60_io_desc[] __initdata = {
+       MSM_DEVICE(QGIC_DIST),
+       MSM_DEVICE(QGIC_CPU),
+       MSM_DEVICE(TMR),
+       MSM_DEVICE(ACC),
+       MSM_DEVICE(GCC),
+};
+
+void __init msm_map_msm8x60_io(void)
+{
+       iotable_init(msm8x60_io_desc, ARRAY_SIZE(msm8x60_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM8X60 */
+
 #ifdef CONFIG_ARCH_MSM7X30
 static struct map_desc msm7x30_io_desc[] __initdata = {
        MSM_DEVICE(VIC),
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
new file mode 100644 (file)
index 0000000..f71747d
--- /dev/null
@@ -0,0 +1,597 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sizes.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+
+DEFINE_SPINLOCK(msm_iommu_lock);
+
+struct msm_priv {
+       unsigned long *pgtable;
+       struct list_head list_attached;
+};
+
+static void __flush_iotlb(struct iommu_domain *domain)
+{
+       struct msm_priv *priv = domain->priv;
+       struct msm_iommu_drvdata *iommu_drvdata;
+       struct msm_iommu_ctx_drvdata *ctx_drvdata;
+
+#ifndef CONFIG_IOMMU_PGTABLES_L2
+       unsigned long *fl_table = priv->pgtable;
+       int i;
+
+       dmac_flush_range(fl_table, fl_table + SZ_16K);
+
+       for (i = 0; i < NUM_FL_PTE; i++)
+               if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
+                       void *sl_table = __va(fl_table[i] & FL_BASE_MASK);
+                       dmac_flush_range(sl_table, sl_table + SZ_4K);
+               }
+#endif
+
+       list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+               if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
+                       BUG();
+
+               iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+               SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
+       }
+}
+
+static void __reset_context(void __iomem *base, int ctx)
+{
+       SET_BPRCOSH(base, ctx, 0);
+       SET_BPRCISH(base, ctx, 0);
+       SET_BPRCNSH(base, ctx, 0);
+       SET_BPSHCFG(base, ctx, 0);
+       SET_BPMTCFG(base, ctx, 0);
+       SET_ACTLR(base, ctx, 0);
+       SET_SCTLR(base, ctx, 0);
+       SET_FSRRESTORE(base, ctx, 0);
+       SET_TTBR0(base, ctx, 0);
+       SET_TTBR1(base, ctx, 0);
+       SET_TTBCR(base, ctx, 0);
+       SET_BFBCR(base, ctx, 0);
+       SET_PAR(base, ctx, 0);
+       SET_FAR(base, ctx, 0);
+       SET_CTX_TLBIALL(base, ctx, 0);
+       SET_TLBFLPTER(base, ctx, 0);
+       SET_TLBSLPTER(base, ctx, 0);
+       SET_TLBLKCR(base, ctx, 0);
+       SET_PRRR(base, ctx, 0);
+       SET_NMRR(base, ctx, 0);
+       SET_CONTEXTIDR(base, ctx, 0);
+}
+
+static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
+{
+       __reset_context(base, ctx);
+
+       /* Set up HTW mode */
+       /* TLB miss configuration: perform HTW on miss */
+       SET_TLBMCFG(base, ctx, 0x3);
+
+       /* V2P configuration: HTW for access */
+       SET_V2PCFG(base, ctx, 0x3);
+
+       SET_TTBCR(base, ctx, 0);
+       SET_TTBR0_PA(base, ctx, (pgtable >> 14));
+
+       /* Invalidate the TLB for this context */
+       SET_CTX_TLBIALL(base, ctx, 0);
+
+       /* Set interrupt number to "secure" interrupt */
+       SET_IRPTNDX(base, ctx, 0);
+
+       /* Enable context fault interrupt */
+       SET_CFEIE(base, ctx, 1);
+
+       /* Stall access on a context fault and let the handler deal with it */
+       SET_CFCFG(base, ctx, 1);
+
+       /* Redirect all cacheable requests to L2 slave port. */
+       SET_RCISH(base, ctx, 1);
+       SET_RCOSH(base, ctx, 1);
+       SET_RCNSH(base, ctx, 1);
+
+       /* Turn on TEX Remap */
+       SET_TRE(base, ctx, 1);
+
+       /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume
+        * TEX class 0 for everything until attributes are properly worked out
+        */
+       SET_PRRR(base, ctx, 0);
+       SET_NMRR(base, ctx, 0);
+
+       /* Turn on BFB prefetch */
+       SET_BFBDFE(base, ctx, 1);
+
+#ifdef CONFIG_IOMMU_PGTABLES_L2
+       /* Configure page tables as inner-cacheable and shareable to reduce
+        * the TLB miss penalty.
+        */
+       SET_TTBR0_SH(base, ctx, 1);
+       SET_TTBR1_SH(base, ctx, 1);
+
+       SET_TTBR0_NOS(base, ctx, 1);
+       SET_TTBR1_NOS(base, ctx, 1);
+
+       SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */
+       SET_TTBR0_IRGNL(base, ctx, 1);
+
+       SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */
+       SET_TTBR1_IRGNL(base, ctx, 1);
+
+       SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */
+       SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
+#endif
+
+       /* Enable the MMU */
+       SET_M(base, ctx, 1);
+}
+
+static int msm_iommu_domain_init(struct iommu_domain *domain)
+{
+       struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+       if (!priv)
+               goto fail_nomem;
+
+       INIT_LIST_HEAD(&priv->list_attached);
+       priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+                                                         get_order(SZ_16K));
+
+       if (!priv->pgtable)
+               goto fail_nomem;
+
+       memset(priv->pgtable, 0, SZ_16K);
+       domain->priv = priv;
+       return 0;
+
+fail_nomem:
+       kfree(priv);
+       return -ENOMEM;
+}
+
+static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+{
+       struct msm_priv *priv;
+       unsigned long flags;
+       unsigned long *fl_table;
+       int i;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+       priv = domain->priv;
+       domain->priv = NULL;
+
+       if (priv) {
+               fl_table = priv->pgtable;
+
+               for (i = 0; i < NUM_FL_PTE; i++)
+                       if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
+                               free_page((unsigned long) __va(((fl_table[i]) &
+                                                               FL_BASE_MASK)));
+
+               free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
+               priv->pgtable = NULL;
+       }
+
+       kfree(priv);
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+       struct msm_priv *priv;
+       struct msm_iommu_ctx_dev *ctx_dev;
+       struct msm_iommu_drvdata *iommu_drvdata;
+       struct msm_iommu_ctx_drvdata *ctx_drvdata;
+       struct msm_iommu_ctx_drvdata *tmp_drvdata;
+       int ret = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+
+       priv = domain->priv;
+
+       if (!priv || !dev) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       iommu_drvdata = dev_get_drvdata(dev->parent);
+       ctx_drvdata = dev_get_drvdata(dev);
+       ctx_dev = dev->platform_data;
+
+       if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
+               if (tmp_drvdata == ctx_drvdata) {
+                       ret = -EBUSY;
+                       goto fail;
+               }
+
+       __program_context(iommu_drvdata->base, ctx_dev->num,
+                         __pa(priv->pgtable));
+
+       list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
+       __flush_iotlb(domain);
+
+fail:
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+       return ret;
+}
+
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+                                struct device *dev)
+{
+       struct msm_priv *priv;
+       struct msm_iommu_ctx_dev *ctx_dev;
+       struct msm_iommu_drvdata *iommu_drvdata;
+       struct msm_iommu_ctx_drvdata *ctx_drvdata;
+       unsigned long flags;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+       priv = domain->priv;
+
+       if (!priv || !dev)
+               goto fail;
+
+       iommu_drvdata = dev_get_drvdata(dev->parent);
+       ctx_drvdata = dev_get_drvdata(dev);
+       ctx_dev = dev->platform_data;
+
+       if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
+               goto fail;
+
+       __flush_iotlb(domain);
+       __reset_context(iommu_drvdata->base, ctx_dev->num);
+       list_del_init(&ctx_drvdata->attached_elm);
+
+fail:
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
+                        phys_addr_t pa, int order, int prot)
+{
+       struct msm_priv *priv;
+       unsigned long flags;
+       unsigned long *fl_table;
+       unsigned long *fl_pte;
+       unsigned long fl_offset;
+       unsigned long *sl_table;
+       unsigned long *sl_pte;
+       unsigned long sl_offset;
+       size_t len = 0x1000UL << order;
+       int ret = 0;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+       priv = domain->priv;
+
+       if (!priv) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       fl_table = priv->pgtable;
+
+       if (len != SZ_16M && len != SZ_1M &&
+           len != SZ_64K && len != SZ_4K) {
+               pr_debug("Bad size: %d\n", len);
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       if (!fl_table) {
+               pr_debug("Null page table\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       fl_offset = FL_OFFSET(va);      /* Upper 12 bits */
+       fl_pte = fl_table + fl_offset;  /* int pointers, 4 bytes */
+
+       if (len == SZ_16M) {
+               int i = 0;
+               for (i = 0; i < 16; i++)
+                       *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
+                                 FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
+                                 FL_SHARED;
+       }
+
+       if (len == SZ_1M)
+               *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
+                                               FL_TYPE_SECT | FL_SHARED;
+
+       /* Need a 2nd level table */
+       if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) {
+               unsigned long *sl;
+               sl = (unsigned long *) __get_free_pages(GFP_KERNEL,
+                                                       get_order(SZ_4K));
+
+               if (!sl) {
+                       pr_debug("Could not allocate second level table\n");
+                       ret = -ENOMEM;
+                       goto fail;
+               }
+
+               memset(sl, 0, SZ_4K);
+               *fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | FL_TYPE_TABLE);
+       }
+
+       sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+       sl_offset = SL_OFFSET(va);
+       sl_pte = sl_table + sl_offset;
+
+
+       if (len == SZ_4K)
+               *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
+                                         SL_SHARED | SL_TYPE_SMALL;
+
+       if (len == SZ_64K) {
+               int i;
+
+               for (i = 0; i < 16; i++)
+                       *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
+                                           SL_AP1 | SL_SHARED | SL_TYPE_LARGE;
+       }
+
+       __flush_iotlb(domain);
+fail:
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+       return ret;
+}
+
+static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+                           int order)
+{
+       struct msm_priv *priv;
+       unsigned long flags;
+       unsigned long *fl_table;
+       unsigned long *fl_pte;
+       unsigned long fl_offset;
+       unsigned long *sl_table;
+       unsigned long *sl_pte;
+       unsigned long sl_offset;
+       size_t len = 0x1000UL << order;
+       int i, ret = 0;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+
+       priv = domain->priv;
+
+       if (!priv) {
+               ret = -ENODEV;
+               goto fail;
+       }
+
+       fl_table = priv->pgtable;
+
+       if (len != SZ_16M && len != SZ_1M &&
+           len != SZ_64K && len != SZ_4K) {
+               pr_debug("Bad length: %d\n", len);
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       if (!fl_table) {
+               pr_debug("Null page table\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       fl_offset = FL_OFFSET(va);      /* Upper 12 bits */
+       fl_pte = fl_table + fl_offset;  /* int pointers, 4 bytes */
+
+       if (*fl_pte == 0) {
+               pr_debug("First level PTE is 0\n");
+               ret = -ENODEV;
+               goto fail;
+       }
+
+       /* Unmap supersection */
+       if (len == SZ_16M)
+               for (i = 0; i < 16; i++)
+                       *(fl_pte+i) = 0;
+
+       if (len == SZ_1M)
+               *fl_pte = 0;
+
+       sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+       sl_offset = SL_OFFSET(va);
+       sl_pte = sl_table + sl_offset;
+
+       if (len == SZ_64K) {
+               for (i = 0; i < 16; i++)
+                       *(sl_pte+i) = 0;
+       }
+
+       if (len == SZ_4K)
+               *sl_pte = 0;
+
+       if (len == SZ_4K || len == SZ_64K) {
+               int used = 0;
+
+               for (i = 0; i < NUM_SL_PTE; i++)
+                       if (sl_table[i])
+                               used = 1;
+               if (!used) {
+                       free_page((unsigned long)sl_table);
+                       *fl_pte = 0;
+               }
+       }
+
+       __flush_iotlb(domain);
+fail:
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+       return ret;
+}
+
+static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
+                                         unsigned long va)
+{
+       struct msm_priv *priv;
+       struct msm_iommu_drvdata *iommu_drvdata;
+       struct msm_iommu_ctx_drvdata *ctx_drvdata;
+       unsigned int par;
+       unsigned long flags;
+       void __iomem *base;
+       phys_addr_t ret = 0;
+       int ctx;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+
+       priv = domain->priv;
+       if (list_empty(&priv->list_attached))
+               goto fail;
+
+       ctx_drvdata = list_entry(priv->list_attached.next,
+                                struct msm_iommu_ctx_drvdata, attached_elm);
+       iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+
+       base = iommu_drvdata->base;
+       ctx = ctx_drvdata->num;
+
+       /* Invalidate context TLB */
+       SET_CTX_TLBIALL(base, ctx, 0);
+       SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT);
+
+       if (GET_FAULT(base, ctx))
+               goto fail;
+
+       par = GET_PAR(base, ctx);
+
+       /* We are dealing with a supersection */
+       if (GET_NOFAULT_SS(base, ctx))
+               ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
+       else    /* Upper 20 bits from PAR, lower 12 from VA */
+               ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+
+fail:
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+       return ret;
+}
+
+static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
+                                   unsigned long cap)
+{
+       return 0;
+}
+
+static void print_ctx_regs(void __iomem *base, int ctx)
+{
+       unsigned int fsr = GET_FSR(base, ctx);
+       pr_err("FAR    = %08x    PAR    = %08x\n",
+              GET_FAR(base, ctx), GET_PAR(base, ctx));
+       pr_err("FSR    = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
+                       (fsr & 0x02) ? "TF " : "",
+                       (fsr & 0x04) ? "AFF " : "",
+                       (fsr & 0x08) ? "APF " : "",
+                       (fsr & 0x10) ? "TLBMF " : "",
+                       (fsr & 0x20) ? "HTWDEEF " : "",
+                       (fsr & 0x40) ? "HTWSEEF " : "",
+                       (fsr & 0x80) ? "MHF " : "",
+                       (fsr & 0x10000) ? "SL " : "",
+                       (fsr & 0x40000000) ? "SS " : "",
+                       (fsr & 0x80000000) ? "MULTI " : "");
+
+       pr_err("FSYNR0 = %08x    FSYNR1 = %08x\n",
+              GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
+       pr_err("TTBR0  = %08x    TTBR1  = %08x\n",
+              GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
+       pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
+              GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
+       pr_err("PRRR   = %08x    NMRR   = %08x\n",
+              GET_PRRR(base, ctx), GET_NMRR(base, ctx));
+}
+
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
+{
+       struct msm_iommu_drvdata *drvdata = dev_id;
+       void __iomem *base;
+       unsigned int fsr = 0;
+       int ncb = 0, i = 0;
+
+       spin_lock(&msm_iommu_lock);
+
+       if (!drvdata) {
+               pr_err("Invalid device ID in context interrupt handler\n");
+               goto fail;
+       }
+
+       base = drvdata->base;
+
+       pr_err("===== WOAH! =====\n");
+       pr_err("Unexpected IOMMU page fault!\n");
+       pr_err("base = %08x\n", (unsigned int) base);
+
+       ncb = GET_NCB(base)+1;
+       for (i = 0; i < ncb; i++) {
+               fsr = GET_FSR(base, i);
+               if (fsr) {
+                       pr_err("Fault occurred in context %d.\n", i);
+                       pr_err("Interesting registers:\n");
+                       print_ctx_regs(base, i);
+                       SET_FSR(base, i, 0x4000000F);
+               }
+       }
+fail:
+       spin_unlock(&msm_iommu_lock);
+       return 0;
+}
+
+static struct iommu_ops msm_iommu_ops = {
+       .domain_init = msm_iommu_domain_init,
+       .domain_destroy = msm_iommu_domain_destroy,
+       .attach_dev = msm_iommu_attach_dev,
+       .detach_dev = msm_iommu_detach_dev,
+       .map = msm_iommu_map,
+       .unmap = msm_iommu_unmap,
+       .iova_to_phys = msm_iommu_iova_to_phys,
+       .domain_has_cap = msm_iommu_domain_has_cap
+};
+
+static int msm_iommu_init(void)
+{
+       register_iommu(&msm_iommu_ops);
+       return 0;
+}
+
+subsys_initcall(msm_iommu_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
new file mode 100644 (file)
index 0000000..c33ae78
--- /dev/null
@@ -0,0 +1,374 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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 version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+
+struct iommu_ctx_iter_data {
+       /* input */
+       const char *name;
+
+       /* output */
+       struct device *dev;
+};
+
+static struct platform_device *msm_iommu_root_dev;
+
+static int each_iommu_ctx(struct device *dev, void *data)
+{
+       struct iommu_ctx_iter_data *res = data;
+       struct msm_iommu_ctx_dev *c = dev->platform_data;
+
+       if (!res || !c || !c->name || !res->name)
+               return -EINVAL;
+
+       if (!strcmp(res->name, c->name)) {
+               res->dev = dev;
+               return 1;
+       }
+       return 0;
+}
+
+static int each_iommu(struct device *dev, void *data)
+{
+       return device_for_each_child(dev, data, each_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+       struct iommu_ctx_iter_data r;
+       int found;
+
+       if (!msm_iommu_root_dev) {
+               pr_err("No root IOMMU device.\n");
+               goto fail;
+       }
+
+       r.name = ctx_name;
+       found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu);
+
+       if (!found) {
+               pr_err("Could not find context <%s>\n", ctx_name);
+               goto fail;
+       }
+
+       return r.dev;
+fail:
+       return NULL;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
+static void msm_iommu_reset(void __iomem *base)
+{
+       int ctx, ncb;
+
+       SET_RPUE(base, 0);
+       SET_RPUEIE(base, 0);
+       SET_ESRRESTORE(base, 0);
+       SET_TBE(base, 0);
+       SET_CR(base, 0);
+       SET_SPDMBE(base, 0);
+       SET_TESTBUSCR(base, 0);
+       SET_TLBRSW(base, 0);
+       SET_GLOBAL_TLBIALL(base, 0);
+       SET_RPU_ACR(base, 0);
+       SET_TLBLKCRWE(base, 1);
+       ncb = GET_NCB(base)+1;
+
+       for (ctx = 0; ctx < ncb; ctx++) {
+               SET_BPRCOSH(base, ctx, 0);
+               SET_BPRCISH(base, ctx, 0);
+               SET_BPRCNSH(base, ctx, 0);
+               SET_BPSHCFG(base, ctx, 0);
+               SET_BPMTCFG(base, ctx, 0);
+               SET_ACTLR(base, ctx, 0);
+               SET_SCTLR(base, ctx, 0);
+               SET_FSRRESTORE(base, ctx, 0);
+               SET_TTBR0(base, ctx, 0);
+               SET_TTBR1(base, ctx, 0);
+               SET_TTBCR(base, ctx, 0);
+               SET_BFBCR(base, ctx, 0);
+               SET_PAR(base, ctx, 0);
+               SET_FAR(base, ctx, 0);
+               SET_CTX_TLBIALL(base, ctx, 0);
+               SET_TLBFLPTER(base, ctx, 0);
+               SET_TLBSLPTER(base, ctx, 0);
+               SET_TLBLKCR(base, ctx, 0);
+               SET_PRRR(base, ctx, 0);
+               SET_NMRR(base, ctx, 0);
+               SET_CONTEXTIDR(base, ctx, 0);
+       }
+}
+
+static int msm_iommu_probe(struct platform_device *pdev)
+{
+       struct resource *r;
+       struct clk *iommu_clk;
+       struct msm_iommu_drvdata *drvdata;
+       struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
+       void __iomem *regs_base;
+       resource_size_t len;
+       int ret = 0, ncb, nm2v, irq;
+
+       if (pdev->id != -1) {
+               drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+
+               if (!drvdata) {
+                       ret = -ENOMEM;
+                       goto fail;
+               }
+
+               if (!iommu_dev) {
+                       ret = -ENODEV;
+                       goto fail;
+               }
+
+               if (iommu_dev->clk_rate != 0) {
+                       iommu_clk = clk_get(&pdev->dev, "iommu_clk");
+
+                       if (IS_ERR(iommu_clk)) {
+                               ret = -ENODEV;
+                               goto fail;
+                       }
+
+                       if (iommu_dev->clk_rate > 0) {
+                               ret = clk_set_rate(iommu_clk,
+                                                       iommu_dev->clk_rate);
+                               if (ret) {
+                                       clk_put(iommu_clk);
+                                       goto fail;
+                               }
+                       }
+
+                       ret = clk_enable(iommu_clk);
+                       if (ret) {
+                               clk_put(iommu_clk);
+                               goto fail;
+                       }
+                       clk_put(iommu_clk);
+               }
+
+               r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                "physbase");
+               if (!r) {
+                       ret = -ENODEV;
+                       goto fail;
+               }
+
+               len = r->end - r->start + 1;
+
+               r = request_mem_region(r->start, len, r->name);
+               if (!r) {
+                       pr_err("Could not request memory region: "
+                       "start=%p, len=%d\n", (void *) r->start, len);
+                       ret = -EBUSY;
+                       goto fail;
+               }
+
+               regs_base = ioremap(r->start, len);
+
+               if (!regs_base) {
+                       pr_err("Could not ioremap: start=%p, len=%d\n",
+                                (void *) r->start, len);
+                       ret = -EBUSY;
+                       goto fail;
+               }
+
+               irq = platform_get_irq_byname(pdev, "secure_irq");
+               if (irq < 0) {
+                       ret = -ENODEV;
+                       goto fail;
+               }
+
+               mb();
+
+               if (GET_IDR(regs_base) == 0) {
+                       pr_err("Invalid IDR value detected\n");
+                       ret = -ENODEV;
+                       goto fail;
+               }
+
+               ret = request_irq(irq, msm_iommu_fault_handler, 0,
+                               "msm_iommu_secure_irpt_handler", drvdata);
+               if (ret) {
+                       pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
+                       goto fail;
+               }
+
+               msm_iommu_reset(regs_base);
+               drvdata->base = regs_base;
+               drvdata->irq = irq;
+
+               nm2v = GET_NM2VCBMT((unsigned long) regs_base);
+               ncb = GET_NCB((unsigned long) regs_base);
+
+               pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
+                       iommu_dev->name, regs_base, irq, ncb+1);
+
+               platform_set_drvdata(pdev, drvdata);
+       } else
+               msm_iommu_root_dev = pdev;
+
+       return 0;
+
+fail:
+       kfree(drvdata);
+       return ret;
+}
+
+static int msm_iommu_remove(struct platform_device *pdev)
+{
+       struct msm_iommu_drvdata *drv = NULL;
+
+       drv = platform_get_drvdata(pdev);
+       if (drv) {
+               memset(drv, 0, sizeof(struct msm_iommu_drvdata));
+               kfree(drv);
+               platform_set_drvdata(pdev, NULL);
+       }
+       return 0;
+}
+
+static int msm_iommu_ctx_probe(struct platform_device *pdev)
+{
+       struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
+       struct msm_iommu_drvdata *drvdata;
+       struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+       int i, ret = 0;
+       if (!c || !pdev->dev.parent) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       drvdata = dev_get_drvdata(pdev->dev.parent);
+
+       if (!drvdata) {
+               ret = -ENODEV;
+               goto fail;
+       }
+
+       ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL);
+       if (!ctx_drvdata) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+       ctx_drvdata->num = c->num;
+       ctx_drvdata->pdev = pdev;
+
+       INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
+       platform_set_drvdata(pdev, ctx_drvdata);
+
+       /* Program the M2V tables for this context */
+       for (i = 0; i < MAX_NUM_MIDS; i++) {
+               int mid = c->mids[i];
+               if (mid == -1)
+                       break;
+
+               SET_M2VCBR_N(drvdata->base, mid, 0);
+               SET_CBACR_N(drvdata->base, c->num, 0);
+
+               /* Set VMID = MID */
+               SET_VMID(drvdata->base, mid, mid);
+
+               /* Set the context number for that MID to this context */
+               SET_CBNDX(drvdata->base, mid, c->num);
+
+               /* Set MID associated with this context bank */
+               SET_CBVMID(drvdata->base, c->num, mid);
+
+               /* Set security bit override to be Non-secure */
+               SET_NSCFG(drvdata->base, mid, 3);
+       }
+
+       pr_info("context device %s with bank index %d\n", c->name, c->num);
+
+       return 0;
+fail:
+       kfree(ctx_drvdata);
+       return ret;
+}
+
+static int msm_iommu_ctx_remove(struct platform_device *pdev)
+{
+       struct msm_iommu_ctx_drvdata *drv = NULL;
+       drv = platform_get_drvdata(pdev);
+       if (drv) {
+               memset(drv, 0, sizeof(struct msm_iommu_ctx_drvdata));
+               kfree(drv);
+               platform_set_drvdata(pdev, NULL);
+       }
+       return 0;
+}
+
+static struct platform_driver msm_iommu_driver = {
+       .driver = {
+               .name   = "msm_iommu",
+       },
+       .probe          = msm_iommu_probe,
+       .remove         = msm_iommu_remove,
+};
+
+static struct platform_driver msm_iommu_ctx_driver = {
+       .driver = {
+               .name   = "msm_iommu_ctx",
+       },
+       .probe          = msm_iommu_ctx_probe,
+       .remove         = msm_iommu_ctx_remove,
+};
+
+static int msm_iommu_driver_init(void)
+{
+       int ret;
+       ret = platform_driver_register(&msm_iommu_driver);
+       if (ret != 0) {
+               pr_err("Failed to register IOMMU driver\n");
+               goto error;
+       }
+
+       ret = platform_driver_register(&msm_iommu_ctx_driver);
+       if (ret != 0) {
+               pr_err("Failed to register IOMMU context driver\n");
+               goto error;
+       }
+
+error:
+       return ret;
+}
+
+static void msm_iommu_driver_exit(void)
+{
+       platform_driver_unregister(&msm_iommu_ctx_driver);
+       platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
index dec5ca622d7daf6963450f612d7062109cae6e92..7689848ec680d28a322040e9bf8e9c7764de27ac 100644 (file)
@@ -28,7 +28,6 @@
 #ifndef MSM_DGT_BASE
 #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
 #endif
-#define MSM_DGT_SHIFT (5)
 
 #define TIMER_MATCH_VAL         0x0000
 #define TIMER_COUNT_VAL         0x0004
 #define TIMER_ENABLE_CLR_ON_MATCH_EN    2
 #define TIMER_ENABLE_EN                 1
 #define TIMER_CLEAR             0x000C
-
+#define DGT_CLK_CTL             0x0034
+enum {
+       DGT_CLK_CTL_DIV_1 = 0,
+       DGT_CLK_CTL_DIV_2 = 1,
+       DGT_CLK_CTL_DIV_3 = 2,
+       DGT_CLK_CTL_DIV_4 = 3,
+};
 #define CSR_PROTECTION          0x0020
 #define CSR_PROTECTION_EN               1
 
 #define GPT_HZ 32768
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60)
+#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#else
 #define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
+#define MSM_DGT_SHIFT (5)
+#endif
 
 struct msm_clock {
        struct clock_event_device   clockevent;
@@ -170,6 +185,10 @@ static void __init msm_timer_init(void)
        int i;
        int res;
 
+#ifdef CONFIG_ARCH_MSM8X60
+       writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+#endif
+
        for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
                struct msm_clock *clock = &msm_clocks[i];
                struct clock_event_device *ce = &clock->clockevent;
index 2d37785e3857d32575a5948f36574e4770a0b917..eaacb6e9b5d0b417d0b78d56a8ebb406cb8ee9cd 100644 (file)
@@ -70,6 +70,25 @@ int mx51_revision(void)
 }
 EXPORT_SYMBOL(mx51_revision);
 
+#ifdef CONFIG_NEON
+
+/*
+ * All versions of the silicon before Rev. 3 have broken NEON implementations.
+ * Dependent on link order - so the assumption is that vfp_init is called
+ * before us.
+ */
+static int __init mx51_neon_fixup(void)
+{
+       if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) {
+               elf_hwcap &= ~HWCAP_NEON;
+               pr_info("Turning off NEON support, detected broken NEON implementation\n");
+       }
+       return 0;
+}
+
+late_initcall(mx51_neon_fixup);
+#endif
+
 static int __init post_cpu_init(void)
 {
        unsigned int reg;
index 25d5cc676e0fbfa9bbe701f34f925d39ddfe43a2..7cca3574308f0403a07c93edf6e427e6d29f0299 100644 (file)
@@ -16,4 +16,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
index 1b2af14df151627b06c2459af6ddb603b7f95094..b001f67d695b28e3ff6f10f16fd1842d7f3742fc 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-#define VMALLOC_END    (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END    0xd8000000
index 9ce9b6e8ad23c6df97167845a85b51e95bf0d23c..4da31e997efead8da47b602699a210f9127231b7 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-#define VMALLOC_END      (PAGE_OFFSET + 0x38000000)
+#define VMALLOC_END      0xf8000000
index 2ad398378aed3241e47bf9dc14237f9acf63bd95..31b65ee07b0b17f498e9796c2704ff6f427f5662 100644 (file)
@@ -17,4 +17,4 @@
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  * area for the same reason. ;)
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
index 7aefb90748527ae5b68550b7e311d1244b55639d..dd235ecc9d6c5946d6610bb7adef42cb57476210 100644 (file)
@@ -8,19 +8,16 @@ config ARCH_LUBBOCK
        bool "Intel DBPXA250 Development Platform (aka Lubbock)"
        select PXA25x
        select SA1111
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_MAINSTONE
        bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
        select PXA27x
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_ZYLONITE
        bool
        select PXA3xx
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_ZYLONITE300
        bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
@@ -44,6 +41,10 @@ config MACH_TAVOREVB
        select PXA3xx
        select CPU_PXA930
 
+config MACH_TAVOREVB3
+       bool "PXA95x Development Platform (aka TavorEVB III)"
+       select CPU_PXA950
+
 config MACH_SAAR
        bool "PXA930 Handheld Platform (aka SAAR)"
        select PXA3xx
@@ -61,7 +62,6 @@ config ARCH_VIPER
        select ISA
        select I2C_GPIO
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
        select PXA_HAVE_ISA_IRQS
        select ARCOM_PCMCIA
 
@@ -69,7 +69,6 @@ config MACH_ARCOM_ZEUS
        bool "Arcom/Eurotech ZEUS SBC"
        select PXA27x
        select ISA
-       select PXA_HAVE_BOARD_IRQS
        select PXA_HAVE_ISA_IRQS
        select ARCOM_PCMCIA
 
@@ -77,7 +76,6 @@ config MACH_BALLOON3
        bool "Balloon 3 board"
        select PXA27x
        select IWMMXT
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_CSB726
        bool "Enable Cogent CSB726 System On a Module"
@@ -140,13 +138,11 @@ config MACH_INTELMOTE2
        bool "Intel Mote 2 Platform"
        select PXA27x
        select IWMMXT
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_STARGATE2
        bool "Intel Stargate 2 Platform"
        select PXA27x
        select IWMMXT
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_XCEP
        bool "Iskratel Electronics XCEP"
@@ -206,13 +202,11 @@ config MACH_LOGICPD_PXA270
        bool "LogicPD PXA270 Card Engine Development Platform"
        select PXA27x
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_PCM027
        bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
        select PXA27x
        select IWMMXT
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_PCM990_BASEBOARD
        bool "PHYTEC PCM-990 development board"
@@ -247,7 +241,6 @@ config MACH_COLIBRI_PXA270_INCOME
        depends on MACH_COLIBRI
        select PXA27x
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_COLIBRI300
        bool "Toradex Colibri PXA300/310"
@@ -274,7 +267,6 @@ config MACH_H4700
        select PXA27x
        select IWMMXT
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_H5000
        bool "HP iPAQ h5000"
@@ -289,7 +281,6 @@ config MACH_MAGICIAN
        select PXA27x
        select IWMMXT
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_MIOA701
        bool "Mitac Mio A701 Support"
@@ -307,7 +298,6 @@ config PXA_EZX
        select PXA27x
        select IWMMXT
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_EZX_A780
        bool "Motorola EZX A780"
@@ -478,7 +468,6 @@ config MACH_POODLE
        depends on PXA_SHARPSL
        select PXA25x
        select SHARP_LOCOMO
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_CORGI
        bool "Enable Sharp SL-C700 (Corgi) Support"
@@ -523,7 +512,6 @@ config MACH_TOSA
        bool "Enable Sharp SL-6000x (Tosa) Support"
        depends on PXA_SHARPSL
        select PXA25x
-       select PXA_HAVE_BOARD_IRQS
 
 config TOSA_BT
        tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
@@ -552,7 +540,6 @@ config MACH_ICONTROL
 config ARCH_PXA_ESERIES
        bool "PXA based Toshiba e-series PDAs"
        select PXA25x
-       select PXA_HAVE_BOARD_IRQS
 
 config MACH_E330
        bool "Toshiba e330"
@@ -606,7 +593,6 @@ config MACH_ZIPIT2
        bool "Zipit Z2 Handheld"
        select PXA27x
        select HAVE_PWM
-       select PXA_HAVE_BOARD_IRQS
 
 endmenu
 
@@ -643,6 +629,7 @@ config CPU_PXA300
 config CPU_PXA310
        bool
        select CPU_PXA300
+       select PXA310_ULPI if USB_ULPI
        help
          PXA310 (codename Monahans-LV)
 
@@ -692,10 +679,10 @@ config SHARPSL_PM_MAX1111
        select HWMON
        select SENSORS_MAX1111
 
-config PXA_HAVE_BOARD_IRQS
+config PXA_HAVE_ISA_IRQS
        bool
 
-config PXA_HAVE_ISA_IRQS
+config PXA310_ULPI
        bool
 
 endif
index 85c7fb324dbb88ee68ce1d0da0cf0f9c0e92035c..e2f89c2c6f4962ea38a98ea9adb6e3dca8e63ed9 100644 (file)
@@ -18,7 +18,7 @@ endif
 # SoC-specific code
 obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)           += mfp-pxa2xx.o pxa2xx.o pxa27x.o
-obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o pxa3xx.o smemc.o
+obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
 obj-$(CONFIG_CPU_PXA300)       += pxa300.o
 obj-$(CONFIG_CPU_PXA320)       += pxa320.o
 obj-$(CONFIG_CPU_PXA930)       += pxa930.o
@@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_ZYLONITE300)        += zylonite.o zylonite_pxa300.o
 obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o
 obj-$(CONFIG_MACH_LITTLETON)   += littleton.o
 obj-$(CONFIG_MACH_TAVOREVB)    += tavorevb.o
+obj-$(CONFIG_MACH_TAVOREVB3)   += tavorevb3.o
 obj-$(CONFIG_MACH_SAAR)                += saar.o
 
 # 3rd Party Dev Platforms
index 9041340fee1db17cdb6aa670ba43a2457a8193bf..79d0f6cf53d777b6c990e2d3dbcc2c33fec5834e 100644 (file)
@@ -68,42 +68,6 @@ static unsigned long balloon3_pin_config[] __initdata = {
 
        /* Reset, configured as GPIO wakeup source */
        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
-
-       /* LEDs */
-       GPIO9_GPIO,     /* NAND activity LED */
-       GPIO10_GPIO,    /* Heartbeat LED */
-
-       /* AC97 */
-       GPIO28_AC97_BITCLK,
-       GPIO29_AC97_SDATA_IN_0,
-       GPIO30_AC97_SDATA_OUT,
-       GPIO31_AC97_SYNC,
-       GPIO113_AC97_nRESET,
-       GPIO95_GPIO,
-
-       /* MMC */
-       GPIO32_MMC_CLK,
-       GPIO92_MMC_DAT_0,
-       GPIO109_MMC_DAT_1,
-       GPIO110_MMC_DAT_2,
-       GPIO111_MMC_DAT_3,
-       GPIO112_MMC_CMD,
-
-       /* USB Host */
-       GPIO88_USBH1_PWR,
-       GPIO89_USBH1_PEN,
-
-       /* PC Card */
-       GPIO48_nPOE,
-       GPIO49_nPWE,
-       GPIO50_nPIOR,
-       GPIO51_nPIOW,
-       GPIO85_nPCE_1,
-       GPIO54_nPCE_2,
-       GPIO79_PSKTSEL,
-       GPIO55_nPREG,
-       GPIO56_nPWAIT,
-       GPIO57_nIOIS16,
 };
 
 /******************************************************************************
@@ -131,6 +95,34 @@ int __init parse_balloon3_features(char *arg)
 }
 early_param("balloon3_features", parse_balloon3_features);
 
+/******************************************************************************
+ * Compact Flash slot
+ ******************************************************************************/
+#if    defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
+static unsigned long balloon3_cf_pin_config[] __initdata = {
+       GPIO48_nPOE,
+       GPIO49_nPWE,
+       GPIO50_nPIOR,
+       GPIO51_nPIOW,
+       GPIO85_nPCE_1,
+       GPIO54_nPCE_2,
+       GPIO79_PSKTSEL,
+       GPIO55_nPREG,
+       GPIO56_nPWAIT,
+       GPIO57_nIOIS16,
+};
+
+static void __init balloon3_cf_init(void)
+{
+       if (!balloon3_has(BALLOON3_FEATURE_CF))
+               return;
+
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config));
+}
+#else
+static inline void balloon3_cf_init(void) {}
+#endif
+
 /******************************************************************************
  * NOR Flash
  ******************************************************************************/
@@ -179,6 +171,15 @@ static inline void balloon3_nor_init(void) {}
  ******************************************************************************/
 #if    defined(CONFIG_TOUCHSCREEN_UCB1400) || \
        defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static unsigned long balloon3_ac97_pin_config[] __initdata = {
+       GPIO28_AC97_BITCLK,
+       GPIO29_AC97_SDATA_IN_0,
+       GPIO30_AC97_SDATA_OUT,
+       GPIO31_AC97_SYNC,
+       GPIO113_AC97_nRESET,
+       GPIO95_GPIO,
+};
+
 static struct ucb1400_pdata vpac270_ucb1400_pdata = {
        .irq            = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ),
 };
@@ -197,6 +198,7 @@ static void __init balloon3_ts_init(void)
        if (!balloon3_has(BALLOON3_FEATURE_AUDIO))
                return;
 
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
        pxa_set_ac97_info(NULL);
        platform_device_register(&balloon3_ucb1400_device);
 }
@@ -208,6 +210,11 @@ static inline void balloon3_ts_init(void) {}
  * Framebuffer
  ******************************************************************************/
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static unsigned long balloon3_lcd_pin_config[] __initdata = {
+       GPIOxx_LCD_TFT_16BPP,
+       GPIO99_GPIO,
+};
+
 static struct pxafb_mode_info balloon3_lcd_modes[] = {
        {
                .pixclock               = 38000,
@@ -242,6 +249,8 @@ static void __init balloon3_lcd_init(void)
        if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY))
                return;
 
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
+
        ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON");
        if (ret) {
                pr_err("Requesting BKL-ON GPIO failed!\n");
@@ -271,6 +280,15 @@ static inline void balloon3_lcd_init(void) {}
  * SD/MMC card controller
  ******************************************************************************/
 #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static unsigned long balloon3_mmc_pin_config[] __initdata = {
+       GPIO32_MMC_CLK,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+       GPIO112_MMC_CMD,
+};
+
 static struct pxamci_platform_data balloon3_mci_platform_data = {
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
        .gpio_card_detect       = -1,
@@ -281,6 +299,7 @@ static struct pxamci_platform_data balloon3_mci_platform_data = {
 
 static void __init balloon3_mmc_init(void)
 {
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
        pxa_set_mci_info(&balloon3_mci_platform_data);
 }
 #else
@@ -339,6 +358,11 @@ static inline void balloon3_irda_init(void) {}
  * USB Host
  ******************************************************************************/
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static unsigned long balloon3_uhc_pin_config[] __initdata = {
+       GPIO88_USBH1_PWR,
+       GPIO89_USBH1_PEN,
+};
+
 static struct pxaohci_platform_data balloon3_ohci_info = {
        .port_mode      = PMM_PERPORT_MODE,
        .flags          = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
@@ -348,6 +372,7 @@ static void __init balloon3_uhc_init(void)
 {
        if (!balloon3_has(BALLOON3_FEATURE_OHCI))
                return;
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config));
        pxa_set_ohci_info(&balloon3_ohci_info);
 }
 #else
@@ -358,6 +383,11 @@ static inline void balloon3_uhc_init(void) {}
  * LEDs
  ******************************************************************************/
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static unsigned long balloon3_led_pin_config[] __initdata = {
+       GPIO9_GPIO,     /* NAND activity LED */
+       GPIO10_GPIO,    /* Heartbeat LED */
+};
+
 struct gpio_led balloon3_gpio_leds[] = {
        {
                .name                   = "balloon3:green:idle",
@@ -436,6 +466,7 @@ static struct platform_device balloon3_pcf_leds = {
 
 static void __init balloon3_leds_init(void)
 {
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config));
        platform_device_register(&balloon3_leds);
        platform_device_register(&balloon3_pcf_leds);
 }
@@ -757,6 +788,7 @@ static void __init balloon3_init(void)
        balloon3_ts_init();
        balloon3_udc_init();
        balloon3_uhc_init();
+       balloon3_cf_init();
 }
 
 static struct map_desc balloon3_io_desc[] __initdata = {
@@ -779,6 +811,7 @@ MACHINE_START(BALLOON3, "Balloon3")
        .phys_io        = 0x40000000,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = balloon3_map_io,
+       .nr_irqs        = BALLOON3_NR_IRQS,
        .init_irq       = balloon3_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = balloon3_init,
index bff6e78f033d250d803c9a9bc82474ac3804b317..ad40e7b141e0efb554490c940dc51fb226096d68 100644 (file)
@@ -33,6 +33,9 @@
 extern void cmx255_init(void);
 extern void cmx270_init(void);
 
+/* reserve IRQs for IT8152 */
+#define CMX2XX_NR_IRQS         (IRQ_BOARD_START + 40)
+
 /* virtual addresses for statically mapped regions */
 #define CMX2XX_VIRT_BASE       (0xe8000000)
 #define CMX2XX_IT8152_VIRT     (CMX2XX_VIRT_BASE)
@@ -514,6 +517,7 @@ MACHINE_START(ARMCORE, "Compulab CM-X2XX")
        .phys_io        = 0x40000000,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = cmx2xx_map_io,
+       .nr_irqs        = CMX2XX_NR_IRQS,
        .init_irq       = cmx2xx_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = cmx2xx_init,
index c70e6c2f4e7c47daf9c8a595bf6fafd11f2971d7..8e0b5622b2779c38b733dc1990b6bc4459a205e6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <linux/gpio.h>
 #include <linux/dm9000.h>
@@ -50,6 +51,7 @@
 #include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
 #include <mach/audio.h>
+#include <mach/pxa3xx-u2d.h>
 
 #include <asm/mach/map.h>
 
@@ -68,6 +70,8 @@
 #define GPIO97_RTC_RD          (97)
 #define GPIO98_RTC_IO          (98)
 
+#define GPIO_ULPI_PHY_RST      (127)
+
 static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
        /* LCD */
        GPIO54_LCD_LDD_0,
@@ -472,6 +476,78 @@ static void __init cm_x300_init_mmc(void)
 static inline void cm_x300_init_mmc(void) {}
 #endif
 
+#if defined(CONFIG_PXA310_ULPI)
+static struct clk *pout_clk;
+
+static int cm_x300_ulpi_phy_reset(void)
+{
+       int err;
+
+       /* reset the PHY */
+       err = gpio_request(GPIO_ULPI_PHY_RST, "ulpi reset");
+       if (err) {
+               pr_err("%s: failed to request ULPI reset GPIO: %d\n",
+                      __func__, err);
+               return err;
+       }
+
+       gpio_direction_output(GPIO_ULPI_PHY_RST, 0);
+       msleep(10);
+       gpio_set_value(GPIO_ULPI_PHY_RST, 1);
+       msleep(10);
+
+       gpio_free(GPIO_ULPI_PHY_RST);
+
+       return 0;
+}
+
+static inline int cm_x300_u2d_init(struct device *dev)
+{
+       int err = 0;
+
+       if (cpu_is_pxa310()) {
+               /* CLK_POUT is connected to the ULPI PHY */
+               pout_clk = clk_get(NULL, "CLK_POUT");
+               if (IS_ERR(pout_clk)) {
+                       err = PTR_ERR(pout_clk);
+                       pr_err("%s: failed to get CLK_POUT: %d\n",
+                              __func__, err);
+                       return err;
+               }
+               clk_enable(pout_clk);
+
+               err = cm_x300_ulpi_phy_reset();
+               if (err) {
+                       clk_disable(pout_clk);
+                       clk_put(pout_clk);
+               }
+       }
+
+       return err;
+}
+
+static void cm_x300_u2d_exit(struct device *dev)
+{
+       if (cpu_is_pxa310()) {
+               clk_disable(pout_clk);
+               clk_put(pout_clk);
+       }
+}
+
+static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = {
+       .ulpi_mode      = ULPI_SER_6PIN,
+       .init           = cm_x300_u2d_init,
+       .exit           = cm_x300_u2d_exit,
+};
+
+static void cm_x300_init_u2d(void)
+{
+       pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data);
+}
+#else
+static inline void cm_x300_init_u2d(void) {}
+#endif
+
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static int cm_x300_ohci_init(struct device *dev)
 {
@@ -754,6 +830,7 @@ static void __init cm_x300_init(void)
        cm_x300_init_da9030();
        cm_x300_init_dm9000();
        cm_x300_init_lcd();
+       cm_x300_init_u2d();
        cm_x300_init_ohci();
        cm_x300_init_mmc();
        cm_x300_init_nand();
index 50d5939a78f1bdc8f318f08360243626a14a6105..58093d9e07be44ea482df319c88acb78c0db3975 100644 (file)
@@ -312,8 +312,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
        freqs.cpu = policy->cpu;
 
        if (freq_debug)
-               pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
-                        "(SDRAM %d Mhz)\n",
+               pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
                         freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
                         (new_freq_mem / 2000) : (new_freq_mem / 1000));
 
index 0a0d0fe99220d7f450e61dc04495d8dfe4492be3..88fbec05ec50f09e1724e431e761b1b9b4f1a261 100644 (file)
@@ -159,7 +159,7 @@ static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy)
 
 static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
 {
-       return get_clk_frequency_khz(0);
+       return pxa3xx_get_clk_frequency_khz(0);
 }
 
 static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
@@ -212,7 +212,8 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
        policy->cpuinfo.min_freq = 104000;
        policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
        policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
-       policy->cur = policy->min = policy->max = get_clk_frequency_khz(0);
+       policy->max = pxa3xx_get_clk_frequency_khz(0);
+       policy->cur = policy->min = policy->max;
 
        if (cpu_is_pxa300() || cpu_is_pxa310())
                ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
index 65447dc736c2fd5b3f0fd4e3ce4c46c3c9711dc3..08b410343870ae2518afb4303110d5807dfc12d1 100644 (file)
@@ -6,11 +6,12 @@
 
 #include <asm/pmu.h>
 #include <mach/udc.h>
+#include <mach/pxa3xx-u2d.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/camera.h>
 #include <mach/audio.h>
@@ -134,6 +135,33 @@ struct platform_device pxa27x_device_udc = {
        }
 };
 
+#ifdef CONFIG_PXA3xx
+static struct resource pxa3xx_u2d_resources[] = {
+       [0] = {
+               .start  = 0x54100000,
+               .end    = 0x54100fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_USB2,
+               .end    = IRQ_USB2,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device pxa3xx_device_u2d = {
+       .name           = "pxa3xx-u2d",
+       .id             = -1,
+       .resource       = pxa3xx_u2d_resources,
+       .num_resources  = ARRAY_SIZE(pxa3xx_u2d_resources),
+};
+
+void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info)
+{
+       pxa_register_device(&pxa3xx_device_u2d, info);
+}
+#endif /* CONFIG_PXA3xx */
+
 static struct resource pxafb_resources[] = {
        [0] = {
                .start  = 0x44000000,
index 50353ea49ba455bc856d371f1e6170861337f8c4..715e8bd02e248930e449c4e6c2c169054c837c6e 100644 (file)
@@ -4,6 +4,7 @@ extern struct platform_device pxa3xx_device_mci2;
 extern struct platform_device pxa3xx_device_mci3;
 extern struct platform_device pxa25x_device_udc;
 extern struct platform_device pxa27x_device_udc;
+extern struct platform_device pxa3xx_device_u2d;
 extern struct platform_device pxa_device_fb;
 extern struct platform_device pxa_device_ffuart;
 extern struct platform_device pxa_device_btuart;
index 0517c17978f3103d96e51954237801fbf34088a0..51286a738a3b02322ebf87a658d55c87a89913d3 100644 (file)
@@ -43,7 +43,7 @@
 #include <mach/pxafb.h>
 #include <mach/ohci.h>
 #include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <plat/i2c.h>
 #include <mach/camera.h>
 #include <mach/pxa2xx_spi.h>
index 349212a1cbd3ab741a60412c431ab43fd1b17330..4971ce119501566a552c4398eca6d52726aeefe5 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
+#include <mach/eseries-irq.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 #include <mach/udc.h>
@@ -183,6 +184,7 @@ MACHINE_START(E330, "Toshiba e330")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e330_init,
@@ -233,6 +235,7 @@ MACHINE_START(E350, "Toshiba e350")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e350_init,
@@ -356,6 +359,7 @@ MACHINE_START(E400, "Toshiba e400")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e400_init,
@@ -545,6 +549,7 @@ MACHINE_START(E740, "Toshiba e740")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e740_init,
@@ -737,6 +742,7 @@ MACHINE_START(E750, "Toshiba e750")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e750_init,
@@ -933,6 +939,7 @@ MACHINE_START(E800, "Toshiba e800")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ESERIES_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .fixup          = eseries_fixup,
        .init_machine   = e800_init,
index 626c82b1397031bef376ddf1acbfd5feb8a9fe41..f997e84555573ba16587ca98ba3e7b6669756382 100644 (file)
 #include <mach/ohci.h>
 #include <plat/i2c.h>
 #include <mach/hardware.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/camera.h>
 
 #include "devices.h"
 #include "generic.h"
 
+#define EZX_NR_IRQS                    (IRQ_BOARD_START + 24)
+
 #define GPIO12_A780_FLIP_LID           12
 #define GPIO15_A1200_FLIP_LID          15
 #define GPIO15_A910_FLIP_LID           15
@@ -800,6 +802,7 @@ MACHINE_START(EZX_A780, "Motorola EZX A780")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = a780_init,
@@ -866,6 +869,7 @@ MACHINE_START(EZX_E680, "Motorola EZX E680")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = e680_init,
@@ -932,6 +936,7 @@ MACHINE_START(EZX_A1200, "Motorola EZX A1200")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = a1200_init,
@@ -1124,6 +1129,7 @@ MACHINE_START(EZX_A910, "Motorola EZX A910")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = a910_init,
@@ -1190,6 +1196,7 @@ MACHINE_START(EZX_E6, "Motorola EZX E6")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = e6_init,
@@ -1230,6 +1237,7 @@ MACHINE_START(EZX_E2, "Motorola EZX E2")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = pxa_map_io,
+       .nr_irqs        = EZX_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = e2_init,
index baabb3ce088e842669bfd70e3a60e56489fcbe00..6451e9c3a93fba45a7a1b1d39693dc98f94a40d2 100644 (file)
@@ -66,8 +66,7 @@ unsigned int get_clk_frequency_khz(int info)
                return pxa25x_get_clk_frequency_khz(info);
        else if (cpu_is_pxa27x())
                return pxa27x_get_clk_frequency_khz(info);
-       else
-               return pxa3xx_get_clk_frequency_khz(info);
+       return 0;
 }
 EXPORT_SYMBOL(get_clk_frequency_khz);
 
@@ -80,8 +79,7 @@ unsigned int get_memclk_frequency_10khz(void)
                return pxa25x_get_memclk_frequency_10khz();
        else if (cpu_is_pxa27x())
                return pxa27x_get_memclk_frequency_10khz();
-       else
-               return pxa3xx_get_memclk_frequency_10khz();
+       return 0;
 }
 EXPORT_SYMBOL(get_memclk_frequency_10khz);
 
index c6305c5b8a72c1497ee05aee42d7795b07513c94..4b1ad2769ed70387fad13ba9e9a775f6e1ce2466 100644 (file)
@@ -54,11 +54,9 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
 
 #ifdef CONFIG_PXA3xx
 extern unsigned pxa3xx_get_clk_frequency_khz(int);
-extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
 extern void pxa3xx_clear_reset_status(unsigned int);
 #else
 #define pxa3xx_get_clk_frequency_khz(x)                (0)
-#define pxa3xx_get_memclk_frequency_10khz()    (0)
 static inline void pxa3xx_clear_reset_status(unsigned int mask) {}
 #endif
 
index 848c861dd23f20acbbd121d32a9e0721acbee45c..10104f16e6e42474bbc82a9ef330df45f08d7ac5 100644 (file)
@@ -874,6 +874,7 @@ MACHINE_START(H4700, "HP iPAQ HX4700")
        .io_pg_offst  = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params  = 0xa0000100,
        .map_io       = pxa_map_io,
+       .nr_irqs      = HX4700_NR_IRQS,
        .init_irq     = pxa27x_init_irq,
        .init_machine = hx4700_init,
        .timer        = &pxa_timer,
index eec92e6fd7cf804f3ba611325cdbc491da3dcf96..561562b4360b7b22477373c8d7fab7a6eb715478 100644 (file)
@@ -174,6 +174,8 @@ enum balloon3_features {
 #define BALLOON3_CODEC_IRQ     IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
 #define BALLOON3_S0_CD_IRQ     IRQ_GPIO(BALLOON3_GPIO_S0_CD)
 
+#define BALLOON3_NR_IRQS       (IRQ_BOARD_START + 4)
+
 extern int balloon3_has(enum balloon3_features feature);
 
 #endif
index f2a93d5e31d303034074425b2735e71f37227bf1..de292b269c63ead3a54c29acc920d5cab1786582 100644 (file)
@@ -25,3 +25,4 @@
 #define TMIO_SD_IRQ     IRQ_TMIO(1)
 #define TMIO_USB_IRQ    IRQ_TMIO(2)
 
+#define ESERIES_NR_IRQS        (IRQ_BOARD_START + 16)
index 7f64d24cd5648df0790c6ec570322195d92359e5..814f1458a06a52ec5af6b37643ca4b6db602dd55 100644 (file)
  * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
  * == 0x3 for pxa300/pxa310/pxa320
  */
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
 #define __cpu_is_pxa2xx(id)                            \
        ({                                              \
                unsigned int _id = (id) >> 13 & 0x7;    \
                _id <= 0x2;                             \
         })
+#else
+#define __cpu_is_pxa2xx(id)    (0)
+#endif
 
+#ifdef CONFIG_PXA3xx
 #define __cpu_is_pxa3xx(id)                            \
        ({                                              \
                unsigned int _id = (id) >> 13 & 0x7;    \
                _id == 0x3;                             \
         })
+#else
+#define __cpu_is_pxa3xx(id)    (0)
+#endif
 
+#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
 #define __cpu_is_pxa93x(id)                            \
        ({                                              \
                unsigned int _id = (id) >> 4 & 0xfff;   \
                _id == 0x683 || _id == 0x693;           \
         })
+#else
+#define __cpu_is_pxa93x(id)    (0)
+#endif
 
 #define cpu_is_pxa2xx()                                        \
        ({                                              \
@@ -309,7 +321,7 @@ extern unsigned long get_clock_tick_rate(void);
 #define PCIBIOS_MIN_IO         0
 #define PCIBIOS_MIN_MEM                0
 #define pcibios_assign_all_busses()    1
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
 #endif
 
-
 #endif  /* _ASM_ARCH_HARDWARE_H */
index 9eaeed1f87f1fad6f8754dfa736473ecf113f33a..37408449ec25e023264ae8852fc3bec9feb381a6 100644 (file)
@@ -17,6 +17,7 @@
 
 #define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO
 #define HX4700_EGPIO_BASE      (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
+#define HX4700_NR_IRQS         (IRQ_BOARD_START + 70)
 
 /*
  * PXA GPIOs
index 262691fb97d86c2ce36de96d7e180a35b4906298..fdca3be47d9bb1fdaa70d8b7b9c112c34b32c495 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
+#include <mach/hardware.h>
+
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
index ffc8314520f2e109b5db96bfebdfb97096f90d90..d372caa75dc737d4ca51f4ddcc34c64ac530bd43 100644 (file)
 /*
  * The following interrupts are for board specific purposes. Since
  * the kernel can only run on one machine at a time, we can re-use
- * these.  There will be 16 IRQs by default.  If it is not enough,
- * IRQ_BOARD_END is allowed be customized for each board, but keep
- * the numbers within sensible limits and in descending order, so
- * when multiple config options are selected, the maximum will be
- * used.
+ * these.
+ * By default, no board IRQ is reserved. It should be finished in
+ * custom board since sparse IRQ is already enabled.
  */
 #define IRQ_BOARD_START                (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
 
-#if defined(CONFIG_MACH_H4700)
-#define IRQ_BOARD_END          (IRQ_BOARD_START + 70)
-#elif defined(CONFIG_MACH_ZYLONITE)
-#define IRQ_BOARD_END          (IRQ_BOARD_START + 32)
-#elif defined(CONFIG_PXA_EZX)
-#define IRQ_BOARD_END          (IRQ_BOARD_START + 23)
-#else
-#define IRQ_BOARD_END          (IRQ_BOARD_START + 16)
-#endif
-
-/*
- * Figure out the MAX IRQ number.
- *
- * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
- * Otherwise, we have the standard IRQs only.
- */
-#ifdef CONFIG_SA1111
-#define NR_IRQS                        (IRQ_BOARD_END + 55)
-#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
-#define NR_IRQS                        (IRQ_BOARD_END)
-#else
 #define NR_IRQS                        (IRQ_BOARD_START)
-#endif
-
-/* add IT8152 IRQs beyond BOARD_END */
-#ifdef CONFIG_PCI_HOST_ITE8152
-#define IT8152_LAST_IRQ         (IRQ_BOARD_END + 40)
-
-#if NR_IRQS < (IT8152_LAST_IRQ+1)
-#undef NR_IRQS
-#define NR_IRQS (IT8152_LAST_IRQ+1)
-#endif
-
-#endif /* CONFIG_PCI_HOST_ITE8152 */
 
 #endif /* __ASM_MACH_IRQS_H */
index 6c9b21c5132254dad261aa1dba4097293248684d..2a5726c15e0e446f855f857d4e773a6785ba8486 100644 (file)
@@ -10,4 +10,6 @@
 #define EXT0_GPIO_BASE (NR_BUILTIN_GPIO)
 #define EXT0_GPIO(x)   (EXT0_GPIO_BASE + (x))
 
+#define LITTLETON_NR_IRQS      (IRQ_BOARD_START + 8)
+
 #endif /* __ASM_ARCH_LITTLETON_H */
index 0e6440c81683d0c18548bdd863016fa9444fe64e..cd070092b6eb708b1397fa82ba3e2e05b6104bf0 100644 (file)
@@ -38,5 +38,6 @@
 #define LPD270_USBC_IRQ                LPD270_IRQ(2)
 #define LPD270_ETHERNET_IRQ    LPD270_IRQ(3)
 #define LPD270_AC97_IRQ                LPD270_IRQ(4)
+#define LPD270_NR_IRQS         (IRQ_BOARD_START + 5)
 
 #endif
index a0d4247f08fc56aedcb845bb1c8403d64f64d11b..2a086e8373eb7bf1104892784aba7a5236a3bd5b 100644 (file)
@@ -45,6 +45,9 @@
 #define LUBBOCK_USB_DISC_IRQ   LUBBOCK_IRQ(6)  /* usb disconnect */
 #define LUBBOCK_LAST_IRQ       LUBBOCK_IRQ(6)
 
+#define LUBBOCK_SA1111_IRQ_BASE        (IRQ_BOARD_START + 16)
+#define LUBBOCK_NR_IRQS                (IRQ_BOARD_START + 16 + 55)
+
 #ifndef __ASSEMBLY__
 extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
 #endif
index 20ef37d4a9a75b2567e73791d1ba8ee5056ae563..0a2efcf7947c5c4da26e7140f4256387f3387769 100644 (file)
@@ -71,6 +71,8 @@
 #define IRQ_MAGICIAN_BT                (IRQ_BOARD_START + 2)
 #define IRQ_MAGICIAN_VBUS      (IRQ_BOARD_START + 3)
 
+#define MAGICIAN_NR_IRQS       (IRQ_BOARD_START + 8)
+
 /*
  * CPLD EGPIOs
  */
index 86e623abd64d6404e3d39848d5fee8b1a50682d4..4c2d11cd824dda4415d1ad74af1a368ffdd9b439 100644 (file)
 #define MAINSTONE_S1_STSCHG_IRQ        MAINSTONE_IRQ(14)
 #define MAINSTONE_S1_IRQ       MAINSTONE_IRQ(15)
 
+#define MAINSTONE_NR_IRQS      (IRQ_BOARD_START + 16)
+
 #endif
index 0d119d3b922143211b12350244c3087209ba3cbd..04f7c97044f3bf4c1a8798b87bf4e86b31086975 100644 (file)
@@ -69,6 +69,7 @@
 #define nBE0_GPIO_60           MFP_CFG(nBE0, AF0)
 #define nBE1_GPIO_61           MFP_CFG(nBE1, AF0)
 #define RDY_GPIO_62            MFP_CFG(RDY, AF0)
+#define PMIC_INT_GPIO83                MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
 
 /* Chip Select */
 #define DF_nCS0_nCS2           MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
@@ -92,6 +93,9 @@
 #define GPIO63_CI2C_SCL                MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
 #define GPIO64_CI2C_SDA                MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
 
+#define GPIO73_CI2C_SCL                MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
+#define GPIO74_CI2C_SDA                MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
+
 #define GPIO77_CI2C_SCL                MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
 #define GPIO78_CI2C_SDA                MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
 
 #define GPIO69_UART1_CTS       MFP_CFG(GPIO69, AF2)
 #define GPIO70_UART1_RTS       MFP_CFG(GPIO70, AF2)
 
+#define GPIO53_UART1_TXD       MFP_CFG(GPIO53, AF2)
+#define GPIO54_UART1_RXD       MFP_CFG(GPIO54, AF2)
+
 /* UART2 - BTUART */
 #define GPIO91_UART2_RXD       MFP_CFG(GPIO91, AF1)
 #define GPIO92_UART2_TXD       MFP_CFG(GPIO92, AF1)
index 04083263167ed5ad0ab84a014cc14420c4175ffd..4bac588478a898ee6dae6107a9cd44fc7d365c69 100644 (file)
@@ -30,6 +30,8 @@
 #define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
 #define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
 
+#define PCM027_NR_IRQS         (IRQ_BOARD_START + 32)
+
 /* I2C RTC */
 #define PCM027_RTC_IRQ_GPIO    0
 #define PCM027_RTC_IRQ         IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
index 0b3e6d051c6425d86238473ab31f25702cd29c92..83d1cfd00fc9f7d05e75c4a0c94383c479407179 100644 (file)
@@ -85,6 +85,8 @@
 #define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
 #define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
 
+#define POODLE_NR_IRQS         (IRQ_BOARD_START + 4)   /* 4 for LoCoMo */
+
 extern struct platform_device poodle_locomo_device;
 
 #endif /* __ASM_ARCH_POODLE_H  */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
new file mode 100644 (file)
index 0000000..9d82cb6
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * PXA3xx U2D header
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __PXA310_U2D__
+#define __PXA310_U2D__
+
+#include <linux/usb/ulpi.h>
+
+struct pxa3xx_u2d_platform_data {
+
+#define ULPI_SER_6PIN  (1 << 0)
+#define ULPI_SER_3PIN  (1 << 1)
+       unsigned int ulpi_mode;
+
+       int (*init)(struct device *);
+       void (*exit)(struct device *);
+};
+
+
+/* Start PXA3xx U2D host */
+int pxa3xx_u2d_start_hc(struct usb_bus *host);
+/* Stop PXA3xx U2D host */
+void pxa3xx_u2d_stop_hc(struct usb_bus *host);
+
+extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info);
+
+#endif /* __PXA310_U2D__ */
index 1bbd1f2e4beb3065ff75d4204d375ac88dc10847..1272c4b56ceb8de05875e75310df11b86b377982 100644 (file)
@@ -20,6 +20,7 @@
 /* Jacket Scoop */
 #define TOSA_SCOOP_PHYS        (PXA_CS5_PHYS + 0x00800000)
 
+#define TOSA_NR_IRQS           (IRQ_BOARD_START + TC6393XB_NR_IRQS)
 /*
  * SCOOP2 internal GPIOs
  */
index 6e119976003e72979af443fb07e2b82c9441f74f..faa408ab7ad72f38c6951849008c86397b866c99 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _MACH_ZEUS_H
 #define _MACH_ZEUS_H
 
+#define ZEUS_NR_IRQS           (IRQ_BOARD_START + 48)
+
 /* Physical addresses */
 #define ZEUS_FLASH_PHYS                PXA_CS0_PHYS
 #define ZEUS_ETH0_PHYS         PXA_CS1_PHYS
index 9edf645368d65989376ca144a2d49a1fbc2d0f74..ea24998b923c27aed8b13d7aa091368b2f47a7ef 100644 (file)
@@ -5,6 +5,8 @@
 
 #define EXT_GPIO(x)            (128 + (x))
 
+#define ZYLONITE_NR_IRQS       (IRQ_BOARD_START + 32)
+
 /* the following variables are processor specific and initialized
  * by the corresponding zylonite_pxa3xx_init()
  */
index 9b9046185b00e3e8c2c7e47b13fd37c478f74640..eb5850624c1d39fdff54d98ca29391dbc87cc4d6 100644 (file)
@@ -43,7 +43,7 @@
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/pxa2xx_spi.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/littleton.h>
 #include <plat/i2c.h>
 #include <plat/pxa3xx_nand.h>
@@ -441,6 +441,7 @@ MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleto
        .boot_params    = 0xa0000100,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = pxa_map_io,
+       .nr_irqs        = LITTLETON_NR_IRQS,
        .init_irq       = pxa3xx_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = littleton_init,
index d279507fc748275dfff6670544699cf6464eee7f..fc9502ef40240426a86bb61f364b71f9eaebd61e 100644 (file)
@@ -509,6 +509,7 @@ MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params    = 0xa0000100,
        .map_io         = lpd270_map_io,
+       .nr_irqs        = LPD270_NR_IRQS,
        .init_irq       = lpd270_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = lpd270_init,
index 330c3282856e620ec879563e16655c6d56d6d2a9..1956c23093d18a68c30340f2b9f9d6dfb1621f73 100644 (file)
@@ -229,7 +229,7 @@ static struct resource sa1111_resources[] = {
 };
 
 static struct sa1111_platform_data sa1111_info = {
-       .irq_base       = IRQ_BOARD_END,
+       .irq_base       = LUBBOCK_SA1111_IRQ_BASE,
 };
 
 static struct platform_device sa1111_device = {
@@ -560,6 +560,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
        .phys_io        = 0x40000000,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = lubbock_map_io,
+       .nr_irqs        = LUBBOCK_NR_IRQS,
        .init_irq       = lubbock_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = lubbock_init,
index e81dd0c8e40dcced02770cb7dc57c4ca4634102b..42a0c2b41281118e108354e0ffb0f5366510defa 100644 (file)
@@ -768,6 +768,7 @@ MACHINE_START(MAGICIAN, "HTC Magician")
        .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .boot_params = 0xa0000100,
        .map_io = pxa_map_io,
+       .nr_irqs = MAGICIAN_NR_IRQS,
        .init_irq = pxa27x_init_irq,
        .init_machine = magician_init,
        .timer = &pxa_timer,
index 5543c64da9efbaedf903d8eaff3904616f90bd7e..8b710024601cf2d156a62ce814edd12c285d1626 100644 (file)
@@ -50,7 +50,7 @@
 #include <mach/mmc.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 
 #include "generic.h"
 #include "devices.h"
@@ -628,6 +628,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
        .boot_params    = 0xa0000100,   /* BLOB boot parameter setting */
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = mainstone_map_io,
+       .nr_irqs        = MAINSTONE_NR_IRQS,
        .init_irq       = mainstone_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = mainstone_init,
index dc66942ef9ab47d6b911bfde28b70c1c43fb5feb..ffb3f5a8a086f88b41877f2ce48534d650299559 100644 (file)
@@ -45,7 +45,7 @@
 
 #include <mach/pxa27x.h>
 #include <mach/regs-rtc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
index 77ad6d34ab5bc9cd0eb5ce2917a461ce8904c55c..405b92a29793d80fa771546418d78b4bec7094cd 100644 (file)
@@ -469,9 +469,13 @@ static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = {
        },
 };
 
+static struct i2c_pxa_platform_data palm27x_i2c_power_info = {
+       .use_pio        = 1,
+};
+
 void __init palm27x_pmic_init(void)
 {
        i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info));
-       pxa27x_set_i2c_power_info(NULL);
+       pxa27x_set_i2c_power_info(&palm27x_i2c_power_info);
 }
 #endif
index 91038eeafe44c10680741f1266ed770d61755274..3ff0c4a1ca4c5ed9f79586bb9f151cad05a2696e 100644 (file)
@@ -39,7 +39,7 @@
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
 #include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/palmasoc.h>
 #include <mach/palm27x.h>
 
index 1c281995f6583faf34faa0e5daa1a5d294a7c3de..5b9f766d14685a8a6cd2062cf6e4e4a4bcda4655 100644 (file)
@@ -39,7 +39,7 @@
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
 #include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/udc.h>
 #include <mach/palmasoc.h>
 #include <mach/palm27x.h>
index 52defd5e42e520edb4912dbbaf676d6beb15d6d6..f685a600a18163b60a236f37f667564abda97055 100644 (file)
@@ -39,7 +39,7 @@
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
 #include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/udc.h>
 #include <mach/ohci.h>
 #include <mach/pxa2xx-regs.h>
index 144dc2b6911f784f6630c8966f60d57befc7a330..89a37922b9d390441aa7365debe5bdd9dc3ed84f 100644 (file)
@@ -43,7 +43,7 @@
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
 #include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/udc.h>
 #include <mach/palmasoc.h>
 #include <mach/palm27x.h>
index 87e4b1044e0b68564c12f27646453123c8eea16c..38f4425bfc95eec139aa4b3b9e2d0f65a122314c 100644 (file)
@@ -41,7 +41,7 @@
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
 #include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/udc.h>
 #include <mach/palmasoc.h>
 #include <mach/palm27x.h>
index 2190af066470e546a151293801f75b2311ed474c..90b08ba8ad1a55a445caffd4c0f93351c3e4f023 100644 (file)
@@ -262,6 +262,7 @@ MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
        .phys_io        = 0x40000000,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = pcm027_map_io,
+       .nr_irqs        = PCM027_NR_IRQS,
        .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = pcm027_init,
index 55e8fcde0141df75dccd32b49c6a452e4f2daaea..c04e025cd790875dc3dd8eb43114f943df28a5f4 100644 (file)
@@ -469,6 +469,7 @@ MACHINE_START(POODLE, "SHARP Poodle")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_poodle,
        .map_io         = pxa_map_io,
+       .nr_irqs        = POODLE_NR_IRQS,       /* 4 for LoCoMo */
        .init_irq       = pxa25x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = poodle_init,
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
new file mode 100644 (file)
index 0000000..ce7168b
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il>
+ *             initial version: pxa310 USB Host mode support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-u2d.h>
+#include <mach/pxa3xx-u2d.h>
+
+struct pxa3xx_u2d_ulpi {
+       struct clk              *clk;
+       void __iomem            *mmio_base;
+
+       struct otg_transceiver  *otg;
+       unsigned int            ulpi_mode;
+};
+
+static struct pxa3xx_u2d_ulpi *u2d;
+
+static inline u32 u2d_readl(u32 reg)
+{
+       return __raw_readl(u2d->mmio_base + reg);
+}
+
+static inline void u2d_writel(u32 reg, u32 val)
+{
+       __raw_writel(val, u2d->mmio_base + reg);
+}
+
+#if defined(CONFIG_PXA310_ULPI)
+enum u2d_ulpi_phy_mode {
+       SYNCH           = 0,
+       CARKIT          = (1 << 0),
+       SER_3PIN        = (1 << 1),
+       SER_6PIN        = (1 << 2),
+       LOWPOWER        = (1 << 3),
+};
+
+static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void)
+{
+       return (u2d_readl(U2DOTGUSR) >> 28) & 0xF;
+}
+
+static int pxa310_ulpi_poll(void)
+{
+       int timeout = 50000;
+
+       while (timeout--) {
+               if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN))
+                       return 0;
+
+               cpu_relax();
+       }
+
+       pr_warning("%s: ULPI access timed out!\n", __func__);
+
+       return -ETIMEDOUT;
+}
+
+static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg)
+{
+       int err;
+
+       if (pxa310_ulpi_get_phymode() != SYNCH) {
+               pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+               return -EBUSY;
+       }
+
+       u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16));
+       msleep(5);
+
+       err = pxa310_ulpi_poll();
+       if (err)
+               return err;
+
+       return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA;
+}
+
+static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+{
+       if (pxa310_ulpi_get_phymode() != SYNCH) {
+               pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+               return -EBUSY;
+       }
+
+       u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8));
+       msleep(5);
+
+       return pxa310_ulpi_poll();
+}
+
+struct otg_io_access_ops pxa310_ulpi_access_ops = {
+       .read   = pxa310_ulpi_read,
+       .write  = pxa310_ulpi_write,
+};
+
+static void pxa310_otg_transceiver_rtsm(void)
+{
+       u32 u2dotgcr;
+
+       /* put PHY to sync mode */
+       u2dotgcr = u2d_readl(U2DOTGCR);
+       u2dotgcr |=  U2DOTGCR_RTSM | U2DOTGCR_UTMID;
+       u2d_writel(U2DOTGCR, u2dotgcr);
+       msleep(10);
+
+       /* setup OTG sync mode */
+       u2dotgcr = u2d_readl(U2DOTGCR);
+       u2dotgcr |= U2DOTGCR_ULAF;
+       u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+       u2d_writel(U2DOTGCR, u2dotgcr);
+}
+
+static int pxa310_start_otg_host_transcvr(struct usb_bus *host)
+{
+       int err;
+
+       pxa310_otg_transceiver_rtsm();
+
+       err = otg_init(u2d->otg);
+       if (err) {
+               pr_err("OTG transceiver init failed");
+               return err;
+       }
+
+       err = otg_set_vbus(u2d->otg, 1);
+       if (err) {
+               pr_err("OTG transceiver VBUS set failed");
+               return err;
+       }
+
+       err = otg_set_host(u2d->otg, host);
+       if (err)
+               pr_err("OTG transceiver Host mode set failed");
+
+       return err;
+}
+
+static int pxa310_start_otg_hc(struct usb_bus *host)
+{
+       u32 u2dotgcr;
+       int err;
+
+       /* disable USB device controller */
+       u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE);
+       u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID);
+       u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+
+       err = pxa310_start_otg_host_transcvr(host);
+       if (err)
+               return err;
+
+       /* set xceiver mode */
+       if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL)
+               u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS);
+       else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL)
+               u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS);
+
+       /* start OTG host controller */
+       u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF;
+       u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF));
+
+       return 0;
+}
+
+static void pxa310_stop_otg_hc(void)
+{
+       pxa310_otg_transceiver_rtsm();
+
+       otg_set_host(u2d->otg, NULL);
+       otg_set_vbus(u2d->otg, 0);
+       otg_shutdown(u2d->otg);
+}
+
+static void pxa310_u2d_setup_otg_hc(void)
+{
+       u32 u2dotgcr;
+
+       u2dotgcr = u2d_readl(U2DOTGCR);
+       u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID;
+       u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+       u2d_writel(U2DOTGCR, u2dotgcr);
+       msleep(5);
+       u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE);
+       msleep(5);
+       u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+}
+
+static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+       unsigned int ulpi_mode = ULPI_OTG_DRVVBUS;
+
+       if (pdata) {
+               if (pdata->ulpi_mode & ULPI_SER_6PIN)
+                       ulpi_mode |= ULPI_IC_6PIN_SERIAL;
+               else if (pdata->ulpi_mode & ULPI_SER_3PIN)
+                       ulpi_mode |= ULPI_IC_3PIN_SERIAL;
+       }
+
+       u2d->ulpi_mode = ulpi_mode;
+
+       u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode);
+       if (!u2d->otg)
+               return -ENOMEM;
+
+       u2d->otg->io_priv = u2d->mmio_base;
+
+       return 0;
+}
+
+static void pxa310_otg_exit(void)
+{
+       kfree(u2d->otg);
+}
+#else
+static inline void pxa310_u2d_setup_otg_hc(void) {}
+static inline int pxa310_start_otg_hc(struct usb_bus *host)
+{
+       return 0;
+}
+static inline void pxa310_stop_otg_hc(void) {}
+static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+       return 0;
+}
+static inline void pxa310_otg_exit(void) {}
+#endif /* CONFIG_PXA310_ULPI */
+
+int pxa3xx_u2d_start_hc(struct usb_bus *host)
+{
+       int err = 0;
+
+       /* In case the PXA3xx ULPI isn't used, do nothing. */
+       if (!u2d)
+               return 0;
+
+       clk_enable(u2d->clk);
+
+       if (cpu_is_pxa310()) {
+               pxa310_u2d_setup_otg_hc();
+               err = pxa310_start_otg_hc(host);
+       }
+
+       return err;
+}
+
+void pxa3xx_u2d_stop_hc(struct usb_bus *host)
+{
+       /* In case the PXA3xx ULPI isn't used, do nothing. */
+       if (!u2d)
+               return;
+
+       if (cpu_is_pxa310())
+               pxa310_stop_otg_hc();
+
+       clk_disable(u2d->clk);
+}
+
+static int pxa3xx_u2d_probe(struct platform_device *pdev)
+{
+       struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+       struct resource *r;
+       int err;
+
+       u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
+       if (!u2d) {
+               dev_err(&pdev->dev, "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       u2d->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(u2d->clk)) {
+               dev_err(&pdev->dev, "failed to get u2d clock\n");
+               err = PTR_ERR(u2d->clk);
+               goto err_free_mem;
+       }
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               dev_err(&pdev->dev, "no IO memory resource defined\n");
+               err = -ENODEV;
+               goto err_put_clk;
+       }
+
+        r = request_mem_region(r->start, resource_size(r), pdev->name);
+        if (!r) {
+                dev_err(&pdev->dev, "failed to request memory resource\n");
+                err = -EBUSY;
+                goto err_put_clk;
+        }
+
+       u2d->mmio_base = ioremap(r->start, resource_size(r));
+       if (!u2d->mmio_base) {
+               dev_err(&pdev->dev, "ioremap() failed\n");
+               err = -ENODEV;
+               goto err_free_res;
+       }
+
+       if (pdata->init) {
+               err = pdata->init(&pdev->dev);
+               if (err)
+                       goto err_free_io;
+       }
+
+       /* Only PXA310 U2D has OTG functionality */
+       if (cpu_is_pxa310()) {
+               err = pxa310_otg_init(pdata);
+               if (err)
+                       goto err_free_plat;
+       }
+
+       platform_set_drvdata(pdev, &u2d);
+
+       return 0;
+
+err_free_plat:
+       if (pdata->exit)
+               pdata->exit(&pdev->dev);
+err_free_io:
+       iounmap(u2d->mmio_base);
+err_free_res:
+       release_mem_region(r->start, resource_size(r));
+err_put_clk:
+       clk_put(u2d->clk);
+err_free_mem:
+       kfree(u2d);
+       return err;
+}
+
+static int pxa3xx_u2d_remove(struct platform_device *pdev)
+{
+       struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+       struct resource *r;
+
+       if (cpu_is_pxa310()) {
+               pxa310_stop_otg_hc();
+               pxa310_otg_exit();
+       }
+
+       if (pdata->exit)
+               pdata->exit(&pdev->dev);
+
+       platform_set_drvdata(pdev, NULL);
+       iounmap(u2d->mmio_base);
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(r->start, resource_size(r));
+
+       clk_put(u2d->clk);
+
+       kfree(u2d);
+
+       return 0;
+}
+
+static struct platform_driver pxa3xx_u2d_ulpi_driver = {
+        .driver                = {
+                .name   = "pxa3xx-u2d",
+               .owner  = THIS_MODULE,
+        },
+        .probe          = pxa3xx_u2d_probe,
+        .remove         = pxa3xx_u2d_remove,
+};
+
+static int pxa3xx_u2d_ulpi_init(void)
+{
+       return platform_driver_register(&pxa3xx_u2d_ulpi_driver);
+}
+module_init(pxa3xx_u2d_ulpi_init);
+
+static void __exit pxa3xx_u2d_ulpi_exit(void)
+{
+       platform_driver_unregister(&pxa3xx_u2d_ulpi_driver);
+}
+module_exit(pxa3xx_u2d_ulpi_exit);
+
+MODULE_DESCRIPTION("PXA3xx U2D ULPI driver");
+MODULE_AUTHOR("Igor Grinberg");
+MODULE_LICENSE("GPL v2");
index fa0014847c71503f4f929870cce2622deb0abd9d..c85c3a7abd314f84cce570a79d4f38ecce21ecce 100644 (file)
@@ -98,23 +98,6 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
        return CLK / 1000;
 }
 
-/*
- * Return the current static memory controller clock frequency
- * in units of 10kHz
- */
-unsigned int pxa3xx_get_memclk_frequency_10khz(void)
-{
-       unsigned long acsr;
-       unsigned int smcfs, clk = 0;
-
-       acsr = ACSR;
-
-       smcfs = (acsr >> 23) & 0x7;
-       clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
-
-       return (clk / 10000);
-}
-
 void pxa3xx_clear_reset_status(unsigned int mask)
 {
        /* RESET_STATUS_* has a 1:1 mapping with ARSR */
@@ -265,7 +248,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
        INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
        INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
        INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
-       INIT_CLKREG(&clk_pxa3xx_u2d, NULL, "U2DCLK"),
+       INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL),
        INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
        INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
        INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
index 064292008288c86f3b4b3bb9a9e7132092cf5067..7d29dd3af79d20cb55c1e20296c7f80adcd171f8 100644 (file)
@@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
 
 static int __init pxa930_init(void)
 {
-       if (cpu_is_pxa930() || cpu_is_pxa935()) {
+       if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa930_mfp_addr_map);
        }
index a654d1e6b38ad11eb6420667028c8395ab10c1ae..62de07341cc62d2177dbd764d8ff8458eec3d07b 100644 (file)
@@ -56,6 +56,8 @@
 #include "devices.h"
 #include "generic.h"
 
+#define STARGATE_NR_IRQS       (IRQ_BOARD_START + 8)
+
 /* Bluetooth */
 #define SG2_BT_RESET           81
 
@@ -1011,6 +1013,7 @@ MACHINE_START(STARGATE2, "Stargate 2")
        .phys_io = 0x40000000,
        .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io = pxa_map_io,
+       .nr_irqs = STARGATE_NR_IRQS,
        .init_irq = pxa27x_init_irq,
        .timer = &pxa_timer,
        .init_machine = stargate2_init,
index f02dcb5b4e97e53e14212e0b61892abc8f3f3046..0f440c9d7cbd5e3cf6a576b8e4500800a269bfb6 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <mach/pxa930.h>
 #include <mach/pxafb.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 
 #include "devices.h"
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c
new file mode 100644 (file)
index 0000000..5eeba64
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *  linux/arch/arm/mach-pxa/tavorevb3.c
+ *
+ *  Support for the Marvell EVB3 Development Platform.
+ *
+ *  Copyright:  (C) Copyright 2008-2010 Marvell International Ltd.
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa930.h>
+
+#include <plat/i2c.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define TAVOREVB3_NR_IRQS      (IRQ_BOARD_START + 24)
+
+static mfp_cfg_t evb3_mfp_cfg[] __initdata = {
+       /* UART */
+       GPIO53_UART1_TXD,
+       GPIO54_UART1_RXD,
+
+       /* PMIC */
+       PMIC_INT_GPIO83,
+};
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct pm860x_touch_pdata evb3_touch = {
+       .gpadc_prebias  = 1,
+       .slot_cycle     = 1,
+       .tsi_prebias    = 6,
+       .pen_prebias    = 16,
+       .pen_prechg     = 2,
+       .res_x          = 300,
+};
+
+static struct pm860x_backlight_pdata evb3_backlight[] = {
+       {
+               .id     = PM8606_ID_BACKLIGHT,
+               .iset   = PM8606_WLED_CURRENT(24),
+               .flags  = PM8606_BACKLIGHT1,
+       },
+       {},
+};
+
+static struct pm860x_led_pdata evb3_led[] = {
+       {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED1_RED,
+       }, {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED1_GREEN,
+       }, {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED1_BLUE,
+       }, {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED2_RED,
+       }, {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED2_GREEN,
+       }, {
+               .id     = PM8606_ID_LED,
+               .iset   = PM8606_LED_CURRENT(12),
+               .flags  = PM8606_LED2_BLUE,
+       },
+};
+
+static struct pm860x_platform_data evb3_pm8607_info = {
+       .touch                          = &evb3_touch,
+       .backlight                      = &evb3_backlight[0],
+       .led                            = &evb3_led[0],
+       .companion_addr                 = 0x10,
+       .irq_mode                       = 0,
+       .irq_base                       = IRQ_BOARD_START,
+
+       .i2c_port                       = GI2C_PORT,
+};
+
+static struct i2c_board_info evb3_i2c_info[] = {
+       {
+               .type           = "88PM860x",
+               .addr           = 0x34,
+               .platform_data  = &evb3_pm8607_info,
+               .irq            = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+       },
+};
+
+static void __init evb3_init_i2c(void)
+{
+       pxa_set_i2c_info(NULL);
+       i2c_register_board_info(0, ARRAY_AND_SIZE(evb3_i2c_info));
+}
+#else
+static inline void evb3_init_i2c(void) {}
+#endif
+
+static void __init evb3_init(void)
+{
+       /* initialize MFP configurations */
+       pxa3xx_mfp_config(ARRAY_AND_SIZE(evb3_mfp_cfg));
+
+       pxa_set_ffuart_info(NULL);
+
+       evb3_init_i2c();
+}
+
+MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)")
+       .phys_io        = 0x40000000,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .nr_irqs        = TAVOREVB3_NR_IRQS,
+       .init_irq       = pxa3xx_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = evb3_init,
+MACHINE_END
index 83cc3a18c2e9a0ded180a0b223f29167b3a290f7..3a06e98b49209282f924932397ea5c30d65232be 100644 (file)
@@ -956,6 +956,7 @@ MACHINE_START(TOSA, "SHARP Tosa")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_tosa,
        .map_io         = pxa_map_io,
+       .nr_irqs        = TOSA_NR_IRQS,
        .init_irq       = pxa25x_init_irq,
        .init_machine   = tosa_init,
        .timer          = &pxa_timer,
index c9b747cedea8fb48a4a9615d52394fa5d2e77fcc..37d6173bbb660868a3cb696cedcaab97b9eee66d 100644 (file)
@@ -240,6 +240,7 @@ static void __init vpac270_onenand_init(void) {}
 #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
 static struct pxamci_platform_data vpac270_mci_platform_data = {
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .gpio_power             = -1,
        .gpio_card_detect       = GPIO53_VPAC270_SD_DETECT_N,
        .gpio_card_ro           = GPIO52_VPAC270_SD_READONLY,
        .detect_delay_ms        = 200,
index f0d02288b4ca3089e754dce9396ff28f23ceb3d4..8c44bc4381ba546be6e614561b3878b519015bfd 100644 (file)
@@ -37,7 +37,7 @@
 #include <mach/z2.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <mach/pxa2xx_spi.h>
 
 #include <plat/i2c.h>
index 03b9cb910e085b1911465e77d57a12ac11a71c9f..9da2b624ba2093dd52de018bdde9da28b3084fc3 100644 (file)
@@ -904,6 +904,7 @@ MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")
        .io_pg_offst    = ((io_p2v(0x40000000) >> 18) & 0xfffc),
        .boot_params    = 0xa0000100,
        .map_io         = zeus_map_io,
+       .nr_irqs        = ZEUS_NR_IRQS,
        .init_irq       = zeus_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = zeus_init,
index c479cbecf784ac3c53f634d2b4fad3e1fefd4daa..69df3edcdd98b2d197b79f7679bdfe0f0af72530 100644 (file)
@@ -30,7 +30,7 @@
 #include <mach/zylonite.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 #include <plat/pxa3xx_nand.h>
 
 #include "devices.h"
@@ -415,6 +415,7 @@ MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
        .boot_params    = 0xa0000100,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .map_io         = pxa_map_io,
+       .nr_irqs        = ZYLONITE_NR_IRQS,
        .init_irq       = pxa3xx_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = zylonite_init,
index 9a96fd69e7051e88f9d031bb91155cc56e4a8844..3bcd86fadb81ad994e771c27441eeb851c0b3d70 100644 (file)
@@ -7,4 +7,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x1c000000)
+#define VMALLOC_END       0xdc000000
index a492b982aa062705a0c24d03dd696b020719b262..405e621289172512bbf01527d9061717a95d55d6 100644 (file)
 #include <mach/map.h>
 #include <mach/gpio-bank-c.h>
 #include <mach/spi-clocks.h>
+#include <mach/irqs.h>
 
 #include <plat/s3c64xx-spi.h>
 #include <plat/gpio-cfg.h>
-#include <plat/irqs.h>
+#include <plat/devs.h>
 
 static char *spi_src_clks[] = {
        [S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
index 5c07d013b23da47dc387a436a2cedbeea2c826b7..e130379ba0e8df2752dfd5e4cae25e25b5dc6630 100644 (file)
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
 
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
 
 static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = {
        [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport = 0,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
        },
        [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport = 1,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
        },
        [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport = 2,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
        },
        [3] = {
-               .hwport      = 3,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport = 3,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
        },
 };
 
 /* DM9000AEP 10/100 ethernet controller */
 
 static struct resource real6410_dm9k_resource[] = {
-        [0] = {
-                .start = S3C64XX_PA_XM0CSN1,
-                .end   = S3C64XX_PA_XM0CSN1 + 1,
-                .flags = IORESOURCE_MEM
-        },
-        [1] = {
-                .start = S3C64XX_PA_XM0CSN1 + 4,
-                .end   = S3C64XX_PA_XM0CSN1 + 5,
-                .flags = IORESOURCE_MEM
-        },
-        [2] = {
-                .start = S3C_EINT(7),
-                .end   = S3C_EINT(7),
-                .flags = IORESOURCE_IRQ,
-        }
+       [0] = {
+               .start  = S3C64XX_PA_XM0CSN1,
+               .end    = S3C64XX_PA_XM0CSN1 + 1,
+               .flags  = IORESOURCE_MEM
+       },
+       [1] = {
+               .start  = S3C64XX_PA_XM0CSN1 + 4,
+               .end    = S3C64XX_PA_XM0CSN1 + 5,
+               .flags  = IORESOURCE_MEM
+       },
+       [2] = {
+               .start  = S3C_EINT(7),
+               .end    = S3C_EINT(7),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+       }
 };
 
 static struct dm9000_plat_data real6410_dm9k_pdata = {
-        .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
 };
 
 static struct platform_device real6410_device_eth = {
-        .name           = "dm9000",
-        .id             = -1,
-        .num_resources  = ARRAY_SIZE(real6410_dm9k_resource),
-        .resource       = real6410_dm9k_resource,
-        .dev            = {
-                .platform_data  = &real6410_dm9k_pdata,
-        },
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(real6410_dm9k_resource),
+       .resource       = real6410_dm9k_resource,
+       .dev            = {
+               .platform_data  = &real6410_dm9k_pdata,
+       },
 };
 
 static struct platform_device *real6410_devices[] __initdata = {
@@ -129,12 +129,12 @@ static void __init real6410_machine_init(void)
        /* set timing for nCS1 suitable for ethernet chip */
 
        __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
-                       (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
-                       (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
-                       (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
-                       (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
-                       (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
-                       (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+               (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+               (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+               (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+               (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+               (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+               (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
 
        platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
 }
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig
deleted file mode 100644 (file)
index 6a4af7f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-# arch/arm/mach-s5p6440/Kconfig
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-#              http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-if ARCH_S5P6440
-
-config CPU_S5P6440
-       bool
-       select S3C_PL330_DMA
-       help
-         Enable S5P6440 CPU support
-
-config S5P6440_SETUP_I2C1
-       bool
-       help
-         Common setup code for i2c bus 1.
-
-config MACH_SMDK6440
-       bool "SMDK6440"
-       select CPU_S5P6440
-       select S3C_DEV_I2C1
-       select S3C_DEV_RTC
-       select S3C_DEV_WDT
-       select SAMSUNG_DEV_ADC
-       select SAMSUNG_DEV_TS
-       select S5P6440_SETUP_I2C1
-       help
-         Machine support for the Samsung SMDK6440
-
-endif
diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile
deleted file mode 100644 (file)
index c3fe4d3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# arch/arm/mach-s5p6440/Makefile
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-#              http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-obj-y                          :=
-obj-m                          :=
-obj-n                          :=
-obj-                           :=
-
-# Core support for S5P6440 system
-
-obj-$(CONFIG_CPU_S5P6440)      += cpu.o init.o clock.o gpio.o dma.o
-obj-$(CONFIG_CPU_S5P6440)      += setup-i2c0.o
-
-# machine support
-
-obj-$(CONFIG_MACH_SMDK6440)    += mach-smdk6440.o
-
-# device support
-obj-y                          += dev-audio.o
-obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
-obj-$(CONFIG_S5P6440_SETUP_I2C1)       += setup-i2c1.o
diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c
deleted file mode 100644 (file)
index ca6e48d..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/clock.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/cpu-freq.h>
-#include <mach/regs-clock.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/clock-clksrc.h>
-#include <plat/s5p-clock.h>
-#include <plat/pll.h>
-#include <plat/s5p6440.h>
-
-/* APLL Mux output clock */
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-               .id             = -1,
-       },
-       .sources        = &clk_src_apll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
-};
-
-static int s5p6440_epll_enable(struct clk *clk, int enable)
-{
-       unsigned int ctrlbit = clk->ctrlbit;
-       unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
-
-       if (enable)
-               __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
-       else
-               __raw_writel(epll_con, S5P_EPLL_CON);
-
-       return 0;
-}
-
-static unsigned long s5p6440_epll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
-static u32 epll_div[][5] = {
-       { 36000000,     0,      48, 1, 4 },
-       { 48000000,     0,      32, 1, 3 },
-       { 60000000,     0,      40, 1, 3 },
-       { 72000000,     0,      48, 1, 3 },
-       { 84000000,     0,      28, 1, 2 },
-       { 96000000,     0,      32, 1, 2 },
-       { 32768000,     45264,  43, 1, 4 },
-       { 45158000,     6903,   30, 1, 3 },
-       { 49152000,     50332,  32, 1, 3 },
-       { 67738000,     10398,  45, 1, 3 },
-       { 73728000,     9961,   49, 1, 3 }
-};
-
-static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned int epll_con, epll_con_k;
-       unsigned int i;
-
-       if (clk->rate == rate)  /* Return if nothing changed */
-               return 0;
-
-       epll_con = __raw_readl(S5P_EPLL_CON);
-       epll_con_k = __raw_readl(S5P_EPLL_CON_K);
-
-       epll_con_k &= ~(PLL90XX_KDIV_MASK);
-       epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
-       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-                if (epll_div[i][0] == rate) {
-                       epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
-                       epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
-                                   (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
-                                   (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(epll_div)) {
-               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-               return -EINVAL;
-       }
-
-       __raw_writel(epll_con, S5P_EPLL_CON);
-       __raw_writel(epll_con_k, S5P_EPLL_CON_K);
-
-       clk->rate = rate;
-
-       return 0;
-}
-
-static struct clk_ops s5p6440_epll_ops = {
-       .get_rate = s5p6440_epll_get_rate,
-       .set_rate = s5p6440_epll_set_rate,
-};
-
-static struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-               .id             = -1,
-       },
-       .sources        = &clk_src_epll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 },
-};
-
-static struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
-               .id             = -1,
-       },
-       .sources        = &clk_src_mpll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
-};
-
-enum perf_level {
-       L0 = 532*1000,
-       L1 = 266*1000,
-       L2 = 133*1000,
-};
-
-static const u32 clock_table[][3] = {
-       /*{ARM_CLK, DIVarm, DIVhclk}*/
-       {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)},
-       {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)},
-       {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)},
-};
-
-static unsigned long s5p6440_armclk_get_rate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-       u32 clkdiv;
-
-       /* divisor mask starts at bit0, so no need to shift */
-       clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
-
-       return rate / (clkdiv + 1);
-}
-
-static unsigned long s5p6440_armclk_round_rate(struct clk *clk,
-                                               unsigned long rate)
-{
-       u32 iter;
-
-       for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
-               if (rate > clock_table[iter][0])
-                       return clock_table[iter-1][0];
-       }
-
-       return clock_table[ARRAY_SIZE(clock_table) - 1][0];
-}
-
-static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate)
-{
-       u32 round_tmp;
-       u32 iter;
-       u32 clk_div0_tmp;
-       u32 cur_rate = clk->ops->get_rate(clk);
-       unsigned long flags;
-
-       round_tmp = clk->ops->round_rate(clk, rate);
-       if (round_tmp == cur_rate)
-               return 0;
-
-
-       for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
-               if (round_tmp == clock_table[iter][0])
-                       break;
-       }
-
-       if (iter >= ARRAY_SIZE(clock_table))
-               iter = ARRAY_SIZE(clock_table) - 1;
-
-       local_irq_save(flags);
-       if (cur_rate > round_tmp) {
-               /* Frequency Down */
-               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
-               clk_div0_tmp |= clock_table[iter][1];
-               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
-               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
-                               ~(S5P_CLKDIV0_HCLK_MASK);
-               clk_div0_tmp |= clock_table[iter][2];
-               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
-
-       } else {
-               /* Frequency Up */
-               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
-                               ~(S5P_CLKDIV0_HCLK_MASK);
-               clk_div0_tmp |= clock_table[iter][2];
-               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-
-               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
-               clk_div0_tmp |= clock_table[iter][1];
-               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
-               }
-       local_irq_restore(flags);
-
-       clk->rate = clock_table[iter][0];
-
-       return 0;
-}
-
-static struct clk_ops s5p6440_clkarm_ops = {
-       .get_rate       = s5p6440_armclk_get_rate,
-       .set_rate       = s5p6440_armclk_set_rate,
-       .round_rate     = s5p6440_armclk_round_rate,
-};
-
-static struct clksrc_clk clk_armclk = {
-       .clk    = {
-               .name   = "armclk",
-               .id     = 1,
-               .parent = &clk_mout_apll.clk,
-               .ops    = &s5p6440_clkarm_ops,
-       },
-       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mpll = {
-       .clk    = {
-               .name   = "dout_mpll",
-               .id     = -1,
-               .parent = &clk_mout_mpll.clk,
-       },
-       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_hclk = {
-       .clk    = {
-               .name   = "clk_hclk",
-               .id     = -1,
-               .parent = &clk_armclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk clk_pclk = {
-       .clk    = {
-               .name   = "clk_pclk",
-               .id     = -1,
-               .parent = &clk_hclk.clk,
-       },
-       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 },
-};
-
-static struct clk *clkset_hclklow_list[] = {
-       &clk_mout_apll.clk,
-       &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_hclklow = {
-       .sources        = clkset_hclklow_list,
-       .nr_sources     = ARRAY_SIZE(clkset_hclklow_list),
-};
-
-static struct clksrc_clk clk_hclk_low = {
-       .clk = {
-               .name   = "hclk_low",
-               .id     = -1,
-       },
-       .sources        = &clkset_hclklow,
-       .reg_src        = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 },
-       .reg_div        = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk clk_pclk_low = {
-       .clk    = {
-               .name   = "pclk_low",
-               .id     = -1,
-               .parent = &clk_hclk_low.clk,
-       },
-       .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
-};
-
-int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
-{
-       unsigned long flags;
-       u32 val;
-
-       /* can't rely on clock lock, this register has other usages */
-       local_irq_save(flags);
-
-       val = __raw_readl(S5P_OTHERS);
-       if (enable)
-               val |= S5P_OTHERS_USB_SIG_MASK;
-       else
-               val &= ~S5P_OTHERS_USB_SIG_MASK;
-
-       __raw_writel(val, S5P_OTHERS);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-static int s5p6440_pclk_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable);
-}
-
-static int s5p6440_hclk0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable);
-}
-
-static int s5p6440_hclk1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable);
-}
-
-static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
-}
-
-static int s5p6440_sclk1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable);
-}
-
-static int s5p6440_mem_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
-}
-
-/*
- * The following clocks will be disabled during clock initialization. It is
- * recommended to keep the following clocks disabled until the driver requests
- * for enabling the clock.
- */
-static struct clk init_clocks_disable[] = {
-       {
-               .name           = "nand",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_mem_ctrl,
-               .ctrlbit        = S5P_CLKCON_MEM0_HCLK_NFCON,
-       }, {
-               .name           = "adc",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_TSADC,
-       }, {
-               .name           = "i2c",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_IIC0,
-       }, {
-               .name           = "i2s_v40",
-               .id             = 0,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_IIS2,
-       }, {
-               .name           = "spi",
-               .id             = 0,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_SPI0,
-       }, {
-               .name           = "spi",
-               .id             = 1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_SPI1,
-       }, {
-               .name           = "sclk_spi_48",
-               .id             = 0,
-               .parent         = &clk_48m,
-               .enable         = s5p6440_sclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_SCLK0_SPI0_48,
-       }, {
-               .name           = "sclk_spi_48",
-               .id             = 1,
-               .parent         = &clk_48m,
-               .enable         = s5p6440_sclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_SCLK0_SPI1_48,
-       }, {
-               .name           = "mmc_48m",
-               .id             = 0,
-               .parent         = &clk_48m,
-               .enable         = s5p6440_sclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_SCLK0_MMC0_48,
-       }, {
-               .name           = "mmc_48m",
-               .id             = 1,
-               .parent         = &clk_48m,
-               .enable         = s5p6440_sclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_SCLK0_MMC1_48,
-       }, {
-               .name           = "mmc_48m",
-               .id             = 2,
-               .parent         = &clk_48m,
-               .enable         = s5p6440_sclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_SCLK0_MMC2_48,
-       }, {
-               .name           = "otg",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK0_USB
-       }, {
-               .name           = "post",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK0_POST0
-       }, {
-               .name           = "lcd",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk1_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK1_DISPCON,
-       }, {
-               .name           = "hsmmc",
-               .id             = 0,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC0,
-       }, {
-               .name           = "hsmmc",
-               .id             = 1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC1,
-       }, {
-               .name           = "hsmmc",
-               .id             = 2,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC2,
-       }, {
-               .name           = "rtc",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_RTC,
-       }, {
-               .name           = "watchdog",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_WDT,
-       }, {
-               .name           = "timers",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_PWM,
-       }, {
-               .name           = "hclk_fimgvg",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_hclk1_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "tsi",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk1_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "pclk_fimgvg",
-               .id             = -1,
-               .parent         = &clk_pclk.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 31),
-       }, {
-               .name           = "dmc0",
-               .id             = -1,
-               .parent         = &clk_pclk.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 30),
-       }, {
-               .name           = "etm",
-               .id             = -1,
-               .parent         = &clk_pclk.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 29),
-       }, {
-               .name           = "dsim",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 28),
-       }, {
-               .name           = "gps",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 25),
-       }, {
-               .name           = "pcm",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "irom",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = (1 << 25),
-       }, {
-               .name           = "dma",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "2d",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-};
-
-/*
- * The following clocks will be enabled during clock initialization.
- */
-static struct clk init_clocks[] = {
-       {
-               .name           = "gpio",
-               .id             = -1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_GPIO,
-       }, {
-               .name           = "uart",
-               .id             = 0,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_UART0,
-       }, {
-               .name           = "uart",
-               .id             = 1,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_UART1,
-       }, {
-               .name           = "uart",
-               .id             = 2,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_UART2,
-       }, {
-               .name           = "uart",
-               .id             = 3,
-               .parent         = &clk_pclk_low.clk,
-               .enable         = s5p6440_pclk_ctrl,
-               .ctrlbit        = S5P_CLKCON_PCLK_UART3,
-       }, {
-               .name           = "mem",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "intc",
-               .id             = -1,
-               .parent         = &clk_hclk.clk,
-               .enable         = s5p6440_hclk0_ctrl,
-               .ctrlbit        = (1 << 1),
-       },
-};
-
-static struct clk clk_iis_cd_v40 = {
-       .name           = "iis_cdclk_v40",
-       .id             = -1,
-};
-
-static struct clk clk_pcm_cd = {
-       .name           = "pcm_cdclk",
-       .id             = -1,
-};
-
-static struct clk *clkset_group1_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll.clk,
-       &clk_fin_epll,
-};
-
-static struct clksrc_sources clkset_group1 = {
-       .sources        = clkset_group1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
-};
-
-static struct clk *clkset_uart_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_uart = {
-       .sources        = clkset_uart_list,
-       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clk *clkset_audio_list[] = {
-       &clk_mout_epll.clk,
-       &clk_dout_mpll.clk,
-       &clk_fin_epll,
-       &clk_iis_cd_v40,
-       &clk_pcm_cd,
-};
-
-static struct clksrc_sources clkset_audio = {
-       .sources        = clkset_audio_list,
-       .nr_sources     = ARRAY_SIZE(clkset_audio_list),
-};
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "mmc_bus",
-                       .id             = 0,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_MMC0,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "mmc_bus",
-                       .id             = 1,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_MMC1,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "mmc_bus",
-                       .id             = 2,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_MMC2,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "uclk1",
-                       .id             = -1,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_UART,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_uart,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 },
-               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "spi_epll",
-                       .id             = 0,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_SPI0,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "spi_epll",
-                       .id             = 1,
-                       .ctrlbit        = S5P_CLKCON_SCLK0_SPI1,
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_post",
-                       .id             = -1,
-                       .ctrlbit        = (1 << 10),
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_dispcon",
-                       .id             = -1,
-                       .ctrlbit        = (1 << 1),
-                       .enable         = s5p6440_sclk1_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimgvg",
-                       .id             = -1,
-                       .ctrlbit        = (1 << 2),
-                       .enable         = s5p6440_sclk1_ctrl,
-               },
-               .sources = &clkset_group1,
-               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
-               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_audio2",
-                       .id             = -1,
-                       .ctrlbit        = (1 << 11),
-                       .enable         = s5p6440_sclk_ctrl,
-               },
-               .sources = &clkset_audio,
-               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 },
-               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 },
-       },
-};
-
-/* Clock initialisation code */
-static struct clksrc_clk *sysclks[] = {
-       &clk_mout_apll,
-       &clk_mout_epll,
-       &clk_mout_mpll,
-       &clk_dout_mpll,
-       &clk_armclk,
-       &clk_hclk,
-       &clk_pclk,
-       &clk_hclk_low,
-       &clk_pclk_low,
-};
-
-void __init_or_cpufreq s5p6440_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long xtal;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long hclk_low;
-       unsigned long pclk;
-       unsigned long pclk_low;
-       unsigned long epll;
-       unsigned long apll;
-       unsigned long mpll;
-       unsigned int ptr;
-
-       /* Set S5P6440 functions for clk_fout_epll */
-       clk_fout_epll.enable = s5p6440_epll_enable;
-       clk_fout_epll.ops = &s5p6440_epll_ops;
-
-       clk_48m.enable = s5p6440_clk48m_ctrl;
-
-       xtal_clk = clk_get(NULL, "ext_xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON),
-                               __raw_readl(S5P_EPLL_CON_K));
-       mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
-       apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
-
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_apll.rate = apll;
-
-       printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
-                       " E=%ld.%ldMHz\n",
-                       print_mhz(apll), print_mhz(mpll), print_mhz(epll));
-
-       fclk = clk_get_rate(&clk_armclk.clk);
-       hclk = clk_get_rate(&clk_hclk.clk);
-       pclk = clk_get_rate(&clk_pclk.clk);
-       hclk_low = clk_get_rate(&clk_hclk_low.clk);
-       pclk_low = clk_get_rate(&clk_pclk_low.clk);
-
-       printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
-                       " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
-                       print_mhz(hclk), print_mhz(hclk_low),
-                       print_mhz(pclk), print_mhz(pclk_low));
-
-       clk_f.rate = fclk;
-       clk_h.rate = hclk;
-       clk_p.rate = pclk;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks[] __initdata = {
-       &clk_ext,
-       &clk_iis_cd_v40,
-       &clk_pcm_cd,
-};
-
-void __init s5p6440_register_clocks(void)
-{
-       struct clk *clkp;
-       int ret;
-       int ptr;
-
-       ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-       if (ret > 0)
-               printk(KERN_ERR "Failed to register %u clocks\n", ret);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
-       clkp = init_clocks_disable;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-               (clkp->enable)(clkp, 0);
-       }
-
-       s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
deleted file mode 100644 (file)
index 526f33a..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/cpu.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/proc-fns.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/s5p6440.h>
-#include <plat/adc-core.h>
-
-static void s5p6440_idle(void)
-{
-       unsigned long val;
-
-       if (!need_resched()) {
-               val = __raw_readl(S5P_PWR_CFG);
-               val &= ~(0x3<<5);
-               val |= (0x1<<5);
-               __raw_writel(val, S5P_PWR_CFG);
-
-               cpu_do_idle();
-       }
-       local_irq_enable();
-}
-
-/* s5p6440_map_io
- *
- * register the standard cpu IO areas
-*/
-
-void __init s5p6440_map_io(void)
-{
-       /* initialize any device information early */
-       s3c_adc_setname("s3c64xx-adc");
-}
-
-void __init s5p6440_init_clocks(int xtal)
-{
-       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
-       s3c24xx_register_baseclocks(xtal);
-       s5p_register_clocks(xtal);
-       s5p6440_register_clocks();
-       s5p6440_setup_clocks();
-}
-
-void __init s5p6440_init_irq(void)
-{
-       /* S5P6440 supports only 2 VIC */
-       u32 vic[2];
-
-       /*
-        * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
-        * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
-        */
-       vic[0] = 0xff800ae7;
-       vic[1] = 0xffbf23e5;
-
-       s5p_init_irq(vic, ARRAY_SIZE(vic));
-}
-
-struct sysdev_class s5p6440_sysclass = {
-       .name   = "s5p6440-core",
-};
-
-static struct sys_device s5p6440_sysdev = {
-       .cls    = &s5p6440_sysclass,
-};
-
-static int __init s5p6440_core_init(void)
-{
-       return sysdev_class_register(&s5p6440_sysclass);
-}
-
-core_initcall(s5p6440_core_init);
-
-int __init s5p6440_init(void)
-{
-       printk(KERN_INFO "S5P6440: Initializing architecture\n");
-
-       /* set idle function */
-       pm_idle = s5p6440_idle;
-
-       return sysdev_register(&s5p6440_sysdev);
-}
diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c
deleted file mode 100644 (file)
index 3ca0d2b..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/dev-audio.c
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-static int s5p6440_cfg_i2s(struct platform_device *pdev)
-{
-       /* configure GPIO for i2s port */
-       switch (pdev->id) {
-       case -1:
-               s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
-               break;
-
-       default:
-               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct s3c_audio_pdata s3c_i2s_pdata = {
-       .cfg_gpio = s5p6440_cfg_i2s,
-};
-
-static struct resource s5p6440_iis0_resource[] = {
-       [0] = {
-               .start = S5P6440_PA_I2S,
-               .end   = S5P6440_PA_I2S + 0x100 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = DMACH_I2S0_TX,
-               .end   = DMACH_I2S0_TX,
-               .flags = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start = DMACH_I2S0_RX,
-               .end   = DMACH_I2S0_RX,
-               .flags = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device s5p6440_device_iis = {
-       .name             = "s3c64xx-iis-v4",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s5p6440_iis0_resource),
-       .resource         = s5p6440_iis0_resource,
-       .dev = {
-               .platform_data = &s3c_i2s_pdata,
-       },
-};
-
-/* PCM Controller platform_devices */
-
-static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
-{
-       switch (pdev->id) {
-       case 0:
-               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
-               break;
-
-       default:
-               printk(KERN_DEBUG "Invalid PCM Controller number!");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
-       .cfg_gpio = s5p6440_pcm_cfg_gpio,
-};
-
-static struct resource s5p6440_pcm0_resource[] = {
-       [0] = {
-               .start = S5P6440_PA_PCM,
-               .end   = S5P6440_PA_PCM + 0x100 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = DMACH_PCM0_TX,
-               .end   = DMACH_PCM0_TX,
-               .flags = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start = DMACH_PCM0_RX,
-               .end   = DMACH_PCM0_RX,
-               .flags = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device s5p6440_device_pcm = {
-       .name             = "samsung-pcm",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s5p6440_pcm0_resource),
-       .resource         = s5p6440_pcm0_resource,
-       .dev = {
-               .platform_data = &s3c_pcm_pdata,
-       },
-};
diff --git a/arch/arm/mach-s5p6440/dev-spi.c b/arch/arm/mach-s5p6440/dev-spi.c
deleted file mode 100644 (file)
index 510af44..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/dev-spi.c
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/spi-clocks.h>
-
-#include <plat/s3c64xx-spi.h>
-#include <plat/gpio-cfg.h>
-
-static char *spi_src_clks[] = {
-       [S5P6440_SPI_SRCCLK_PCLK] = "pclk",
-       [S5P6440_SPI_SRCCLK_SCLK] = "spi_epll",
-};
-
-/* SPI Controller platform_devices */
-
-/* Since we emulate multi-cs capability, we do not touch the CS.
- * The emulated CS is toggled by board specific mechanism, as it can
- * be either some immediate GPIO or some signal out of some other
- * chip in between ... or some yet another way.
- * We simply do not assume anything about CS.
- */
-static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
-{
-       switch (pdev->id) {
-       case 0:
-               s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
-               break;
-
-       case 1:
-               s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
-               break;
-
-       default:
-               dev_err(&pdev->dev, "Invalid SPI Controller number!");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct resource s5p6440_spi0_resource[] = {
-       [0] = {
-               .start = S5P6440_PA_SPI0,
-               .end   = S5P6440_PA_SPI0 + 0x100 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = DMACH_SPI0_TX,
-               .end   = DMACH_SPI0_TX,
-               .flags = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start = DMACH_SPI0_RX,
-               .end   = DMACH_SPI0_RX,
-               .flags = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start = IRQ_SPI0,
-               .end   = IRQ_SPI0,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
-       .cfg_gpio = s5p6440_spi_cfg_gpio,
-       .fifo_lvl_mask = 0x1ff,
-       .rx_lvl_offset = 15,
-};
-
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s5p6440_device_spi0 = {
-       .name             = "s3c64xx-spi",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s5p6440_spi0_resource),
-       .resource         = s5p6440_spi0_resource,
-       .dev = {
-               .dma_mask               = &spi_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-               .platform_data = &s5p6440_spi0_pdata,
-       },
-};
-
-static struct resource s5p6440_spi1_resource[] = {
-       [0] = {
-               .start = S5P6440_PA_SPI1,
-               .end   = S5P6440_PA_SPI1 + 0x100 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = DMACH_SPI1_TX,
-               .end   = DMACH_SPI1_TX,
-               .flags = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start = DMACH_SPI1_RX,
-               .end   = DMACH_SPI1_RX,
-               .flags = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start = IRQ_SPI1,
-               .end   = IRQ_SPI1,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
-       .cfg_gpio = s5p6440_spi_cfg_gpio,
-       .fifo_lvl_mask = 0x7f,
-       .rx_lvl_offset = 15,
-};
-
-struct platform_device s5p6440_device_spi1 = {
-       .name             = "s3c64xx-spi",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s5p6440_spi1_resource),
-       .resource         = s5p6440_spi1_resource,
-       .dev = {
-               .dma_mask               = &spi_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-               .platform_data = &s5p6440_spi1_pdata,
-       },
-};
-
-void __init s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
-{
-       struct s3c64xx_spi_info *pd;
-
-       /* Reject invalid configuration */
-       if (!num_cs || src_clk_nr < 0
-                       || src_clk_nr > S5P6440_SPI_SRCCLK_SCLK) {
-               printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
-               return;
-       }
-
-       switch (cntrlr) {
-       case 0:
-               pd = &s5p6440_spi0_pdata;
-               break;
-       case 1:
-               pd = &s5p6440_spi1_pdata;
-               break;
-       default:
-               printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
-                                                       __func__, cntrlr);
-               return;
-       }
-
-       pd->num_cs = num_cs;
-       pd->src_clk_nr = src_clk_nr;
-       pd->src_clk_name = spi_src_clks[src_clk_nr];
-}
diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S
deleted file mode 100644 (file)
index 1347d7f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-
-       /* note, for the boot process to work we have to keep the UART
-        * virtual address aligned to an 1MiB boundary for the L1
-        * mapping the head code makes. We keep the UART virtual address
-        * aligned and add in the offset when we load the value here.
-        */
-
-       .macro addruart, rx, rtmp
-               mrc     p15, 0, \rx, c1, c0
-               tst     \rx, #1
-               ldreq   \rx, = S3C_PA_UART
-               ldrne   \rx, = S3C_VA_UART
-#if CONFIG_DEBUG_S3C_UART != 0
-               add     \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
-#endif
-       .endm
-
-/* include the reset of the code which will do the work, we're only
- * compiling for a single cpu processor type so the default of s3c2440
- * will be fine with us.
- */
-
-#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p6440/include/mach/gpio.h b/arch/arm/mach-s5p6440/include/mach/gpio.h
deleted file mode 100644 (file)
index 2178383..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H __FILE__
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
-/* GPIO bank sizes */
-#define S5P6440_GPIO_A_NR      (6)
-#define S5P6440_GPIO_B_NR      (7)
-#define S5P6440_GPIO_C_NR      (8)
-#define S5P6440_GPIO_F_NR      (2)
-#define S5P6440_GPIO_G_NR      (7)
-#define S5P6440_GPIO_H_NR      (10)
-#define S5P6440_GPIO_I_NR      (16)
-#define S5P6440_GPIO_J_NR      (12)
-#define S5P6440_GPIO_N_NR      (16)
-#define S5P6440_GPIO_P_NR      (8)
-#define S5P6440_GPIO_R_NR      (15)
-
-/* GPIO bank numbers */
-
-/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
- * space for debugging purposes so that any accidental
- * change from one gpio bank to another can be caught.
-*/
-#define S5P6440_GPIO_NEXT(__gpio) \
-       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s5p_gpio_number {
-       S5P6440_GPIO_A_START = 0,
-       S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A),
-       S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B),
-       S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C),
-       S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F),
-       S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G),
-       S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H),
-       S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I),
-       S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J),
-       S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N),
-       S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P),
-};
-
-/* S5P6440 GPIO number definitions. */
-#define S5P6440_GPA(_nr)       (S5P6440_GPIO_A_START + (_nr))
-#define S5P6440_GPB(_nr)       (S5P6440_GPIO_B_START + (_nr))
-#define S5P6440_GPC(_nr)       (S5P6440_GPIO_C_START + (_nr))
-#define S5P6440_GPF(_nr)       (S5P6440_GPIO_F_START + (_nr))
-#define S5P6440_GPG(_nr)       (S5P6440_GPIO_G_START + (_nr))
-#define S5P6440_GPH(_nr)       (S5P6440_GPIO_H_START + (_nr))
-#define S5P6440_GPI(_nr)       (S5P6440_GPIO_I_START + (_nr))
-#define S5P6440_GPJ(_nr)       (S5P6440_GPIO_J_START + (_nr))
-#define S5P6440_GPN(_nr)       (S5P6440_GPIO_N_START + (_nr))
-#define S5P6440_GPP(_nr)       (S5P6440_GPIO_P_START + (_nr))
-#define S5P6440_GPR(_nr)       (S5P6440_GPIO_R_START + (_nr))
-
-/* the end of the S5P6440 specific gpios */
-#define S5P6440_GPIO_END       (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
-#define S3C_GPIO_END           S5P6440_GPIO_END
-
-/* define the number of gpios we need to the one after the GPR() range */
-#define ARCH_NR_GPIOS          (S5P6440_GPR(S5P6440_GPIO_R_NR) +       \
-                                CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/io.h b/arch/arm/mach-s5p6440/include/mach/io.h
deleted file mode 100644 (file)
index fa2d69c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/mach-s5p6440/include/mach/io.h
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben-linux@fluff.org>
- *
- * Default IO routines for S3C64XX based
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/* No current ISA/PCI bus support. */
-#define __io(a)                __typesafe_io(a)
-#define __mem_pci(a)   (a)
-
-#define IO_SPACE_LIMIT (0xFFFFFFFF)
-
-#endif
diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h
deleted file mode 100644 (file)
index 6cc5cbc..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/map.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-#include <plat/map-s5p.h>
-
-#define S5P6440_PA_CHIPID      (0xE0000000)
-#define S5P_PA_CHIPID          S5P6440_PA_CHIPID
-
-#define S5P6440_PA_SYSCON      (0xE0100000)
-#define S5P6440_PA_CLK         (S5P6440_PA_SYSCON + 0x0)
-#define S5P_PA_SYSCON          S5P6440_PA_SYSCON
-
-#define S5P6440_PA_GPIO                (0xE0308000)
-#define S5P_PA_GPIO            S5P6440_PA_GPIO
-
-#define S5P6440_PA_VIC0                (0xE4000000)
-#define S5P_PA_VIC0            S5P6440_PA_VIC0
-
-#define S5P6440_PA_PDMA                0xE9000000
-
-#define S5P6440_PA_VIC1                (0xE4100000)
-#define S5P_PA_VIC1            S5P6440_PA_VIC1
-
-#define S5P6440_PA_TIMER       (0xEA000000)
-#define S5P_PA_TIMER           S5P6440_PA_TIMER
-
-#define S5P6440_PA_RTC         (0xEA100000)
-
-#define S5P6440_PA_WDT         (0xEA200000)
-#define S5P_PA_WDT             S5P6440_PA_WDT
-
-#define S5P6440_PA_UART                (0xEC000000)
-
-#define S5P_PA_UART0           (S5P6440_PA_UART + 0x0)
-#define S5P_PA_UART1           (S5P6440_PA_UART + 0x400)
-#define S5P_PA_UART2           (S5P6440_PA_UART + 0x800)
-#define S5P_PA_UART3           (S5P6440_PA_UART + 0xC00)
-
-#define S5P_SZ_UART            SZ_256
-
-#define S5P6440_PA_IIC0                (0xEC104000)
-#define S5P6440_PA_IIC1                (0xEC20F000)
-
-#define S5P6440_PA_SPI0                0xEC400000
-#define S5P6440_PA_SPI1                0xEC500000
-
-#define S5P6440_PA_HSOTG       (0xED100000)
-
-#define S5P6440_PA_HSMMC0      (0xED800000)
-#define S5P6440_PA_HSMMC1      (0xED900000)
-#define S5P6440_PA_HSMMC2      (0xEDA00000)
-
-#define S5P6440_PA_SDRAM       (0x20000000)
-#define S5P_PA_SDRAM           S5P6440_PA_SDRAM
-
-/* I2S */
-#define S5P6440_PA_I2S         0xF2000000
-
-/* PCM */
-#define S5P6440_PA_PCM         0xF2100000
-
-#define S5P6440_PA_ADC         (0xF3000000)
-
-/* compatibiltiy defines. */
-#define S3C_PA_UART            S5P6440_PA_UART
-#define S3C_PA_IIC             S5P6440_PA_IIC0
-#define S3C_PA_RTC             S5P6440_PA_RTC
-#define S3C_PA_IIC1            S5P6440_PA_IIC1
-#define S3C_PA_WDT             S5P6440_PA_WDT
-
-#define SAMSUNG_PA_ADC         S5P6440_PA_ADC
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h
deleted file mode 100644 (file)
index c783ecc..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - Clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_CLOCK_H
-#define __ASM_ARCH_REGS_CLOCK_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_CLKREG(x)          (S3C_VA_SYS + (x))
-
-#define S5P_APLL_LOCK          S5P_CLKREG(0x00)
-#define S5P_MPLL_LOCK          S5P_CLKREG(0x04)
-#define S5P_EPLL_LOCK          S5P_CLKREG(0x08)
-#define S5P_APLL_CON           S5P_CLKREG(0x0C)
-#define S5P_MPLL_CON           S5P_CLKREG(0x10)
-#define S5P_EPLL_CON           S5P_CLKREG(0x14)
-#define S5P_EPLL_CON_K         S5P_CLKREG(0x18)
-#define S5P_CLK_SRC0           S5P_CLKREG(0x1C)
-#define S5P_CLK_DIV0           S5P_CLKREG(0x20)
-#define S5P_CLK_DIV1           S5P_CLKREG(0x24)
-#define S5P_CLK_DIV2           S5P_CLKREG(0x28)
-#define S5P_CLK_OUT            S5P_CLKREG(0x2C)
-#define S5P_CLK_GATE_HCLK0     S5P_CLKREG(0x30)
-#define S5P_CLK_GATE_PCLK      S5P_CLKREG(0x34)
-#define S5P_CLK_GATE_SCLK0     S5P_CLKREG(0x38)
-#define S5P_CLK_GATE_MEM0      S5P_CLKREG(0x3C)
-#define S5P_CLK_DIV3           S5P_CLKREG(0x40)
-#define S5P_CLK_GATE_HCLK1     S5P_CLKREG(0x44)
-#define S5P_CLK_GATE_SCLK1     S5P_CLKREG(0x48)
-#define S5P_AHB_CON0                   S5P_CLKREG(0x100)
-#define S5P_CLK_SRC1                   S5P_CLKREG(0x10C)
-#define S5P_SWRESET            S5P_CLKREG(0x114)
-#define S5P_SYS_ID             S5P_CLKREG(0x118)
-#define S5P_SYS_OTHERS         S5P_CLKREG(0x11C)
-#define S5P_MEM_CFG_STAT       S5P_CLKREG(0x12C)
-#define S5P_PWR_CFG            S5P_CLKREG(0x804)
-#define S5P_EINT_WAKEUP_MASK   S5P_CLKREG(0x808)
-#define S5P_NORMAL_CFG         S5P_CLKREG(0x810)
-#define S5P_STOP_CFG           S5P_CLKREG(0x814)
-#define S5P_SLEEP_CFG          S5P_CLKREG(0x818)
-#define S5P_OSC_FREQ           S5P_CLKREG(0x820)
-#define S5P_OSC_STABLE         S5P_CLKREG(0x824)
-#define S5P_PWR_STABLE         S5P_CLKREG(0x828)
-#define S5P_MTC_STABLE         S5P_CLKREG(0x830)
-#define S5P_OTHERS             S5P_CLKREG(0x900)
-#define S5P_RST_STAT           S5P_CLKREG(0x904)
-#define S5P_WAKEUP_STAT                S5P_CLKREG(0x908)
-#define S5P_SLPEN              S5P_CLKREG(0x930)
-#define S5P_INFORM0            S5P_CLKREG(0xA00)
-#define S5P_INFORM1            S5P_CLKREG(0xA04)
-#define S5P_INFORM2            S5P_CLKREG(0xA08)
-#define S5P_INFORM3            S5P_CLKREG(0xA0C)
-
-/* CLKDIV0 */
-#define S5P_CLKDIV0_PCLK_MASK          (0xf << 12)
-#define S5P_CLKDIV0_PCLK_SHIFT         (12)
-#define S5P_CLKDIV0_HCLK_MASK          (0xf << 8)
-#define S5P_CLKDIV0_HCLK_SHIFT         (8)
-#define S5P_CLKDIV0_MPLL_MASK          (0x1 << 4)
-#define S5P_CLKDIV0_ARM_MASK           (0xf << 0)
-#define S5P_CLKDIV0_ARM_SHIFT          (0)
-
-/* CLKDIV3 */
-#define S5P_CLKDIV3_PCLK_LOW_MASK      (0xf << 12)
-#define S5P_CLKDIV3_PCLK_LOW_SHIFT     (12)
-#define S5P_CLKDIV3_HCLK_LOW_MASK      (0xf << 8)
-#define S5P_CLKDIV3_HCLK_LOW_SHIFT     (8)
-
-/* HCLK0 GATE Registers */
-#define S5P_CLKCON_HCLK0_USB           (1<<20)
-#define S5P_CLKCON_HCLK0_HSMMC2                (1<<19)
-#define S5P_CLKCON_HCLK0_HSMMC1                (1<<18)
-#define S5P_CLKCON_HCLK0_HSMMC0                (1<<17)
-#define S5P_CLKCON_HCLK0_POST0         (1<<5)
-
-/* HCLK1 GATE Registers */
-#define S5P_CLKCON_HCLK1_DISPCON       (1<<1)
-
-/* PCLK GATE Registers */
-#define S5P_CLKCON_PCLK_IIS2           (1<<26)
-#define S5P_CLKCON_PCLK_SPI1           (1<<22)
-#define S5P_CLKCON_PCLK_SPI0           (1<<21)
-#define S5P_CLKCON_PCLK_GPIO           (1<<18)
-#define S5P_CLKCON_PCLK_IIC0           (1<<17)
-#define S5P_CLKCON_PCLK_TSADC          (1<<12)
-#define S5P_CLKCON_PCLK_PWM            (1<<7)
-#define S5P_CLKCON_PCLK_RTC            (1<<6)
-#define S5P_CLKCON_PCLK_WDT            (1<<5)
-#define S5P_CLKCON_PCLK_UART3          (1<<4)
-#define S5P_CLKCON_PCLK_UART2          (1<<3)
-#define S5P_CLKCON_PCLK_UART1          (1<<2)
-#define S5P_CLKCON_PCLK_UART0          (1<<1)
-
-/* SCLK0 GATE Registers */
-#define S5P_CLKCON_SCLK0_MMC2_48       (1<<29)
-#define S5P_CLKCON_SCLK0_MMC1_48       (1<<28)
-#define S5P_CLKCON_SCLK0_MMC0_48       (1<<27)
-#define S5P_CLKCON_SCLK0_MMC2          (1<<26)
-#define S5P_CLKCON_SCLK0_MMC1          (1<<25)
-#define S5P_CLKCON_SCLK0_MMC0          (1<<24)
-#define S5P_CLKCON_SCLK0_SPI1_48       (1<<23)
-#define S5P_CLKCON_SCLK0_SPI0_48       (1<<22)
-#define S5P_CLKCON_SCLK0_SPI1          (1<<21)
-#define S5P_CLKCON_SCLK0_SPI0          (1<<20)
-#define S5P_CLKCON_SCLK0_UART          (1<<5)
-
-/* SCLK1 GATE Registers */
-
-/* MEM0 GATE Registers */
-#define S5P_CLKCON_MEM0_HCLK_NFCON     (1<<2)
-
-/*OTHERS Resgister */
-#define S5P_OTHERS_USB_SIG_MASK                (1<<16)
-#define S5P_OTHERS_HCLK_LOW_SEL_MPLL   (1<<6)
-
-/* Compatibility defines */
-#define ARM_CLK_DIV                    S5P_CLK_DIV0
-#define ARM_DIV_RATIO_SHIFT            0
-#define ARM_DIV_MASK                   (0xf << ARM_DIV_RATIO_SHIFT)
-
-#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h b/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
deleted file mode 100644 (file)
index 5fbca50..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __S5P6440_PLAT_SPI_CLKS_H
-#define __S5P6440_PLAT_SPI_CLKS_H __FILE__
-
-#define S5P6440_SPI_SRCCLK_PCLK                0
-#define S5P6440_SPI_SRCCLK_SCLK                1
-
-#endif /* __S5P6440_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h
deleted file mode 100644 (file)
index 7c1f600..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       /* we do not need to do any cpu detection here at the moment. */
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p6440/init.c b/arch/arm/mach-s5p6440/init.c
deleted file mode 100644 (file)
index a1f3727..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/arch/arm/mach-s5p6440/init.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P6440 - Init support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s5p6440.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = {
-       [0] = {
-               .name           = "pclk_low",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       },
-       [1] = {
-               .name           = "uclk1",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       },
-};
-
-/* uart registration process */
-void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       struct s3c2410_uartcfg *tcfg = cfg;
-       u32 ucnt;
-
-       for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
-               if (!tcfg->clocks) {
-                       tcfg->clocks = s5p6440_serial_clocks;
-                       tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks);
-               }
-       }
-
-       s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
-}
index a48fb553fd01cf5d42e1ab590146d7cad1e7680f..842af86bda6def3db35fcab32bd36127f5e14aad 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-s5p6442/cpu.c
  *
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ *             http://www.samsung.com
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -46,11 +47,31 @@ static struct map_desc s5p6442_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(S5P6442_PA_SYSTIMER),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .pfn            = __phys_to_pfn(S5P6442_PA_GPIO),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC0,
+               .pfn            = __phys_to_pfn(S5P6442_PA_VIC0),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC1,
+               .pfn            = __phys_to_pfn(S5P6442_PA_VIC1),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)VA_VIC2,
                .pfn            = __phys_to_pfn(S5P6442_PA_VIC2),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S3C_PA_UART),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
        }
 };
 
@@ -62,10 +83,11 @@ static void s5p6442_idle(void)
        local_irq_enable();
 }
 
-/* s5p6442_map_io
+/*
+ * s5p6442_map_io
  *
  * register the standard cpu IO areas
-*/
+ */
 
 void __init s5p6442_map_io(void)
 {
index 281d256faafb0d6e4e817261ac78e5b091a4078d..31fb2e68d527915080df5f9ff498c835218f972c 100644 (file)
 #define S5P_PA_SYSCON          S5P6442_PA_SYSCON
 
 #define S5P6442_PA_GPIO                (0xE0200000)
-#define S5P_PA_GPIO            S5P6442_PA_GPIO
 
 #define S5P6442_PA_VIC0                (0xE4000000)
-#define S5P_PA_VIC0            S5P6442_PA_VIC0
-
 #define S5P6442_PA_VIC1                (0xE4100000)
-#define S5P_PA_VIC1            S5P6442_PA_VIC1
-
 #define S5P6442_PA_VIC2                (0xE4200000)
-#define S5P_PA_VIC2            S5P6442_PA_VIC2
 
 #define S5P6442_PA_MDMA                0xE8000000
 #define S5P6442_PA_PDMA                0xE9000000
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
new file mode 100644 (file)
index 0000000..fbcae93
--- /dev/null
@@ -0,0 +1,57 @@
+# arch/arm/mach-s5p64x0/Kconfig
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+if ARCH_S5P64X0
+
+config CPU_S5P6440
+       bool
+       select PLAT_S5P
+       select S3C_PL330_DMA
+       help
+         Enable S5P6440 CPU support
+
+config CPU_S5P6450
+       bool
+       select PLAT_S5P
+       select S3C_PL330_DMA
+       help
+         Enable S5P6450 CPU support
+
+config S5P64X0_SETUP_I2C1
+       bool
+       help
+         Common setup code for i2c bus 1.
+
+# machine support
+
+config MACH_SMDK6440
+       bool "SMDK6440"
+       select CPU_S5P6440
+       select S3C_DEV_I2C1
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C64XX_DEV_SPI
+       select SAMSUNG_DEV_ADC
+       select SAMSUNG_DEV_TS
+       select S5P64X0_SETUP_I2C1
+       help
+         Machine support for the Samsung SMDK6440
+
+config MACH_SMDK6450
+       bool "SMDK6450"
+       select CPU_S5P6450
+       select S3C_DEV_I2C1
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C64XX_DEV_SPI
+       select SAMSUNG_DEV_ADC
+       select SAMSUNG_DEV_TS
+       select S5P64X0_SETUP_I2C1
+       help
+         Machine support for the Samsung SMDK6450
+
+endif
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
new file mode 100644 (file)
index 0000000..2655829
--- /dev/null
@@ -0,0 +1,30 @@
+# arch/arm/mach-s5p64x0/Makefile
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+# Core support for S5P64X0 system
+
+obj-$(CONFIG_ARCH_S5P64X0)     += cpu.o init.o clock.o dma.o
+obj-$(CONFIG_ARCH_S5P64X0)     += setup-i2c0.o
+obj-$(CONFIG_CPU_S5P6440)      += clock-s5p6440.o gpio.o
+obj-$(CONFIG_CPU_S5P6450)      += clock-s5p6450.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6440)    += mach-smdk6440.o
+obj-$(CONFIG_MACH_SMDK6450)    += mach-smdk6450.o
+
+# device support
+
+obj-y                          += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
+
+obj-$(CONFIG_S5P64X0_SETUP_I2C1)       += setup-i2c1.o
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
new file mode 100644 (file)
index 0000000..f93dcd8
--- /dev/null
@@ -0,0 +1,626 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6440.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P6440 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+
+static u32 epll_div[][5] = {
+       { 36000000,     0,      48, 1, 4 },
+       { 48000000,     0,      32, 1, 3 },
+       { 60000000,     0,      40, 1, 3 },
+       { 72000000,     0,      48, 1, 3 },
+       { 84000000,     0,      28, 1, 2 },
+       { 96000000,     0,      32, 1, 2 },
+       { 32768000,     45264,  43, 1, 4 },
+       { 45158000,     6903,   30, 1, 3 },
+       { 49152000,     50332,  32, 1, 3 },
+       { 67738000,     10398,  45, 1, 3 },
+       { 73728000,     9961,   49, 1, 3 }
+};
+
+static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con, epll_con_k;
+       unsigned int i;
+
+       if (clk->rate == rate)  /* Return if nothing changed */
+               return 0;
+
+       epll_con = __raw_readl(S5P64X0_EPLL_CON);
+       epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+       epll_con_k &= ~(PLL90XX_KDIV_MASK);
+       epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+                if (epll_div[i][0] == rate) {
+                       epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+                       epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+                                   (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+                                   (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(epll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(epll_con, S5P64X0_EPLL_CON);
+       __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+       .get_rate = s5p64x0_epll_get_rate,
+       .set_rate = s5p6440_epll_set_rate,
+};
+
+static struct clksrc_clk clk_hclk = {
+       .clk    = {
+               .name           = "clk_hclk",
+               .id             = -1,
+               .parent         = &clk_armclk.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+       .clk    = {
+               .name           = "clk_pclk",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_hclk_low = {
+       .clk    = {
+               .name           = "clk_hclk_low",
+               .id             = -1,
+       },
+       .sources        = &clkset_hclk_low,
+       .reg_src        = { .reg = S5P64X0_SYS_OTHERS, .shift = 6, .size = 1 },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+       .clk    = {
+               .name           = "clk_pclk_low",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "nand",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_mem_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "post",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 5)
+       }, {
+               .name           = "2d",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "hsmmc",
+               .id             = 1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "hsmmc",
+               .id             = 2,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 19),
+       }, {
+               .name           = "otg",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 20)
+       }, {
+               .name           = "irom",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "hclk_fimgvg",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "tsi",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "pcm",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 22),
+       }, {
+               .name           = "gps",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "i2s_v40",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 26),
+       }, {
+               .name           = "dsim",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 28),
+       }, {
+               .name           = "etm",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 29),
+       }, {
+               .name           = "dmc0",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 30),
+       }, {
+               .name           = "pclk_fimgvg",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 31),
+       }, {
+               .name           = "sclk_spi_48",
+               .id             = 0,
+               .parent         = &clk_48m,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 22),
+       }, {
+               .name           = "sclk_spi_48",
+               .id             = 1,
+               .parent         = &clk_48m,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 23),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 0,
+               .parent         = &clk_48m,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 27),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 1,
+               .parent         = &clk_48m,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 28),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 2,
+               .parent         = &clk_48m,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 29),
+       },
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+       {
+               .name           = "intc",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "mem",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "dma",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 18),
+       },
+};
+
+static struct clk clk_iis_cd_v40 = {
+       .name           = "iis_cdclk_v40",
+       .id             = -1,
+};
+
+static struct clk clk_pcm_cd = {
+       .name           = "pcm_cdclk",
+       .id             = -1,
+};
+
+static struct clk *clkset_group1_list[] = {
+       &clk_mout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_group1 = {
+       .sources        = clkset_group1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+       &clk_mout_epll.clk,
+       &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+       .sources        = clkset_uart_list,
+       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_audio_list[] = {
+       &clk_mout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_fin_epll,
+       &clk_iis_cd_v40,
+       &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio = {
+       .sources        = clkset_audio_list,
+       .nr_sources     = ARRAY_SIZE(clkset_audio_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 24),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 25),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 26),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 5),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 20),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 21),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_post",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_dispcon",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5p64x0_sclk1_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimgvg",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 2),
+                       .enable         = s5p64x0_sclk1_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio2",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 11),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_audio,
+               .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 },
+       },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_apll,
+       &clk_mout_epll,
+       &clk_mout_mpll,
+       &clk_dout_mpll,
+       &clk_armclk,
+       &clk_hclk,
+       &clk_pclk,
+       &clk_hclk_low,
+       &clk_pclk_low,
+};
+
+void __init_or_cpufreq s5p6440_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+
+       unsigned long xtal;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long hclk_low;
+       unsigned long pclk;
+       unsigned long pclk_low;
+
+       unsigned long apll;
+       unsigned long mpll;
+       unsigned long epll;
+       unsigned int ptr;
+
+       /* Set S5P6440 functions for clk_fout_epll */
+
+       clk_fout_epll.enable = s5p64x0_epll_enable;
+       clk_fout_epll.ops = &s5p6440_epll_ops;
+
+       clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+       xtal_clk = clk_get(NULL, "ext_xtal");
+       BUG_ON(IS_ERR(xtal_clk));
+
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+       mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+       epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+                               __raw_readl(S5P64X0_EPLL_CON_K));
+
+       clk_fout_apll.rate = apll;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+
+       printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+                       " E=%ld.%ldMHz\n",
+                       print_mhz(apll), print_mhz(mpll), print_mhz(epll));
+
+       fclk = clk_get_rate(&clk_armclk.clk);
+       hclk = clk_get_rate(&clk_hclk.clk);
+       pclk = clk_get_rate(&clk_pclk.clk);
+       hclk_low = clk_get_rate(&clk_hclk_low.clk);
+       pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+       printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+                       " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+                       print_mhz(hclk), print_mhz(hclk_low),
+                       print_mhz(pclk), print_mhz(pclk_low));
+
+       clk_f.rate = fclk;
+       clk_h.rate = hclk;
+       clk_p.rate = pclk;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_iis_cd_v40,
+       &clk_pcm_cd,
+};
+
+void __init s5p6440_register_clocks(void)
+{
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+               (clkp->enable)(clkp, 0);
+       }
+
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
new file mode 100644 (file)
index 0000000..f9afb05
--- /dev/null
@@ -0,0 +1,655 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P6450 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6450.h>
+
+static struct clksrc_clk clk_mout_dpll = {
+       .clk    = {
+               .name           = "mout_dpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_dpll,
+       .reg_src        = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
+};
+
+static u32 epll_div[][5] = {
+       { 133000000,    27307,  55, 2, 2 },
+       { 100000000,    43691,  41, 2, 2 },
+       { 480000000,    0,      80, 2, 0 },
+};
+
+static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con, epll_con_k;
+       unsigned int i;
+
+       if (clk->rate == rate)  /* Return if nothing changed */
+               return 0;
+
+       epll_con = __raw_readl(S5P64X0_EPLL_CON);
+       epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+       epll_con_k &= ~(PLL90XX_KDIV_MASK);
+       epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+                if (epll_div[i][0] == rate) {
+                       epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+                       epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+                                   (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+                                   (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(epll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(epll_con, S5P64X0_EPLL_CON);
+       __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops s5p6450_epll_ops = {
+       .get_rate = s5p64x0_epll_get_rate,
+       .set_rate = s5p6450_epll_set_rate,
+};
+
+static struct clksrc_clk clk_dout_epll = {
+       .clk    = {
+               .name           = "dout_epll",
+               .id             = -1,
+               .parent         = &clk_mout_epll.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_mout_hclk_sel = {
+       .clk    = {
+               .name           = "mout_hclk_sel",
+               .id             = -1,
+       },
+       .sources        = &clkset_hclk_low,
+       .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 },
+};
+
+static struct clk *clkset_hclk_list[] = {
+       &clk_mout_hclk_sel.clk,
+       &clk_armclk.clk,
+};
+
+static struct clksrc_sources clkset_hclk = {
+       .sources        = clkset_hclk_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hclk_list),
+};
+
+static struct clksrc_clk clk_hclk = {
+       .clk    = {
+               .name           = "clk_hclk",
+               .id             = -1,
+       },
+       .sources        = &clkset_hclk,
+       .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+       .clk    = {
+               .name           = "clk_pclk",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+       },
+       .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_dout_pwm_ratio0 = {
+       .clk    = {
+               .name           = "clk_dout_pwm_ratio0",
+               .id             = -1,
+               .parent         = &clk_mout_hclk_sel.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_to_wdt_pwm = {
+       .clk    = {
+               .name           = "clk_pclk_to_wdt_pwm",
+               .id             = -1,
+               .parent         = &clk_dout_pwm_ratio0.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 },
+};
+
+static struct clksrc_clk clk_hclk_low = {
+       .clk    = {
+               .name           = "clk_hclk_low",
+               .id             = -1,
+       },
+       .sources        = &clkset_hclk_low,
+       .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+       .clk    = {
+               .name           = "clk_pclk_low",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "usbhost",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "hsmmc",
+               .id             = 1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "hsmmc",
+               .id             = 2,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 19),
+       }, {
+               .name           = "usbotg",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 20),
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s5p64x0_hclk1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 22),
+       }, {
+               .name           = "iis",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 26),
+       }, {
+               .name           = "i2c",
+               .id             = 1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 27),
+       }, {
+               .name           = "dmc0",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 30),
+       }
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+       {
+               .name           = "intc",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "mem",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "dma",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_pclk_to_wdt_pwm.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p64x0_pclk_ctrl,
+               .ctrlbit        = (1 << 18),
+       },
+};
+
+static struct clk *clkset_uart_list[] = {
+       &clk_dout_epll.clk,
+       &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+       .sources        = clkset_uart_list,
+       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_mali_list[] = {
+       &clk_mout_epll.clk,
+       &clk_mout_apll.clk,
+       &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_mali = {
+       .sources        = clkset_mali_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mali_list),
+};
+
+static struct clk *clkset_group2_list[] = {
+       &clk_dout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_ext_xtal_mux,
+};
+
+static struct clksrc_sources clkset_group2 = {
+       .sources        = clkset_group2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group2_list),
+};
+
+static struct clk *clkset_dispcon_list[] = {
+       &clk_dout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_ext_xtal_mux,
+       &clk_mout_dpll.clk,
+};
+
+static struct clksrc_sources clkset_dispcon = {
+       .sources        = clkset_dispcon_list,
+       .nr_sources     = ARRAY_SIZE(clkset_dispcon_list),
+};
+
+static struct clk *clkset_hsmmc44_list[] = {
+       &clk_dout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_ext_xtal_mux,
+       &s5p_clk_27m,
+       &clk_48m,
+};
+
+static struct clksrc_sources clkset_hsmmc44 = {
+       .sources        = clkset_hsmmc44_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hsmmc44_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+       [0] = &clk_dout_epll.clk,
+       [1] = &clk_dout_mpll.clk,
+       [2] = &clk_ext_xtal_mux,
+       [3] = NULL,
+       [4] = NULL,
+};
+
+static struct clksrc_sources clkset_sclk_audio0 = {
+       .sources        = clkset_sclk_audio0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+       .clk            = {
+               .name           = "audio-bus",
+               .id             = -1,
+               .enable         = s5p64x0_sclk_ctrl,
+               .ctrlbit        = (1 << 8),
+               .parent         = &clk_dout_epll.clk,
+       },
+       .sources        = &clkset_sclk_audio0,
+       .reg_src        = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "sclk_mmc",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 24),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mmc",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 25),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mmc",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 26),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 5),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 20),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 21),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "aclk_mali",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 2),
+                       .enable         = s5p64x0_sclk1_ctrl,
+               },
+               .sources = &clkset_mali,
+               .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_2d",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 12),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_mali,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_usi",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 7),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_camif",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 6),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_dispcon",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5p64x0_sclk1_ctrl,
+               },
+               .sources = &clkset_dispcon,
+               .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_hsmmc44",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 30),
+                       .enable         = s5p64x0_sclk_ctrl,
+               },
+               .sources = &clkset_hsmmc44,
+               .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 },
+               .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 },
+       },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_apll,
+       &clk_mout_epll,
+       &clk_dout_epll,
+       &clk_mout_mpll,
+       &clk_dout_mpll,
+       &clk_armclk,
+       &clk_mout_hclk_sel,
+       &clk_dout_pwm_ratio0,
+       &clk_pclk_to_wdt_pwm,
+       &clk_hclk,
+       &clk_pclk,
+       &clk_hclk_low,
+       &clk_pclk_low,
+       &clk_sclk_audio0,
+};
+
+void __init_or_cpufreq s5p6450_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+
+       unsigned long xtal;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long hclk_low;
+       unsigned long pclk;
+       unsigned long pclk_low;
+
+       unsigned long apll;
+       unsigned long mpll;
+       unsigned long epll;
+       unsigned long dpll;
+       unsigned int ptr;
+
+       /* Set S5P6450 functions for clk_fout_epll */
+
+       clk_fout_epll.enable = s5p64x0_epll_enable;
+       clk_fout_epll.ops = &s5p6450_epll_ops;
+
+       clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+       xtal_clk = clk_get(NULL, "ext_xtal");
+       BUG_ON(IS_ERR(xtal_clk));
+
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+       mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+       epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+                               __raw_readl(S5P64X0_EPLL_CON_K));
+       dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON),
+                               __raw_readl(S5P6450_DPLL_CON_K), pll_4650c);
+
+       clk_fout_apll.rate = apll;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_fout_dpll.rate = dpll;
+
+       printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+                       " E=%ld.%ldMHz, D=%ld.%ldMHz\n",
+                       print_mhz(apll), print_mhz(mpll), print_mhz(epll),
+                       print_mhz(dpll));
+
+       fclk = clk_get_rate(&clk_armclk.clk);
+       hclk = clk_get_rate(&clk_hclk.clk);
+       pclk = clk_get_rate(&clk_pclk.clk);
+       hclk_low = clk_get_rate(&clk_hclk_low.clk);
+       pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+       printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+                       " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+                       print_mhz(hclk), print_mhz(hclk_low),
+                       print_mhz(pclk), print_mhz(pclk_low));
+
+       clk_f.rate = fclk;
+       clk_h.rate = hclk;
+       clk_p.rate = pclk;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+void __init s5p6450_register_clocks(void)
+{
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+               (clkp->enable)(clkp, 0);
+       }
+
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
new file mode 100644 (file)
index 0000000..523ba80
--- /dev/null
@@ -0,0 +1,253 @@
+/* linux/arch/arm/mach-s5p64x0/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+
+struct clksrc_clk clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_apll,
+       .reg_src        = { .reg = S5P64X0_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_mpll = {
+       .clk    = {
+               .name           = "mout_mpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mpll,
+       .reg_src        = { .reg = S5P64X0_CLK_SRC0, .shift = 1, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P64X0_CLK_SRC0, .shift = 2, .size = 1 },
+};
+
+enum perf_level {
+       L0 = 532*1000,
+       L1 = 266*1000,
+       L2 = 133*1000,
+};
+
+static const u32 clock_table[][3] = {
+       /*{ARM_CLK, DIVarm, DIVhclk}*/
+       {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+       {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+       {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+};
+
+int s5p64x0_epll_enable(struct clk *clk, int enable)
+{
+       unsigned int ctrlbit = clk->ctrlbit;
+       unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit;
+
+       if (enable)
+               __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON);
+       else
+               __raw_writel(epll_con, S5P64X0_EPLL_CON);
+
+       return 0;
+}
+
+unsigned long s5p64x0_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       u32 clkdiv;
+
+       /* divisor mask starts at bit0, so no need to shift */
+       clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
+
+       return rate / (clkdiv + 1);
+}
+
+unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
+{
+       u32 iter;
+
+       for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+               if (rate > clock_table[iter][0])
+                       return clock_table[iter-1][0];
+       }
+
+       return clock_table[ARRAY_SIZE(clock_table) - 1][0];
+}
+
+int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
+{
+       u32 round_tmp;
+       u32 iter;
+       u32 clk_div0_tmp;
+       u32 cur_rate = clk->ops->get_rate(clk);
+       unsigned long flags;
+
+       round_tmp = clk->ops->round_rate(clk, rate);
+       if (round_tmp == cur_rate)
+               return 0;
+
+
+       for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+               if (round_tmp == clock_table[iter][0])
+                       break;
+       }
+
+       if (iter >= ARRAY_SIZE(clock_table))
+               iter = ARRAY_SIZE(clock_table) - 1;
+
+       local_irq_save(flags);
+       if (cur_rate > round_tmp) {
+               /* Frequency Down */
+               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+               clk_div0_tmp |= clock_table[iter][1];
+               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+                               ~(S5P64X0_CLKDIV0_HCLK_MASK);
+               clk_div0_tmp |= clock_table[iter][2];
+               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+
+       } else {
+               /* Frequency Up */
+               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+                               ~(S5P64X0_CLKDIV0_HCLK_MASK);
+               clk_div0_tmp |= clock_table[iter][2];
+               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+               clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+               clk_div0_tmp |= clock_table[iter][1];
+               __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+       }
+       local_irq_restore(flags);
+
+       clk->rate = clock_table[iter][0];
+
+       return 0;
+}
+
+struct clk_ops s5p64x0_clkarm_ops = {
+       .get_rate       = s5p64x0_armclk_get_rate,
+       .set_rate       = s5p64x0_armclk_set_rate,
+       .round_rate     = s5p64x0_armclk_round_rate,
+};
+
+struct clksrc_clk clk_armclk = {
+       .clk    = {
+               .name           = "armclk",
+               .id             = 1,
+               .parent         = &clk_mout_apll.clk,
+               .ops            = &s5p64x0_clkarm_ops,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 0, .size = 4 },
+};
+
+struct clksrc_clk clk_dout_mpll = {
+       .clk    = {
+               .name           = "dout_mpll",
+               .id             = -1,
+               .parent         = &clk_mout_mpll.clk,
+       },
+       .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 },
+};
+
+struct clk *clkset_hclk_low_list[] = {
+       &clk_mout_apll.clk,
+       &clk_mout_mpll.clk,
+};
+
+struct clksrc_sources clkset_hclk_low = {
+       .sources        = clkset_hclk_low_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hclk_low_list),
+};
+
+int s5p64x0_pclk_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_PCLK, clk, enable);
+}
+
+int s5p64x0_hclk0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK0, clk, enable);
+}
+
+int s5p64x0_hclk1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK1, clk, enable);
+}
+
+int s5p64x0_sclk_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK0, clk, enable);
+}
+
+int s5p64x0_sclk1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK1, clk, enable);
+}
+
+int s5p64x0_mem_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P64X0_CLK_GATE_MEM0, clk, enable);
+}
+
+int s5p64x0_clk48m_ctrl(struct clk *clk, int enable)
+{
+       unsigned long flags;
+       u32 val;
+
+       /* can't rely on clock lock, this register has other usages */
+       local_irq_save(flags);
+
+       val = __raw_readl(S5P64X0_OTHERS);
+       if (enable)
+               val |= S5P64X0_OTHERS_USB_SIG_MASK;
+       else
+               val &= ~S5P64X0_OTHERS_USB_SIG_MASK;
+
+       __raw_writel(val, S5P64X0_OTHERS);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
new file mode 100644 (file)
index 0000000..b8d02eb
--- /dev/null
@@ -0,0 +1,209 @@
+/* linux/arch/arm/mach-s5p64x0/cpu.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/adc-core.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5p64x0_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .pfn            = __phys_to_pfn(S5P64X0_PA_GPIO),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC0,
+               .pfn            = __phys_to_pfn(S5P64X0_PA_VIC0),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC1,
+               .pfn            = __phys_to_pfn(S5P64X0_PA_VIC1),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc s5p6440_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S5P6440_PA_UART(0)),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc s5p6450_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S5P6450_PA_UART(0)),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART + SZ_512K,
+               .pfn            = __phys_to_pfn(S5P6450_PA_UART(5)),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void s5p64x0_idle(void)
+{
+       unsigned long val;
+
+       if (!need_resched()) {
+               val = __raw_readl(S5P64X0_PWR_CFG);
+               val &= ~(0x3 << 5);
+               val |= (0x1 << 5);
+               __raw_writel(val, S5P64X0_PWR_CFG);
+
+               cpu_do_idle();
+       }
+       local_irq_enable();
+}
+
+/*
+ * s5p64x0_map_io
+ *
+ * register the standard CPU IO areas
+ */
+
+void __init s5p6440_map_io(void)
+{
+       /* initialize any device information early */
+       s3c_adc_setname("s3c64xx-adc");
+
+       iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+       iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+}
+
+void __init s5p6450_map_io(void)
+{
+       /* initialize any device information early */
+       s3c_adc_setname("s3c64xx-adc");
+
+       iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+       iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+}
+
+/*
+ * s5p64x0_init_clocks
+ *
+ * register and setup the CPU clocks
+ */
+
+void __init s5p6440_init_clocks(int xtal)
+{
+       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+       s3c24xx_register_baseclocks(xtal);
+       s5p_register_clocks(xtal);
+       s5p6440_register_clocks();
+       s5p6440_setup_clocks();
+}
+
+void __init s5p6450_init_clocks(int xtal)
+{
+       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+       s3c24xx_register_baseclocks(xtal);
+       s5p_register_clocks(xtal);
+       s5p6450_register_clocks();
+       s5p6450_setup_clocks();
+}
+
+/*
+ * s5p64x0_init_irq
+ *
+ * register the CPU interrupts
+ */
+
+void __init s5p6440_init_irq(void)
+{
+       /* S5P6440 supports 2 VIC */
+       u32 vic[2];
+
+       /*
+        * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+        * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+        */
+       vic[0] = 0xff800ae7;
+       vic[1] = 0xffbf23e5;
+
+       s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+void __init s5p6450_init_irq(void)
+{
+       /* S5P6450 supports only 2 VIC */
+       u32 vic[2];
+
+       /*
+        * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
+        * VIC1 is missing IRQ VIC1[12, 14, 23]
+        */
+       vic[0] = 0xff9f1fff;
+       vic[1] = 0xff7fafff;
+
+       s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+struct sysdev_class s5p64x0_sysclass = {
+       .name   = "s5p64x0-core",
+};
+
+static struct sys_device s5p64x0_sysdev = {
+       .cls    = &s5p64x0_sysclass,
+};
+
+static int __init s5p64x0_core_init(void)
+{
+       return sysdev_class_register(&s5p64x0_sysclass);
+}
+core_initcall(s5p64x0_core_init);
+
+int __init s5p64x0_init(void)
+{
+       printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
+
+       /* set idle function */
+       pm_idle = s5p64x0_idle;
+
+       return sysdev_register(&s5p64x0_sysdev);
+}
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
new file mode 100644 (file)
index 0000000..fa097bd
--- /dev/null
@@ -0,0 +1,164 @@
+/* linux/arch/arm/mach-s5p64x0/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5p6440_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case -1:
+               s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int s5p6450_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case -1:
+               s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5));
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_i2s_pdata = {
+       .cfg_gpio = s5p6440_cfg_i2s,
+};
+
+static struct s3c_audio_pdata s5p6450_i2s_pdata = {
+       .cfg_gpio = s5p6450_cfg_i2s,
+};
+
+static struct resource s5p64x0_iis0_resource[] = {
+       [0] = {
+               .start  = S5P64X0_PA_I2S,
+               .end    = S5P64X0_PA_I2S + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_I2S0_TX,
+               .end    = DMACH_I2S0_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_I2S0_RX,
+               .end    = DMACH_I2S0_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6440_device_iis = {
+       .name           = "s3c64xx-iis-v4",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p64x0_iis0_resource),
+       .resource       = s5p64x0_iis0_resource,
+       .dev = {
+               .platform_data = &s5p6440_i2s_pdata,
+       },
+};
+
+struct platform_device s5p6450_device_iis0 = {
+       .name           = "s3c64xx-iis-v4",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p64x0_iis0_resource),
+       .resource       = s5p64x0_iis0_resource,
+       .dev = {
+               .platform_data = &s5p6450_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
+               break;
+
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_pcm_pdata = {
+       .cfg_gpio = s5p6440_pcm_cfg_gpio,
+};
+
+static struct resource s5p6440_pcm0_resource[] = {
+       [0] = {
+               .start  = S5P64X0_PA_PCM,
+               .end    = S5P64X0_PA_PCM + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_PCM0_TX,
+               .end    = DMACH_PCM0_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_PCM0_RX,
+               .end    = DMACH_PCM0_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6440_device_pcm = {
+       .name           = "samsung-pcm",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p6440_pcm0_resource),
+       .resource       = s5p6440_pcm0_resource,
+       .dev = {
+               .platform_data = &s5p6440_pcm_pdata,
+       },
+};
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
new file mode 100644 (file)
index 0000000..5b69ec4
--- /dev/null
@@ -0,0 +1,232 @@
+/* linux/arch/arm/mach-s5p64x0/dev-spi.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+
+static char *s5p64x0_spi_src_clks[] = {
+       [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
+       [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
+               break;
+
+       case 1:
+               s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
+               break;
+
+       default:
+               dev_err(&pdev->dev, "Invalid SPI Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP);
+               break;
+
+       case 1:
+               s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP);
+               s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP);
+               break;
+
+       default:
+               dev_err(&pdev->dev, "Invalid SPI Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct resource s5p64x0_spi0_resource[] = {
+       [0] = {
+               .start  = S5P64X0_PA_SPI0,
+               .end    = S5P64X0_PA_SPI0 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_SPI0_TX,
+               .end    = DMACH_SPI0_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_SPI0_RX,
+               .end    = DMACH_SPI0_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start  = IRQ_SPI0,
+               .end    = IRQ_SPI0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
+       .cfg_gpio       = s5p6440_spi_cfg_gpio,
+       .fifo_lvl_mask  = 0x1ff,
+       .rx_lvl_offset  = 15,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
+       .cfg_gpio       = s5p6450_spi_cfg_gpio,
+       .fifo_lvl_mask  = 0x1ff,
+       .rx_lvl_offset  = 15,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p64x0_device_spi0 = {
+       .name           = "s3c64xx-spi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p64x0_spi0_resource),
+       .resource       = s5p64x0_spi0_resource,
+       .dev = {
+               .dma_mask               = &spi_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+static struct resource s5p64x0_spi1_resource[] = {
+       [0] = {
+               .start  = S5P64X0_PA_SPI1,
+               .end    = S5P64X0_PA_SPI1 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_SPI1_TX,
+               .end    = DMACH_SPI1_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_SPI1_RX,
+               .end    = DMACH_SPI1_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start  = IRQ_SPI1,
+               .end    = IRQ_SPI1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
+       .cfg_gpio       = s5p6440_spi_cfg_gpio,
+       .fifo_lvl_mask  = 0x7f,
+       .rx_lvl_offset  = 15,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
+       .cfg_gpio       = s5p6450_spi_cfg_gpio,
+       .fifo_lvl_mask  = 0x7f,
+       .rx_lvl_offset  = 15,
+};
+
+struct platform_device s5p64x0_device_spi1 = {
+       .name           = "s3c64xx-spi",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p64x0_spi1_resource),
+       .resource       = s5p64x0_spi1_resource,
+       .dev = {
+               .dma_mask               = &spi_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+       unsigned int id;
+       struct s3c64xx_spi_info *pd;
+
+       id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+       /* Reject invalid configuration */
+       if (!num_cs || src_clk_nr < 0
+                       || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
+               printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+               return;
+       }
+
+       switch (cntrlr) {
+       case 0:
+               if (id == 0x50000)
+                       pd = &s5p6450_spi0_pdata;
+               else
+                       pd = &s5p6440_spi0_pdata;
+
+               s5p64x0_device_spi0.dev.platform_data = pd;
+               break;
+       case 1:
+               if (id == 0x50000)
+                       pd = &s5p6450_spi1_pdata;
+               else
+                       pd = &s5p6440_spi1_pdata;
+
+               s5p64x0_device_spi1.dev.platform_data = pd;
+               break;
+       default:
+               printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+                                                       __func__, cntrlr);
+               return;
+       }
+
+       pd->num_cs = num_cs;
+       pd->src_clk_nr = src_clk_nr;
+       pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
+}
similarity index 55%
rename from arch/arm/mach-s5p6440/dma.c
rename to arch/arm/mach-s5p64x0/dma.c
index 07606ad57519a21656b6dcac2af45eea419f6013..29a8c2410049f7fa6b41c51a71f938abcdec9eb7 100644 (file)
@@ -1,4 +1,8 @@
-/*
+/* linux/arch/arm/mach-s5p64x0/dma.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
  * Copyright (C) 2010 Samsung Electronics Co. Ltd.
  *     Jaswinder Singh <jassi.brar@samsung.com>
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+*/
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
-#include <plat/devs.h>
-#include <plat/irqs.h>
-
 #include <mach/map.h>
 #include <mach/irqs.h>
+#include <mach/regs-clock.h>
 
+#include <plat/devs.h>
 #include <plat/s3c-pl330-pdata.h>
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-static struct resource s5p6440_pdma_resource[] = {
+static struct resource s5p64x0_pdma_resource[] = {
        [0] = {
-               .start  = S5P6440_PA_PDMA,
-               .end    = S5P6440_PA_PDMA + SZ_4K,
-               .flags = IORESOURCE_MEM,
+               .start  = S5P64X0_PA_PDMA,
+               .end    = S5P64X0_PA_PDMA + SZ_4K,
+               .flags  = IORESOURCE_MEM,
        },
        [1] = {
                .start  = IRQ_DMA0,
@@ -80,26 +83,67 @@ static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
        },
 };
 
-static struct platform_device s5p6440_device_pdma = {
+static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
+       .peri = {
+               [0] = DMACH_UART0_RX,
+               [1] = DMACH_UART0_TX,
+               [2] = DMACH_UART1_RX,
+               [3] = DMACH_UART1_TX,
+               [4] = DMACH_UART2_RX,
+               [5] = DMACH_UART2_TX,
+               [6] = DMACH_UART3_RX,
+               [7] = DMACH_UART3_TX,
+               [8] = DMACH_UART4_RX,
+               [9] = DMACH_UART4_TX,
+               [10] = DMACH_PCM0_TX,
+               [11] = DMACH_PCM0_RX,
+               [12] = DMACH_I2S0_TX,
+               [13] = DMACH_I2S0_RX,
+               [14] = DMACH_SPI0_TX,
+               [15] = DMACH_SPI0_RX,
+               [16] = DMACH_PCM1_TX,
+               [17] = DMACH_PCM1_RX,
+               [18] = DMACH_PCM2_TX,
+               [19] = DMACH_PCM2_RX,
+               [20] = DMACH_SPI1_TX,
+               [21] = DMACH_SPI1_RX,
+               [22] = DMACH_USI_TX,
+               [23] = DMACH_USI_RX,
+               [24] = DMACH_MAX,
+               [25] = DMACH_I2S1_TX,
+               [26] = DMACH_I2S1_RX,
+               [27] = DMACH_I2S2_TX,
+               [28] = DMACH_I2S2_RX,
+               [29] = DMACH_PWM,
+               [30] = DMACH_UART5_RX,
+               [31] = DMACH_UART5_TX,
+       },
+};
+
+static struct platform_device s5p64x0_device_pdma = {
        .name           = "s3c-pl330",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(s5p6440_pdma_resource),
-       .resource       = s5p6440_pdma_resource,
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p64x0_pdma_resource),
+       .resource       = s5p64x0_pdma_resource,
        .dev            = {
                .dma_mask = &dma_dmamask,
                .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = &s5p6440_pdma_pdata,
        },
 };
 
-static struct platform_device *s5p6440_dmacs[] __initdata = {
-       &s5p6440_device_pdma,
-};
-
-static int __init s5p6440_dma_init(void)
+static int __init s5p64x0_dma_init(void)
 {
-       platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs));
+       unsigned int id;
+
+       id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+       if (id == 0x50000)
+               s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
+       else
+               s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+
+       platform_device_register(&s5p64x0_device_pdma);
 
        return 0;
 }
-arch_initcall(s5p6440_dma_init);
+arch_initcall(s5p64x0_dma_init);
similarity index 74%
rename from arch/arm/mach-s5p6440/gpio.c
rename to arch/arm/mach-s5p64x0/gpio.c
index 8bf6e0ce51c9cd9b95830770e6e62edf8710d83f..39159dd5a29ac7bf091e457a03d6eed14ef6573d 100644 (file)
@@ -1,14 +1,14 @@
-/* arch/arm/mach-s5p6440/gpio.c
+/* linux/arch/arm/mach-s5p64x0/gpio.c
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - GPIOlib support
+ * S5P64X0 - GPIOlib support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- */
+*/
 
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
-/* GPIO bank summary:
-*
-* Bank GPIOs   Style   SlpCon  ExtInt Group
-* A    6       4Bit    Yes     1
-* B    7       4Bit    Yes     1
-* C    8       4Bit    Yes     2
-* F    2       2Bit    Yes     4 [1]
-* G    7       4Bit    Yes     5
-* H    10      4Bit[2] Yes     6
-* I    16      2Bit    Yes     None
-* J    12      2Bit    Yes     None
-* N    16      2Bit    No      IRQ_EINT
-* P    8       2Bit    Yes     8
-* R    15      4Bit[2] Yes     8
-*
-* [1] BANKF pins 14,15 do not form part of the external interrupt sources
-* [2] BANK has two control registers, GPxCON0 and GPxCON1
-*/
+/* To be implemented S5P6450 GPIO */
+
+/*
+ * S5P6440 GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   SlpCon  ExtInt Group
+ * A   6       4Bit    Yes     1
+ * B   7       4Bit    Yes     1
+ * C   8       4Bit    Yes     2
+ * F   2       2Bit    Yes     4 [1]
+ * G   7       4Bit    Yes     5
+ * H   10      4Bit[2] Yes     6
+ * I   16      2Bit    Yes     None
+ * J   12      2Bit    Yes     None
+ * N   16      2Bit    No      IRQ_EINT
+ * P   8       2Bit    Yes     8
+ * R   15      4Bit[2] Yes     8
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
 
-static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
+static int s5p64x0_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
                                             unsigned int offset)
 {
        struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
@@ -77,7 +80,7 @@ static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
        return 0;
 }
 
-static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+static int s5p64x0_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
                                              unsigned int offset, int value)
 {
        struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
@@ -124,12 +127,11 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
        return 0;
 }
 
-int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+int s5p64x0_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
                                   unsigned int off, unsigned int cfg)
 {
        void __iomem *reg = chip->base;
        unsigned int shift;
-       unsigned long flags;
        u32 con;
 
        switch (off) {
@@ -155,26 +157,22 @@ int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
                cfg <<= shift;
        }
 
-       s3c_gpio_lock(chip, flags);
-
        con = __raw_readl(reg);
        con &= ~(0xf << shift);
        con |= cfg;
        __raw_writel(con, reg);
 
-       s3c_gpio_unlock(chip, flags);
-
        return 0;
 }
 
-static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
+static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
        {
                .cfg_eint       = 0,
        }, {
                .cfg_eint       = 7,
        }, {
                .cfg_eint       = 3,
-               .set_config     = s5p6440_gpio_setcfg_4bit_rbank,
+               .set_config     = s5p64x0_gpio_setcfg_4bit_rbank,
        }, {
                .cfg_eint       = 0,
                .set_config     = s3c_gpio_setcfg_s3c24xx,
@@ -193,7 +191,7 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
 static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
        {
                .base   = S5P6440_GPA_BASE,
-               .config = &s5p6440_gpio_cfgs[1],
+               .config = &s5p64x0_gpio_cfgs[1],
                .chip   = {
                        .base   = S5P6440_GPA(0),
                        .ngpio  = S5P6440_GPIO_A_NR,
@@ -201,7 +199,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
                },
        }, {
                .base   = S5P6440_GPB_BASE,
-               .config = &s5p6440_gpio_cfgs[1],
+               .config = &s5p64x0_gpio_cfgs[1],
                .chip   = {
                        .base   = S5P6440_GPB(0),
                        .ngpio  = S5P6440_GPIO_B_NR,
@@ -209,7 +207,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
                },
        }, {
                .base   = S5P6440_GPC_BASE,
-               .config = &s5p6440_gpio_cfgs[1],
+               .config = &s5p64x0_gpio_cfgs[1],
                .chip   = {
                        .base   = S5P6440_GPC(0),
                        .ngpio  = S5P6440_GPIO_C_NR,
@@ -217,7 +215,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
                },
        }, {
                .base   = S5P6440_GPG_BASE,
-               .config = &s5p6440_gpio_cfgs[1],
+               .config = &s5p64x0_gpio_cfgs[1],
                .chip   = {
                        .base   = S5P6440_GPG(0),
                        .ngpio  = S5P6440_GPIO_G_NR,
@@ -229,7 +227,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
 static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
        {
                .base   = S5P6440_GPH_BASE + 0x4,
-               .config = &s5p6440_gpio_cfgs[1],
+               .config = &s5p64x0_gpio_cfgs[1],
                .chip   = {
                        .base   = S5P6440_GPH(0),
                        .ngpio  = S5P6440_GPIO_H_NR,
@@ -238,10 +236,10 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
        },
 };
 
-static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
        {
                .base   = S5P6440_GPR_BASE + 0x4,
-               .config = &s5p6440_gpio_cfgs[2],
+               .config = &s5p64x0_gpio_cfgs[2],
                .chip   = {
                        .base   = S5P6440_GPR(0),
                        .ngpio  = S5P6440_GPIO_R_NR,
@@ -253,7 +251,7 @@ static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
 static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
        {
                .base   = S5P6440_GPF_BASE,
-               .config = &s5p6440_gpio_cfgs[5],
+               .config = &s5p64x0_gpio_cfgs[5],
                .chip   = {
                        .base   = S5P6440_GPF(0),
                        .ngpio  = S5P6440_GPIO_F_NR,
@@ -261,7 +259,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
                },
        }, {
                .base   = S5P6440_GPI_BASE,
-               .config = &s5p6440_gpio_cfgs[3],
+               .config = &s5p64x0_gpio_cfgs[3],
                .chip   = {
                        .base   = S5P6440_GPI(0),
                        .ngpio  = S5P6440_GPIO_I_NR,
@@ -269,7 +267,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
                },
        }, {
                .base   = S5P6440_GPJ_BASE,
-               .config = &s5p6440_gpio_cfgs[3],
+               .config = &s5p64x0_gpio_cfgs[3],
                .chip   = {
                        .base   = S5P6440_GPJ(0),
                        .ngpio  = S5P6440_GPIO_J_NR,
@@ -277,7 +275,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
                },
        }, {
                .base   = S5P6440_GPN_BASE,
-               .config = &s5p6440_gpio_cfgs[4],
+               .config = &s5p64x0_gpio_cfgs[4],
                .chip   = {
                        .base   = S5P6440_GPN(0),
                        .ngpio  = S5P6440_GPIO_N_NR,
@@ -285,7 +283,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
                },
        }, {
                .base   = S5P6440_GPP_BASE,
-               .config = &s5p6440_gpio_cfgs[5],
+               .config = &s5p64x0_gpio_cfgs[5],
                .chip   = {
                        .base   = S5P6440_GPP(0),
                        .ngpio  = S5P6440_GPIO_P_NR,
@@ -294,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
        },
 };
 
-void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
+void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
 {
        for (; nr_chips > 0; nr_chips--, chipcfg++) {
                if (!chipcfg->set_config)
@@ -308,13 +306,13 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
        }
 }
 
-static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
+static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
                                                int nr_chips)
 {
        for (; nr_chips > 0; nr_chips--, chip++) {
-               chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input;
+               chip->chip.direction_input = s5p64x0_gpiolib_rbank_4bit2_input;
                chip->chip.direction_output =
-                                       s5p6440_gpiolib_rbank_4bit2_output;
+                                       s5p64x0_gpiolib_rbank_4bit2_output;
                s3c_gpiolib_add(chip);
        }
 }
@@ -324,8 +322,8 @@ static int __init s5p6440_gpiolib_init(void)
        struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
        int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
 
-       s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs,
-                               ARRAY_SIZE(s5p6440_gpio_cfgs));
+       s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
+                               ARRAY_SIZE(s5p64x0_gpio_cfgs));
 
        for (; nr_chips > 0; nr_chips--, chips++)
                s3c_gpiolib_add(chips);
@@ -336,8 +334,8 @@ static int __init s5p6440_gpiolib_init(void)
        samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
                                ARRAY_SIZE(s5p6440_gpio_4bit2));
 
-       s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2,
-                               ARRAY_SIZE(gpio_rbank_4bit2));
+       s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
+                               ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
 
        return 0;
 }
diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..79b04e6
--- /dev/null
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#include <plat/regs-serial.h>
+
+       .macro addruart, rp, rv
+               mov     \rp, #0xE0000000
+               orr     \rp, \rp, #0x00100000
+               ldr     \rp, [\rp, #0x118 ]
+               and     \rp, \rp, #0xff000
+               teq     \rp, #0x50000           @@ S5P6450
+               ldreq   \rp, =0xEC800000
+               movne   \rp, #0xEC000000        @@ S5P6440
+               ldrne   \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+               add     \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+               add     \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+       .endm
+
+#include <plat/debug-macro.S>
similarity index 58%
rename from arch/arm/mach-s5p6440/include/mach/entry-macro.S
rename to arch/arm/mach-s5p64x0/include/mach/entry-macro.S
index e65f1b9672626d512d95e004aa8f740e30b4ae43..10b62b4f821177aa2c45fd2d7c91748411973d44 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S
+/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * Low-level IRQ helper macros for the Samsung S5P6440
+ * Low-level IRQ helper macros for the Samsung S5P64X0
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..5486c8f
--- /dev/null
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/gpio.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep  __gpio_cansleep
+#define gpio_to_irq    __gpio_to_irq
+
+/* GPIO bank sizes */
+
+#define S5P6440_GPIO_A_NR      (6)
+#define S5P6440_GPIO_B_NR      (7)
+#define S5P6440_GPIO_C_NR      (8)
+#define S5P6440_GPIO_F_NR      (2)
+#define S5P6440_GPIO_G_NR      (7)
+#define S5P6440_GPIO_H_NR      (10)
+#define S5P6440_GPIO_I_NR      (16)
+#define S5P6440_GPIO_J_NR      (12)
+#define S5P6440_GPIO_N_NR      (16)
+#define S5P6440_GPIO_P_NR      (8)
+#define S5P6440_GPIO_R_NR      (15)
+
+#define S5P6450_GPIO_A_NR      (6)
+#define S5P6450_GPIO_B_NR      (7)
+#define S5P6450_GPIO_C_NR      (8)
+#define S5P6450_GPIO_D_NR      (8)
+#define S5P6450_GPIO_F_NR      (2)
+#define S5P6450_GPIO_G_NR      (14)
+#define S5P6450_GPIO_H_NR      (10)
+#define S5P6450_GPIO_I_NR      (16)
+#define S5P6450_GPIO_J_NR      (12)
+#define S5P6450_GPIO_K_NR      (5)
+#define S5P6450_GPIO_N_NR      (16)
+#define S5P6450_GPIO_P_NR      (11)
+#define S5P6450_GPIO_Q_NR      (14)
+#define S5P6450_GPIO_R_NR      (15)
+#define S5P6450_GPIO_S_NR      (8)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5P64X0_GPIO_NEXT(__gpio) \
+       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p6440_gpio_number {
+       S5P6440_GPIO_A_START    = 0,
+       S5P6440_GPIO_B_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_A),
+       S5P6440_GPIO_C_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_B),
+       S5P6440_GPIO_F_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_C),
+       S5P6440_GPIO_G_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_F),
+       S5P6440_GPIO_H_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_G),
+       S5P6440_GPIO_I_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_H),
+       S5P6440_GPIO_J_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_I),
+       S5P6440_GPIO_N_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_J),
+       S5P6440_GPIO_P_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_N),
+       S5P6440_GPIO_R_START    = S5P64X0_GPIO_NEXT(S5P6440_GPIO_P),
+};
+
+enum s5p6450_gpio_number {
+       S5P6450_GPIO_A_START    = 0,
+       S5P6450_GPIO_B_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_A),
+       S5P6450_GPIO_C_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_B),
+       S5P6450_GPIO_D_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_C),
+       S5P6450_GPIO_F_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_D),
+       S5P6450_GPIO_G_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_F),
+       S5P6450_GPIO_H_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_G),
+       S5P6450_GPIO_I_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_H),
+       S5P6450_GPIO_J_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_I),
+       S5P6450_GPIO_K_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_J),
+       S5P6450_GPIO_N_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_K),
+       S5P6450_GPIO_P_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_N),
+       S5P6450_GPIO_Q_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_P),
+       S5P6450_GPIO_R_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_Q),
+       S5P6450_GPIO_S_START    = S5P64X0_GPIO_NEXT(S5P6450_GPIO_R),
+};
+
+/* GPIO number definitions */
+
+#define S5P6440_GPA(_nr)       (S5P6440_GPIO_A_START + (_nr))
+#define S5P6440_GPB(_nr)       (S5P6440_GPIO_B_START + (_nr))
+#define S5P6440_GPC(_nr)       (S5P6440_GPIO_C_START + (_nr))
+#define S5P6440_GPF(_nr)       (S5P6440_GPIO_F_START + (_nr))
+#define S5P6440_GPG(_nr)       (S5P6440_GPIO_G_START + (_nr))
+#define S5P6440_GPH(_nr)       (S5P6440_GPIO_H_START + (_nr))
+#define S5P6440_GPI(_nr)       (S5P6440_GPIO_I_START + (_nr))
+#define S5P6440_GPJ(_nr)       (S5P6440_GPIO_J_START + (_nr))
+#define S5P6440_GPN(_nr)       (S5P6440_GPIO_N_START + (_nr))
+#define S5P6440_GPP(_nr)       (S5P6440_GPIO_P_START + (_nr))
+#define S5P6440_GPR(_nr)       (S5P6440_GPIO_R_START + (_nr))
+
+#define S5P6450_GPA(_nr)       (S5P6450_GPIO_A_START + (_nr))
+#define S5P6450_GPB(_nr)       (S5P6450_GPIO_B_START + (_nr))
+#define S5P6450_GPC(_nr)       (S5P6450_GPIO_C_START + (_nr))
+#define S5P6450_GPD(_nr)       (S5P6450_GPIO_D_START + (_nr))
+#define S5P6450_GPF(_nr)       (S5P6450_GPIO_F_START + (_nr))
+#define S5P6450_GPG(_nr)       (S5P6450_GPIO_G_START + (_nr))
+#define S5P6450_GPH(_nr)       (S5P6450_GPIO_H_START + (_nr))
+#define S5P6450_GPI(_nr)       (S5P6450_GPIO_I_START + (_nr))
+#define S5P6450_GPJ(_nr)       (S5P6450_GPIO_J_START + (_nr))
+#define S5P6450_GPK(_nr)       (S5P6450_GPIO_K_START + (_nr))
+#define S5P6450_GPN(_nr)       (S5P6450_GPIO_N_START + (_nr))
+#define S5P6450_GPP(_nr)       (S5P6450_GPIO_P_START + (_nr))
+#define S5P6450_GPQ(_nr)       (S5P6450_GPIO_Q_START + (_nr))
+#define S5P6450_GPR(_nr)       (S5P6450_GPIO_R_START + (_nr))
+#define S5P6450_GPS(_nr)       (S5P6450_GPIO_S_START + (_nr))
+
+/* the end of the S5P64X0 specific gpios */
+
+#define S5P6440_GPIO_END       (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
+#define S5P6450_GPIO_END       (S5P6450_GPS(S5P6450_GPIO_S_NR) + 1)
+
+#define S5P64X0_GPIO_END       (S5P6440_GPIO_END > S5P6450_GPIO_END ?  \
+                                S5P6440_GPIO_END : S5P6450_GPIO_END)
+
+#define S3C_GPIO_END           S5P64X0_GPIO_END
+
+/* define the number of gpios we need to the one after the last GPIO range */
+
+#define ARCH_NR_GPIOS          (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
similarity index 67%
rename from arch/arm/mach-s5p6440/include/mach/hardware.h
rename to arch/arm/mach-s5p64x0/include/mach/hardware.h
index be8b26e875db5fb51211b676a34e4cb1448f2cbc..d3e87996dd9a752db134b0f790fe9fda94673933 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/hardware.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - Hardware support
+ * S5P64X0 - Hardware support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/i2c.h b/arch/arm/mach-s5p64x0/include/mach/i2c.h
new file mode 100644 (file)
index 0000000..887d252
--- /dev/null
@@ -0,0 +1,17 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/i2c.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 I2C configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s5p6440_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6440_i2c1_cfg_gpio(struct platform_device *dev);
+
+extern void s5p6450_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6450_i2c1_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h
new file mode 100644 (file)
index 0000000..a3e095c
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/io.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5P64X0 based
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
similarity index 71%
rename from arch/arm/mach-s5p6440/include/mach/irqs.h
rename to arch/arm/mach-s5p64x0/include/mach/irqs.h
index 16a761270de108fd76dc9159da3f2af9dbae4600..513abffc760495a1ac1cdf69fce010682d707478 100644 (file)
@@ -1,17 +1,17 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/irqs.h
  *
- * Copyright 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - IRQ definitions
+ * S5P64X0 - IRQ definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
 
-#ifndef __ASM_ARCH_S5P_IRQS_H
-#define __ASM_ARCH_S5P_IRQS_H __FILE__
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
 
 #include <plat/irqs.h>
 
 #define IRQ_EINT0_3            S5P_IRQ_VIC0(0)
 #define IRQ_EINT4_11           S5P_IRQ_VIC0(1)
 #define IRQ_RTC_TIC            S5P_IRQ_VIC0(2)
+#define IRQ_IIS1               S5P_IRQ_VIC0(3) /* for only S5P6450 */
+#define IRQ_IIS2               S5P_IRQ_VIC0(4) /* for only S5P6450 */
 #define IRQ_IIC1               S5P_IRQ_VIC0(5)
 #define IRQ_I2SV40             S5P_IRQ_VIC0(6)
-#define IRQ_GPS                        S5P_IRQ_VIC0(7)
-#define IRQ_POST0              S5P_IRQ_VIC0(9)
+#define IRQ_GPS                        S5P_IRQ_VIC0(7) /* for only S5P6450 */
+
 #define IRQ_2D                 S5P_IRQ_VIC0(11)
 #define IRQ_TIMER0_VIC         S5P_IRQ_VIC0(23)
 #define IRQ_TIMER1_VIC         S5P_IRQ_VIC0(24)
 
 #define IRQ_EINT12_15          S5P_IRQ_VIC1(0)
 #define IRQ_PCM0               S5P_IRQ_VIC1(2)
+#define IRQ_PCM1               S5P_IRQ_VIC1(3) /* for only S5P6450 */
+#define IRQ_PCM2               S5P_IRQ_VIC1(4) /* for only S5P6450 */
 #define IRQ_UART0              S5P_IRQ_VIC1(5)
 #define IRQ_UART1              S5P_IRQ_VIC1(6)
 #define IRQ_UART2              S5P_IRQ_VIC1(7)
 #define IRQ_UART3              S5P_IRQ_VIC1(8)
 #define IRQ_DMA0               S5P_IRQ_VIC1(9)
+#define IRQ_UART4              S5P_IRQ_VIC1(10)        /* S5P6450 */
+#define IRQ_UART5              S5P_IRQ_VIC1(11)        /* S5P6450 */
 #define IRQ_NFC                        S5P_IRQ_VIC1(13)
+#define IRQ_USI                        S5P_IRQ_VIC1(15)        /* S5P6450 */
 #define IRQ_SPI0               S5P_IRQ_VIC1(16)
 #define IRQ_SPI1               S5P_IRQ_VIC1(17)
+#define IRQ_HSMMC2             S5P_IRQ_VIC1(17)        /* Shared */
 #define IRQ_IIC                        S5P_IRQ_VIC1(18)
 #define IRQ_DISPCON3           S5P_IRQ_VIC1(19)
-#define IRQ_FIMGVG             S5P_IRQ_VIC1(20)
 #define IRQ_EINT_GROUPS                S5P_IRQ_VIC1(21)
-#define IRQ_PMU                        S5P_IRQ_VIC1(23)
+#define IRQ_PMU                        S5P_IRQ_VIC1(23)        /* S5P6440 */
 #define IRQ_HSMMC0             S5P_IRQ_VIC1(24)
 #define IRQ_HSMMC1             S5P_IRQ_VIC1(25)
-#define IRQ_HSMMC2             IRQ_SPI1        /* shared with SPI1 */
 #define IRQ_OTG                        S5P_IRQ_VIC1(26)
 #define IRQ_DSI                        S5P_IRQ_VIC1(27)
 #define IRQ_RTC_ALARM          S5P_IRQ_VIC1(28)
 #define IRQ_TC                 IRQ_PENDN
 #define IRQ_ADC                        S5P_IRQ_VIC1(31)
 
+/* UART interrupts, S5P6450 has 5 UARTs */
+#define IRQ_S5P_UART_BASE4     (96)
+#define IRQ_S5P_UART_BASE5     (100)
+
+#define IRQ_S5P_UART_RX4       (IRQ_S5P_UART_BASE4 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX4       (IRQ_S5P_UART_BASE4 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR4      (IRQ_S5P_UART_BASE4 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX5       (IRQ_S5P_UART_BASE5 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX5       (IRQ_S5P_UART_BASE5 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR5      (IRQ_S5P_UART_BASE5 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX4                IRQ_S5P_UART_RX4
+#define IRQ_S3CUART_RX5                IRQ_S5P_UART_RX5
+
+/* S5P6450 EINT feature will be added */
+
 /*
  * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined
  * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place
 
 #define NR_IRQS                        (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
 
-#endif /* __ASM_ARCH_S5P_IRQS_H */
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
new file mode 100644 (file)
index 0000000..31e5341
--- /dev/null
@@ -0,0 +1,83 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/map.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P64X0_PA_SDRAM       (0x20000000)
+
+#define S5P64X0_PA_CHIPID      (0xE0000000)
+#define S5P_PA_CHIPID          S5P64X0_PA_CHIPID
+
+#define S5P64X0_PA_SYSCON      (0xE0100000)
+#define S5P_PA_SYSCON          S5P64X0_PA_SYSCON
+
+#define S5P64X0_PA_GPIO                (0xE0308000)
+
+#define S5P64X0_PA_VIC0                (0xE4000000)
+#define S5P64X0_PA_VIC1                (0xE4100000)
+
+#define S5P64X0_PA_PDMA                (0xE9000000)
+
+#define S5P64X0_PA_TIMER       (0xEA000000)
+#define S5P_PA_TIMER           S5P64X0_PA_TIMER
+
+#define S5P64X0_PA_RTC         (0xEA100000)
+
+#define S5P64X0_PA_WDT         (0xEA200000)
+
+#define S5P6440_PA_UART(x)     (0xEC000000 + ((x) * S3C_UART_OFFSET))
+#define S5P6450_PA_UART(x)     ((x < 5) ? (0xEC800000 + ((x) * S3C_UART_OFFSET)) : (0xEC000000))
+
+#define S5P_PA_UART0           S5P6450_PA_UART(0)
+#define S5P_PA_UART1           S5P6450_PA_UART(1)
+#define S5P_PA_UART2           S5P6450_PA_UART(2)
+#define S5P_PA_UART3           S5P6450_PA_UART(3)
+#define S5P_PA_UART4           S5P6450_PA_UART(4)
+#define S5P_PA_UART5           S5P6450_PA_UART(5)
+
+#define S5P_SZ_UART            SZ_256
+
+#define S5P6440_PA_IIC0                (0xEC104000)
+#define S5P6440_PA_IIC1                (0xEC20F000)
+#define S5P6450_PA_IIC0                (0xEC100000)
+#define S5P6450_PA_IIC1                (0xEC200000)
+
+#define S5P64X0_PA_SPI0                (0xEC400000)
+#define S5P64X0_PA_SPI1                (0xEC500000)
+
+#define S5P64X0_PA_HSOTG       (0xED100000)
+
+#define S5P64X0_PA_HSMMC(x)    (0xED800000 + ((x) * 0x100000))
+
+#define S5P64X0_PA_I2S         (0xF2000000)
+
+#define S5P64X0_PA_PCM         (0xF2100000)
+
+#define S5P64X0_PA_ADC         (0xF3000000)
+
+/* compatibiltiy defines. */
+
+#define S3C_PA_HSMMC0          S5P64X0_PA_HSMMC(0)
+#define S3C_PA_HSMMC1          S5P64X0_PA_HSMMC(1)
+#define S3C_PA_HSMMC2          S5P64X0_PA_HSMMC(2)
+#define S3C_PA_IIC             S5P6440_PA_IIC0
+#define S3C_PA_IIC1            S5P6440_PA_IIC1
+#define S3C_PA_RTC             S5P64X0_PA_RTC
+#define S3C_PA_WDT             S5P64X0_PA_WDT
+
+#define SAMSUNG_PA_ADC         S5P64X0_PA_ADC
+
+#endif /* __ASM_ARCH_MAP_H */
similarity index 55%
rename from arch/arm/mach-s5p6440/include/mach/memory.h
rename to arch/arm/mach-s5p64x0/include/mach/memory.h
index d62910c71b566af0b5214a9eb426b55572eb541f..1b036b0a24cee858c35676e0609e744c56e3381b 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/memory.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - Memory definitions
+ * S5P64X0 - Memory definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,9 +11,9 @@
 */
 
 #ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H __FILE__
 
-#define PHYS_OFFSET            UL(0x20000000)
+#define PHYS_OFFSET            UL(0x20000000)
 #define CONSISTENT_DMA_SIZE    SZ_8M
 
 #endif /* __ASM_ARCH_MEMORY_H */
similarity index 86%
rename from arch/arm/mach-s5p6440/include/mach/pwm-clock.h
rename to arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
index 6a2a02fdf12a23df33ce6783c7a7181923348ddb..19fff8b701c0bf73126c93d9f1c33d6676a0b5ae 100644 (file)
@@ -1,16 +1,14 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
  *      http://armlinux.simtec.co.uk/
  *
- * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
- *
- * S5P6440 - pwm clock and timer support
+ * S5P64X0 - pwm clock and timer support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..58e1bc8
--- /dev/null
@@ -0,0 +1,63 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)                  (S3C_VA_SYS + (x))
+
+#define S5P64X0_APLL_CON               S5P_CLKREG(0x0C)
+#define S5P64X0_MPLL_CON               S5P_CLKREG(0x10)
+#define S5P64X0_EPLL_CON               S5P_CLKREG(0x14)
+#define S5P64X0_EPLL_CON_K             S5P_CLKREG(0x18)
+
+#define S5P64X0_CLK_SRC0               S5P_CLKREG(0x1C)
+
+#define S5P64X0_CLK_DIV0               S5P_CLKREG(0x20)
+#define S5P64X0_CLK_DIV1               S5P_CLKREG(0x24)
+#define S5P64X0_CLK_DIV2               S5P_CLKREG(0x28)
+
+#define S5P64X0_CLK_GATE_HCLK0         S5P_CLKREG(0x30)
+#define S5P64X0_CLK_GATE_PCLK          S5P_CLKREG(0x34)
+#define S5P64X0_CLK_GATE_SCLK0         S5P_CLKREG(0x38)
+#define S5P64X0_CLK_GATE_MEM0          S5P_CLKREG(0x3C)
+
+#define S5P64X0_CLK_DIV3               S5P_CLKREG(0x40)
+
+#define S5P64X0_CLK_GATE_HCLK1         S5P_CLKREG(0x44)
+#define S5P64X0_CLK_GATE_SCLK1         S5P_CLKREG(0x48)
+
+#define S5P6450_DPLL_CON               S5P_CLKREG(0x50)
+#define S5P6450_DPLL_CON_K             S5P_CLKREG(0x54)
+
+#define S5P64X0_CLK_SRC1               S5P_CLKREG(0x10C)
+
+#define S5P64X0_SYS_ID                 S5P_CLKREG(0x118)
+#define S5P64X0_SYS_OTHERS             S5P_CLKREG(0x11C)
+
+#define S5P64X0_PWR_CFG                        S5P_CLKREG(0x804)
+#define S5P64X0_OTHERS                 S5P_CLKREG(0x900)
+
+#define S5P64X0_CLKDIV0_HCLK_SHIFT     (8)
+#define S5P64X0_CLKDIV0_HCLK_MASK      (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
+
+#define S5P64X0_OTHERS_USB_SIG_MASK    (1 << 16)
+
+/* Compatibility defines */
+
+#define ARM_CLK_DIV                    S5P64X0_CLK_DIV0
+#define ARM_DIV_RATIO_SHIFT            0
+#define ARM_DIV_MASK                   (0xF << ARM_DIV_RATIO_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
similarity index 79%
rename from arch/arm/mach-s5p6440/include/mach/regs-gpio.h
rename to arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 82ff753913da73ccdc77f5dd2c6ebd4f560ffc3f..85f448e20a8b22cc537f3c844ac16e0612418f4f 100644 (file)
@@ -1,21 +1,24 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - GPIO register definitions
+ * S5P64X0 - GPIO register definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- */
+*/
 
 #ifndef __ASM_ARCH_REGS_GPIO_H
 #define __ASM_ARCH_REGS_GPIO_H __FILE__
 
 #include <mach/map.h>
 
+/* Will be implemented S5P6442 GPIOlib */
+
 /* Base addresses for each of the banks */
+
 #define S5P6440_GPA_BASE               (S5P_VA_GPIO + 0x0000)
 #define S5P6440_GPB_BASE               (S5P_VA_GPIO + 0x0020)
 #define S5P6440_GPC_BASE               (S5P_VA_GPIO + 0x0040)
@@ -27,6 +30,7 @@
 #define S5P6440_GPN_BASE               (S5P_VA_GPIO + 0x0830)
 #define S5P6440_GPP_BASE               (S5P_VA_GPIO + 0x0160)
 #define S5P6440_GPR_BASE               (S5P_VA_GPIO + 0x0290)
+
 #define S5P6440_EINT0CON0              (S5P_VA_GPIO + 0x900)
 #define S5P6440_EINT0FLTCON0           (S5P_VA_GPIO + 0x910)
 #define S5P6440_EINT0FLTCON1           (S5P_VA_GPIO + 0x914)
 #define S5P6440_EINT0PEND              (S5P_VA_GPIO + 0x924)
 
 /* for LCD */
+
 #define S5P6440_SPCON_LCD_SEL_RGB      (1 << 0)
 #define S5P6440_SPCON_LCD_SEL_MASK     (3 << 0)
 
-/* These set of macros are not really useful for the
- * GPF/GPI/GPJ/GPN/GPP,
- * useful for others set of GPIO's (4 bit)
+/*
+ * These set of macros are not really useful for the
+ * GPF/GPI/GPJ/GPN/GPP, useful for others set of GPIO's (4 bit)
  */
+
 #define S5P6440_GPIO_CONMASK(__gpio)   (0xf << ((__gpio) * 4))
 #define S5P6440_GPIO_INPUT(__gpio)     (0x0 << ((__gpio) * 4))
 #define S5P6440_GPIO_OUTPUT(__gpio)    (0x1 << ((__gpio) * 4))
 
-/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
- * */
+/*
+ * Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
+ */
+
 #define S5P6440_GPIO2_CONMASK(__gpio)  (0x3 << ((__gpio) * 2))
 #define S5P6440_GPIO2_INPUT(__gpio)    (0x0 << ((__gpio) * 2))
 #define S5P6440_GPIO2_OUTPUT(__gpio)   (0x1 << ((__gpio) * 2))
similarity index 66%
rename from arch/arm/mach-s5p6440/include/mach/regs-irq.h
rename to arch/arm/mach-s5p64x0/include/mach/regs-irq.h
index a961f4beeb0c2b3c0785c6cbdf4135e6803cd10d..4aaebdace55f9fe5b3cb86cd3bbf2e441f08391d 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - IRQ register definitions
+ * S5P64X0 - IRQ register definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
new file mode 100644 (file)
index 0000000..ff85b4b
--- /dev/null
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for s5p64x0 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clksrc_clk clk_mout_apll;
+extern struct clksrc_clk clk_mout_mpll;
+extern struct clksrc_clk clk_mout_epll;
+
+extern int s5p64x0_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p64x0_epll_get_rate(struct clk *clk);
+
+extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk);
+extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate);
+extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate);
+
+extern struct clk_ops s5p64x0_clkarm_ops;
+
+extern struct clksrc_clk clk_armclk;
+extern struct clksrc_clk clk_dout_mpll;
+
+extern struct clk *clkset_hclk_low_list[];
+extern struct clksrc_sources clkset_hclk_low;
+
+extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_mem_ctrl(struct clk *clk, int enable);
+
+extern int s5p64x0_clk48m_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
new file mode 100644 (file)
index 0000000..170a20a
--- /dev/null
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPI_CLKS_H
+#define __ASM_ARCH_SPI_CLKS_H __FILE__
+
+#define S5P64X0_SPI_SRCCLK_PCLK                0
+#define S5P64X0_SPI_SRCCLK_SCLK                1
+
+#endif /* __ASM_ARCH_SPI_CLKS_H */
similarity index 69%
rename from arch/arm/mach-s5p6440/include/mach/system.h
rename to arch/arm/mach-s5p64x0/include/mach/system.h
index a359ee3fa51083b6b0314e67b16506e522ec2398..60f57532c970eca7f1c140156bcbbc2de069bb5a 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/system.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/system.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - system support header
+ * S5P64X0 - system support header
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
similarity index 60%
rename from arch/arm/mach-s5p6440/include/mach/tick.h
rename to arch/arm/mach-s5p64x0/include/mach/tick.h
index 2f25c7f079700bbe8c268ac65533cfbfe7388d35..00aa7f1d8e51c803e16a970df1f8b1d6b5322d6b 100644 (file)
@@ -1,9 +1,14 @@
-/* linux/arch/arm/mach-s5p6440/include/mach/tick.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/tick.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
- * S5P6440 - Timer tick support definitions
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P64X0 - Timer tick support definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
similarity index 80%
rename from arch/arm/mach-s5p6440/include/mach/timex.h
rename to arch/arm/mach-s5p64x0/include/mach/timex.h
index fb2e8cd4082931255fa4df5dad45a23d4939b002..4b91faa195a85546d03f68e3c97d1dfdc7f7903f 100644 (file)
@@ -1,9 +1,12 @@
-/* arch/arm/mach-s3c64xx/include/mach/timex.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * Copyright (c) 2003-2005 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C6400 - time parameters
+ * S5P64X0 - time parameters
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..c65b229
--- /dev/null
@@ -0,0 +1,212 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+
+/*
+ * cannot use commonly <plat/uncompress.h>
+ * because uart base of S5P6440 and S5P6450 is different
+ */
+
+typedef unsigned int upf_t;    /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+static unsigned int fifo_mask;
+static unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX        (14)
+
+static unsigned long uart_base;
+
+static __inline__ void get_uart_base(void)
+{
+       unsigned int chipid;
+
+       chipid = *(const volatile unsigned int __force *) 0xE0100118;
+
+       uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
+
+       if ((chipid & 0xff000) == 0x50000)
+               uart_base += 0xEC800000;
+       else
+               uart_base += 0xEC000000;
+}
+
+static __inline__ void uart_wr(unsigned int reg, unsigned int val)
+{
+       volatile unsigned int *ptr;
+
+       get_uart_base();
+       ptr = (volatile unsigned int *)(reg + uart_base);
+       *ptr = val;
+}
+
+static __inline__ unsigned int uart_rd(unsigned int reg)
+{
+       volatile unsigned int *ptr;
+
+       get_uart_base();
+       ptr = (volatile unsigned int *)(reg + uart_base);
+       return *ptr;
+}
+
+/*
+ * we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+ */
+
+static void putc(int ch)
+{
+       if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+               int level;
+
+               while (1) {
+                       level = uart_rd(S3C2410_UFSTAT);
+                       level &= fifo_mask;
+
+                       if (level < fifo_max)
+                               break;
+               }
+
+       } else {
+               /* not using fifos */
+
+               while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+                       barrier();
+       }
+
+       /* write byte to transmission register */
+       uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad)                    \
+       do {                                                    \
+               *((volatile unsigned int __force *)(ad)) = (d); \
+       } while (0)
+
+/*
+ * CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+ */
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+       __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+       putstr("\n\n");
+       putstr(x);
+       putstr("\n\n -- System resetting\n");
+
+       __raw_writel(0x4000, S3C2410_WTDAT);
+       __raw_writel(0x4000, S3C2410_WTCNT);
+       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+       while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+       u32 fifocon = uart_rd(S3C2410_UFCON);
+
+       if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+               fifocon |= S3C2410_UFCON_RESETBOTH;
+               uart_wr(S3C2410_UFCON, fifocon);
+
+               /* wait for fifo reset to complete */
+               while (1) {
+                       fifocon = uart_rd(S3C2410_UFCON);
+                       if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+                               break;
+               }
+       }
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+static void arch_decomp_setup(void)
+{
+       /*
+        * we may need to setup the uart(s) here if we are not running
+        * on an BAST... the BAST will have left the uarts configured
+        * after calling linux.
+        */
+
+       arch_detect_cpu();
+       arch_decomp_wdog_start();
+
+       /*
+        * Enable the UART FIFOs if they where not enabled and our
+        * configuration says we should turn them on.
+        */
+
+       arch_enable_uart_fifo();
+}
+
+
+
+static void arch_detect_cpu(void)
+{
+       /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
similarity index 74%
rename from arch/arm/mach-s5p6440/include/mach/vmalloc.h
rename to arch/arm/mach-s5p64x0/include/mach/vmalloc.h
index e3f0eebf5205b592724f9de4b5cd5fda2670396c..97a9df38f1cf5ef2438cce77a77f95c5cfad88c7 100644 (file)
@@ -1,4 +1,7 @@
-/* arch/arm/mach-s5p6440/include/mach/vmalloc.h
+/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
  *
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
new file mode 100644 (file)
index 0000000..79833ca
--- /dev/null
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-s5p64x0/init.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - Init support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
+       [0] = {
+               .name           = "pclk_low",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       },
+       [1] = {
+               .name           = "uclk1",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       },
+};
+
+/* uart registration process */
+
+void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       struct s3c2410_uartcfg *tcfg = cfg;
+       u32 ucnt;
+
+       for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+               if (!tcfg->clocks) {
+                       tcfg->clocks = s5p64x0_serial_clocks;
+                       tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
+               }
+       }
+}
+
+void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       int uart;
+
+       for (uart = 0; uart < no; uart++) {
+               s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
+               s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
+       }
+
+       s5p64x0_common_init_uarts(cfg, no);
+       s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
+
+void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s5p64x0_common_init_uarts(cfg, no);
+       s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
similarity index 66%
rename from arch/arm/mach-s5p6440/mach-smdk6440.c
rename to arch/arm/mach-s5p64x0/mach-smdk6440.c
index 9202aaac3b566d5f41f39fcc27ebcda01c007285..28de0a57208c23599887f8d15513d180d1d5fe08 100644 (file)
@@ -1,7 +1,7 @@
-/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6440.c
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
 
 #include <mach/hardware.h>
 #include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
 
 #include <plat/regs-serial.h>
-
+#include <plat/gpio-cfg.h>
 #include <plat/s5p6440.h>
 #include <plat/clock.h>
-#include <mach/regs-clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/iic.h>
 
 static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
        [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = SMDK6440_UCON_DEFAULT,
-               .ulcon       = SMDK6440_ULCON_DEFAULT,
-               .ufcon       = SMDK6440_UFCON_DEFAULT,
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = SMDK6440_UCON_DEFAULT,
+               .ulcon          = SMDK6440_ULCON_DEFAULT,
+               .ufcon          = SMDK6440_UFCON_DEFAULT,
        },
        [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = SMDK6440_UCON_DEFAULT,
-               .ulcon       = SMDK6440_ULCON_DEFAULT,
-               .ufcon       = SMDK6440_UFCON_DEFAULT,
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = SMDK6440_UCON_DEFAULT,
+               .ulcon          = SMDK6440_ULCON_DEFAULT,
+               .ufcon          = SMDK6440_UFCON_DEFAULT,
        },
        [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = SMDK6440_UCON_DEFAULT,
-               .ulcon       = SMDK6440_ULCON_DEFAULT,
-               .ufcon       = SMDK6440_UFCON_DEFAULT,
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = SMDK6440_UCON_DEFAULT,
+               .ulcon          = SMDK6440_ULCON_DEFAULT,
+               .ufcon          = SMDK6440_UFCON_DEFAULT,
        },
        [3] = {
-               .hwport      = 3,
-               .flags       = 0,
-               .ucon        = SMDK6440_UCON_DEFAULT,
-               .ulcon       = SMDK6440_ULCON_DEFAULT,
-               .ufcon       = SMDK6440_UFCON_DEFAULT,
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = SMDK6440_UCON_DEFAULT,
+               .ulcon          = SMDK6440_ULCON_DEFAULT,
+               .ufcon          = SMDK6440_UFCON_DEFAULT,
        },
 };
 
 static struct platform_device *smdk6440_devices[] __initdata = {
-       &s5p6440_device_iis,
        &s3c_device_adc,
        &s3c_device_rtc,
        &s3c_device_i2c0,
        &s3c_device_i2c1,
        &s3c_device_ts,
        &s3c_device_wdt,
+       &s5p6440_device_iis,
+};
+
+static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+       .cfg_gpio       = s5p6440_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
+       .flags          = 0,
+       .bus_num        = 1,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+       .cfg_gpio       = s5p6440_i2c1_cfg_gpio,
 };
 
 static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
@@ -113,7 +131,7 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
 
 static void __init smdk6440_map_io(void)
 {
-       s5p_init_io(NULL, 0, S5P_SYS_ID);
+       s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
 }
@@ -122,9 +140,8 @@ static void __init smdk6440_machine_init(void)
 {
        s3c24xx_ts_set_platdata(&s3c_ts_platform);
 
-       /* I2C */
-       s3c_i2c0_set_platdata(NULL);
-       s3c_i2c1_set_platdata(NULL);
+       s3c_i2c0_set_platdata(&s5p6440_i2c0_data);
+       s3c_i2c1_set_platdata(&s5p6440_i2c1_data);
        i2c_register_board_info(0, smdk6440_i2c_devs0,
                        ARRAY_SIZE(smdk6440_i2c_devs0));
        i2c_register_board_info(1, smdk6440_i2c_devs1,
@@ -135,9 +152,9 @@ static void __init smdk6440_machine_init(void)
 
 MACHINE_START(SMDK6440, "SMDK6440")
        /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       .phys_io        = S3C_PA_UART & 0xfff00000,
+       .phys_io        = S5P6440_PA_UART(0) & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S5P_PA_SDRAM + 0x100,
+       .boot_params    = S5P64X0_PA_SDRAM + 0x100,
 
        .init_irq       = s5p6440_init_irq,
        .map_io         = smdk6440_map_io,
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
new file mode 100644 (file)
index 0000000..8e98217
--- /dev/null
@@ -0,0 +1,182 @@
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
+
+#include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s5p6450.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/pll.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+
+#define SMDK6450_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
+                               S3C2410_UCON_RXILEVEL |         \
+                               S3C2410_UCON_TXIRQMODE |        \
+                               S3C2410_UCON_RXIRQMODE |        \
+                               S3C2410_UCON_RXFIFO_TOI |       \
+                               S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK6450_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK6450_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
+                               S3C2440_UFCON_TXTRIG16 |        \
+                               S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+       [4] = {
+               .hwport         = 4,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+#endif
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+       [5] = {
+               .hwport         = 5,
+               .flags          = 0,
+               .ucon           = SMDK6450_UCON_DEFAULT,
+               .ulcon          = SMDK6450_ULCON_DEFAULT,
+               .ufcon          = SMDK6450_UFCON_DEFAULT,
+       },
+#endif
+};
+
+static struct platform_device *smdk6450_devices[] __initdata = {
+       &s3c_device_adc,
+       &s3c_device_rtc,
+       &s3c_device_i2c0,
+       &s3c_device_i2c1,
+       &s3c_device_ts,
+       &s3c_device_wdt,
+       &s5p6450_device_iis0,
+       /* s5p6450_device_spi0 will be added */
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+       .cfg_gpio       = s5p6450_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
+       .flags          = 0,
+       .bus_num        = 1,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+       .cfg_gpio       = s5p6450_i2c1_cfg_gpio,
+};
+
+static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
+       { I2C_BOARD_INFO("24c08", 0x50), },     /* Samsung KS24C080C EEPROM */
+};
+
+static struct i2c_board_info smdk6450_i2c_devs1[] __initdata = {
+       { I2C_BOARD_INFO("24c128", 0x57), },/* Samsung S524AD0XD1 EEPROM */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+       .delay                  = 10000,
+       .presc                  = 49,
+       .oversampling_shift     = 2,
+};
+
+static void __init smdk6450_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+       s3c24xx_init_clocks(19200000);
+       s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
+}
+
+static void __init smdk6450_machine_init(void)
+{
+       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+       s3c_i2c0_set_platdata(&s5p6450_i2c0_data);
+       s3c_i2c1_set_platdata(&s5p6450_i2c1_data);
+       i2c_register_board_info(0, smdk6450_i2c_devs0,
+                       ARRAY_SIZE(smdk6450_i2c_devs0));
+       i2c_register_board_info(1, smdk6450_i2c_devs1,
+                       ARRAY_SIZE(smdk6450_i2c_devs1));
+
+       platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
+}
+
+MACHINE_START(SMDK6450, "SMDK6450")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .phys_io        = S5P6450_PA_UART(0) & 0xfff00000,
+       .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S5P64X0_PA_SDRAM + 0x100,
+
+       .init_irq       = s5p6450_init_irq,
+       .map_io         = smdk6450_map_io,
+       .init_machine   = smdk6450_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
similarity index 52%
rename from arch/arm/mach-s5p6440/setup-i2c0.c
rename to arch/arm/mach-s5p64x0/setup-i2c0.c
index 2c99d14f7ac7bd55cccd8adc42eccfffdde600d8..dc4cc65a5019c3ba74321dc3fd78247003df6cae 100644 (file)
@@ -1,11 +1,11 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c0.c
+/* linux/arch/arm/mach-s5p64x0/setup-i2c0.c
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * I2C0 GPIO configuration.
  *
- * Based on plat-s3c64xx/setup-i2c0.c
+ * Based on plat-s3c64x0/setup-i2c0.c
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/gpio.h>
 
 struct platform_device; /* don't need the contents */
 
-#include <linux/gpio.h>
 #include <plat/gpio-cfg.h>
 #include <plat/iic.h>
 
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+#include <mach/i2c.h>
+
+void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
 {
        s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2));
        s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP);
        s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
        s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
 }
+
+void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
similarity index 55%
rename from arch/arm/mach-s5p6440/setup-i2c1.c
rename to arch/arm/mach-s5p64x0/setup-i2c1.c
index 9a1537f786e0e793f2dfbaf4fa60286cf9cbb364..2edd7912f8e405afa674b17d02e0f6a93d1ea04d 100644 (file)
@@ -1,7 +1,7 @@
-/* linux/arch/arm/mach-s5p6440/setup-i2c1.c
+/* linux/arch/arm/mach-s5p64xx/setup-i2c1.c
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * I2C1 GPIO configuration.
  *
@@ -21,10 +21,22 @@ struct platform_device; /* don't need the contents */
 #include <plat/gpio-cfg.h>
 #include <plat/iic.h>
 
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+#include <mach/i2c.h>
+
+void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
 {
        s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6));
        s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP);
        s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
        s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
 }
+
+void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6));
+       s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
+       s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
index 251c92ac5b227e05a28251ed7b890ff1f84eccfb..fd2708e7d8a9f4aa61bf645abad7f644149720e7 100644 (file)
@@ -1,4 +1,7 @@
 /* linux/arch/arm/mach-s5pc100/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * Copyright 2009 Samsung Electronics Co.
  *     Byungho Min <bhmin@samsung.com>
@@ -21,6 +24,7 @@
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -55,11 +59,31 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(S5PC100_PA_SYSTIMER),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .pfn            = __phys_to_pfn(S5PC100_PA_GPIO),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC0,
+               .pfn            = __phys_to_pfn(S5PC100_PA_VIC0),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC1,
+               .pfn            = __phys_to_pfn(S5PC100_PA_VIC1),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)VA_VIC2,
-               .pfn            = __phys_to_pfn(S5P_PA_VIC2),
+               .pfn            = __phys_to_pfn(S5PC100_PA_VIC2),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S3C_PA_UART),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5PC100_VA_OTHERS,
                .pfn            = __phys_to_pfn(S5PC100_PA_OTHERS),
index 01b9134feff0d055fd33418f7b07bc68c000b885..8751ef4a6804d481d3f1d4ae2c5842dd88f4635a 100644 (file)
 #define S5PC100_PA_OTHERS      (0xE0200000)
 #define S5PC100_VA_OTHERS      (S3C_VA_SYS + 0x10000)
 
-#define S5P_PA_GPIO            (0xE0300000)
+#define S5PC100_PA_GPIO                (0xE0300000)
 #define S5PC1XX_VA_GPIO                S3C_ADDR(0x00500000)
 
 /* Interrupt */
-#define S5PC100_PA_VIC         (0xE4000000)
+#define S5PC100_PA_VIC0                (0xE4000000)
+#define S5PC100_PA_VIC1                (0xE4100000)
+#define S5PC100_PA_VIC2                (0xE4200000)
 #define S5PC100_VA_VIC         S3C_VA_IRQ
-#define S5PC100_PA_VIC_OFFSET  0x100000
 #define S5PC100_VA_VIC_OFFSET  0x10000
-#define S5PC1XX_PA_VIC(x)      (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
 #define S5PC1XX_VA_VIC(x)      (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
-#define S5P_PA_VIC0            S5PC1XX_PA_VIC(0)
-#define S5P_PA_VIC1            S5PC1XX_PA_VIC(1)
-#define S5P_PA_VIC2            S5PC1XX_PA_VIC(2)
 
 
 #define S5PC100_PA_ONENAND     (0xE7100000)
index d3a38955c7418cc626e6bfea534613b090bb0262..5315fec3db86ae31df32ff0629a91e913b66a502 100644 (file)
@@ -53,11 +53,6 @@ config S5PV210_SETUP_SDHCI_GPIO
        help
          Common setup code for SDHCI gpio.
 
-config S5PC110_DEV_ONENAND
-       bool
-       help
-         Compile in platform device definition for OneNAND1 controller
-
 menu "S5PC110 Machines"
 
 config MACH_AQUILA
@@ -71,7 +66,7 @@ config MACH_AQUILA
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
-       select S5PC110_DEV_ONENAND
+       select S5P_DEV_ONENAND
        select S5PV210_SETUP_FB_24BPP
        select S5PV210_SETUP_SDHCI
        help
@@ -88,7 +83,7 @@ config MACH_GONI
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
-       select S5PC110_DEV_ONENAND
+       select S5P_DEV_ONENAND
        select S5PV210_SETUP_FB_24BPP
        select S5PV210_SETUP_SDHCI
        help
index 05048c5aa4c6e7e7e8eb94d435b9cb8c2243ddbd..7045489124082d69715df5c9f4ec62061738763b 100644 (file)
@@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_GONI)               += mach-goni.o
 
 obj-y                          += dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
-obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)   += setup-fb-24bpp.o
 obj-$(CONFIG_S5PV210_SETUP_I2C1)       += setup-i2c1.o
index af91fefef2c6c77899c4f96ffc9bed03cacee633..d562670e1b0b44005ade9644f69338de44b459bb 100644 (file)
@@ -173,11 +173,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
 }
 
-static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
-}
-
 static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
@@ -280,6 +275,24 @@ static struct clk init_clocks_disable[] = {
                .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1<<29),
+       }, {
+               .name           = "fimc",
+               .id             = 0,
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 24),
+       }, {
+               .name           = "fimc",
+               .id             = 1,
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "fimc",
+               .id             = 2,
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 26),
        }, {
                .name           = "otg",
                .id             = -1,
@@ -357,7 +370,7 @@ static struct clk init_clocks_disable[] = {
                .id             = 1,
                .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
-               .ctrlbit        = (1<<8),
+               .ctrlbit        = (1 << 10),
        }, {
                .name           = "i2c",
                .id             = 2,
index b9f4d677cf5541460747a5086fb25f5fbcea744e..2f16bfc0a116cd4bde8298b8c83ed4f076145080 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-s5pv210/cpu.c
  *
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ *             http://www.samsung.com
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/sysdev.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -47,7 +48,22 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
        {
                .virtual        = (unsigned long)S5P_VA_SYSTIMER,
                .pfn            = __phys_to_pfn(S5PV210_PA_SYSTIMER),
-               .length         = SZ_1M,
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .pfn            = __phys_to_pfn(S5PV210_PA_GPIO),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC0,
+               .pfn            = __phys_to_pfn(S5PV210_PA_VIC0),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)VA_VIC1,
+               .pfn            = __phys_to_pfn(S5PV210_PA_VIC1),
+               .length         = SZ_16K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)VA_VIC2,
@@ -59,6 +75,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(S5PV210_PA_VIC3),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S3C_PA_UART),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5P_VA_SROMC,
                .pfn            = __phys_to_pfn(S5PV210_PA_SROMC),
index dd4fb6bf14b506a463fb77de68d78baa85c41106..bd9afd52466ad2cb787ed90ba394cc1f73870cb0 100644 (file)
 #include <plat/map-s5p.h>
 
 #define S5PC110_PA_ONENAND     (0xB0000000)
+#define S5P_PA_ONENAND         S5PC110_PA_ONENAND
+
 #define S5PC110_PA_ONENAND_DMA (0xB0600000)
+#define S5P_PA_ONENAND_DMA     S5PC110_PA_ONENAND_DMA
 
 #define S5PV210_PA_CHIPID      (0xE0000000)
 #define S5P_PA_CHIPID          S5PV210_PA_CHIPID
@@ -26,7 +29,6 @@
 #define S5P_PA_SYSCON          S5PV210_PA_SYSCON
 
 #define S5PV210_PA_GPIO                (0xE0200000)
-#define S5P_PA_GPIO            S5PV210_PA_GPIO
 
 /* SPI */
 #define S5PV210_PA_SPI0                0xE1300000
 #define S5PV210_PA_HSMMC(x)    (0xEB000000 + ((x) * 0x100000))
 
 #define S5PV210_PA_VIC0                (0xF2000000)
-#define S5P_PA_VIC0            S5PV210_PA_VIC0
-
 #define S5PV210_PA_VIC1                (0xF2100000)
-#define S5P_PA_VIC1            S5PV210_PA_VIC1
-
 #define S5PV210_PA_VIC2                (0xF2200000)
-#define S5P_PA_VIC2            S5PV210_PA_VIC2
-
 #define S5PV210_PA_VIC3                (0xF2300000)
-#define S5P_PA_VIC3            S5PV210_PA_VIC3
 
 #define S5PV210_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5PV210_PA_SDRAM
index 0dda8012d6b22c029a6da035a19a934c6092e5e3..bf772de6b0c33c81e9148d019b59f59f863fadd0 100644 (file)
@@ -477,7 +477,7 @@ static struct platform_device *aquila_devices[] __initdata = {
        &aquila_i2c_gpio_pmic,
        &aquila_device_gpiokeys,
        &s3c_device_fb,
-       &s5pc110_device_onenand,
+       &s5p_device_onenand,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
        &s3c_device_hsmmc2,
index 53754d7d364ef513c233c5e77fcdee038e734635..fdc5cca4eb41a9acd4931293b846dba475405d28 100644 (file)
@@ -456,7 +456,7 @@ static void goni_setup_sdhci(void)
 
 static struct platform_device *goni_devices[] __initdata = {
        &s3c_device_fb,
-       &s5pc110_device_onenand,
+       &s5p_device_onenand,
        &goni_i2c_gpio_pmic,
        &goni_device_gpiokeys,
        &s5p_device_fimc0,
index e5b261a99ab2678e5860d9c0055d493137ef1e42..4add39853ff9dcf34f3e3c4aeeb25ea8e194da80 100644 (file)
@@ -31,29 +31,39 @@ extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
 /* Initial IO mappings */
 static struct map_desc s5pv310_iodesc[] __initdata = {
        {
-               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
-               .pfn            = __phys_to_pfn(S5PV310_PA_COREPERI),
-               .length         = SZ_8K,
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(S5PV310_PA_SYSRAM),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_CMU,
+               .pfn            = __phys_to_pfn(S5PV310_PA_CMU),
+               .length         = SZ_128K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
                .pfn            = __phys_to_pfn(S5PV310_PA_COMBINER),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
+               .pfn            = __phys_to_pfn(S5PV310_PA_COREPERI),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5P_VA_L2CC,
                .pfn            = __phys_to_pfn(S5PV310_PA_L2CC),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
        }, {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(S5PV310_PA_SYSRAM),
+               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .pfn            = __phys_to_pfn(S5PV310_PA_GPIO1),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
        }, {
-               .virtual        = (unsigned long)S5P_VA_CMU,
-               .pfn            = __phys_to_pfn(S5PV310_PA_CMU),
-               .length         = SZ_128K,
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S3C_PA_UART),
+               .length         = SZ_512K,
                .type           = MT_DEVICE,
        },
 };
index 4cdedda6e652b61297c877ac2c0205b81b9112ad..471fc3bb199a7a10becae92cd99fae46871ad997 100644 (file)
@@ -68,6 +68,8 @@
 
 #define IRQ_IIC                        COMBINER_IRQ(27, 0)
 
+#define IRQ_ONENAND_AUDI       COMBINER_IRQ(34, 0)
+
 /* Set the default NR_IRQS */
 
 #define NR_IRQS                        COMBINER_IRQ(MAX_COMBINER_NR, 0)
index 213e1101a3b325b60ada7c5bc5014035c1d8e74b..aff6d23624bb6d457e118ee7381a004a79968ceb 100644 (file)
 
 #define S5PV310_PA_SYSRAM              (0x02025000)
 
+#define S5PC210_PA_ONENAND             (0x0C000000)
+#define S5P_PA_ONENAND                 S5PC210_PA_ONENAND
+
+#define S5PC210_PA_ONENAND_DMA         (0x0C600000)
+#define S5P_PA_ONENAND_DMA             S5PC210_PA_ONENAND_DMA
+
 #define S5PV310_PA_CHIPID              (0x10000000)
 #define S5P_PA_CHIPID                  S5PV310_PA_CHIPID
 
@@ -46,7 +52,6 @@
 #define S5PV310_PA_GPIO1               (0x11400000)
 #define S5PV310_PA_GPIO2               (0x11000000)
 #define S5PV310_PA_GPIO3               (0x03860000)
-#define S5P_PA_GPIO                    S5PV310_PA_GPIO1
 
 #define S5PV310_PA_HSMMC(x)            (0x12510000 + ((x) * 0x10000))
 
index f6c6837c5451888257a86601ae8031a9d0a598d5..8e845b6a7cb57a3f74b9f00c16ba12b2bc0dd6f9 100644 (file)
@@ -1,4 +1,4 @@
 /*
  * arch/arm/mach-shark/include/mach/vmalloc.h
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END       0xd0000000
diff --git a/arch/arm/mach-tcc8k/Kconfig b/arch/arm/mach-tcc8k/Kconfig
new file mode 100644 (file)
index 0000000..ad86415
--- /dev/null
@@ -0,0 +1,11 @@
+if ARCH_TCC8K
+
+comment "TCC8000 systems:"
+
+config MACH_TCC8000_SDK
+       bool "Telechips TCC8000-SDK development kit"
+       default y
+       help
+         Support for the Telechips TCC8000-SDK board.
+
+endif
diff --git a/arch/arm/mach-tcc8k/Makefile b/arch/arm/mach-tcc8k/Makefile
new file mode 100644 (file)
index 0000000..9bacf31
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for TCC8K boards and common files.
+#
+
+# Common support
+obj-y += clock.o irq.o time.o io.o devices.o
+
+# Board specific support
+obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o
diff --git a/arch/arm/mach-tcc8k/Makefile.boot b/arch/arm/mach-tcc8k/Makefile.boot
new file mode 100644 (file)
index 0000000..f135c9d
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y          := 0x20008000
+params_phys-y          := 0x20000100
+initrd_phys-y          := 0x20800000
diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
new file mode 100644 (file)
index 0000000..4e42555
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/clock.h>
+
+#include "common.h"
+
+#define XI_FREQUENCY   12000000
+#define XTI_FREQUENCY  32768
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND */
+static struct tcc_nand_platform_data tcc8k_sdk_nand_data = {
+       .width = 1,
+       .hw_ecc = 0,
+};
+#endif
+
+static void __init tcc8k_init(void)
+{
+#ifdef CONFIG_MTD_NAND_TCC
+       tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data;
+       platform_device_register(&tcc_nand_device);
+#endif
+}
+
+static void __init tcc8k_init_timer(void)
+{
+       tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY);
+}
+
+static struct sys_timer tcc8k_timer = {
+       .init   = tcc8k_init_timer,
+};
+
+static void __init tcc8k_map_io(void)
+{
+       tcc8k_map_common_io();
+}
+
+MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
+       .phys_io        = 0x90000000,
+       .io_pg_offst    = ((0xf1000000) >> 18) & 0xfffc,
+       .boot_params    = PHYS_OFFSET + 0x00000100,
+       .map_io         = tcc8k_map_io,
+       .init_irq       = tcc8k_init_irq,
+       .init_machine   = tcc8k_init,
+       .timer          = &tcc8k_timer,
+MACHINE_END
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
new file mode 100644 (file)
index 0000000..ba32a15
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Lowlevel clock handling for Telechips TCC8xxx SoCs
+ *
+ * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/irqs.h>
+#include <mach/tcc8k-regs.h>
+
+#include "common.h"
+
+#define BCLKCTR0       (CKC_BASE + BCLKCTR0_OFFS)
+#define BCLKCTR1       (CKC_BASE + BCLKCTR1_OFFS)
+
+#define ACLKREF                (CKC_BASE + ACLKREF_OFFS)
+#define ACLKUART0      (CKC_BASE + ACLKUART0_OFFS)
+#define ACLKUART1      (CKC_BASE + ACLKUART1_OFFS)
+#define ACLKUART2      (CKC_BASE + ACLKUART2_OFFS)
+#define ACLKUART3      (CKC_BASE + ACLKUART3_OFFS)
+#define ACLKUART4      (CKC_BASE + ACLKUART4_OFFS)
+#define ACLKI2C                (CKC_BASE + ACLKI2C_OFFS)
+#define ACLKADC                (CKC_BASE + ACLKADC_OFFS)
+#define ACLKUSBH       (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKLCD                (CKC_BASE + ACLKLCD_OFFS)
+#define ACLKSDH0       (CKC_BASE + ACLKSDH0_OFFS)
+#define ACLKSDH1       (CKC_BASE + ACLKSDH1_OFFS)
+#define ACLKSPI0       (CKC_BASE + ACLKSPI0_OFFS)
+#define ACLKSPI1       (CKC_BASE + ACLKSPI1_OFFS)
+#define ACLKSPDIF      (CKC_BASE + ACLKSPDIF_OFFS)
+#define ACLKC3DEC      (CKC_BASE + ACLKC3DEC_OFFS)
+#define ACLKCAN0       (CKC_BASE + ACLKCAN0_OFFS)
+#define ACLKCAN1       (CKC_BASE + ACLKCAN1_OFFS)
+#define ACLKGSB0       (CKC_BASE + ACLKGSB0_OFFS)
+#define ACLKGSB1       (CKC_BASE + ACLKGSB1_OFFS)
+#define ACLKGSB2       (CKC_BASE + ACLKGSB2_OFFS)
+#define ACLKGSB3       (CKC_BASE + ACLKGSB3_OFFS)
+#define ACLKUSBH       (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKTCT                (CKC_BASE + ACLKTCT_OFFS)
+#define ACLKTCX                (CKC_BASE + ACLKTCX_OFFS)
+#define ACLKTCZ                (CKC_BASE + ACLKTCZ_OFFS)
+
+/* Crystal frequencies */
+static unsigned long xi_rate, xti_rate;
+
+static void __iomem *pll_cfg_addr(int pll)
+{
+       switch (pll) {
+       case 0: return (CKC_BASE + PLL0CFG_OFFS);
+       case 1: return (CKC_BASE + PLL1CFG_OFFS);
+       case 2: return (CKC_BASE + PLL2CFG_OFFS);
+       default:
+               BUG();
+       }
+}
+
+static int pll_enable(int pll, int enable)
+{
+       u32 reg;
+       void __iomem *addr = pll_cfg_addr(pll);
+
+       reg = __raw_readl(addr);
+       if (enable)
+               reg &= ~PLLxCFG_PD;
+       else
+               reg |= PLLxCFG_PD;
+
+       __raw_writel(reg, addr);
+       return 0;
+}
+
+static int xi_enable(int enable)
+{
+       u32 reg;
+
+       reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+       if (enable)
+               reg |= CLKCTRL_XE;
+       else
+               reg &= ~CLKCTRL_XE;
+
+       __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS);
+       return 0;
+}
+
+static int root_clk_enable(enum root_clks src)
+{
+       switch (src) {
+       case CLK_SRC_PLL0: return pll_enable(0, 1);
+       case CLK_SRC_PLL1: return pll_enable(1, 1);
+       case CLK_SRC_PLL2: return pll_enable(2, 1);
+       case CLK_SRC_XI: return xi_enable(1);
+       default:
+               BUG();
+       }
+       return 0;
+}
+
+static int root_clk_disable(enum root_clks root_src)
+{
+       switch (root_src) {
+       case CLK_SRC_PLL0: return pll_enable(0, 0);
+       case CLK_SRC_PLL1: return pll_enable(1, 0);
+       case CLK_SRC_PLL2: return pll_enable(2, 0);
+       case CLK_SRC_XI: return xi_enable(0);
+       default:
+               BUG();
+       }
+       return 0;
+}
+
+static int enable_clk(struct clk *clk)
+{
+       u32 reg;
+
+       if (clk->root_id != CLK_SRC_NOROOT)
+               return root_clk_enable(clk->root_id);
+
+       if (clk->aclkreg) {
+               reg = __raw_readl(clk->aclkreg);
+               reg |= ACLK_EN;
+               __raw_writel(reg, clk->aclkreg);
+       }
+       if (clk->bclkctr) {
+               reg = __raw_readl(clk->bclkctr);
+               reg |= 1 << clk->bclk_shift;
+               __raw_writel(reg, clk->bclkctr);
+       }
+       return 0;
+}
+
+static void disable_clk(struct clk *clk)
+{
+       u32 reg;
+
+       if (clk->root_id != CLK_SRC_NOROOT) {
+               root_clk_disable(clk->root_id);
+               return;
+       }
+
+       if (clk->bclkctr) {
+               reg = __raw_readl(clk->bclkctr);
+               reg &= ~(1 << clk->bclk_shift);
+               __raw_writel(reg, clk->bclkctr);
+       }
+       if (clk->aclkreg) {
+               reg = __raw_readl(clk->aclkreg);
+               reg &= ~ACLK_EN;
+               __raw_writel(reg, clk->aclkreg);
+       }
+}
+
+static unsigned long get_rate_pll(int pll)
+{
+       u32 reg;
+       unsigned long s, m, p;
+       void __iomem *addr = pll_cfg_addr(pll);
+
+       reg = __raw_readl(addr);
+       s = (reg >> 16) & 0x07;
+       m = (reg >> 8) & 0xff;
+       p = reg & 0x3f;
+
+       return (m * xi_rate) / (p * (1 << s));
+}
+
+static unsigned long get_rate_pll_div(int pll)
+{
+       u32 reg;
+       unsigned long div = 0;
+       void __iomem *addr;
+
+       switch (pll) {
+       case 0:
+               addr = CKC_BASE + CLKDIVC0_OFFS;
+               reg = __raw_readl(addr);
+               if (reg & CLKDIVC0_P0E)
+                       div = (reg >> 24) & 0x3f;
+               break;
+       case 1:
+               addr = CKC_BASE + CLKDIVC0_OFFS;
+               reg = __raw_readl(addr);
+               if (reg & CLKDIVC0_P1E)
+                       div = (reg >> 16) & 0x3f;
+               break;
+       case 2:
+               addr = CKC_BASE + CLKDIVC1_OFFS;
+               reg = __raw_readl(addr);
+               if (reg & CLKDIVC1_P2E)
+                       div = __raw_readl(addr) & 0x3f;
+               break;
+       }
+       return get_rate_pll(pll) / (div + 1);
+}
+
+static unsigned long get_rate_xi_div(void)
+{
+       unsigned long div = 0;
+       u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+       if (reg & CLKDIVC0_XE)
+               div = (reg >> 8) & 0x3f;
+
+       return xi_rate / (div + 1);
+}
+
+static unsigned long get_rate_xti_div(void)
+{
+       unsigned long div = 0;
+       u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+       if (reg & CLKDIVC0_XTE)
+               div = reg & 0x3f;
+
+       return xti_rate / (div + 1);
+}
+
+static unsigned long root_clk_get_rate(enum root_clks src)
+{
+       switch (src) {
+       case CLK_SRC_PLL0: return get_rate_pll(0);
+       case CLK_SRC_PLL1: return get_rate_pll(1);
+       case CLK_SRC_PLL2: return get_rate_pll(2);
+       case CLK_SRC_PLL0DIV: return get_rate_pll_div(0);
+       case CLK_SRC_PLL1DIV: return get_rate_pll_div(1);
+       case CLK_SRC_PLL2DIV: return get_rate_pll_div(2);
+       case CLK_SRC_XI: return xi_rate;
+       case CLK_SRC_XTI: return xti_rate;
+       case CLK_SRC_XIDIV: return get_rate_xi_div();
+       case CLK_SRC_XTIDIV: return get_rate_xti_div();
+       default: return 0;
+       }
+}
+
+static unsigned long aclk_get_rate(struct clk *clk)
+{
+       u32 reg;
+       unsigned long div;
+       unsigned int src;
+
+       reg = __raw_readl(clk->aclkreg);
+       div = reg & 0x0fff;
+       src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK;
+       return root_clk_get_rate(src) / (div + 1);
+}
+
+static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
+{
+       unsigned long div, src, freq, r1, r2;
+
+       src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+       src &= CLK_SRC_MASK;
+       freq = root_clk_get_rate(src);
+       div = freq / rate + 1;
+       r1 = freq / div;
+       r2 = freq / (div + 1);
+       if (r2 >= rate)
+               return div + 1;
+       if ((rate - r2) < (r1 - rate))
+               return div + 1;
+
+       return div;
+}
+
+static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int src;
+
+       src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+       src &= CLK_SRC_MASK;
+
+       return root_clk_get_rate(src) / aclk_best_div(clk, rate);
+}
+
+static int aclk_set_rate(struct clk *clk, unsigned long rate)
+{
+       u32 reg;
+
+       reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
+       reg |= aclk_best_div(clk, rate);
+       return 0;
+}
+
+static unsigned long get_rate_sys(struct clk *clk)
+{
+       unsigned int src;
+
+       src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK;
+               return root_clk_get_rate(src);
+}
+
+static unsigned long get_rate_bus(struct clk *clk)
+{
+       unsigned int div;
+
+       div = (__raw_readl(CKC_BASE + CLKCTRL_OFFS) >> 4) & 0xff;
+       return get_rate_sys(clk) / (div + 1);
+}
+
+static unsigned long get_rate_cpu(struct clk *clk)
+{
+       unsigned int reg, div, fsys, fbus;
+
+       fbus = get_rate_bus(clk);
+       reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+       if (reg & (1 << 29))
+               return fbus;
+       fsys = get_rate_sys(clk);
+       div = (reg >> 16) & 0x0f;
+       return fbus + ((fsys - fbus) * (div + 1)) / 16;
+}
+
+static unsigned long get_rate_root(struct clk *clk)
+{
+       return root_clk_get_rate(clk->root_id);
+}
+
+static int aclk_set_parent(struct clk *clock, struct clk *parent)
+{
+       u32 reg;
+
+       if (clock->parent == parent)
+               return 0;
+
+       clock->parent = parent;
+
+       if (!parent)
+               return 0;
+
+       if (parent->root_id == CLK_SRC_NOROOT)
+               return 0;
+       reg = __raw_readl(clock->aclkreg);
+       reg &= ~ACLK_SEL_MASK;
+       reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK;
+       __raw_writel(reg, clock->aclkreg);
+
+       return 0;
+}
+
+#define DEFINE_ROOT_CLOCK(name, ri, p) \
+       static struct clk name = {              \
+               .root_id = ri,                  \
+               .get_rate = get_rate_root,                      \
+               .enable = enable_clk,           \
+               .disable = disable_clk,         \
+               .parent = p,                    \
+       };
+
+#define DEFINE_SPECIAL_CLOCK(name, gr, p)      \
+       static struct clk name = {              \
+               .root_id = CLK_SRC_NOROOT,      \
+               .get_rate = gr,                 \
+               .parent = p,                    \
+       };
+
+#define DEFINE_ACLOCK(name, bc, bs, ar)                \
+       static struct clk name = {              \
+               .root_id = CLK_SRC_NOROOT,      \
+               .bclkctr = bc,                  \
+               .bclk_shift = bs,               \
+               .aclkreg = ar,                  \
+               .get_rate = aclk_get_rate,      \
+               .set_rate = aclk_set_rate,      \
+               .round_rate = aclk_round_rate,  \
+               .enable = enable_clk,           \
+               .disable = disable_clk,         \
+               .set_parent = aclk_set_parent,  \
+       };
+
+#define DEFINE_BCLOCK(name, bc, bs, gr, p)     \
+       static struct clk name = {              \
+               .root_id = CLK_SRC_NOROOT,      \
+               .bclkctr = bc,                  \
+               .bclk_shift = bs,               \
+               .get_rate = gr,                 \
+               .enable = enable_clk,           \
+               .disable = disable_clk,         \
+               .parent = p,                    \
+       };
+
+DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL)
+DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL)
+DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi)
+DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti)
+DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi)
+DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi)
+DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi)
+DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0)
+DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1)
+DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2)
+
+/* The following 3 clocks are special and are initialized explicitly later */
+DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL)
+DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys)
+DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys)
+
+DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT)
+DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX)
+DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ)
+DEFINE_ACLOCK(ref, NULL, 0, ACLKREF)
+DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0)
+DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1)
+DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2)
+DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3)
+DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4)
+DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C)
+DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC)
+DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH)
+DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD)
+DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0)
+DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1)
+DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0)
+DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1)
+DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF)
+DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC)
+DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0)
+DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1)
+DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0)
+DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1)
+DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2)
+DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3)
+DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH)
+
+DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL)
+DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL)
+DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL)
+DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL)
+DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL)
+DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL)
+DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL)
+DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL)
+DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL)
+DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL)
+DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL)
+DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL)
+DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL)
+DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL)
+DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL)
+DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL)
+DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL)
+DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL)
+DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL)
+DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL)
+DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL)
+DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL)
+
+#define _REGISTER_CLOCK(d, n, c) \
+       { \
+               .dev_id = d, \
+               .con_id = n, \
+               .clk = &c, \
+       },
+
+static struct clk_lookup lookups[] = {
+       _REGISTER_CLOCK(NULL, "bus", bus)
+       _REGISTER_CLOCK(NULL, "cpu", cpu)
+       _REGISTER_CLOCK(NULL, "tct", tct)
+       _REGISTER_CLOCK(NULL, "tcx", tcx)
+       _REGISTER_CLOCK(NULL, "tcz", tcz)
+       _REGISTER_CLOCK(NULL, "ref", ref)
+       _REGISTER_CLOCK(NULL, "dai0", dai0)
+       _REGISTER_CLOCK(NULL, "pic", pic)
+       _REGISTER_CLOCK(NULL, "tc", tc)
+       _REGISTER_CLOCK(NULL, "gpio", gpio)
+       _REGISTER_CLOCK(NULL, "usbd", usbd)
+       _REGISTER_CLOCK("tcc-uart.0", NULL, uart0)
+       _REGISTER_CLOCK("tcc-uart.2", NULL, uart2)
+       _REGISTER_CLOCK("tcc-i2c", NULL, i2c)
+       _REGISTER_CLOCK("tcc-uart.3", NULL, uart3)
+       _REGISTER_CLOCK(NULL, "ecc", ecc)
+       _REGISTER_CLOCK(NULL, "adc", adc)
+       _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0)
+       _REGISTER_CLOCK(NULL, "gdma0", gdma0)
+       _REGISTER_CLOCK(NULL, "lcd", lcd)
+       _REGISTER_CLOCK(NULL, "rtc", rtc)
+       _REGISTER_CLOCK(NULL, "nfc", nfc)
+       _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0)
+       _REGISTER_CLOCK(NULL, "g2d", g2d)
+       _REGISTER_CLOCK(NULL, "gdma1", gdma1)
+       _REGISTER_CLOCK("tcc-uart.1", NULL, uart1)
+       _REGISTER_CLOCK("tcc-spi.0", NULL, spi0)
+       _REGISTER_CLOCK(NULL, "mscl", mscl)
+       _REGISTER_CLOCK("tcc-spi.1", NULL, spi1)
+       _REGISTER_CLOCK(NULL, "bdma", bdma)
+       _REGISTER_CLOCK(NULL, "adma0", adma0)
+       _REGISTER_CLOCK(NULL, "spdif", spdif)
+       _REGISTER_CLOCK(NULL, "scfg", scfg)
+       _REGISTER_CLOCK(NULL, "cid", cid)
+       _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1)
+       _REGISTER_CLOCK("tcc-uart.4", NULL, uart4)
+       _REGISTER_CLOCK(NULL, "dai1", dai1)
+       _REGISTER_CLOCK(NULL, "adma1", adma1)
+       _REGISTER_CLOCK(NULL, "c3dec", c3dec)
+       _REGISTER_CLOCK("tcc-can.0", NULL, can0)
+       _REGISTER_CLOCK("tcc-can.1", NULL, can1)
+       _REGISTER_CLOCK(NULL, "gps", gps)
+       _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0)
+       _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1)
+       _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2)
+       _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3)
+       _REGISTER_CLOCK(NULL, "gdma2", gdma2)
+       _REGISTER_CLOCK(NULL, "gdma3", gdma3)
+       _REGISTER_CLOCK(NULL, "ddrc", ddrc)
+       _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1)
+};
+
+static struct clk *root_clk_by_index(enum root_clks src)
+{
+       switch (src) {
+       case CLK_SRC_PLL0: return &pll0;
+       case CLK_SRC_PLL1: return &pll1;
+       case CLK_SRC_PLL2: return &pll2;
+       case CLK_SRC_PLL0DIV: return &pll0div;
+       case CLK_SRC_PLL1DIV: return &pll1div;
+       case CLK_SRC_PLL2DIV: return &pll2div;
+       case CLK_SRC_XI: return &xi;
+       case CLK_SRC_XTI: return &xti;
+       case CLK_SRC_XIDIV: return &xidiv;
+       case CLK_SRC_XTIDIV: return &xtidiv;
+       default: return NULL;
+       }
+}
+
+static void find_aclk_parent(struct clk *clk)
+{
+       unsigned int src;
+       struct clk *clock;
+
+       if (!clk->aclkreg)
+               return;
+
+       src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+       src &= CLK_SRC_MASK;
+
+       clock = root_clk_by_index(src);
+       if (!clock)
+               return;
+
+       clk->parent = clock;
+       clk->set_parent = aclk_set_parent;
+}
+
+void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq)
+{
+       int i;
+
+       xi_rate = xi_freq;
+       xti_rate = xti_freq;
+
+       /* fixup parents and add the clock */
+       for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+               find_aclk_parent(lookups[i].clk);
+               clkdev_add(&lookups[i]);
+       }
+       tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32);
+}
diff --git a/arch/arm/mach-tcc8k/common.h b/arch/arm/mach-tcc8k/common.h
new file mode 100644 (file)
index 0000000..705690a
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef MACH_TCC8K_COMMON_H
+#define MACH_TCC8K_COMMON_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device tcc_nand_device;
+
+struct clk;
+
+extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq);
+extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq);
+extern void tcc8k_init_irq(void);
+extern void tcc8k_map_common_io(void);
+
+#endif
diff --git a/arch/arm/mach-tcc8k/devices.c b/arch/arm/mach-tcc8k/devices.c
new file mode 100644 (file)
index 0000000..6722ad7
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/arm/mach-tcc8k/devices.c
+ *
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of GPL v2.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND controller */
+static struct resource tcc_nand_resources[] = {
+       {
+               .start  = (resource_size_t)NFC_BASE,
+               .end    = (resource_size_t)NFC_BASE + 0x7f,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = INT_NFC,
+               .end    = INT_NFC,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device tcc_nand_device = {
+       .name = "tcc_nand",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(tcc_nand_resources),
+       .resource = tcc_nand_resources,
+};
+#endif
+
+#ifdef CONFIG_MMC_TCC8K
+/* MMC controller */
+static struct resource tcc8k_mmc0_resource[] = {
+       {
+               .start = INT_SD0,
+               .end   = INT_SD0,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource tcc8k_mmc1_resource[] = {
+       {
+               .start = INT_SD1,
+               .end   = INT_SD1,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device tcc8k_mmc0_device = {
+       .name           = "tcc-mmc",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(tcc8k_mmc0_resource),
+       .resource       = tcc8k_mmc0_resource,
+       .dev            = {
+               .dma_mask               = &tcc8k_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+struct platform_device tcc8k_mmc1_device = {
+       .name           = "tcc-mmc",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(tcc8k_mmc1_resource),
+       .resource       = tcc8k_mmc1_resource,
+       .dev            = {
+               .dma_mask               = &tcc8k_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+static inline void tcc8k_init_mmc(void)
+{
+       u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+       reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
+       __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+       platform_device_register(&tcc8k_mmc0_device);
+       platform_device_register(&tcc8k_mmc1_device);
+}
+#else
+static inline void tcc8k_init_mmc(void) { }
+#endif
+
+#ifdef CONFIG_USB_OHCI_HCD
+static int tcc8k_ohci_init(struct device *dev)
+{
+       u32 reg;
+
+       /* Use GPIO PK19 as VBUS control output */
+       reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
+       reg &= ~(1 << 19);
+       __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
+       reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
+       reg &= ~(1 << 19);
+       __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
+
+       reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
+       reg |= (1 << 19);
+       __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
+       /* Turn on VBUS */
+       reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
+       reg |= (1 << 19);
+       __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
+
+       return 0;
+}
+
+static struct resource tcc8k_ohci0_resources[] = {
+       [0] = {
+               .start = (resource_size_t)USBH0_BASE,
+               .end   = (resource_size_t)USBH0_BASE + 0x5c,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = INT_USBH0,
+               .end   = INT_USBH0,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource tcc8k_ohci1_resources[] = {
+       [0] = {
+               .start = (resource_size_t)USBH1_BASE,
+               .end   = (resource_size_t)USBH1_BASE + 0x5c,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = INT_USBH1,
+               .end   = INT_USBH1,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
+       .controller     = 0,
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = tcc8k_ohci_init,
+};
+
+static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
+       .controller     = 1,
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = tcc8k_ohci_init,
+};
+
+static struct platform_device ohci0_device = {
+       .name = "tcc-ohci",
+       .id = 0,
+       .dev = {
+               .dma_mask = &tcc8k_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &tcc8k_ohci0_platform_data,
+       },
+       .num_resources  = ARRAY_SIZE(tcc8k_ohci0_resources),
+       .resource       = tcc8k_ohci0_resources,
+};
+
+static struct platform_device ohci1_device = {
+       .name = "tcc-ohci",
+       .id = 1,
+       .dev = {
+               .dma_mask = &tcc8k_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &tcc8k_ohci1_platform_data,
+       },
+       .num_resources  = ARRAY_SIZE(tcc8k_ohci1_resources),
+       .resource       = tcc8k_ohci1_resources,
+};
+
+static void __init tcc8k_init_usbhost(void)
+{
+       platform_device_register(&ohci0_device);
+       platform_device_register(&ohci1_device);
+}
+#else
+static void __init tcc8k_init_usbhost(void) { }
+#endif
+
+/* USB device controller*/
+#ifdef CONFIG_USB_GADGET_TCC8K
+static struct resource udc_resources[] = {
+       [0] = {
+               .start = INT_USBD,
+               .end   = INT_USBD,
+               .flags = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start = INT_UDMA,
+               .end   = INT_UDMA,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device tcc8k_udc_device = {
+       .name = "tcc-udc",
+       .id = 0,
+       .resource = udc_resources,
+       .num_resources = ARRAY_SIZE(udc_resources),
+       .dev = {
+                .dma_mask = &tcc8k_dmamask,
+                .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+static void __init tcc8k_init_usb_gadget(void)
+{
+       platform_device_register(&tcc8k_udc_device);
+}
+#else
+static void __init tcc8k_init_usb_gadget(void) { }
+#endif /* CONFIG_USB_GADGET_TCC83X */
+
+static int __init tcc8k_init_devices(void)
+{
+       tcc8k_init_mmc();
+       tcc8k_init_usbhost();
+       tcc8k_init_usb_gadget();
+       return 0;
+}
+
+arch_initcall(tcc8k_init_devices);
diff --git a/arch/arm/mach-tcc8k/io.c b/arch/arm/mach-tcc8k/io.c
new file mode 100644 (file)
index 0000000..9b39d7f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-tcc8k/io.c
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * derived from TCC83xx io.c
+ * Copyright (C) Telechips, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc tcc8k_io_desc[] __initdata = {
+       {
+               .virtual        = (unsigned long)CS1_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CS1_BASE),
+               .length         = CS1_SIZE,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)AHB_PERI_BASE_VIRT,
+               .pfn            = __phys_to_pfn(AHB_PERI_BASE),
+               .length         = AHB_PERI_SIZE,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)APB0_PERI_BASE_VIRT,
+               .pfn            = __phys_to_pfn(APB0_PERI_BASE),
+               .length         = APB0_PERI_SIZE,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)APB1_PERI_BASE_VIRT,
+               .pfn            = __phys_to_pfn(APB1_PERI_BASE),
+               .length         = APB1_PERI_SIZE,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)EXT_MEM_CTRL_BASE_VIRT,
+               .pfn            = __phys_to_pfn(EXT_MEM_CTRL_BASE),
+               .length         = EXT_MEM_CTRL_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+
+/*
+ * Maps common IO regions for tcc8k.
+ *
+ */
+void __init tcc8k_map_common_io(void)
+{
+       iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc));
+}
diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c
new file mode 100644 (file)
index 0000000..34575c4
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU GPL version 2.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+/* Disable IRQ */
+static void tcc8000_mask_ack_irq0(unsigned int irq)
+{
+       PIC0_IEN &= ~(1 << irq);
+       PIC0_CREQ |=  (1 << irq);
+}
+
+static void tcc8000_mask_ack_irq1(unsigned int irq)
+{
+       PIC1_IEN &= ~(1 << (irq - 32));
+       PIC1_CREQ |= (1 << (irq - 32));
+}
+
+static void tcc8000_mask_irq0(unsigned int irq)
+{
+       PIC0_IEN &= ~(1 << irq);
+}
+
+static void tcc8000_mask_irq1(unsigned int irq)
+{
+       PIC1_IEN &= ~(1 << (irq - 32));
+}
+
+static void tcc8000_ack_irq0(unsigned int irq)
+{
+       PIC0_CREQ |=  (1 << irq);
+}
+
+static void tcc8000_ack_irq1(unsigned int irq)
+{
+       PIC1_CREQ |= (1 << (irq - 32));
+}
+
+/* Enable IRQ */
+static void tcc8000_unmask_irq0(unsigned int irq)
+{
+       PIC0_IEN |= (1 << irq);
+       PIC0_INTOEN |= (1 << irq);
+}
+
+static void tcc8000_unmask_irq1(unsigned int irq)
+{
+       PIC1_IEN |= (1 << (irq - 32));
+       PIC1_INTOEN |= (1 << (irq - 32));
+}
+
+static struct irq_chip tcc8000_irq_chip0 = {
+       .name           = "tcc_irq0",
+       .mask           = tcc8000_mask_irq0,
+       .ack            = tcc8000_ack_irq0,
+       .mask_ack       = tcc8000_mask_ack_irq0,
+       .unmask         = tcc8000_unmask_irq0,
+};
+
+static struct irq_chip tcc8000_irq_chip1 = {
+       .name           = "tcc_irq1",
+       .mask           = tcc8000_mask_irq1,
+       .ack            = tcc8000_ack_irq1,
+       .mask_ack       = tcc8000_mask_ack_irq1,
+       .unmask         = tcc8000_unmask_irq1,
+};
+
+void __init tcc8k_init_irq(void)
+{
+       int irqno;
+
+       /* Mask and clear all interrupts */
+       PIC0_IEN = 0x00000000;
+       PIC0_CREQ = 0xffffffff;
+       PIC1_IEN = 0x00000000;
+       PIC1_CREQ = 0xffffffff;
+
+       PIC0_MEN0 = 0x00000003;
+       PIC1_MEN1 = 0x00000003;
+       PIC1_MEN = 0x00000003;
+
+       /* let all IRQs be level triggered */
+       PIC0_TMODE = 0xffffffff;
+       PIC1_TMODE = 0xffffffff;
+       /* all IRQs are IRQs (not FIQs) */
+       PIC0_IRQSEL = 0xffffffff;
+       PIC1_IRQSEL = 0xffffffff;
+
+       for (irqno = 0; irqno < NR_IRQS; irqno++) {
+               if (irqno < 32)
+                       set_irq_chip(irqno, &tcc8000_irq_chip0);
+               else
+                       set_irq_chip(irqno, &tcc8000_irq_chip1);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+}
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
new file mode 100644 (file)
index 0000000..78d0600
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * TCC8000 system timer setup
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL version 2.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static void __iomem *timer_base;
+
+static cycle_t tcc_get_cycles(struct clocksource *cs)
+{
+       return __raw_readl(timer_base + TC32MCNT_OFFS);
+}
+
+static struct clocksource clocksource_tcc = {
+       .name           = "tcc_tc32",
+       .rating         = 200,
+       .read           = tcc_get_cycles,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 28,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int tcc_set_next_event(unsigned long evt,
+                             struct clock_event_device *unused)
+{
+       unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS);
+
+       __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS);
+       return 0;
+}
+
+static void tcc_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+{
+       unsigned long tc32irq;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_ONESHOT:
+               tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+               tc32irq |= TC32IRQ_IRQEN0;
+               __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+               tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+               tc32irq &= ~TC32IRQ_IRQEN0;
+               __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+               break;
+       case CLOCK_EVT_MODE_PERIODIC:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       /* Acknowledge TC32 interrupt by reading TC32IRQ */
+       __raw_readl(timer_base + TC32IRQ_OFFS);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_tcc = {
+       .name           = "tcc_timer1",
+       .features       = CLOCK_EVT_FEAT_ONESHOT,
+       .shift          = 32,
+       .set_mode       = tcc_set_mode,
+       .set_next_event = tcc_set_next_event,
+       .rating         = 200,
+};
+
+static struct irqaction tcc8k_timer_irq = {
+       .name           = "TC32_timer",
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .handler        = tcc8k_timer_interrupt,
+       .dev_id         = &clockevent_tcc,
+};
+
+static int __init tcc_clockevent_init(struct clk *clock)
+{
+       unsigned int c = clk_get_rate(clock);
+
+       clocksource_tcc.mult = clocksource_hz2mult(c,
+                                       clocksource_tcc.shift);
+       clocksource_register(&clocksource_tcc);
+
+       clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
+                                       clockevent_tcc.shift);
+       clockevent_tcc.max_delta_ns =
+                       clockevent_delta2ns(0xfffffffe, &clockevent_tcc);
+       clockevent_tcc.min_delta_ns =
+                       clockevent_delta2ns(0xff, &clockevent_tcc);
+
+       clockevent_tcc.cpumask = cpumask_of(0);
+
+       clockevents_register_device(&clockevent_tcc);
+
+       return 0;
+}
+
+void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq)
+{
+       u32 reg;
+
+       timer_base = base;
+       tcc8k_timer_irq.irq = irq;
+
+       /* Enable clocks */
+       clk_enable(clock);
+
+       /* Initialize 32-bit timer */
+       reg = __raw_readl(timer_base + TC32EN_OFFS);
+       reg &= ~TC32EN_ENABLE; /* Disable timer */
+       __raw_writel(reg, timer_base + TC32EN_OFFS);
+       /* Free running timer, counting from 0 to 0xffffffff */
+       __raw_writel(0, timer_base + TC32EN_OFFS);
+       __raw_writel(0, timer_base + TC32LDV_OFFS);
+       reg = __raw_readl(timer_base + TC32IRQ_OFFS);
+       reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */
+       __raw_writel(reg, timer_base + TC32IRQ_OFFS);
+
+       __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS);
+
+       tcc_clockevent_init(clock);
+       setup_irq(irq, &tcc8k_timer_irq);
+}
index 7b1fc984abb64c85dd3124eba6b6b108000835b9..d5a71abcbaeaf5a8da0255e50e89f5982fd447d4 100644 (file)
@@ -273,6 +273,9 @@ extern void gpio_pullup(unsigned gpio, int value);
 extern int gpio_get_value(unsigned gpio);
 extern void gpio_set_value(unsigned gpio, int value);
 
+#define gpio_get_value_cansleep gpio_get_value
+#define gpio_set_value_cansleep gpio_set_value
+
 /* wrappers to sleep-enable the previous two functions */
 static inline unsigned gpio_to_irq(unsigned gpio)
 {
index 427e3612db5d1f48202cae06b310c1b9f5f03477..ebd8a2543d3b811f5be94118e1c9c9798f134275 100644 (file)
@@ -18,4 +18,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END            (PAGE_OFFSET + 0x18000000)
+#define VMALLOC_END            0xd8000000
index 577df6cccb0891503bf0188f3c0f33103c159000..71fb173495209572817a0e15f8794ab8c756b70f 100644 (file)
@@ -68,7 +68,7 @@ static void __init ct_ca9x4_init_irq(void)
 }
 
 #if 0
-static void ct_ca9x4_timer_init(void)
+static void __init ct_ca9x4_timer_init(void)
 {
        writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
        writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
@@ -222,12 +222,18 @@ static struct platform_device pmu_device = {
        .resource       = pmu_resources,
 };
 
-static void ct_ca9x4_init(void)
+static void __init ct_ca9x4_init(void)
 {
        int i;
 
 #ifdef CONFIG_CACHE_L2X0
-       l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff);
+       void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
+
+       /* set RAM latencies to 1 cycle for this core tile. */
+       writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
+       writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+       l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 #endif
 
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
index 817f0ad38a0b5100ec0884e8c908c84af471bec4..7eaa232180a5ae627c3639ba642755444a5d3e27 100644 (file)
@@ -48,7 +48,7 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
 }
 
 
-static void v2m_timer_init(void)
+static void __init v2m_timer_init(void)
 {
        writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
        writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
index d073b64ae87ec4f6652c67959244292dbb3e69ad..724ba3bce72c952ff44645d2a50e5566b568c943 100644 (file)
@@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 
        if (ai_usermode & UM_SIGNAL)
                force_sig(SIGBUS, current);
-       else
-               set_cr(cr_no_alignment);
+       else {
+               /*
+                * We're about to disable the alignment trap and return to
+                * user space.  But if an interrupt occurs before actually
+                * reaching user space, then the IRQ vector entry code will
+                * notice that we were still in kernel space and therefore
+                * the alignment trap won't be re-enabled in that case as it
+                * is presumed to be always on from kernel space.
+                * Let's prevent that race by disabling interrupts here (they
+                * are disabled on the way back to user space anyway in
+                * entry-common.S) and disable the alignment trap only if
+                * there is no work pending for this thread.
+                */
+               raw_local_irq_disable();
+               if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+                       set_cr(cr_no_alignment);
+       }
 
        return 0;
 }
index ab506272b2d3ef459b264b7741d61af46f6aa6b8..17e7b0b57e49f80e6e30c8bbe65ea9d1ebcf14a6 100644 (file)
@@ -204,8 +204,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
        /*
         * Don't allow RAM to be mapped - this causes problems with ARMv6+
         */
-       if (WARN_ON(pfn_valid(pfn)))
-               return NULL;
+       if (pfn_valid(pfn)) {
+               printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory.  This leads\n"
+                      KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
+                      KERN_WARNING "will fail in the next kernel release.  Please fix your driver.\n");
+               WARN_ON(1);
+       }
 
        type = get_mem_type(mtype);
        if (!type)
index 4f5b39687df541a417d4c3a9ac888fc53a31b999..b0a98305055c53e54cc9be3edda6c82afb6275b8 100644 (file)
@@ -144,3 +144,25 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
 {
        return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
 }
+
+#ifdef CONFIG_STRICT_DEVMEM
+
+#include <linux/ioport.h>
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain
+ * address is valid. The argument is a physical page number.
+ * We mimic x86 here by disallowing access to system RAM as well as
+ * device-exclusive MMIO regions. This effectively disable read()/write()
+ * on /dev/mem.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+       if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+               return 0;
+       if (!page_is_ram(pfn))
+               return 1;
+       return 0;
+}
+
+#endif
index 6e1c4f6a2b3f3a09ed3f10be9aeafab36c9a0924..e8ed9dc461fe39631efeeb4746b80854e13415c6 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/nodemask.h>
 #include <linux/memblock.h>
 #include <linux/sort.h>
+#include <linux/fs.h>
 
 #include <asm/cputype.h>
 #include <asm/sections.h>
@@ -246,6 +247,9 @@ static struct mem_type mem_types[] = {
                .domain    = DOMAIN_USER,
        },
        [MT_MEMORY] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_WRITE | L_PTE_EXEC,
+               .prot_l1   = PMD_TYPE_TABLE,
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_KERNEL,
        },
@@ -254,6 +258,9 @@ static struct mem_type mem_types[] = {
                .domain    = DOMAIN_KERNEL,
        },
        [MT_MEMORY_NONCACHED] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+               .prot_l1   = PMD_TYPE_TABLE,
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_KERNEL,
        },
@@ -411,9 +418,12 @@ static void __init build_mem_type_table(void)
         * Enable CPU-specific coherency if supported.
         * (Only available on XSC3 at the moment.)
         */
-       if (arch_is_coherent() && cpu_is_xsc3())
+       if (arch_is_coherent() && cpu_is_xsc3()) {
                mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-
+               mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+               mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+               mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+       }
        /*
         * ARMv6 and above have extended page tables.
         */
@@ -438,7 +448,9 @@ static void __init build_mem_type_table(void)
                mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
                mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
                mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+               mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
                mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+               mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
 #endif
        }
 
@@ -475,6 +487,8 @@ static void __init build_mem_type_table(void)
        mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
        mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
        mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+       mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+       mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
        mem_types[MT_ROM].prot_sect |= cp->pmd;
 
        switch (cp->pmd) {
@@ -498,6 +512,19 @@ static void __init build_mem_type_table(void)
        }
 }
 
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+                             unsigned long size, pgprot_t vma_prot)
+{
+       if (!pfn_valid(pfn))
+               return pgprot_noncached(vma_prot);
+       else if (file->f_flags & O_SYNC)
+               return pgprot_writecombine(vma_prot);
+       return vma_prot;
+}
+EXPORT_SYMBOL(phys_mem_access_prot);
+#endif
+
 #define vectors_base() (vectors_high() ? 0xffff0000 : 0)
 
 static void __init *early_alloc(unsigned long sz)
index 6a8506d99ee9abbb0845f39d94d663f802c56885..197f21bed5e919f3a13f3cbc9404d428ad80fb97 100644 (file)
@@ -186,13 +186,14 @@ cpu_v7_name:
  *     It is assumed that:
  *     - cache type register is implemented
  */
-__v7_setup:
+__v7_ca9mp_setup:
 #ifdef CONFIG_SMP
        mrc     p15, 0, r0, c1, c0, 1
        tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
        orreq   r0, r0, #(1 << 6) | (1 << 0)    @ Enable SMP/nAMP mode and
        mcreq   p15, 0, r0, c1, c0, 1           @ TLB ops broadcasting
 #endif
+__v7_setup:
        adr     r12, __v7_setup_stack           @ the local stack
        stmia   r12, {r0-r5, r7, r9, r11, lr}
        bl      v7_flush_dcache_all
@@ -201,11 +202,16 @@ __v7_setup:
        mrc     p15, 0, r0, c0, c0, 0           @ read main ID register
        and     r10, r0, #0xff000000            @ ARM?
        teq     r10, #0x41000000
-       bne     2f
+       bne     3f
        and     r5, r0, #0x00f00000             @ variant
        and     r6, r0, #0x0000000f             @ revision
-       orr     r0, r6, r5, lsr #20-4           @ combine variant and revision
+       orr     r6, r6, r5, lsr #20-4           @ combine variant and revision
+       ubfx    r0, r0, #4, #12                 @ primary part number
 
+       /* Cortex-A8 Errata */
+       ldr     r10, =0x00000c08                @ Cortex-A8 primary part number
+       teq     r0, r10
+       bne     2f
 #ifdef CONFIG_ARM_ERRATA_430973
        teq     r5, #0x00100000                 @ only present in r1p*
        mrceq   p15, 0, r10, c1, c0, 1          @ read aux control register
@@ -213,21 +219,50 @@ __v7_setup:
        mcreq   p15, 0, r10, c1, c0, 1          @ write aux control register
 #endif
 #ifdef CONFIG_ARM_ERRATA_458693
-       teq     r0, #0x20                       @ only present in r2p0
+       teq     r6, #0x20                       @ only present in r2p0
        mrceq   p15, 0, r10, c1, c0, 1          @ read aux control register
        orreq   r10, r10, #(1 << 5)             @ set L1NEON to 1
        orreq   r10, r10, #(1 << 9)             @ set PLDNOP to 1
        mcreq   p15, 0, r10, c1, c0, 1          @ write aux control register
 #endif
 #ifdef CONFIG_ARM_ERRATA_460075
-       teq     r0, #0x20                       @ only present in r2p0
+       teq     r6, #0x20                       @ only present in r2p0
        mrceq   p15, 1, r10, c9, c0, 2          @ read L2 cache aux ctrl register
        tsteq   r10, #1 << 22
        orreq   r10, r10, #(1 << 22)            @ set the Write Allocate disable bit
        mcreq   p15, 1, r10, c9, c0, 2          @ write the L2 cache aux ctrl register
 #endif
+       b       3f
 
-2:     mov     r10, #0
+       /* Cortex-A9 Errata */
+2:     ldr     r10, =0x00000c09                @ Cortex-A9 primary part number
+       teq     r0, r10
+       bne     3f
+#ifdef CONFIG_ARM_ERRATA_742230
+       cmp     r6, #0x22                       @ only present up to r2p2
+       mrcle   p15, 0, r10, c15, c0, 1         @ read diagnostic register
+       orrle   r10, r10, #1 << 4               @ set bit #4
+       mcrle   p15, 0, r10, c15, c0, 1         @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_742231
+       teq     r6, #0x20                       @ present in r2p0
+       teqne   r6, #0x21                       @ present in r2p1
+       teqne   r6, #0x22                       @ present in r2p2
+       mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
+       orreq   r10, r10, #1 << 12              @ set bit #12
+       orreq   r10, r10, #1 << 22              @ set bit #22
+       mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_743622
+       teq     r6, #0x20                       @ present in r2p0
+       teqne   r6, #0x21                       @ present in r2p1
+       teqne   r6, #0x22                       @ present in r2p2
+       mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
+       orreq   r10, r10, #1 << 6               @ set bit #6
+       mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
+#endif
+
+3:     mov     r10, #0
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
 #endif
@@ -323,6 +358,29 @@ cpu_elf_name:
 
        .section ".proc.info.init", #alloc, #execinstr
 
+       .type   __v7_ca9mp_proc_info, #object
+__v7_ca9mp_proc_info:
+       .long   0x410fc090              @ Required ID value
+       .long   0xff0ffff0              @ Mask for ID
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_FLAGS
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_XN | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
+       b       __v7_ca9mp_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
+       .long   cpu_v7_name
+       .long   v7_processor_functions
+       .long   v7wbi_tlb_fns
+       .long   v6_user_fns
+       .long   v7_cache_fns
+       .size   __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
+
        /*
         * Match any ARMv7 processor core.
         */
index 0691176899ffc24f0a176d154a34f5b7200c6047..72e09eb642dd7c7a00d47fce210bb1290e926fd9 100644 (file)
@@ -102,6 +102,7 @@ static int op_create_counter(int cpu, int event)
        if (IS_ERR(pevent)) {
                ret = PTR_ERR(pevent);
        } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
+               perf_event_release_kernel(pevent);
                pr_warning("oprofile: failed to enable event %d "
                                "on CPU %d\n", event, cpu);
                ret = -EBUSY;
@@ -365,6 +366,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        ret = init_driverfs();
        if (ret) {
                kfree(counter_config);
+               counter_config = NULL;
                return ret;
        }
 
@@ -402,7 +404,6 @@ void oprofile_arch_exit(void)
        struct perf_event *event;
 
        if (*perf_events) {
-               exit_driverfs();
                for_each_possible_cpu(cpu) {
                        for (id = 0; id < perf_num_counters; ++id) {
                                event = perf_events[cpu][id];
@@ -413,8 +414,10 @@ void oprofile_arch_exit(void)
                }
        }
 
-       if (counter_config)
+       if (counter_config) {
                kfree(counter_config);
+               exit_driverfs();
+       }
 }
 #else
 int __init oprofile_arch_init(struct oprofile_operations *ops)
index ea3ca86c52836ba1ec9fe780da9c1629db91723f..aedf9c1d645e4a820c8f1f9dd884fdf5fd1cebf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mach-nomadik/timer.c
+ *  linux/arch/arm/plat-nomadik/timer.c
  *
  * Copyright (C) 2008 STMicroelectronics
  * Copyright (C) 2010 Alessandro Rubini
@@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode,
                cr = readl(mtu_base + MTU_CR(1));
                writel(0, mtu_base + MTU_LR(1));
                writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
-               writel(0x2, mtu_base + MTU_IMSC);
+               writel(1 << 1, mtu_base + MTU_IMSC);
                break;
        case CLOCK_EVT_MODE_SHUTDOWN:
        case CLOCK_EVT_MODE_UNUSED:
@@ -131,25 +131,23 @@ void __init nmdk_timer_init(void)
 {
        unsigned long rate;
        struct clk *clk0;
-       struct clk *clk1;
-       u32 cr;
+       u32 cr = MTU_CRn_32BITS;
 
        clk0 = clk_get_sys("mtu0", NULL);
        BUG_ON(IS_ERR(clk0));
 
-       clk1 = clk_get_sys("mtu1", NULL);
-       BUG_ON(IS_ERR(clk1));
-
        clk_enable(clk0);
-       clk_enable(clk1);
 
        /*
-        * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500:
-        * use a divide-by-16 counter if it's more than 16MHz
+        * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
+        * for ux500.
+        * Use a divide-by-16 counter if the tick rate is more than 32MHz.
+        * At 32 MHz, the timer (with 32 bit counter) can be programmed
+        * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer
+        * with 16 gives too low timer resolution.
         */
-       cr = MTU_CRn_32BITS;;
        rate = clk_get_rate(clk0);
-       if (rate > 16 << 20) {
+       if (rate > 32000000) {
                rate /= 16;
                cr |= MTU_CRn_PRESCALE_16;
        } else {
@@ -170,15 +168,8 @@ void __init nmdk_timer_init(void)
                pr_err("timer: failed to initialize clock source %s\n",
                       nmdk_clksrc.name);
 
-       /* Timer 1 is used for events, fix according to rate */
-       cr = MTU_CRn_32BITS;
-       rate = clk_get_rate(clk1);
-       if (rate > 16 << 20) {
-               rate /= 16;
-               cr |= MTU_CRn_PRESCALE_16;
-       } else {
-               cr |= MTU_CRn_PRESCALE_1;
-       }
+       /* Timer 1 is used for events */
+
        clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
 
        writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
index e39a417a368dc92ad6776a68ef6fefc22a046b76..a92cb499313fdc9583890ebcc182ecae280cdc09 100644 (file)
@@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES
 config OMAP_DEBUG_LEDS
        bool
        depends on OMAP_DEBUG_DEVICES
-       default y if LEDS
+       default y if LEDS_CLASS
 
 config OMAP_RESET_CLOCKS
        bool "Reset unused clocks during boot"
index a202a2ce6e3d0018ee3022ead0ba835527e3a4b0..6cd151b31bc5f7ee37afe54882737ddb60be1fbf 100644 (file)
@@ -320,6 +320,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da)
                if ((start <= da) && (da < start + bytes)) {
                        dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
                                __func__, start, da, bytes);
+                       iotlb_load_cr(obj, &cr);
                        iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
                }
        }
index e31496e35b0f452d4ff9e375855718fc0a078d40..0c8612fd831237164968b1f2120a1134618557e3 100644 (file)
@@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
                /* Writing zero to RSYNC_ERR clears the IRQ */
                MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
        } else {
-               complete(&mcbsp_rx->tx_irq_completion);
+               complete(&mcbsp_rx->rx_irq_completion);
        }
 
        return IRQ_HANDLED;
index 226b2e858d6c9617243a91138821fb0e355daf56..10b3b4c63372f406e6ee206ce691977753017e56 100644 (file)
@@ -220,20 +220,7 @@ void __init omap_map_sram(void)
        if (omap_sram_size == 0)
                return;
 
-       if (cpu_is_omap24xx()) {
-               omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
-
-               base = OMAP2_SRAM_PA;
-               base = ROUND_DOWN(base, PAGE_SIZE);
-               omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
-       }
-
        if (cpu_is_omap34xx()) {
-               omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA;
-               base = OMAP3_SRAM_PA;
-               base = ROUND_DOWN(base, PAGE_SIZE);
-               omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
-
                /*
                 * SRAM must be marked as non-cached on OMAP3 since the
                 * CORE DPLL M2 divider change code (in SRAM) runs with the
@@ -244,13 +231,11 @@ void __init omap_map_sram(void)
                omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
        }
 
-       if (cpu_is_omap44xx()) {
-               omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA;
-               base = OMAP4_SRAM_PA;
-               base = ROUND_DOWN(base, PAGE_SIZE);
-               omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
-       }
-       omap_sram_io_desc[0].length = 1024 * 1024;      /* Use section desc */
+       omap_sram_io_desc[0].virtual = omap_sram_base;
+       base = omap_sram_start;
+       base = ROUND_DOWN(base, PAGE_SIZE);
+       omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
+       omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE);
        iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 
        printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
similarity index 83%
rename from arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
rename to arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
index 7b4eadc6df3a8c7762329304b1cec2fefbc900ff..abcc36eb12425ac04a28da7e61f6e9fa171ddac0 100644 (file)
  *
  * 4. matrix key and direct key will use the same debounce_interval by
  *    default, which should be sufficient in most cases
+ *
+ * pxa168 keypad platform specific parameter
+ *
+ * NOTE:
+ * clear_wakeup_event callback is a workaround required to clear the
+ * keypad interrupt. The keypad wake must be cleared in addition to
+ * reading the MI/DI bits in the KPC register.
  */
 struct pxa27x_keypad_platform_data {
 
@@ -52,6 +59,9 @@ struct pxa27x_keypad_platform_data {
 
        /* key debounce interval */
        unsigned int    debounce_interval;
+
+       /* clear wakeup event requirement for pxa168 */
+       void            (*clear_wakeup_event)(void);
 };
 
 extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
index c6a855db2fb6f327bc962b0b3e1913630c9252d6..25960966af7c7f1acf54c168ddc06e36ca97b91c 100644 (file)
@@ -7,7 +7,7 @@
 
 config PLAT_S5P
        bool
-       depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310)
+       depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310)
        default y
        select ARM_VIC if !ARCH_S5PV310
        select ARM_GIC if ARCH_S5PV310
@@ -30,7 +30,7 @@ config S5P_EXT_INT
        bool
        help
          Use the external interrupts (other than GPIO interrupts.)
-         Note: Do not choose this for S5P6440.
+         Note: Do not choose this for S5P6440 and S5P6450.
 
 config S5P_DEV_FIMC0
        bool
@@ -46,3 +46,8 @@ config S5P_DEV_FIMC2
        bool
        help
          Compile in platform device definitions for FIMC controller 2
+
+config S5P_DEV_ONENAND
+       bool
+       help
+         Compile in platform device definition for OneNAND controller
index b2e029673950fb028b2a936a2d0bbf7d9ee771e3..f3e917e27da870341a5d7c9d6b0c56b5964f9430 100644 (file)
@@ -24,3 +24,4 @@ obj-$(CONFIG_S5P_EXT_INT)     += irq-eint.o
 obj-$(CONFIG_S5P_DEV_FIMC0)    += dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)    += dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)    += dev-fimc2.o
+obj-$(CONFIG_S5P_DEV_ONENAND)  += dev-onenand.o
index b5e255265f20de4085bac619341f8bb9c1c40fd7..8aaf4e6b60c300760c443aa6fe4548fe165ff3b6 100644 (file)
@@ -74,6 +74,13 @@ struct clk clk_fout_epll = {
        .ctrlbit        = (1 << 31),
 };
 
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+       .name           = "fout_dpll",
+       .id             = -1,
+       .ctrlbit        = (1 << 31),
+};
+
 /* VPLL clock output */
 struct clk clk_fout_vpll = {
        .name           = "fout_vpll",
@@ -122,6 +129,17 @@ struct clksrc_sources clk_src_epll = {
        .nr_sources     = ARRAY_SIZE(clk_src_epll_list),
 };
 
+/* Possible clock sources for DPLL Mux */
+static struct clk *clk_src_dpll_list[] = {
+       [0] = &clk_fin_dpll,
+       [1] = &clk_fout_dpll,
+};
+
+struct clksrc_sources clk_src_dpll = {
+       .sources        = clk_src_dpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_dpll_list),
+};
+
 struct clk clk_vpll = {
        .name           = "vpll",
        .id             = -1,
@@ -145,6 +163,7 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_apll,
        &clk_fout_mpll,
        &clk_fout_epll,
+       &clk_fout_dpll,
        &clk_fout_vpll,
        &clk_arm,
        &clk_vpll,
index b07a078fd28449b80c9171d46f10975a5998b2b9..74f7f5a5446cdaf4bdc9a3212f1dc9679611abfb 100644 (file)
@@ -19,6 +19,7 @@
 #include <plat/cpu.h>
 #include <plat/s5p6440.h>
 #include <plat/s5p6442.h>
+#include <plat/s5p6450.h>
 #include <plat/s5pc100.h>
 #include <plat/s5pv210.h>
 #include <plat/s5pv310.h>
@@ -27,6 +28,7 @@
 
 static const char name_s5p6440[] = "S5P6440";
 static const char name_s5p6442[] = "S5P6442";
+static const char name_s5p6450[] = "S5P6450";
 static const char name_s5pc100[] = "S5PC100";
 static const char name_s5pv210[] = "S5PV210/S5PC110";
 static const char name_s5pv310[] = "S5PV310";
@@ -38,7 +40,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .map_io         = s5p6440_map_io,
                .init_clocks    = s5p6440_init_clocks,
                .init_uarts     = s5p6440_init_uarts,
-               .init           = s5p6440_init,
+               .init           = s5p64x0_init,
                .name           = name_s5p6440,
        }, {
                .idcode         = 0x36442000,
@@ -48,6 +50,14 @@ static struct cpu_table cpu_ids[] __initdata = {
                .init_uarts     = s5p6442_init_uarts,
                .init           = s5p6442_init,
                .name           = name_s5p6442,
+       }, {
+               .idcode         = 0x36450000,
+               .idmask         = 0xffffff00,
+               .map_io         = s5p6450_map_io,
+               .init_clocks    = s5p6450_init_clocks,
+               .init_uarts     = s5p6450_init_uarts,
+               .init           = s5p64x0_init,
+               .name           = name_s5p6450,
        }, {
                .idcode         = 0x43100000,
                .idmask         = 0xfffff000,
@@ -88,33 +98,11 @@ static struct map_desc s5p_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(S5P_PA_SYSCON),
                .length         = SZ_64K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_UART,
-               .pfn            = __phys_to_pfn(S3C_PA_UART),
-               .length         = SZ_512K,
-               .type           = MT_DEVICE,
-#ifdef CONFIG_ARM_VIC
-       }, {
-               .virtual        = (unsigned long)VA_VIC0,
-               .pfn            = __phys_to_pfn(S5P_PA_VIC0),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)VA_VIC1,
-               .pfn            = __phys_to_pfn(S5P_PA_VIC1),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-#endif
        }, {
                .virtual        = (unsigned long)S3C_VA_TIMER,
                .pfn            = __phys_to_pfn(S5P_PA_TIMER),
                .length         = SZ_16K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO,
-               .pfn            = __phys_to_pfn(S5P_PA_GPIO),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S3C_VA_WATCHDOG,
                .pfn            = __phys_to_pfn(S3C_PA_WDT),
index d3f1a9b5d2b5a4d01f040ba784a13185629b5938..608770fc1531335967f4e42a4c9355ed8e5f6c87 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -18,7 +19,7 @@
 static struct resource s5p_fimc0_resource[] = {
        [0] = {
                .start  = S5P_PA_FIMC0,
-               .end    = S5P_PA_FIMC0 + SZ_1M - 1,
+               .end    = S5P_PA_FIMC0 + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -28,9 +29,15 @@ static struct resource s5p_fimc0_resource[] = {
        },
 };
 
+static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32);
+
 struct platform_device s5p_device_fimc0 = {
        .name           = "s5p-fimc",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(s5p_fimc0_resource),
        .resource       = s5p_fimc0_resource,
+       .dev            = {
+               .dma_mask               = &s5p_fimc0_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
 };
index 41bd6986d0ad03210cf85c4e32f1f497a29d67f6..76e3a97a87d37c934f95da3ab2187831b9eb6da6 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -18,7 +19,7 @@
 static struct resource s5p_fimc1_resource[] = {
        [0] = {
                .start  = S5P_PA_FIMC1,
-               .end    = S5P_PA_FIMC1 + SZ_1M - 1,
+               .end    = S5P_PA_FIMC1 + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -28,9 +29,15 @@ static struct resource s5p_fimc1_resource[] = {
        },
 };
 
+static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32);
+
 struct platform_device s5p_device_fimc1 = {
        .name           = "s5p-fimc",
        .id             = 1,
        .num_resources  = ARRAY_SIZE(s5p_fimc1_resource),
        .resource       = s5p_fimc1_resource,
+       .dev            = {
+               .dma_mask               = &s5p_fimc1_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
 };
index dfddeda6d4a373445abdabbbe3e59155c61fa84e..24d29816fa2c03711ad0b5a62e2561caabd11e3b 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -18,7 +19,7 @@
 static struct resource s5p_fimc2_resource[] = {
        [0] = {
                .start  = S5P_PA_FIMC2,
-               .end    = S5P_PA_FIMC2 + SZ_1M - 1,
+               .end    = S5P_PA_FIMC2 + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -28,9 +29,15 @@ static struct resource s5p_fimc2_resource[] = {
        },
 };
 
+static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32);
+
 struct platform_device s5p_device_fimc2 = {
        .name           = "s5p-fimc",
        .id             = 2,
        .num_resources  = ARRAY_SIZE(s5p_fimc2_resource),
        .resource       = s5p_fimc2_resource,
+       .dev            = {
+               .dma_mask               = &s5p_fimc2_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
 };
similarity index 59%
rename from arch/arm/mach-s5pv210/dev-onenand.c
rename to arch/arm/plat-s5p/dev-onenand.c
index f8ede33ee82b8e1d0acee891e54d6772a628d650..6db926202caa6adcb193b899e21eb78584c28ff0 100644 (file)
@@ -1,10 +1,12 @@
-/*
- * linux/arch/arm/mach-s5pv210/dev-onenand.c
+/* linux/arch/arm/plat-s5p/dev-onenand.c
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  *  Copyright (c) 2008-2010 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
- * S5PC110 series device definition for OneNAND devices
+ * S5P series device definition for OneNAND devices
  *
  * 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
 #include <mach/irqs.h>
 #include <mach/map.h>
 
-static struct resource s5pc110_onenand_resources[] = {
+static struct resource s5p_onenand_resources[] = {
        [0] = {
-               .start  = S5PC110_PA_ONENAND,
-               .end    = S5PC110_PA_ONENAND + SZ_128K - 1,
+               .start  = S5P_PA_ONENAND,
+               .end    = S5P_PA_ONENAND + SZ_128K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = S5PC110_PA_ONENAND_DMA,
-               .end    = S5PC110_PA_ONENAND_DMA + SZ_8K - 1,
+               .start  = S5P_PA_ONENAND_DMA,
+               .end    = S5P_PA_ONENAND_DMA + SZ_8K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [2] = {
@@ -37,19 +39,19 @@ static struct resource s5pc110_onenand_resources[] = {
        },
 };
 
-struct platform_device s5pc110_device_onenand = {
+struct platform_device s5p_device_onenand = {
        .name           = "s5pc110-onenand",
        .id             = -1,
-       .num_resources  = ARRAY_SIZE(s5pc110_onenand_resources),
-       .resource       = s5pc110_onenand_resources,
+       .num_resources  = ARRAY_SIZE(s5p_onenand_resources),
+       .resource       = s5p_onenand_resources,
 };
 
-void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata)
+void s5p_onenand_set_platdata(struct onenand_platform_data *pdata)
 {
        struct onenand_platform_data *pd;
 
        pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
        if (!pd)
                printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-       s5pc110_device_onenand.dev.platform_data = pd;
+       s5p_device_onenand.dev.platform_data = pd;
 }
index a89331ef4ae172b97d6f21aba05fd8cd80c7eb09..6a7342886171fde25d9c531f4e86db6c7ef52f1b 100644 (file)
@@ -119,6 +119,56 @@ static struct resource s5p_uart3_resource[] = {
 #endif
 };
 
+static struct resource s5p_uart4_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+       [0] = {
+               .start  = S5P_PA_UART4,
+               .end    = S5P_PA_UART4 + S5P_SZ_UART,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_S5P_UART_RX4,
+               .end    = IRQ_S5P_UART_RX4,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = IRQ_S5P_UART_TX4,
+               .end    = IRQ_S5P_UART_TX4,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = IRQ_S5P_UART_ERR4,
+               .end    = IRQ_S5P_UART_ERR4,
+               .flags  = IORESOURCE_IRQ,
+       },
+#endif
+};
+
+static struct resource s5p_uart5_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+       [0] = {
+               .start  = S5P_PA_UART5,
+               .end    = S5P_PA_UART5 + S5P_SZ_UART,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_S5P_UART_RX5,
+               .end    = IRQ_S5P_UART_RX5,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = IRQ_S5P_UART_TX5,
+               .end    = IRQ_S5P_UART_TX5,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = IRQ_S5P_UART_ERR5,
+               .end    = IRQ_S5P_UART_ERR5,
+               .flags  = IORESOURCE_IRQ,
+       },
+#endif
+};
+
 struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
        [0] = {
                .resources      = s5p_uart0_resource,
@@ -136,4 +186,12 @@ struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
                .resources      = s5p_uart3_resource,
                .nr_resources   = ARRAY_SIZE(s5p_uart3_resource),
        },
+       [4] = {
+               .resources      = s5p_uart4_resource,
+               .nr_resources   = ARRAY_SIZE(s5p_uart4_resource),
+       },
+       [5] = {
+               .resources      = s5p_uart5_resource,
+               .nr_resources   = ARRAY_SIZE(s5p_uart5_resource),
+       },
 };
index 4e8fe08cb70d96ad13dee8c1288e95f206c4bb17..bf28fadee7ae07c931174fab01d14875e396b316 100644 (file)
@@ -47,6 +47,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
 }
 
 #define PLL46XX_KDIV_MASK      (0xFFFF)
+#define PLL4650C_KDIV_MASK     (0xFFF)
 #define PLL46XX_MDIV_MASK      (0x1FF)
 #define PLL46XX_PDIV_MASK      (0x3F)
 #define PLL46XX_SDIV_MASK      (0x7)
@@ -57,6 +58,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
 enum pll46xx_type_t {
        pll_4600,
        pll_4650,
+       pll_4650c,
 };
 
 static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
@@ -72,6 +74,11 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
        sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
        kdiv = pll_con1 & PLL46XX_KDIV_MASK;
 
+       if (pll_type == pll_4650c)
+               kdiv = pll_con1 & PLL4650C_KDIV_MASK;
+       else
+               kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
        tmp = baseclk;
 
        if (pll_type == pll_4600) {
index 09418b1101fe582a374b4ded78010e36de392d11..17036c898409adafc0756b2064bb77e9f1e8e187 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
  *
- * Copyright 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  * Header file for s5p clock support
  *
@@ -20,6 +20,7 @@
 #define clk_fin_apll clk_ext_xtal_mux
 #define clk_fin_mpll clk_ext_xtal_mux
 #define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_dpll clk_ext_xtal_mux
 #define clk_fin_vpll clk_ext_xtal_mux
 #define clk_fin_hpll clk_ext_xtal_mux
 
@@ -30,6 +31,7 @@ extern struct clk s5p_clk_27m;
 extern struct clk clk_fout_apll;
 extern struct clk clk_fout_mpll;
 extern struct clk clk_fout_epll;
+extern struct clk clk_fout_dpll;
 extern struct clk clk_fout_vpll;
 extern struct clk clk_arm;
 extern struct clk clk_vpll;
@@ -37,8 +39,8 @@ extern struct clk clk_vpll;
 extern struct clksrc_sources clk_src_apll;
 extern struct clksrc_sources clk_src_mpll;
 extern struct clksrc_sources clk_src_epll;
+extern struct clksrc_sources clk_src_dpll;
 
-extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable);
 extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
 
 #endif /* __ASM_PLAT_S5P_CLOCK_H */
index a4cd75afeb3bf4efcd09dce436e198b341b58a54..528585d2cafcef8a0bae0926fd2318ede7d4a474 100644 (file)
 
  /* Common init code for S5P6440 related SoCs */
 
-extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5p6440_register_clocks(void);
 extern void s5p6440_setup_clocks(void);
 
 #ifdef CONFIG_CPU_S5P6440
 
-extern  int s5p6440_init(void);
+extern  int s5p64x0_init(void);
 extern void s5p6440_init_irq(void);
 extern void s5p6440_map_io(void);
 extern void s5p6440_init_clocks(int xtal);
 
-#define s5p6440_init_uarts s5p6440_common_init_uarts
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
 #else
 #define s5p6440_init_clocks NULL
 #define s5p6440_init_uarts NULL
 #define s5p6440_map_io NULL
-#define s5p6440_init NULL
+#define s5p64x0_init NULL
 #endif
 
 /* S5P6440 timer */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h
new file mode 100644 (file)
index 0000000..640a41c
--- /dev/null
@@ -0,0 +1,36 @@
+/* arch/arm/plat-s5p/include/plat/s5p6450.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for s5p6450 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5P6450 related SoCs */
+
+extern void s5p6450_register_clocks(void);
+extern void s5p6450_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6450
+
+extern  int s5p64x0_init(void);
+extern void s5p6450_init_irq(void);
+extern void s5p6450_map_io(void);
+extern void s5p6450_init_clocks(int xtal);
+
+extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6450_init_clocks NULL
+#define s5p6450_init_uarts NULL
+#define s5p6450_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6450 timer */
+
+extern struct sys_timer s5p6450_timer;
index 04d9521ddc9f0e652d62453a99bbb19fa877c7fa..e8f2be2d67f2cac33961487b47a7880b68f33832 100644 (file)
@@ -435,7 +435,6 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
 static int s3c_adc_resume(struct platform_device *pdev)
 {
        struct adc_device *adc = platform_get_drvdata(pdev);
-       unsigned long flags;
 
        clk_enable(adc->clk);
        enable_irq(adc->irq);
index 90a20512d68d5a40d9fa789b15c24620a0c8f9b3..e8d20b0bc50e11ee43d78f230b811409def1cb87 100644 (file)
@@ -48,6 +48,9 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 
+#include <linux/serial_core.h>
+#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */
+
 /* clock information */
 
 static LIST_HEAD(clocks);
@@ -65,6 +68,28 @@ static int clk_null_enable(struct clk *clk, int enable)
        return 0;
 }
 
+static int dev_is_s3c_uart(struct device *dev)
+{
+       struct platform_device **pdev = s3c24xx_uart_devs;
+       int i;
+       for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
+               if (*pdev && dev == &(*pdev)->dev)
+                       return 1;
+       return 0;
+}
+
+/*
+ * Serial drivers call get_clock() very early, before platform bus
+ * has been set up, this requires a special check to let them get
+ * a proper clock
+ */
+
+static int dev_is_platform_device(struct device *dev)
+{
+       return dev->bus == &platform_bus_type ||
+              (dev->bus == NULL && dev_is_s3c_uart(dev));
+}
+
 /* Clock API calls */
 
 struct clk *clk_get(struct device *dev, const char *id)
@@ -73,7 +98,7 @@ struct clk *clk_get(struct device *dev, const char *id)
        struct clk *clk = ERR_PTR(-ENOENT);
        int idno;
 
-       if (dev == NULL || dev->bus != &platform_bus_type)
+       if (dev == NULL || !dev_is_platform_device(dev))
                idno = -1;
        else
                idno = to_platform_device(dev)->id;
index 57b68a50f45e93aa14852500ace0df1fdc48da8b..e3d41eaed1ffd9feed571cef0af6bf5bf0841bf2 100644 (file)
@@ -273,13 +273,13 @@ s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
        if (!chip)
                return -EINVAL;
 
-       off = chip->chip.base - pin;
+       off = pin - chip->chip.base;
        shift = off * 2;
        reg = chip->base + 0x0C;
 
        drvstr = __raw_readl(reg);
-       drvstr = 0xffff & (0x3 << shift);
        drvstr = drvstr >> shift;
+       drvstr &= 0x3;
 
        return (__force s5p_gpio_drvstr_t)drvstr;
 }
@@ -296,11 +296,12 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
        if (!chip)
                return -EINVAL;
 
-       off = chip->chip.base - pin;
+       off = pin - chip->chip.base;
        shift = off * 2;
        reg = chip->base + 0x0C;
 
        tmp = __raw_readl(reg);
+       tmp &= ~(0x3 << shift);
        tmp |= drvstr << shift;
 
        __raw_writel(tmp, reg);
index 6412933d6fbb813050b840e1d71e788758b9a9fc..9addb3dfb4bc31d83227acc18bcd654da748d380 100644 (file)
@@ -79,7 +79,7 @@ extern struct sysdev_class s3c2442_sysclass;
 extern struct sysdev_class s3c2443_sysclass;
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
-extern struct sysdev_class s5p6440_sysclass;
+extern struct sysdev_class s5p64x0_sysclass;
 extern struct sysdev_class s5p6442_sysclass;
 extern struct sysdev_class s5pv210_sysclass;
 
index 85f6f23a510f56cd1b9ce5f1f7871f0923b26c11..7d448e13879241c8a62da6f26604ea00ecc1a3d1 100644 (file)
@@ -67,13 +67,15 @@ extern struct platform_device s5pv210_device_spi0;
 extern struct platform_device s5pv210_device_spi1;
 extern struct platform_device s5p6440_device_spi0;
 extern struct platform_device s5p6440_device_spi1;
+extern struct platform_device s5p6450_device_spi0;
+extern struct platform_device s5p6450_device_spi1;
 
 extern struct platform_device s3c_device_hwmon;
 
 extern struct platform_device s3c_device_nand;
 extern struct platform_device s3c_device_onenand;
 extern struct platform_device s3c64xx_device_onenand1;
-extern struct platform_device s5pc110_device_onenand;
+extern struct platform_device s5p_device_onenand;
 
 extern struct platform_device s3c_device_usbgadget;
 extern struct platform_device s3c_device_usb_hsotg;
@@ -95,6 +97,9 @@ extern struct platform_device s5p6442_device_spi;
 extern struct platform_device s5p6440_device_pcm;
 extern struct platform_device s5p6440_device_iis;
 
+extern struct platform_device s5p6450_device_iis0;
+extern struct platform_device s5p6450_device_pcm0;
+
 extern struct platform_device s5pc100_device_ac97;
 extern struct platform_device s5pc100_device_pcm0;
 extern struct platform_device s5pc100_device_pcm1;
index db4112c6f2becd7371fc86428c5ca4b50a07bbdd..1c6b92947c5db7e8b955ac3831214bbf556bf2bb 100644 (file)
@@ -143,12 +143,12 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
 /* Define values for the drvstr available for each gpio pin.
  *
  * These values control the value of the output signal driver strength,
- * configurable on most pins on the S5C series.
+ * configurable on most pins on the S5P series.
  */
-#define S5P_GPIO_DRVSTR_LV1    ((__force s5p_gpio_drvstr_t)0x00)
-#define S5P_GPIO_DRVSTR_LV2    ((__force s5p_gpio_drvstr_t)0x01)
-#define S5P_GPIO_DRVSTR_LV3    ((__force s5p_gpio_drvstr_t)0x10)
-#define S5P_GPIO_DRVSTR_LV4    ((__force s5p_gpio_drvstr_t)0x11)
+#define S5P_GPIO_DRVSTR_LV1    ((__force s5p_gpio_drvstr_t)0x0)
+#define S5P_GPIO_DRVSTR_LV2    ((__force s5p_gpio_drvstr_t)0x2)
+#define S5P_GPIO_DRVSTR_LV3    ((__force s5p_gpio_drvstr_t)0x1)
+#define S5P_GPIO_DRVSTR_LV4    ((__force s5p_gpio_drvstr_t)0x3)
 
 /**
  * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin
index 5fe6721b57f7060acd8180522c3d2df41ad8cf62..81074421312068bfc24e5f9329d8d44d60538c8b 100644 (file)
@@ -32,6 +32,12 @@ enum dma_ch {
        DMACH_UART2_TX,
        DMACH_UART3_RX,
        DMACH_UART3_TX,
+       DMACH_UART4_RX,
+       DMACH_UART4_TX,
+       DMACH_UART5_RX,
+       DMACH_UART5_TX,
+       DMACH_USI_RX,
+       DMACH_USI_TX,
        DMACH_IRDA,
        DMACH_I2S0_RX,
        DMACH_I2S0_TX,
@@ -64,6 +70,20 @@ enum dma_ch {
        DMACH_MSM_REQ2,
        DMACH_MSM_REQ1,
        DMACH_MSM_REQ0,
+       DMACH_SLIMBUS0_RX,
+       DMACH_SLIMBUS0_TX,
+       DMACH_SLIMBUS0AUX_RX,
+       DMACH_SLIMBUS0AUX_TX,
+       DMACH_SLIMBUS1_RX,
+       DMACH_SLIMBUS1_TX,
+       DMACH_SLIMBUS2_RX,
+       DMACH_SLIMBUS2_TX,
+       DMACH_SLIMBUS3_RX,
+       DMACH_SLIMBUS3_TX,
+       DMACH_SLIMBUS4_RX,
+       DMACH_SLIMBUS4_TX,
+       DMACH_SLIMBUS5_RX,
+       DMACH_SLIMBUS5_TX,
        /* END Marker, also used to denote a reserved channel */
        DMACH_MAX,
 };
index e5aba8f95b791355f8d01a77347482053099933d..ae8e802bdca8f97aeee71b6799a144b3a6014390 100644 (file)
@@ -65,7 +65,7 @@ struct s3c64xx_spi_info {
 extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
-extern void s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 
 #endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-tcc/Kconfig b/arch/arm/plat-tcc/Kconfig
new file mode 100644 (file)
index 0000000..1bf4995
--- /dev/null
@@ -0,0 +1,20 @@
+if ARCH_TCC_926
+
+menu "Telechips ARM926-based CPUs"
+
+choice
+       prompt "Telechips CPU type:"
+       default ARCH_TCC8K
+
+config ARCH_TCC8K
+       bool TCC8000
+       select USB_ARCH_HAS_OHCI
+       help
+         Support for Telechips TCC8000 systems
+
+endchoice
+
+source "arch/arm/mach-tcc8k/Kconfig"
+
+endmenu
+endif
diff --git a/arch/arm/plat-tcc/Makefile b/arch/arm/plat-tcc/Makefile
new file mode 100644 (file)
index 0000000..eceabc8
--- /dev/null
@@ -0,0 +1,3 @@
+# "Telechips Platform Common Modules"
+
+obj-y := clock.o system.o
diff --git a/arch/arm/plat-tcc/clock.c b/arch/arm/plat-tcc/clock.c
new file mode 100644 (file)
index 0000000..f3ced10
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Clock framework for Telechips SoCs
+ * Based on arch/arm/plat-mxc/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2010 Hans J. Koch, hjk@linutronix.de
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+       BUG_ON(clk->refcount == 0);
+
+       if (!(--clk->refcount) && clk->disable) {
+               /* Unconditionally disable the clock in hardware */
+               clk->disable(clk);
+               /* recursively disable parents */
+               if (clk->parent)
+                       __clk_disable(clk->parent);
+       }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (clk->refcount++ == 0 && clk->enable) {
+               if (clk->parent)
+                       ret = __clk_enable(clk->parent);
+               if (ret)
+                       return ret;
+               else
+                       return clk->enable(clk);
+       }
+
+       return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return -EINVAL;
+
+       mutex_lock(&clocks_mutex);
+       ret = __clk_enable(clk);
+       mutex_unlock(&clocks_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       mutex_lock(&clocks_mutex);
+       __clk_disable(clk);
+       mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+       if (!clk)
+               return 0UL;
+
+       if (clk->get_rate)
+               return clk->get_rate(clk);
+
+       return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (!clk)
+               return 0;
+       if (!clk->round_rate)
+               return 0;
+
+       return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret = -EINVAL;
+
+       if (!clk)
+               return ret;
+       if (!clk->set_rate || !rate)
+               return ret;
+
+       mutex_lock(&clocks_mutex);
+       ret = clk->set_rate(clk, rate);
+       mutex_unlock(&clocks_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       struct clk *old;
+       int ret = -EINVAL;
+
+       if (!clk)
+               return ret;
+       if (!clk->set_parent || !parent)
+               return ret;
+
+       mutex_lock(&clocks_mutex);
+       old = clk->parent;
+       if (clk->refcount)
+               __clk_enable(parent);
+       ret = clk->set_parent(clk, parent);
+       if (ret)
+               old = parent;
+       if (clk->refcount)
+               __clk_disable(old);
+       mutex_unlock(&clocks_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+       if (!clk)
+               return NULL;
+
+       return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..04b37a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/clock.h b/arch/arm/plat-tcc/include/mach/clock.h
new file mode 100644 (file)
index 0000000..a12f58a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Low level clock header file for Telechips TCC architecture
+ * (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_TCC_CLOCK_H__
+#define __ASM_ARCH_TCC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+
+struct clk {
+       struct clk *parent;
+       /* id number of a root clock, 0 for normal clocks */
+       int root_id;
+       /* Reference count of clock enable/disable */
+       int refcount;
+       /* Address of associated BCLKCTRx register. Must be set. */
+       void __iomem *bclkctr;
+       /* Bit position for BCLKCTRx. Must be set. */
+       int bclk_shift;
+       /* Address of ACLKxxx register, if any. */
+       void __iomem *aclkreg;
+       /* get the current clock rate (always a fresh value) */
+       unsigned long (*get_rate) (struct clk *);
+       /* Function ptr to set the clock to a new rate. The rate must match a
+          supported rate returned from round_rate. Leave blank if clock is not
+          programmable */
+       int (*set_rate) (struct clk *, unsigned long);
+       /* Function ptr to round the requested clock rate to the nearest
+          supported rate that is less than or equal to the requested rate. */
+       unsigned long (*round_rate) (struct clk *, unsigned long);
+       /* Function ptr to enable the clock. Leave blank if clock can not
+          be gated. */
+       int (*enable) (struct clk *);
+       /* Function ptr to disable the clock. Leave blank if clock can not
+          be gated. */
+       void (*disable) (struct clk *);
+       /* Function ptr to set the parent clock of the clock. */
+       int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..9753784
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+               .macro  addruart,rx,tmp
+               mrc     p15, 0, \rx, c1, c0
+               tst     \rx, #1                 @ MMU enabled?
+               moveq   \rx, #0x90000000        @ physical base address
+               movne   \rx, #0xF1000000        @ virtual base
+               orr     \rx, \rx, #0x00007000   @ UART0
+               .endm
+
+               .macro  senduart,rd,rx
+               strb    \rd, [\rx, #0x44]
+               .endm
+
+               .macro  waituart,rd,rx
+               .endm
+
+               .macro  busyuart,rd,rx
+1001:
+               ldr \rd, [\rx, #0x14]
+               tst \rd, #0x20
+
+               beq 1001b
+               .endm
diff --git a/arch/arm/plat-tcc/include/mach/entry-macro.S b/arch/arm/plat-tcc/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..748f401
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * include/asm-arm/arch-tcc83x/entry-macro.S
+ *
+ * Author : <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: Low-level IRQ helper macros for Telechips-based platforms
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * 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 <mach/hardware.h>
+#include <mach/irqs.h>
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               ldr     \base, =0xF2003000 @ base address of PIC registers
+
+               @@ read MREQ register of PIC0
+
+               mov     \irqnr, #0
+               ldr     \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts
+               cmp     \irqstat, #0
+               bne     1001f
+
+               @@ read MREQ register of PIC1
+
+               ldr     \irqstat, [\base, #0x00000094]  @ upper 32 interrupts
+               cmp     \irqstat, #0
+               beq     1002f
+               mov     \irqnr, #0x20
+
+1001:
+               movs    \tmp, \irqstat, lsl #16
+               movne   \irqstat, \tmp
+               addeq   \irqnr, \irqnr, #16
+
+               movs    \tmp, \irqstat, lsl #8
+               movne   \irqstat, \tmp
+               addeq   \irqnr, \irqnr, #8
+
+               movs    \tmp, \irqstat, lsl #4
+               movne   \irqstat, \tmp
+               addeq   \irqnr, \irqnr, #4
+
+               movs    \tmp, \irqstat, lsl #2
+               movne   \irqstat, \tmp
+               addeq   \irqnr, \irqnr, #2
+
+               movs    \tmp, \irqstat, lsl #1
+               addeq   \irqnr, \irqnr, #1
+               orrs    \base, \base, #1
+1002:
+               @@ exit here, Z flag unset if IRQ
+
+       .endm
diff --git a/arch/arm/plat-tcc/include/mach/hardware.h b/arch/arm/plat-tcc/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..e70d126
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ *                          and Dirk Behme <dirk.behme@de.bosch.com>
+ * Rewritten by:    <linux@telechips.com>
+ * Description: Hardware definitions for TCC8300 processors and boards
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Pulic License version 2.
+ */
+
+#ifndef __ASM_ARCH_TCC_HARDWARE_H
+#define __ASM_ARCH_TCC_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#endif
+#include <mach/io.h>
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE                0xfffece00
+#define ARM_CKCTL              (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1            (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2            (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT             (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1             (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2             (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST              (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3            (CLKGEN_REG_BASE + 0x24)
+
+/* DPLL control registers */
+#define DPLL_CTL               0xfffecf00
+
+#endif /* __ASM_ARCH_TCC_HARDWARE_H */
diff --git a/arch/arm/plat-tcc/include/mach/io.h b/arch/arm/plat-tcc/include/mach/io.h
new file mode 100644 (file)
index 0000000..3e911d3
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * IO definitions for TCC8000 processors and boards
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Public License version 2.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                        __typesafe_io(a)
+#define __mem_pci(a)           (a)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/irqs.h b/arch/arm/plat-tcc/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..da86389
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * IRQ definitions for TCC8xxx
+ *
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_TCC_IRQS_H
+#define __ASM_ARCH_TCC_IRQS_H
+
+#define NR_IRQS 64
+
+/* PIC0 interrupts */
+#define INT_ADMA1      0
+#define INT_BDMA       1
+#define INT_ADMA0      2
+#define INT_GDMA1      3
+#define INT_I2S0RX     4
+#define INT_I2S0TX     5
+#define INT_TC         6
+#define INT_UART0      7
+#define INT_USBD       8
+#define INT_SPI0TX     9
+#define INT_UDMA       10
+#define INT_LIRQ       11
+#define INT_GDMA2      12
+#define INT_GDMA0      13
+#define INT_TC32       14
+#define INT_LCD                15
+#define INT_ADC                16
+#define INT_I2C                17
+#define INT_RTCP       18
+#define INT_RTCA       19
+#define INT_NFC                20
+#define INT_SD0                21
+#define INT_GSB0       22
+#define INT_PK         23
+#define INT_USBH0      24
+#define INT_USBH1      25
+#define INT_G2D                26
+#define INT_ECC                27
+#define INT_SPI0RX     28
+#define INT_UART1      29
+#define INT_MSCL       30
+#define INT_GSB1       31
+/* PIC1 interrupts */
+#define INT_E0         32
+#define INT_E1         33
+#define INT_E2         34
+#define INT_E3         35
+#define INT_E4         36
+#define INT_E5         37
+#define INT_E6         38
+#define INT_E7         39
+#define INT_UART2      40
+#define INT_UART3      41
+#define INT_SPI1TX     42
+#define INT_SPI1RX     43
+#define INT_GSB2       44
+#define INT_SPDIF      45
+#define INT_CDIF       46
+#define INT_VBON       47
+#define INT_VBOFF      48
+#define INT_SD1                49
+#define INT_UART4      50
+#define INT_GDMA3      51
+#define INT_I2S1RX     52
+#define INT_I2S1TX     53
+#define INT_CAN0       54
+#define INT_CAN1       55
+#define INT_GSB3       56
+#define INT_KRST       57
+#define INT_UNUSED     58
+#define INT_SD0D3      59
+#define INT_SD1D3      60
+#define INT_GPS0       61
+#define INT_GPS1       62
+#define INT_GPS2       63
+
+#endif  /* ASM_ARCH_TCC_IRQS_H */
diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h
new file mode 100644 (file)
index 0000000..cd91ba8
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET            UL(0x20000000)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/system.h b/arch/arm/plat-tcc/include/mach/system.h
new file mode 100644 (file)
index 0000000..909e603
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: LINUX SYSTEM FUNCTIONS for TCC83x
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+extern void plat_tcc_reboot(void);
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       plat_tcc_reboot();
+}
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/tcc8k-regs.h b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
new file mode 100644 (file)
index 0000000..1d94282
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * Telechips TCC8000 register definitions
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPLv2.
+ */
+
+#ifndef TCC8K_REGS_H
+#define TCC8K_REGS_H
+
+#include <linux/types.h>
+
+#define EXT_SDRAM_BASE         0x20000000
+#define INT_SRAM_BASE          0x30000000
+#define INT_SRAM_SIZE          SZ_32K
+#define CS0_BASE               0x40000000
+#define CS1_BASE               0x50000000
+#define CS1_SIZE               SZ_64K
+#define CS2_BASE               0x60000000
+#define CS3_BASE               0x70000000
+#define AHB_PERI_BASE          0x80000000
+#define AHB_PERI_SIZE          SZ_64K
+#define APB0_PERI_BASE         0x90000000
+#define APB0_PERI_SIZE         SZ_128K
+#define APB1_PERI_BASE         0x98000000
+#define APB1_PERI_SIZE         SZ_128K
+#define DATA_TCM_BASE          0xa0000000
+#define DATA_TCM_SIZE          SZ_8K
+#define EXT_MEM_CTRL_BASE      0xf0000000
+#define EXT_MEM_CTRL_SIZE      SZ_4K
+
+#define CS1_BASE_VIRT          (void __iomem *)0xf7000000
+#define AHB_PERI_BASE_VIRT     (void __iomem *)0xf4000000
+#define APB0_PERI_BASE_VIRT    (void __iomem *)0xf1000000
+#define APB1_PERI_BASE_VIRT    (void __iomem *)0xf2000000
+#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000
+#define INT_SRAM_BASE_VIRT     (void __iomem *)0xf5000000
+#define DATA_TCM_BASE_VIRT     (void __iomem *)0xf6000000
+
+#define __REG(x)     (*((volatile u32 *)(x)))
+
+/* USB Device Controller Registers */
+#define UDC_BASE       (AHB_PERI_BASE_VIRT + 0x8000)
+#define UDC_BASE_PHYS  (AHB_PERI_BASE + 0x8000)
+
+#define UDC_IR_OFFS            0x00
+#define UDC_EIR_OFFS           0x04
+#define UDC_EIER_OFFS          0x08
+#define UDC_FAR_OFFS           0x0c
+#define UDC_FNR_OFFS           0x10
+#define UDC_EDR_OFFS           0x14
+#define UDC_RT_OFFS            0x18
+#define UDC_SSR_OFFS           0x1c
+#define UDC_SCR_OFFS           0x20
+#define UDC_EP0SR_OFFS         0x24
+#define UDC_EP0CR_OFFS         0x28
+
+#define UDC_ESR_OFFS           0x2c
+#define UDC_ECR_OFFS           0x30
+#define UDC_BRCR_OFFS          0x34
+#define UDC_BWCR_OFFS          0x38
+#define UDC_MPR_OFFS           0x3c
+#define UDC_DCR_OFFS           0x40
+#define UDC_DTCR_OFFS          0x44
+#define UDC_DFCR_OFFS          0x48
+#define UDC_DTTCR1_OFFS                0x4c
+#define UDC_DTTCR2_OFFS                0x50
+#define UDC_ESR2_OFFS          0x54
+
+#define UDC_SCR2_OFFS          0x58
+#define UDC_EP0BUF_OFFS                0x60
+#define UDC_EP1BUF_OFFS                0x64
+#define UDC_EP2BUF_OFFS                0x68
+#define UDC_EP3BUF_OFFS                0x6c
+#define UDC_PLICR_OFFS         0xa0
+#define UDC_PCR_OFFS           0xa4
+
+#define UDC_UPCR0_OFFS         0xc8
+#define UDC_UPCR1_OFFS         0xcc
+#define UDC_UPCR2_OFFS         0xd0
+#define UDC_UPCR3_OFFS         0xd4
+
+/* Bits in UDC_EIR */
+#define UDC_EIR_EP0I           (1 << 0)
+#define UDC_EIR_EP1I           (1 << 1)
+#define UDC_EIR_EP2I           (1 << 2)
+#define UDC_EIR_EP3I           (1 << 3)
+#define UDC_EIR_EPI_MASK       0x0f
+
+/* Bits in UDC_EIER */
+#define UDC_EIER_EP0IE         (1 << 0)
+#define UDC_EIER_EP1IE         (1 << 1)
+#define UDC_EIER_EP2IE         (1 << 2)
+#define UDC_EIER_EP3IE         (1 << 3)
+
+/* Bits in UDC_FNR */
+#define UDC_FNR_FN_MASK                0x7ff
+#define UDC_FNR_SM             (1 << 13)
+#define UDC_FNR_FTL            (1 << 14)
+
+/* Bits in UDC_SSR */
+#define UDC_SSR_HFRES          (1 << 0)
+#define UDC_SSR_HFSUSP         (1 << 1)
+#define UDC_SSR_HFRM           (1 << 2)
+#define UDC_SSR_SDE            (1 << 3)
+#define UDC_SSR_HSP            (1 << 4)
+#define UDC_SSR_DM             (1 << 5)
+#define UDC_SSR_DP             (1 << 6)
+#define UDC_SSR_TBM            (1 << 7)
+#define UDC_SSR_VBON           (1 << 8)
+#define UDC_SSR_VBOFF          (1 << 9)
+#define UDC_SSR_EOERR          (1 << 10)
+#define UDC_SSR_DCERR          (1 << 11)
+#define UDC_SSR_TCERR          (1 << 12)
+#define UDC_SSR_BSERR          (1 << 13)
+#define UDC_SSR_TMERR          (1 << 14)
+#define UDC_SSR_BAERR          (1 << 15)
+
+/* Bits in UDC_SCR */
+#define UDC_SCR_HRESE          (1 << 0)
+#define UDC_SCR_HSSPE          (1 << 1)
+#define UDC_SCR_RRDE           (1 << 5)
+#define UDC_SCR_SPDEN          (1 << 6)
+#define UDC_SCR_DIEN           (1 << 12)
+
+/* Bits in UDC_EP0SR */
+#define UDC_EP0SR_RSR          (1 << 0)
+#define UDC_EP0SR_TST          (1 << 1)
+#define UDC_EP0SR_SHT          (1 << 4)
+#define UDC_EP0SR_LWO          (1 << 6)
+
+/* Bits in UDC_EP0CR */
+#define UDC_EP0CR_ESS          (1 << 1)
+
+/* Bits in UDC_ESR */
+#define UDC_ESR_RPS            (1 << 0)
+#define UDC_ESR_TPS            (1 << 1)
+#define UDC_ESR_LWO            (1 << 4)
+#define UDC_ESR_FFS            (1 << 6)
+
+/* Bits in UDC_ECR */
+#define UDC_ECR_ESS            (1 << 1)
+#define UDC_ECR_CDP            (1 << 2)
+
+#define UDC_ECR_FLUSH          (1 << 6)
+#define UDC_ECR_DUEN           (1 << 7)
+
+/* Bits in UDC_UPCR0 */
+#define UDC_UPCR0_VBD          (1 << 1)
+#define UDC_UPCR0_VBDS         (1 << 6)
+#define UDC_UPCR0_RCD_12       (0x0 << 9)
+#define UDC_UPCR0_RCD_24       (0x1 << 9)
+#define UDC_UPCR0_RCD_48       (0x2 << 9)
+#define UDC_UPCR0_RCS_EXT      (0x1 << 11)
+#define UDC_UPCR0_RCS_XTAL     (0x0 << 11)
+
+/* Bits in UDC_UPCR1 */
+#define UDC_UPCR1_CDT(x)       ((x) << 0)
+#define UDC_UPCR1_OTGT(x)      ((x) << 3)
+#define UDC_UPCR1_SQRXT(x)     ((x) << 8)
+#define UDC_UPCR1_TXFSLST(x)   ((x) << 12)
+
+/* Bits in UDC_UPCR2 */
+#define UDC_UPCR2_TP           (1 << 0)
+#define UDC_UPCR2_TXRT(x)      ((x) << 2)
+#define UDC_UPCR2_TXVRT(x)     ((x) << 5)
+#define UDC_UPCR2_OPMODE(x)    ((x) << 9)
+#define UDC_UPCR2_XCVRSEL(x)   ((x) << 12)
+#define UDC_UPCR2_TM           (1 << 14)
+
+/* USB Host Controller registers */
+#define USBH0_BASE     (AHB_PERI_BASE_VIRT + 0xb000)
+#define USBH1_BASE     (AHB_PERI_BASE_VIRT + 0xb800)
+
+#define OHCI_INT_ENABLE_OFFS   0x10
+
+#define RH_DESCRIPTOR_A_OFFS   0x48
+#define RH_DESCRIPTOR_B_OFFS   0x4c
+
+#define USBHTCFG0_OFFS         0x100
+#define USBHHCFG0_OFFS         0x104
+#define USBHHCFG1_OFFS         0x104
+
+/* DMA controller registers */
+#define DMAC0_BASE     (AHB_PERI_BASE + 0x4000)
+#define DMAC1_BASE     (AHB_PERI_BASE + 0xa000)
+#define DMAC2_BASE     (AHB_PERI_BASE + 0x4800)
+#define DMAC3_BASE     (AHB_PERI_BASE + 0xa800)
+
+#define DMAC_CH_OFFSET(ch)     (ch * 0x30)
+
+#define ST_SADR_OFFS           0x00
+#define SPARAM_OFFS            0x04
+#define C_SADR_OFFS            0x0c
+#define ST_DADR_OFFS           0x10
+#define DPARAM_OFFS            0x14
+#define C_DADR_OFFS            0x1c
+#define HCOUNT_OFFS            0x20
+#define CHCTRL_OFFS            0x24
+#define RPTCTRL_OFFS           0x28
+#define EXTREQ_A_OFFS          0x2c
+
+/* Bits in CHCTRL register */
+#define CHCTRL_EN              (1 << 0)
+
+#define CHCTRL_IEN             (1 << 2)
+#define CHCTRL_FLAG            (1 << 3)
+#define CHCTRL_WSIZE8          (0 << 4)
+#define CHCTRL_WSIZE16         (1 << 4)
+#define CHCTRL_WSIZE32         (2 << 4)
+
+#define CHCTRL_BSIZE1          (0 << 6)
+#define CHCTRL_BSIZE2          (1 << 6)
+#define CHCTRL_BSIZE4          (2 << 6)
+#define CHCTRL_BSIZE8          (3 << 6)
+
+#define CHCTRL_TYPE_SINGLE_E   (0 << 8)
+#define CHCTRL_TYPE_HW         (1 << 8)
+#define CHCTRL_TYPE_SW         (2 << 8)
+#define CHCTRL_TYPE_SINGLE_L   (3 << 8)
+
+#define CHCTRL_BST             (1 << 10)
+
+/* Use DMA controller 0, channel 2 for USB */
+#define USB_DMA_BASE           (DMAC0_BASE + DMAC_CH_OFFSET(2))
+
+/* NAND flash controller registers */
+#define NFC_BASE       (AHB_PERI_BASE_VIRT + 0xd000)
+#define NFC_BASE_PHYS  (AHB_PERI_BASE + 0xd000)
+
+#define NFC_CMD_OFFS           0x00
+#define NFC_LADDR_OFFS         0x04
+#define NFC_BADDR_OFFS         0x08
+#define NFC_SADDR_OFFS         0x0c
+#define NFC_WDATA_OFFS         0x10
+#define NFC_LDATA_OFFS         0x20
+#define NFC_SDATA_OFFS         0x40
+#define NFC_CTRL_OFFS          0x50
+#define NFC_PSTART_OFFS                0x54
+#define NFC_RSTART_OFFS                0x58
+#define NFC_DSIZE_OFFS         0x5c
+#define NFC_IREQ_OFFS          0x60
+#define NFC_RST_OFFS           0x64
+#define NFC_CTRL1_OFFS         0x68
+#define NFC_MDATA_OFFS         0x70
+
+#define NFC_WDATA_PHYS_ADDR    (NFC_BASE_PHYS + NFC_WDATA_OFFS)
+
+/* Bits in NFC_CTRL */
+#define NFC_CTRL_BHLD_MASK     (0xf << 0)
+#define NFC_CTRL_BPW_MASK      (0xf << 4)
+#define NFC_CTRL_BSTP_MASK     (0xf << 8)
+#define NFC_CTRL_CADDR_MASK    (0x7 << 12)
+#define NFC_CTRL_CADDR_1       (0x0 << 12)
+#define NFC_CTRL_CADDR_2       (0x1 << 12)
+#define NFC_CTRL_CADDR_3       (0x2 << 12)
+#define NFC_CTRL_CADDR_4       (0x3 << 12)
+#define NFC_CTRL_CADDR_5       (0x4 << 12)
+#define NFC_CTRL_MSK           (1 << 15)
+#define NFC_CTRL_PSIZE256      (0 << 16)
+#define NFC_CTRL_PSIZE512      (1 << 16)
+#define NFC_CTRL_PSIZE1024     (2 << 16)
+#define NFC_CTRL_PSIZE2048     (3 << 16)
+#define NFC_CTRL_PSIZE4096     (4 << 16)
+#define NFC_CTRL_PSIZE_MASK    (7 << 16)
+#define NFC_CTRL_BSIZE1                (0 << 19)
+#define NFC_CTRL_BSIZE2                (1 << 19)
+#define NFC_CTRL_BSIZE4                (2 << 19)
+#define NFC_CTRL_BSIZE8                (3 << 19)
+#define NFC_CTRL_BSIZE_MASK    (3 << 19)
+#define NFC_CTRL_RDY           (1 << 21)
+#define NFC_CTRL_CS0SEL                (1 << 22)
+#define NFC_CTRL_CS1SEL                (1 << 23)
+#define NFC_CTRL_CS2SEL                (1 << 24)
+#define NFC_CTRL_CS3SEL                (1 << 25)
+#define NFC_CTRL_CSMASK                (0xf << 22)
+#define NFC_CTRL_BW            (1 << 26)
+#define NFC_CTRL_FS            (1 << 27)
+#define NFC_CTRL_DEN           (1 << 28)
+#define NFC_CTRL_READ_IEN      (1 << 29)
+#define NFC_CTRL_PROG_IEN      (1 << 30)
+#define NFC_CTRL_RDY_IEN       (1 << 31)
+
+/* Bits in NFC_IREQ */
+#define NFC_IREQ_IRQ0          (1 << 0)
+#define NFC_IREQ_IRQ1          (1 << 1)
+#define NFC_IREQ_IRQ2          (1 << 2)
+
+#define NFC_IREQ_FLAG0         (1 << 4)
+#define NFC_IREQ_FLAG1         (1 << 5)
+#define NFC_IREQ_FLAG2         (1 << 6)
+
+/* MMC controller registers */
+#define MMC0_BASE      (AHB_PERI_BASE_VIRT + 0xe000)
+#define MMC1_BASE      (AHB_PERI_BASE_VIRT + 0xe800)
+
+/* UART base addresses */
+
+#define UART0_BASE     (APB0_PERI_BASE_VIRT + 0x07000)
+#define UART0_BASE_PHYS        (APB0_PERI_BASE + 0x07000)
+#define UART1_BASE     (APB0_PERI_BASE_VIRT + 0x08000)
+#define UART1_BASE_PHYS        (APB0_PERI_BASE + 0x08000)
+#define UART2_BASE     (APB0_PERI_BASE_VIRT + 0x09000)
+#define UART2_BASE_PHYS        (APB0_PERI_BASE + 0x09000)
+#define UART3_BASE     (APB0_PERI_BASE_VIRT + 0x0a000)
+#define UART3_BASE_PHYS        (APB0_PERI_BASE + 0x0a000)
+#define UART4_BASE     (APB0_PERI_BASE_VIRT + 0x15000)
+#define UART4_BASE_PHYS        (APB0_PERI_BASE + 0x15000)
+
+#define UART_BASE      UART0_BASE
+#define UART_BASE_PHYS UART0_BASE_PHYS
+
+/* ECC controller */
+#define ECC_CTR_BASE   (APB0_PERI_BASE_VIRT + 0xd000)
+
+#define ECC_CTRL_OFFS          0x00
+#define ECC_BASE_OFFS          0x04
+#define ECC_MASK_OFFS          0x08
+#define ECC_CLEAR_OFFS         0x0c
+#define ECC4_0_OFFS            0x10
+#define ECC4_1_OFFS            0x14
+
+#define ECC_EADDR0_OFFS                0x50
+
+#define ECC_ERRNUM_OFFS                0x90
+#define ECC_IREQ_OFFS          0x94
+
+/* Bits in ECC_CTRL */
+#define ECC_CTRL_ECC4_DIEN     (1 << 28)
+#define ECC_CTRL_ECC8_DIEN     (1 << 29)
+#define ECC_CTRL_ECC12_DIEN    (1 << 30)
+#define ECC_CTRL_ECC_DISABLE   0x0
+#define ECC_CTRL_ECC_SLC_ENC   0x8
+#define ECC_CTRL_ECC_SLC_DEC   0x9
+#define ECC_CTRL_ECC4_ENC      0xa
+#define ECC_CTRL_ECC4_DEC      0xb
+#define ECC_CTRL_ECC8_ENC      0xc
+#define ECC_CTRL_ECC8_DEC      0xd
+#define ECC_CTRL_ECC12_ENC     0xe
+#define ECC_CTRL_ECC12_DEC     0xf
+
+/* Bits in ECC_IREQ */
+#define ECC_IREQ_E4DI          (1 << 4)
+
+#define ECC_IREQ_E4DF          (1 << 20)
+#define ECC_IREQ_E4EF          (1 << 21)
+
+/* Interrupt controller */
+
+#define PIC0_BASE      (APB1_PERI_BASE_VIRT + 0x3000)
+#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000)
+
+#define PIC0_IEN_OFFS          0x00
+#define PIC0_CREQ_OFFS         0x04
+#define PIC0_IREQ_OFFS         0x08
+#define PIC0_IRQSEL_OFFS       0x0c
+#define PIC0_SRC_OFFS          0x10
+#define PIC0_MREQ_OFFS         0x14
+#define PIC0_TSTREQ_OFFS       0x18
+#define PIC0_POL_OFFS          0x1c
+#define PIC0_IRQ_OFFS          0x20
+#define PIC0_FIQ_OFFS          0x24
+#define PIC0_MIRQ_OFFS         0x28
+#define PIC0_MFIQ_OFFS         0x2c
+#define PIC0_TMODE_OFFS                0x30
+#define PIC0_SYNC_OFFS         0x34
+#define PIC0_WKUP_OFFS         0x38
+#define PIC0_TMODEA_OFFS       0x3c
+#define PIC0_INTOEN_OFFS       0x40
+#define PIC0_MEN0_OFFS         0x44
+#define PIC0_MEN_OFFS          0x48
+
+#define PIC0_IEN               __REG(PIC0_BASE + PIC0_IEN_OFFS)
+#define PIC0_IEN_PHYS          __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS)
+#define PIC0_CREQ              __REG(PIC0_BASE + PIC0_CREQ_OFFS)
+#define PIC0_CREQ_PHYS         __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS)
+#define PIC0_IREQ              __REG(PIC0_BASE + PIC0_IREQ_OFFS)
+#define PIC0_IRQSEL            __REG(PIC0_BASE + PIC0_IRQSEL_OFFS)
+#define PIC0_IRQSEL_PHYS       __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS)
+#define PIC0_SRC               __REG(PIC0_BASE + PIC0_SRC_OFFS)
+#define PIC0_MREQ              __REG(PIC0_BASE + PIC0_MREQ_OFFS)
+#define PIC0_TSTREQ            __REG(PIC0_BASE + PIC0_TSTREQ_OFFS)
+#define PIC0_POL               __REG(PIC0_BASE + PIC0_POL_OFFS)
+#define PIC0_IRQ               __REG(PIC0_BASE + PIC0_IRQ_OFFS)
+#define PIC0_FIQ               __REG(PIC0_BASE + PIC0_FIQ_OFFS)
+#define PIC0_MIRQ              __REG(PIC0_BASE + PIC0_MIRQ_OFFS)
+#define PIC0_MFIQ              __REG(PIC0_BASE + PIC0_MFIQ_OFFS)
+#define PIC0_TMODE             __REG(PIC0_BASE + PIC0_TMODE_OFFS)
+#define PIC0_TMODE_PHYS                __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS)
+#define PIC0_SYNC              __REG(PIC0_BASE + PIC0_SYNC_OFFS)
+#define PIC0_WKUP              __REG(PIC0_BASE + PIC0_WKUP_OFFS)
+#define PIC0_TMODEA            __REG(PIC0_BASE + PIC0_TMODEA_OFFS)
+#define PIC0_INTOEN            __REG(PIC0_BASE + PIC0_INTOEN_OFFS)
+#define PIC0_MEN0              __REG(PIC0_BASE + PIC0_MEN0_OFFS)
+#define PIC0_MEN               __REG(PIC0_BASE + PIC0_MEN_OFFS)
+
+#define PIC1_BASE      (APB1_PERI_BASE_VIRT + 0x3080)
+
+#define PIC1_IEN_OFFS          0x00
+#define PIC1_CREQ_OFFS         0x04
+#define PIC1_IREQ_OFFS         0x08
+#define PIC1_IRQSEL_OFFS       0x0c
+#define PIC1_SRC_OFFS          0x10
+#define PIC1_MREQ_OFFS         0x14
+#define PIC1_TSTREQ_OFFS       0x18
+#define PIC1_POL_OFFS          0x1c
+#define PIC1_IRQ_OFFS          0x20
+#define PIC1_FIQ_OFFS          0x24
+#define PIC1_MIRQ_OFFS         0x28
+#define PIC1_MFIQ_OFFS         0x2c
+#define PIC1_TMODE_OFFS                0x30
+#define PIC1_SYNC_OFFS         0x34
+#define PIC1_WKUP_OFFS         0x38
+#define PIC1_TMODEA_OFFS       0x3c
+#define PIC1_INTOEN_OFFS       0x40
+#define PIC1_MEN1_OFFS         0x44
+#define PIC1_MEN_OFFS          0x48
+
+#define PIC1_IEN       __REG(PIC1_BASE + PIC1_IEN_OFFS)
+#define PIC1_CREQ      __REG(PIC1_BASE + PIC1_CREQ_OFFS)
+#define PIC1_IREQ      __REG(PIC1_BASE + PIC1_IREQ_OFFS)
+#define PIC1_IRQSEL    __REG(PIC1_BASE + PIC1_IRQSEL_OFFS)
+#define PIC1_SRC       __REG(PIC1_BASE + PIC1_SRC_OFFS)
+#define PIC1_MREQ      __REG(PIC1_BASE + PIC1_MREQ_OFFS)
+#define PIC1_TSTREQ    __REG(PIC1_BASE + PIC1_TSTREQ_OFFS)
+#define PIC1_POL       __REG(PIC1_BASE + PIC1_POL_OFFS)
+#define PIC1_IRQ       __REG(PIC1_BASE + PIC1_IRQ_OFFS)
+#define PIC1_FIQ       __REG(PIC1_BASE + PIC1_FIQ_OFFS)
+#define PIC1_MIRQ      __REG(PIC1_BASE + PIC1_MIRQ_OFFS)
+#define PIC1_MFIQ      __REG(PIC1_BASE + PIC1_MFIQ_OFFS)
+#define PIC1_TMODE     __REG(PIC1_BASE + PIC1_TMODE_OFFS)
+#define PIC1_SYNC      __REG(PIC1_BASE + PIC1_SYNC_OFFS)
+#define PIC1_WKUP      __REG(PIC1_BASE + PIC1_WKUP_OFFS)
+#define PIC1_TMODEA    __REG(PIC1_BASE + PIC1_TMODEA_OFFS)
+#define PIC1_INTOEN    __REG(PIC1_BASE + PIC1_INTOEN_OFFS)
+#define PIC1_MEN1      __REG(PIC1_BASE + PIC1_MEN1_OFFS)
+#define PIC1_MEN       __REG(PIC1_BASE + PIC1_MEN_OFFS)
+
+/* Timer registers */
+#define TIMER_BASE             (APB1_PERI_BASE_VIRT + 0x4000)
+#define TIMER_BASE_PHYS                (APB1_PERI_BASE + 0x4000)
+
+#define TWDCFG_OFFS            0x70
+
+#define TC32EN_OFFS            0x80
+#define TC32LDV_OFFS           0x84
+#define TC32CMP0_OFFS          0x88
+#define TC32CMP1_OFFS          0x8c
+#define TC32PCNT_OFFS          0x90
+#define TC32MCNT_OFFS          0x94
+#define TC32IRQ_OFFS           0x98
+
+/* Bits in TC32EN */
+#define TC32EN_PRESCALE_MASK   0x00ffffff
+#define TC32EN_ENABLE          (1 << 24)
+#define TC32EN_LOADZERO                (1 << 25)
+#define TC32EN_STOPMODE                (1 << 26)
+#define TC32EN_LDM0            (1 << 28)
+#define TC32EN_LDM1            (1 << 29)
+
+/* Bits in TC32IRQ */
+#define TC32IRQ_MSTAT_MASK     0x0000001f
+#define TC32IRQ_RSTAT_MASK     (0x1f << 8)
+#define TC32IRQ_IRQEN0         (1 << 16)
+#define TC32IRQ_IRQEN1         (1 << 17)
+#define TC32IRQ_IRQEN2         (1 << 18)
+#define TC32IRQ_IRQEN3         (1 << 19)
+#define TC32IRQ_IRQEN4         (1 << 20)
+#define TC32IRQ_RSYNC          (1 << 30)
+#define TC32IRQ_IRQCLR         (1 << 31)
+
+/* GPIO registers */
+#define GPIOPD_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPD_DAT_OFFS                0x00
+#define GPIOPD_DOE_OFFS                0x04
+#define GPIOPD_FS0_OFFS                0x08
+#define GPIOPD_FS1_OFFS                0x0c
+#define GPIOPD_FS2_OFFS                0x10
+#define GPIOPD_RPU_OFFS                0x30
+#define GPIOPD_RPD_OFFS                0x34
+#define GPIOPD_DV0_OFFS                0x38
+#define GPIOPD_DV1_OFFS                0x3c
+
+#define GPIOPS_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPS_DAT_OFFS                0x40
+#define GPIOPS_DOE_OFFS                0x44
+#define GPIOPS_FS0_OFFS                0x48
+#define GPIOPS_FS1_OFFS                0x4c
+#define GPIOPS_FS2_OFFS                0x50
+#define GPIOPS_FS3_OFFS                0x54
+#define GPIOPS_RPU_OFFS                0x70
+#define GPIOPS_RPD_OFFS                0x74
+#define GPIOPS_DV0_OFFS                0x78
+#define GPIOPS_DV1_OFFS                0x7c
+
+#define GPIOPS_FS1_SDH0_BITS   0x000000ff
+#define GPIOPS_FS1_SDH1_BITS   0x0000ff00
+
+#define GPIOPU_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPU_DAT_OFFS                0x80
+#define GPIOPU_DOE_OFFS                0x84
+#define GPIOPU_FS0_OFFS                0x88
+#define GPIOPU_FS1_OFFS                0x8c
+#define GPIOPU_FS2_OFFS                0x90
+#define GPIOPU_RPU_OFFS                0xb0
+#define GPIOPU_RPD_OFFS                0xb4
+#define GPIOPU_DV0_OFFS                0xb8
+#define GPIOPU_DV1_OFFS                0xbc
+
+#define GPIOPU_FS0_TXD0                (1 << 0)
+#define GPIOPU_FS0_RXD0                (1 << 1)
+#define GPIOPU_FS0_CTS0                (1 << 2)
+#define GPIOPU_FS0_RTS0                (1 << 3)
+#define GPIOPU_FS0_TXD1                (1 << 4)
+#define GPIOPU_FS0_RXD1                (1 << 5)
+#define GPIOPU_FS0_CTS1                (1 << 6)
+#define GPIOPU_FS0_RTS1                (1 << 7)
+#define GPIOPU_FS0_TXD2                (1 << 8)
+#define GPIOPU_FS0_RXD2                (1 << 9)
+#define GPIOPU_FS0_CTS2                (1 << 10)
+#define GPIOPU_FS0_RTS2                (1 << 11)
+#define GPIOPU_FS0_TXD3                (1 << 12)
+#define GPIOPU_FS0_RXD3                (1 << 13)
+#define GPIOPU_FS0_CTS3                (1 << 14)
+#define GPIOPU_FS0_RTS3                (1 << 15)
+#define GPIOPU_FS0_TXD4                (1 << 16)
+#define GPIOPU_FS0_RXD4                (1 << 17)
+#define GPIOPU_FS0_CTS4                (1 << 18)
+#define GPIOPU_FS0_RTS4                (1 << 19)
+
+#define GPIOFC_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFC_DAT_OFFS                0xc0
+#define GPIOFC_DOE_OFFS                0xc4
+#define GPIOFC_FS0_OFFS                0xc8
+#define GPIOFC_FS1_OFFS                0xcc
+#define GPIOFC_FS2_OFFS                0xd0
+#define GPIOFC_FS3_OFFS                0xd4
+#define GPIOFC_RPU_OFFS                0xf0
+#define GPIOFC_RPD_OFFS                0xf4
+#define GPIOFC_DV0_OFFS                0xf8
+#define GPIOFC_DV1_OFFS                0xfc
+
+#define GPIOFD_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFD_DAT_OFFS                0x100
+#define GPIOFD_DOE_OFFS                0x104
+#define GPIOFD_FS0_OFFS                0x108
+#define GPIOFD_FS1_OFFS                0x10c
+#define GPIOFD_FS2_OFFS                0x110
+#define GPIOFD_RPU_OFFS                0x130
+#define GPIOFD_RPD_OFFS                0x134
+#define GPIOFD_DV0_OFFS                0x138
+#define GPIOFD_DV1_OFFS                0x13c
+
+#define GPIOLC_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLC_DAT_OFFS                0x140
+#define GPIOLC_DOE_OFFS                0x144
+#define GPIOLC_FS0_OFFS                0x148
+#define GPIOLC_FS1_OFFS                0x14c
+#define GPIOLC_RPU_OFFS                0x170
+#define GPIOLC_RPD_OFFS                0x174
+#define GPIOLC_DV0_OFFS                0x178
+#define GPIOLC_DV1_OFFS                0x17c
+
+#define GPIOLD_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLD_DAT_OFFS                0x180
+#define GPIOLD_DOE_OFFS                0x184
+#define GPIOLD_FS0_OFFS                0x188
+#define GPIOLD_FS1_OFFS                0x18c
+#define GPIOLD_FS2_OFFS                0x190
+#define GPIOLD_RPU_OFFS                0x1b0
+#define GPIOLD_RPD_OFFS                0x1b4
+#define GPIOLD_DV0_OFFS                0x1b8
+#define GPIOLD_DV1_OFFS                0x1bc
+
+#define GPIOAD_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOAD_DAT_OFFS                0x1c0
+#define GPIOAD_DOE_OFFS                0x1c4
+#define GPIOAD_FS0_OFFS                0x1c8
+#define GPIOAD_RPU_OFFS                0x1f0
+#define GPIOAD_RPD_OFFS                0x1f4
+#define GPIOAD_DV0_OFFS                0x1f8
+#define GPIOAD_DV1_OFFS                0x1fc
+
+#define GPIOXC_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXC_DAT_OFFS                0x200
+#define GPIOXC_DOE_OFFS                0x204
+#define GPIOXC_FS0_OFFS                0x208
+#define GPIOXC_RPU_OFFS                0x230
+#define GPIOXC_RPD_OFFS                0x234
+#define GPIOXC_DV0_OFFS                0x238
+#define GPIOXC_DV1_OFFS                0x23c
+
+#define GPIOXC_FS0             __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS)
+
+#define GPIOXC_FS0_CS0         (1 << 26)
+#define GPIOXC_FS0_CS1         (1 << 27)
+
+#define GPIOXD_BASE            (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXD_DAT_OFFS                0x240
+#define GPIOXD_FS0_OFFS                0x248
+#define GPIOXD_RPU_OFFS                0x270
+#define GPIOXD_RPD_OFFS                0x274
+#define GPIOXD_DV0_OFFS                0x278
+#define GPIOXD_DV1_OFFS                0x27c
+
+#define GPIOPK_BASE            (APB1_PERI_BASE_VIRT + 0x1c000)
+
+#define GPIOPK_RST_OFFS                0x008
+#define GPIOPK_DAT_OFFS                0x100
+#define GPIOPK_DOE_OFFS                0x104
+#define GPIOPK_FS0_OFFS                0x108
+#define GPIOPK_FS1_OFFS                0x10c
+#define GPIOPK_FS2_OFFS                0x110
+#define GPIOPK_IRQST_OFFS      0x210
+#define GPIOPK_IRQEN_OFFS      0x214
+#define GPIOPK_IRQPOL_OFFS     0x218
+#define GPIOPK_IRQTM0_OFFS     0x21c
+#define GPIOPK_IRQTM1_OFFS     0x220
+#define GPIOPK_CTL_OFFS                0x22c
+
+#define PMGPIO_BASE            (APB1_PERI_BASE_VIRT + 0x10000)
+#define BACKUP_RAM_BASE                PMGPIO_BASE
+
+#define PMGPIO_DAT_OFFS                0x800
+#define PMGPIO_DOE_OFFS                0x804
+#define PMGPIO_FS0_OFFS                0x808
+#define PMGPIO_RPU_OFFS                0x810
+#define PMGPIO_RPD_OFFS                0x814
+#define PMGPIO_DV0_OFFS                0x818
+#define PMGPIO_DV1_OFFS                0x81c
+#define PMGPIO_EE0_OFFS                0x820
+#define PMGPIO_EE1_OFFS                0x824
+#define PMGPIO_CTL_OFFS                0x828
+#define PMGPIO_DI_OFFS         0x82c
+#define PMGPIO_STR_OFFS                0x830
+#define PMGPIO_STF_OFFS                0x834
+#define PMGPIO_POL_OFFS                0x838
+#define PMGPIO_APB_OFFS                0x800
+
+/* Clock controller registers */
+#define CKC_BASE       ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000))
+
+#define CLKCTRL_OFFS           0x00
+#define PLL0CFG_OFFS           0x04
+#define PLL1CFG_OFFS           0x08
+#define CLKDIVC0_OFFS          0x0c
+
+#define BCLKCTR0_OFFS          0x14
+#define SWRESET0_OFFS          0x18
+
+#define BCLKCTR1_OFFS          0x60
+#define SWRESET1_OFFS          0x64
+#define PWDCTL_OFFS            0x68
+#define PLL2CFG_OFFS           0x6c
+#define CLKDIVC1_OFFS          0x70
+
+#define ACLKREF_OFFS           0x80
+#define ACLKI2C_OFFS           0x84
+#define ACLKSPI0_OFFS          0x88
+#define ACLKSPI1_OFFS          0x8c
+#define ACLKUART0_OFFS         0x90
+#define ACLKUART1_OFFS         0x94
+#define ACLKUART2_OFFS         0x98
+#define ACLKUART3_OFFS         0x9c
+#define ACLKUART4_OFFS         0xa0
+#define ACLKTCT_OFFS           0xa4
+#define ACLKTCX_OFFS           0xa8
+#define ACLKTCZ_OFFS           0xac
+#define ACLKADC_OFFS           0xb0
+#define ACLKDAI0_OFFS          0xb4
+#define ACLKDAI1_OFFS          0xb8
+#define ACLKLCD_OFFS           0xbc
+#define ACLKSPDIF_OFFS         0xc0
+#define ACLKUSBH_OFFS          0xc4
+#define ACLKSDH0_OFFS          0xc8
+#define ACLKSDH1_OFFS          0xcc
+#define ACLKC3DEC_OFFS         0xd0
+#define ACLKEXT_OFFS           0xd4
+#define ACLKCAN0_OFFS          0xd8
+#define ACLKCAN1_OFFS          0xdc
+#define ACLKGSB0_OFFS          0xe0
+#define ACLKGSB1_OFFS          0xe4
+#define ACLKGSB2_OFFS          0xe8
+#define ACLKGSB3_OFFS          0xec
+
+#define PLLxCFG_PD             (1 << 31)
+
+/* CLKCTRL bits */
+#define CLKCTRL_XE             (1 << 31)
+
+/* CLKDIVCx bits */
+#define CLKDIVC0_XTE           (1 << 7)
+#define CLKDIVC0_XE            (1 << 15)
+#define CLKDIVC0_P1E           (1 << 23)
+#define CLKDIVC0_P0E           (1 << 31)
+
+#define CLKDIVC1_P2E           (1 << 7)
+
+/* BCLKCTR0 clock bits */
+#define BCLKCTR0_USBD          (1 << 4)
+#define BCLKCTR0_ECC           (1 << 9)
+#define BCLKCTR0_USBH0         (1 << 11)
+#define BCLKCTR0_NFC           (1 << 16)
+
+/* BCLKCTR1 clock bits */
+#define BCLKCTR1_USBH1         (1 << 20)
+
+/* SWRESET0 bits */
+#define SWRESET0_USBD          (1 << 4)
+#define SWRESET0_USBH0         (1 << 11)
+
+/* SWRESET1 bits */
+#define SWRESET1_USBH1         (1 << 20)
+
+/* System clock sources.
+ * Note: These are the clock sources that serve as parents for
+ * all other clocks. They have no parents themselves.
+ *
+ * These values are used for struct clk->root_id. All clocks
+ * that are not system clock sources have this value set to
+ * CLK_SRC_NOROOT.
+ * The values for system clocks start with CLK_SRC_PLL0 == 0
+ * because this gives us exactly the values needed for the lower
+ * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is
+ * defined as -1 to not disturb the order.
+ */
+enum root_clks {
+       CLK_SRC_NOROOT = -1,
+       CLK_SRC_PLL0 = 0,
+       CLK_SRC_PLL1,
+       CLK_SRC_PLL0DIV,
+       CLK_SRC_PLL1DIV,
+       CLK_SRC_XI,
+       CLK_SRC_XIDIV,
+       CLK_SRC_XTI,
+       CLK_SRC_XTIDIV,
+       CLK_SRC_PLL2,
+       CLK_SRC_PLL2DIV,
+       CLK_SRC_PK0,
+       CLK_SRC_PK1,
+       CLK_SRC_PK2,
+       CLK_SRC_PK3,
+       CLK_SRC_PK4,
+       CLK_SRC_48MHZ
+};
+
+#define CLK_SRC_MASK           0xf
+
+/* Bits in ACLK* registers */
+#define ACLK_EN                (1 << 28)
+#define ACLK_SEL_SHIFT         24
+#define ACLK_SEL_MASK          0x0f000000
+#define ACLK_DIV_MASK          0x00000fff
+
+/* System configuration registers */
+
+#define SCFG_BASE              (APB1_PERI_BASE_VIRT + 0x13000)
+
+#define        BMI_OFFS                0x00
+#define AHBCON0_OFFS           0x04
+#define APBPWE_OFFS            0x08
+#define DTCMWAIT_OFFS          0x0c
+#define ECCSEL_OFFS            0x10
+#define AHBCON1_OFFS           0x14
+#define SDHCFG_OFFS            0x18
+#define REMAP_OFFS             0x20
+#define LCDSIAE_OFFS           0x24
+#define XMCCFG_OFFS            0xe0
+#define IMCCFG_OFFS            0xe4
+
+/* Values for ECCSEL */
+#define ECCSEL_EXTMEM          0x0
+#define ECCSEL_DTCM            0x1
+#define ECCSEL_INT_SRAM                0x2
+#define ECCSEL_AHB             0x3
+
+/* Bits in XMCCFG */
+#define XMCCFG_NFCE            (1 << 1)
+#define XMCCFG_FDXD            (1 << 2)
+
+/* External memory controller registers */
+
+#define EMC_BASE               EXT_MEM_CTRL_BASE
+
+#define SDCFG_OFFS             0x00
+#define SDFSM_OFFS             0x04
+#define MCFG_OFFS              0x08
+
+#define CSCFG0_OFFS            0x10
+#define CSCFG1_OFFS            0x14
+#define CSCFG2_OFFS            0x18
+#define CSCFG3_OFFS            0x1c
+
+#define MCFG_SDEN              (1 << 4)
+
+#endif /* TCC8K_REGS_H */
diff --git a/arch/arm/plat-tcc/include/mach/timex.h b/arch/arm/plat-tcc/include/mach/timex.h
new file mode 100644 (file)
index 0000000..057acbe
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * A definition needed by arch core code.
+ *
+ */
+#define CLOCK_TICK_RATE                (HZ * 100000UL)
diff --git a/arch/arm/plat-tcc/include/mach/uncompress.h b/arch/arm/plat-tcc/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..7a3e33a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This file is licensed under the terms of the GPL version 2.
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/types.h>
+
+#include <mach/tcc8k-regs.h>
+
+unsigned int system_rev;
+
+#define ID_MASK                        0x7fff
+
+static void putc(int c)
+{
+       u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2));
+       u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2));
+
+       while (!(*uart_lsr & UART_LSR_THRE))
+               barrier();
+       *uart_tx = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/plat-tcc/include/mach/vmalloc.h b/arch/arm/plat-tcc/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..99414d9
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ *
+ * Copyright (C) 2000 Russell King.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+#define VMALLOC_END    0xf0000000UL
diff --git a/arch/arm/plat-tcc/system.c b/arch/arm/plat-tcc/system.c
new file mode 100644 (file)
index 0000000..cc208fa
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * System functions for Telechips TCCxxxx SoCs
+ *
+ * Copyright (C) Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#include <linux/io.h>
+
+#include <mach/tcc8k-regs.h>
+
+/* System reboot */
+void plat_tcc_reboot(void)
+{
+       /* Make sure clocks are on */
+       __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS);
+
+       /* Enable watchdog reset */
+       __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS);
+       /* Wait for reset */
+       while(1)
+               ;
+}
index f51572772e217d5ba9b674ffa2a5d68e5f13ca00..9ac87255a03a335917d994ddaa855f1ba180da79 100644 (file)
@@ -90,6 +90,7 @@ config PLATFORM_AT32AP
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_ALLOCATOR
        select HAVE_FB_ATMEL
+       select HAVE_NET_MACB
 
 #
 # CPU types
index 98f94d041d9c1dd212a0519efac60def8034b7db..a727f54d64d6e633d58ae2836bbbfae4c82f0017 100644 (file)
@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
        vfree(module->arch.syminfo);
        module->arch.syminfo = NULL;
 
-       return module_bug_finalize(hdr, sechdrs, module);
+       return 0;
 }
 
 void module_arch_cleanup(struct module *module)
 {
-       module_bug_cleanup(module);
 }
index 0974c0ecc594817ee9d8067aeba0eee7e3379dbf..bab01298b58ee2873fd7ef85de9230ac7af354f7 100644 (file)
@@ -121,6 +121,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
        struct user_context *user = current->thread.user;
        unsigned long tbr, psr;
 
+       /* Always make any pending restarted system calls return -EINTR */
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
        tbr = user->i.tbr;
        psr = user->i.psr;
        if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
@@ -250,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
        struct sigframe __user *frame;
        int rsig;
 
+       set_fs(USER_DS);
+
        frame = get_sigframe(ka, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -293,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
                                   (unsigned long) (frame->retcode + 2));
        }
 
-       /* set up registers for signal handler */
-       __frame->sp   = (unsigned long) frame;
-       __frame->lr   = (unsigned long) &frame->retcode;
-       __frame->gr8  = sig;
-
+       /* Set up registers for the signal handler */
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
                        (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
-               __get_user(__frame->pc, &funcptr->text);
-               __get_user(__frame->gr15, &funcptr->GOT);
+               struct fdpic_func_descriptor desc;
+               if (copy_from_user(&desc, funcptr, sizeof(desc)))
+                       goto give_sigsegv;
+               __frame->pc = desc.text;
+               __frame->gr15 = desc.GOT;
        } else {
                __frame->pc   = (unsigned long) ka->sa.sa_handler;
                __frame->gr15 = 0;
        }
 
-       set_fs(USER_DS);
+       __frame->sp   = (unsigned long) frame;
+       __frame->lr   = (unsigned long) &frame->retcode;
+       __frame->gr8  = sig;
 
        /* the tracer may want to single-step inside the handler */
        if (test_thread_flag(TIF_SINGLESTEP))
@@ -323,7 +329,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
        return 0;
 
 give_sigsegv:
-       force_sig(SIGSEGV, current);
+       force_sigsegv(sig, current);
        return -EFAULT;
 
 } /* end setup_frame() */
@@ -338,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        struct rt_sigframe __user *frame;
        int rsig;
 
+       set_fs(USER_DS);
+
        frame = get_sigframe(ka, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -392,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        /* Set up registers for signal handler */
-       __frame->sp  = (unsigned long) frame;
-       __frame->lr   = (unsigned long) &frame->retcode;
-       __frame->gr8 = sig;
-       __frame->gr9 = (unsigned long) &frame->info;
-
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
                        (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
-               __get_user(__frame->pc, &funcptr->text);
-               __get_user(__frame->gr15, &funcptr->GOT);
+               struct fdpic_func_descriptor desc;
+               if (copy_from_user(&desc, funcptr, sizeof(desc)))
+                       goto give_sigsegv;
+               __frame->pc = desc.text;
+               __frame->gr15 = desc.GOT;
        } else {
                __frame->pc   = (unsigned long) ka->sa.sa_handler;
                __frame->gr15 = 0;
        }
 
-       set_fs(USER_DS);
+       __frame->sp  = (unsigned long) frame;
+       __frame->lr  = (unsigned long) &frame->retcode;
+       __frame->gr8 = sig;
+       __frame->gr9 = (unsigned long) &frame->info;
 
        /* the tracer may want to single-step inside the handler */
        if (test_thread_flag(TIF_SINGLESTEP))
@@ -422,7 +431,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        return 0;
 
 give_sigsegv:
-       force_sig(SIGSEGV, current);
+       force_sigsegv(sig, current);
        return -EFAULT;
 
 } /* end setup_rt_frame() */
@@ -437,7 +446,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        int ret;
 
        /* Are we from a system call? */
-       if (in_syscall(__frame)) {
+       if (__frame->syscallno != -1) {
                /* If so, check system call restarting.. */
                switch (__frame->gr8) {
                case -ERESTART_RESTARTBLOCK:
@@ -456,6 +465,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
                        __frame->gr8 = __frame->orig_gr8;
                        __frame->pc -= 4;
                }
+               __frame->syscallno = -1;
        }
 
        /* Set up the stack frame */
@@ -538,10 +548,11 @@ no_signal:
                        break;
 
                case -ERESTART_RESTARTBLOCK:
-                       __frame->gr8 = __NR_restart_syscall;
+                       __frame->gr7 = __NR_restart_syscall;
                        __frame->pc -= 4;
                        break;
                }
+               __frame->syscallno = -1;
        }
 
        /* if there's no signal to deliver, we just put the saved sigmask
index 0865e291c20d2948c95edc70f52925121409599d..db4953dc4e1b445adbdd7e004a68890a5c1c07a6 100644 (file)
@@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
 {
-       return module_bug_finalize(hdr, sechdrs, me);
+       return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
-       module_bug_cleanup(mod);
 }
index f90edc85b50933a9df52391d041ad9f8b1a8ee66..9301a2821615b66cacd781eeba3e53d57e60fe75 100644 (file)
@@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr)
 }
 
 static __inline__ void __user *
-compat_alloc_user_space (long len)
+arch_compat_alloc_user_space (long len)
 {
        struct pt_regs *regs = task_pt_regs(current);
        return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
index 3567d54f8cee7533ecba41847c5f9957d9481296..331d42bda77ae97f457b13f970aa83c40e11d4b0 100644 (file)
@@ -420,22 +420,31 @@ EX(.fail_efault, ld8 r14=[r33])                   // r14 <- *set
        ;;
 
        RSM_PSR_I(p0, r18, r19)                 // mask interrupt delivery
-       mov ar.ccv=0
        andcm r14=r14,r17                       // filter out SIGKILL & SIGSTOP
+       mov r8=EINVAL                   // default to EINVAL
 
 #ifdef CONFIG_SMP
-       mov r17=1
+       // __ticket_spin_trylock(r31)
+       ld4 r17=[r31]
        ;;
-       cmpxchg4.acq r18=[r31],r17,ar.ccv       // try to acquire the lock
-       mov r8=EINVAL                   // default to EINVAL
+       mov.m ar.ccv=r17
+       extr.u r9=r17,17,15
+       adds r19=1,r17
+       extr.u r18=r17,0,15
+       ;;
+       cmp.eq p6,p7=r9,r18
        ;;
+(p6)   cmpxchg4.acq r9=[r31],r19,ar.ccv
+(p6)   dep.z r20=r19,1,15              // next serving ticket for unlock
+(p7)   br.cond.spnt.many .lock_contention
+       ;;
+       cmp4.eq p0,p7=r9,r17
+       adds r31=2,r31
+(p7)   br.cond.spnt.many .lock_contention
        ld8 r3=[r2]                     // re-read current->blocked now that we hold the lock
-       cmp4.ne p6,p0=r18,r0
-(p6)   br.cond.spnt.many .lock_contention
        ;;
 #else
        ld8 r3=[r2]                     // re-read current->blocked now that we hold the lock
-       mov r8=EINVAL                   // default to EINVAL
 #endif
        add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16
        add r19=IA64_TASK_SIGNAL_OFFSET,r16
@@ -490,7 +499,9 @@ EX(.fail_efault, ld8 r14=[r33])                     // r14 <- *set
 (p6)   br.cond.spnt.few 1b                     // yes -> retry
 
 #ifdef CONFIG_SMP
-       st4.rel [r31]=r0                        // release the lock
+       // __ticket_spin_unlock(r31)
+       st2.rel [r31]=r20
+       mov r20=0                                       // i must not leak kernel bits...
 #endif
        SSM_PSR_I(p0, p9, r31)
        ;;
@@ -512,7 +523,8 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
 
 .sig_pending:
 #ifdef CONFIG_SMP
-       st4.rel [r31]=r0                        // release the lock
+       // __ticket_spin_unlock(r31)
+       st2.rel [r31]=r20                       // release the lock
 #endif
        SSM_PSR_I(p0, p9, r17)
        ;;
index 9c1acb2b1a928984c8f62ce4a5cd91a25329dc21..b2eeb0de1c8d337a6d7ab5abef363b4797ab7e9a 100644 (file)
@@ -157,7 +157,6 @@ typedef struct sigaltstack {
 #undef __HAVE_ARCH_SIG_BITOPS
 
 struct pt_regs;
-extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
 
 #define ptrace_signal_deliver(regs, cookie)    do { } while (0)
 
index 76125777483ccda07d9d31d55c2f8f3b3201ea05..c70545689da83ef2ffaef987b2c3374fadca04fc 100644 (file)
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
 #define __IGNORE_lchown
 #define __IGNORE_setuid
index 403869833b98fe6c95fd360d80cd762f3a5008e2..225412bc227e690bcb313743dd16f58fca5c4115 100644 (file)
@@ -235,10 +235,9 @@ work_resched:
 work_notifysig:                                ; deal with pending signals and
                                        ; notify-resume requests
        mv      r0, sp                  ; arg1 : struct pt_regs *regs
-       ldi     r1, #0                  ; arg2 : sigset_t *oldset
-       mv      r2, r9                  ; arg3 : __u32 thread_info_flags
+       mv      r1, r9                  ; arg2 : __u32 thread_info_flags
        bl      do_notify_resume
-       bra     restore_all
+       bra     resume_userspace
 
        ; perform syscall exit tracing
        ALIGN
index e555091eb97cbcf8bbe261851be3b72e90e6075e..0021ade4cba8c86bf1d2fd348b283d8cac591955 100644 (file)
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child)
 
        if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
            != sizeof(insn))
-               break;
+               return -EIO;
 
        compute_next_pc(insn, pc, &next_pc, child);
        if (next_pc & 0x80000000)
-               break;
+               return -EIO;
 
        if (embed_debug_trap(child, next_pc))
-               break;
+               return -EIO;
 
        invalidate_cache();
+       return 0;
 }
 
 void user_disable_single_step(struct task_struct *child)
index 144b0f124fc72f08b20f93336f96da81327fe61c..7bbe38645ed5559395f85c5b5fce93eb3f4992e3 100644 (file)
 
 #define DEBUG_SIG 0
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-int do_signal(struct pt_regs *, sigset_t *);
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
-                 unsigned long r2, unsigned long r3, unsigned long r4,
-                 unsigned long r5, unsigned long r6, struct pt_regs *regs)
-{
-       sigset_t newset;
-
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
-
-       if (copy_from_user(&newset, unewset, sizeof(newset)))
-               return -EFAULT;
-       sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
-
-       spin_lock_irq(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       set_thread_flag(TIF_RESTORE_SIGMASK);
-       return -ERESTARTNOHAND;
-}
-
 asmlinkage int
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
                unsigned long r2, unsigned long r3, unsigned long r4,
@@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
        return (void __user *)((sp - frame_size) & -8ul);
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
@@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                current->comm, current->pid, frame, regs->pc);
 #endif
 
-       return;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
+       return -EFAULT;
+}
+
+static int prev_insn(struct pt_regs *regs)
+{
+       u16 inst;
+       if (get_user(&inst, (u16 __user *)(regs->bpc - 2)))
+               return -EFAULT;
+       if ((inst & 0xfff0) == 0x10f0)  /* trap ? */
+               regs->bpc -= 2;
+       else
+               regs->bpc -= 4;
+       regs->syscall_nr = -1;
+       return 0;
 }
 
 /*
  * OK, we're invoking a handler
  */
 
-static void
+static int
 handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
              sigset_t *oldset, struct pt_regs *regs)
 {
-       unsigned short inst;
-
        /* Are we from a system call? */
        if (regs->syscall_nr >= 0) {
                /* If so, check system call restarting.. */
@@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
                        /* fallthrough */
                        case -ERESTARTNOINTR:
                                regs->r0 = regs->orig_r0;
-                               inst = *(unsigned short *)(regs->bpc - 2);
-                               if ((inst & 0xfff0) == 0x10f0)  /* trap ? */
-                                       regs->bpc -= 2;
-                               else
-                                       regs->bpc -= 4;
+                               if (prev_insn(regs) < 0)
+                                       return -EFAULT;
                }
        }
 
        /* Set up the stack frame */
-       setup_rt_frame(sig, ka, info, oldset, regs);
+       if (setup_rt_frame(sig, ka, info, oldset, regs))
+               return -EFAULT;
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
                sigaddset(&current->blocked,sig);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+       return 0;
 }
 
 /*
@@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static void do_signal(struct pt_regs *regs)
 {
        siginfo_t info;
        int signr;
        struct k_sigaction ka;
-       unsigned short inst;
+       sigset_t *oldset;
 
        /*
         * We want the common case to go fast, which
@@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
         * if so.
         */
        if (!user_mode(regs))
-               return 1;
+               return;
 
        if (try_to_freeze()) 
                goto no_signal;
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                 */
 
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &ka, &info, oldset, regs);
-               return 1;
+               if (handle_signal(signr, &ka, &info, oldset, regs) == 0)
+                       clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+               return;
        }
 
  no_signal:
@@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                    regs->r0 == -ERESTARTSYS ||
                    regs->r0 == -ERESTARTNOINTR) {
                        regs->r0 = regs->orig_r0;
-                       inst = *(unsigned short *)(regs->bpc - 2);
-                       if ((inst & 0xfff0) == 0x10f0)  /* trap ? */
-                               regs->bpc -= 2;
-                       else
-                               regs->bpc -= 4;
-               }
-               if (regs->r0 == -ERESTART_RESTARTBLOCK){
+                       prev_insn(regs);
+               } else if (regs->r0 == -ERESTART_RESTARTBLOCK){
                        regs->r0 = regs->orig_r0;
                        regs->r7 = __NR_restart_syscall;
-                       inst = *(unsigned short *)(regs->bpc - 2);
-                       if ((inst & 0xfff0) == 0x10f0)  /* trap ? */
-                               regs->bpc -= 2;
-                       else
-                               regs->bpc -= 4;
+                       prev_insn(regs);
                }
        }
-       return 0;
+       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+       }
 }
 
 /*
  * notification of userspace execution resumption
  * - triggered by current->work.notify_resume
  */
-void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
-                     __u32 thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
 {
        /* Pending single-step? */
        if (thread_info_flags & _TIF_SINGLESTEP)
@@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
 
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(regs,oldset);
+               do_signal(regs);
 
        if (thread_info_flags & _TIF_NOTIFY_RESUME) {
                clear_thread_flag(TIF_NOTIFY_RESUME);
index 60b15d0aa07290bfd2494423ecc4c331c33c3032..b43b36beafe37aed63baf7714a92ba55a7cf2f1c 100644 (file)
 #define __NR_set_thread_area   334
 #define __NR_atomic_cmpxchg_32 335
 #define __NR_atomic_barrier    336
+#define __NR_fanotify_init     337
+#define __NR_fanotify_mark     338
+#define __NR_prlimit64         339
 
 #ifdef __KERNEL__
 
-#define NR_syscalls            337
+#define NR_syscalls            340
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index 2391bdff09962e7a51d36c7842290ea90932ca54..6360c437dcf51c5491e192151b95ce6c1a6923a2 100644 (file)
@@ -765,4 +765,7 @@ sys_call_table:
        .long sys_set_thread_area
        .long sys_atomic_cmpxchg_32     /* 335 */
        .long sys_atomic_barrier
+       .long sys_fanotify_init
+       .long sys_fanotify_mark
+       .long sys_prlimit64
 
index 8f0640847ad2bf7bf99d0a184ed10ce8272a84f8..05285d08e54767a71a814773c23a506386f9626a 100644 (file)
@@ -162,7 +162,7 @@ static void mac_init_asc( void )
 void mac_mksound( unsigned int freq, unsigned int length )
 {
        __u32 cfreq = ( freq << 5 ) / 468;
-       __u32 flags;
+       unsigned long flags;
        int i;
 
        if ( mac_special_bell == NULL )
@@ -224,7 +224,7 @@ static void mac_nosound( unsigned long ignored )
  */
 static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume )
 {
-       __u32 flags;
+       unsigned long flags;
 
        /* if the bell is already ringing, ring longer */
        if ( mac_bell_duration > 0 )
@@ -271,7 +271,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig
 static void mac_quadra_ring_bell( unsigned long ignored )
 {
        int     i, count = mac_asc_samplespersec / HZ;
-       __u32 flags;
+       unsigned long flags;
 
        /*
         * we neither want a sound buffer overflow nor underflow, so we need to match
index b30b3eb197a5d2c157d6e96f8d60de45395d4a21..79b1ed198c070dd40dbb3cf4f03dd6f24b79cb71 100644 (file)
@@ -355,6 +355,9 @@ ENTRY(sys_call_table)
        .long sys_set_thread_area
        .long sys_atomic_cmpxchg_32     /* 335 */
        .long sys_atomic_barrier
+       .long sys_fanotify_init
+       .long sys_fanotify_mark
+       .long sys_prlimit64
 
        .rept NR_syscalls-(.-sys_call_table)/4
                .long sys_ni_syscall
index 3ad59dde485209bce858c425e4fc8a2f64b04c09..5526faabfc21433cf3e3fa679c9fcf802646c96c 100644 (file)
@@ -13,6 +13,7 @@ config MIPS
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select RTC_LIB if !MACH_LOONGSON
+       select GENERIC_ATOMIC64 if !64BIT
 
 mainmenu "Linux/MIPS Kernel Configuration"
 
@@ -1646,8 +1647,16 @@ config MIPS_MT_SMP
        select SYS_SUPPORTS_SMP
        select SMP_UP
        help
-         This is a kernel model which is also known a VSMP or lately
-         has been marketesed into SMVP.
+         This is a kernel model which is known a VSMP but lately has been
+         marketesed into SMVP.
+         Virtual SMP uses the processor's VPEs  to implement virtual
+         processors. In currently available configuration of the 34K processor
+         this allows for a dual processor. Both processors will share the same
+         primary caches; each will obtain the half of the TLB for it's own
+         exclusive use. For a layman this model can be described as similar to
+         what Intel calls Hyperthreading.
+
+         For further information see http://www.linux-mips.org/wiki/34K#VSMP
 
 config MIPS_MT_SMTC
        bool "SMTC: Use all TCs on all VPEs for SMP"
@@ -1664,6 +1673,14 @@ config MIPS_MT_SMTC
        help
          This is a kernel model which is known a SMTC or lately has been
          marketesed into SMVP.
+         is presenting the available TC's of the core as processors to Linux.
+         On currently available 34K processors this means a Linux system will
+         see up to 5 processors. The implementation of the SMTC kernel differs
+         significantly from VSMP and cannot efficiently coexist in the same
+         kernel binary so the choice between VSMP and SMTC is a compile time
+         decision.
+
+         For further information see http://www.linux-mips.org/wiki/34K#SMTC
 
 endchoice
 
index c29511b11d44fd6732b0dd153d009dbd7051555d..5340210596297fa54c8723e866aebaeb8c20269e 100644 (file)
@@ -43,7 +43,7 @@ int prom_argc;
 char **prom_argv;
 char **prom_envp;
 
-void prom_init_cmdline(void)
+void __init prom_init_cmdline(void)
 {
        int i;
 
@@ -104,7 +104,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
        }
 }
 
-int prom_get_ethernet_addr(char *ethernet_addr)
+int __init prom_get_ethernet_addr(char *ethernet_addr)
 {
        char *ethaddr_str;
 
@@ -123,7 +123,6 @@ int prom_get_ethernet_addr(char *ethernet_addr)
 
        return 0;
 }
-EXPORT_SYMBOL(prom_get_ethernet_addr);
 
 void __init prom_free_prom_memory(void)
 {
index ed9bb709c9a3816a4738d0ceef91db8c8de20cd4..5fd7f7a58b7eb9b02446e8ea2aa3e2e9b1e48e8f 100644 (file)
@@ -59,7 +59,7 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
 hostprogs-y := calc_vmlinuz_load_addr
 
 VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
-               $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS))
+               $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
 
 vmlinuzobjs-y += $(obj)/piggy.o
 
index 094c17e38e163ab691b71bef78710f73848c7645..47323ca452dcbde751536c58c9f613dd1d9d51c8 100644 (file)
@@ -83,3 +83,7 @@ config ARCH_SPARSEMEM_ENABLE
        def_bool y
        select SPARSEMEM_STATIC
        depends on CPU_CAVIUM_OCTEON
+
+config CAVIUM_OCTEON_HELPER
+       def_bool y
+       depends on OCTEON_ETHERNET || PCI
index c664c8cc2b42cb8970b9f57531a03e2998075566..a5b427909b5cac04d28c4da1b099342ee72df4ce 100644 (file)
@@ -41,7 +41,7 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
        return NOTIFY_OK;               /* Let default notifier send signals */
 }
 
-static int cnmips_cu2_setup(void)
+static int __init cnmips_cu2_setup(void)
 {
        return cu2_notifier(cnmips_cu2_call, 0);
 }
index 2fd66db6939e0f981c338015127c69788d960843..7f41c5be2190ddca03fc92a00e8f21bd735414f5 100644 (file)
@@ -11,4 +11,4 @@
 
 obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
 
-obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o
+obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o
index c63c56bfd18461b558e0cba7380d6297fc47115e..47d87da379f947c8a578f2a2b84e7da804f559a8 100644 (file)
@@ -782,6 +782,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
  */
 #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
 
+#else /* !CONFIG_64BIT */
+
+#include <asm-generic/atomic64.h>
+
 #endif /* CONFIG_64BIT */
 
 /*
index 613f6912dfc1d024b2aa6b28fb4215ba8b251552..dbc51065df5b3fe53611ff15e9cc259188ff0dbc 100644 (file)
@@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = (struct pt_regs *)
                ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
index 2cb2f0c2c4f89342ae5256a79d8082f01af4d319..3532e2c5f098ae46a4a79f7455cd004d699dd4a9 100644 (file)
@@ -24,7 +24,7 @@ extern int cu2_notifier_call_chain(unsigned long val, void *v);
 
 #define cu2_notifier(fn, pri)                                          \
 ({                                                                     \
-       static struct notifier_block fn##_nb __cpuinitdata = {          \
+       static struct notifier_block fn##_nb = {                        \
                .notifier_call = fn,                                    \
                .priority = pri                                         \
        };                                                              \
index 9b9436a4d816bfe7f26a1eb8a7e7cb677507c388..86548da650e765f79db345f4d3964a5d0eb6c0fe 100644 (file)
@@ -321,6 +321,7 @@ struct gic_intrmask_regs {
  */
 struct gic_intr_map {
        unsigned int cpunum;    /* Directed to this CPU */
+#define GIC_UNUSED             0xdead                  /* Dummy data */
        unsigned int pin;       /* Directed to this Pin */
        unsigned int polarity;  /* Polarity : +/-       */
        unsigned int trigtype;  /* Trigger  : Edge/Levl */
index b74caf65482b2e068b86d2763daa81733bc45503..ff9a8b86cb9363c1fb458546c56550fc35a7a3ab 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __ASM_MACH_TX49XX_KMALLOC_H
 #define __ASM_MACH_TX49XX_KMALLOC_H
 
-#define ARCH_KMALLOC_MINALIGN  L1_CACHE_BYTES
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
 
 #endif /* __ASM_MACH_TX49XX_KMALLOC_H */
index cea872fc6f5c0d1ae92f00f920f7f991c8b9b806..d11aa02a956a57ca41ff890dbe16bbdd0145db53 100644 (file)
@@ -88,9 +88,6 @@
 
 #define GIC_EXT_INTR(x)                x
 
-/* Dummy data */
-#define X                      0xdead
-
 /* External Interrupts used for IPI */
 #define GIC_IPI_EXT_INTR_RESCHED_VPE0  16
 #define GIC_IPI_EXT_INTR_CALLFNC_VPE0  17
index a16beafcea91dd091f0b491ea572b5902e272a3d..e59cd1ac09c2f82eb8c91af1bdb0b6a520513d89 100644 (file)
@@ -150,6 +150,20 @@ typedef struct { unsigned long pgprot; } pgprot_t;
     ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
 #endif
 #define __va(x)                ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+
+/*
+ * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad
+ * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org).  The
+ * discussion can be found in lkml posting
+ * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is
+ * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html
+ *
+ * It is unclear if the misscompilations mentioned in
+ * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one
+ * until GCC 3.x has been retired before we can apply
+ * https://patchwork.linux-mips.org/patch/1541/
+ */
+
 #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
 
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
index 96e28f18dad11fbc0dabf41e4fbaf25f1302f3b0..1ca64b4d33d96844da375d3df443246f781e564a 100644 (file)
@@ -88,6 +88,7 @@ typedef struct siginfo {
 #ifdef __ARCH_SI_TRAPNO
                        int _trapno;    /* TRAP # which caused the signal */
 #endif
+                       short _addr_lsb;
                } _sigfault;
 
                /* SIGPOLL, SIGXFSZ (To do ...)  */
index 2376f2e06e470a264eeff5115dc692c80e9f37c3..70df9c0d3c5be20e2d7b646460276a44374fc077 100644 (file)
@@ -146,7 +146,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_LOAD_WATCH                (1<<TIF_LOAD_WATCH)
 
 /* work to do on interrupt/exception return */
-#define _TIF_WORK_MASK         (0x0000ffef & ~_TIF_SECCOMP)
+#define _TIF_WORK_MASK         (0x0000ffef &                           \
+                                       ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK      (0x8000ffff & ~_TIF_SECCOMP)
 
index baa318a59c97f8c2791842df809c1218796c7492..550725b881d5edec666a5b32bbe1200164ac7fd8 100644 (file)
 #define __NR_perf_event_open           (__NR_Linux + 333)
 #define __NR_accept4                   (__NR_Linux + 334)
 #define __NR_recvmmsg                  (__NR_Linux + 335)
+#define __NR_fanotify_init             (__NR_Linux + 336)
+#define __NR_fanotify_mark             (__NR_Linux + 337)
+#define __NR_prlimit64                 (__NR_Linux + 338)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            335
+#define __NR_Linux_syscalls            338
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                335
+#define __NR_O32_Linux_syscalls                338
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_perf_event_open           (__NR_Linux + 292)
 #define __NR_accept4                   (__NR_Linux + 293)
 #define __NR_recvmmsg                  (__NR_Linux + 294)
+#define __NR_fanotify_init             (__NR_Linux + 295)
+#define __NR_fanotify_mark             (__NR_Linux + 296)
+#define __NR_prlimit64                 (__NR_Linux + 297)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            294
+#define __NR_Linux_syscalls            297
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         294
+#define __NR_64_Linux_syscalls         297
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_accept4                   (__NR_Linux + 297)
 #define __NR_recvmmsg                  (__NR_Linux + 298)
 #define __NR_getdents64                        (__NR_Linux + 299)
+#define __NR_fanotify_init             (__NR_Linux + 300)
+#define __NR_fanotify_mark             (__NR_Linux + 301)
+#define __NR_prlimit64                 (__NR_Linux + 302)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            299
+#define __NR_Linux_syscalls            302
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                299
+#define __NR_N32_Linux_syscalls                302
 
 #ifdef __KERNEL__
 
index b181f2f0ea8e71709f331c8ee32a7f6792999106..82ba9f62f49e3b2faa98abc1f6da2fe1e062a4ed 100644 (file)
@@ -7,7 +7,6 @@
 #include <asm/io.h>
 #include <asm/gic.h>
 #include <asm/gcmpregs.h>
-#include <asm/mips-boards/maltaint.h>
 #include <asm/irq.h>
 #include <linux/hardirq.h>
 #include <asm-generic/bitops/find.h>
@@ -131,7 +130,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        int             i;
 
        irq -= _irqbase;
-       pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq);
+       pr_debug("%s(%d) called\n", __func__, irq);
        cpumask_and(&tmp, cpumask, cpu_online_mask);
        if (cpus_empty(tmp))
                return -1;
@@ -222,7 +221,7 @@ static void __init gic_basic_init(int numintrs, int numvpes,
        /* Setup specifics */
        for (i = 0; i < mapsize; i++) {
                cpu = intrmap[i].cpunum;
-               if (cpu == X)
+               if (cpu == GIC_UNUSED)
                        continue;
                if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
                        continue;
index 1f4e2fa64140ee8204aed74ecf82eba7bab056be..f4546e97c60db111215495f924aa567595c39581 100644 (file)
@@ -283,7 +283,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
        struct pt_regs *regs = args->regs;
        int trap = (regs->cp0_cause & 0x7c) >> 2;
 
-       /* Userpace events, ignore. */
+       /* Userspace events, ignore. */
        if (user_mode(regs))
                return NOTIFY_DONE;
 
index 80e2ba694babcd0d70bd8266a6be941996e2a8a8..29811f043399588604da9bbc00efd9f0997aa530 100644 (file)
@@ -251,7 +251,7 @@ void sp_work_handle_request(void)
                memset(&tz, 0, sizeof(tz));
                if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
                                             (int)&tz, 0, 0)) == 0)
-               ret.retval = tv.tv_sec;
+                       ret.retval = tv.tv_sec;
                break;
 
        case MTSP_SYSCALL_EXIT:
index c2dab140dc98fb1588259063699c7ba09b6f8ed7..6343b4a5b8350cb3a93edea5d75f3154cde48343 100644 (file)
@@ -341,3 +341,10 @@ asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
 {
        return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
 }
+
+SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
+               u64, a3, u64, a4, int, dfd, const char  __user *, pathname)
+{
+       return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4),
+                                dfd, pathname);
+}
index 17202bbe843f91172534dd30e41e8a9542e0d762..584415eef8c92ae9168790b4ef824470c2034f73 100644 (file)
@@ -583,7 +583,10 @@ einval:    li      v0, -ENOSYS
        sys     sys_rt_tgsigqueueinfo   4
        sys     sys_perf_event_open     5
        sys     sys_accept4             4
-       sys     sys_recvmmsg            5
+       sys     sys_recvmmsg            5       /* 4335 */
+       sys     sys_fanotify_init       2
+       sys     sys_fanotify_mark       6
+       sys     sys_prlimit64           4
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index a8a6c596eb0405bab886e8dfff6ffeb8097d7fc6..5573f8e4e326910b3873007c2b216fb31fe566d4 100644 (file)
@@ -416,9 +416,12 @@ sys_call_table:
        PTR     sys_pipe2
        PTR     sys_inotify_init1
        PTR     sys_preadv
-       PTR     sys_pwritev                     /* 5390 */
+       PTR     sys_pwritev                     /* 5290 */
        PTR     sys_rt_tgsigqueueinfo
        PTR     sys_perf_event_open
        PTR     sys_accept4
-       PTR     sys_recvmmsg
+       PTR     sys_recvmmsg
+       PTR     sys_fanotify_init               /* 5295 */
+       PTR     sys_fanotify_mark
+       PTR     sys_prlimit64
        .size   sys_call_table,.-sys_call_table
index a3d66137731ac24386972c82426a4679d9ff9be3..1e38ec97672ed82d30b238ad7bbd6adbb2c10b9f 100644 (file)
@@ -419,5 +419,8 @@ EXPORT(sysn32_call_table)
        PTR     sys_perf_event_open
        PTR     sys_accept4
        PTR     compat_sys_recvmmsg
-       PTR     sys_getdents
+       PTR     sys_getdents64
+       PTR     sys_fanotify_init               /* 6300 */
+       PTR     sys_fanotify_mark
+       PTR     sys_prlimit64
        .size   sysn32_call_table,.-sysn32_call_table
index 813689ef23847c6a2db230ebd6dcae60e0ff79f6..171979fc98e59a5169049d44001ad75383268684 100644 (file)
@@ -538,5 +538,8 @@ sys_call_table:
        PTR     compat_sys_rt_tgsigqueueinfo
        PTR     sys_perf_event_open
        PTR     sys_accept4
-       PTR     compat_sys_recvmmsg
+       PTR     compat_sys_recvmmsg             /* 4335 */
+       PTR     sys_fanotify_init
+       PTR     sys_32_fanotify_mark
+       PTR     sys_prlimit64
        .size   sys_call_table,.-sys_call_table
index 7ba890860d98cb3916c84f369e3fef0200b07f2b..469d4019f795bd072b0aa4ba109d075b5377f55c 100644 (file)
@@ -44,27 +44,39 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev)
 
 static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
 {
+       gfp_t dma_flag;
+
        /* ignore region specifiers */
        gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
 
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ISA
        if (dev == NULL)
-               gfp |= __GFP_DMA;
-       else if (dev->coherent_dma_mask < DMA_BIT_MASK(24))
-               gfp |= __GFP_DMA;
+               dma_flag = __GFP_DMA;
        else
 #endif
-#ifdef CONFIG_ZONE_DMA32
+#if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA)
             if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
-               gfp |= __GFP_DMA32;
+                       dma_flag = __GFP_DMA;
+       else if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+                       dma_flag = __GFP_DMA32;
+       else
+#endif
+#if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA)
+            if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+               dma_flag = __GFP_DMA32;
+       else
+#endif
+#if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32)
+            if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+               dma_flag = __GFP_DMA;
        else
 #endif
-               ;
+               dma_flag = 0;
 
        /* Don't invoke OOM killer */
        gfp |= __GFP_NORETRY;
 
-       return gfp;
+       return gfp | dma_flag;
 }
 
 void *dma_alloc_noncoherent(struct device *dev, size_t size,
index 1ef75cd80a0d819827f5057549fdd2622442a752..274af3be1442b42fa41d3cb960b598ddcbf5b8c2 100644 (file)
@@ -30,7 +30,7 @@
 #define tc_lsize       32
 
 extern unsigned long icache_way_size, dcache_way_size;
-unsigned long tcache_size;
+static unsigned long tcache_size;
 
 #include <asm/r4kcache.h>
 
index 15949b0be811f9718af9e2896d4bd9e947c84897..b79b24afe3a2fc67ab6687a082e44d45bf219242 100644 (file)
@@ -385,6 +385,8 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
  */
 
 #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+#define X GIC_UNUSED
+
 static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
        { X, X,            X,           X,              0 },
        { X, X,            X,           X,              0 },
@@ -404,6 +406,7 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
        { X, X,            X,           X,              0 },
        /* The remainder of this table is initialised by fill_ipi_map */
 };
+#undef X
 
 /*
  * GCMP needs to be detected before any SMP initialisation
index 71f7d27b0d4cccf28dba3777b0a8848de53f82c4..f31218e17d3c1437f4f8ef15a7d1855ddc6a32fb 100644 (file)
@@ -118,7 +118,7 @@ static int __init rc32434_pcibridge_init(void)
        if (!((pcicvalue == PCIM_H_EA) ||
              (pcicvalue == PCIM_H_IA_FIX) ||
              (pcicvalue == PCIM_H_IA_RR))) {
-               pr_err(KERN_ERR "PCI init error!!!\n");
+               pr_err("PCI init error!!!\n");
                /* Not in Host Mode, return ERROR */
                return -1;
        }
index fadd8744a6bccfbf25283369608c66b16afeab04..e7a12ff304b9475c0db2e6097989c510b288a3c4 100644 (file)
  */
 #include <linux/kernel.h>
 
+#include <asm/processor.h>
 #include <asm/reboot.h>
 #include <glb.h>
 
 void pnx8550_machine_restart(char *command)
 {
-       char head[] = "************* Machine restart *************";
-       char foot[] = "*******************************************";
-
-       printk("\n\n");
-       printk("%s\n", head);
-       if (command != NULL)
-               printk("* %s\n", command);
-       printk("%s\n", foot);
-
        PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
 }
 
 void pnx8550_machine_halt(void)
 {
-       printk("*** Machine halt. (Not implemented) ***\n");
-}
-
-void pnx8550_machine_power_off(void)
-{
-       printk("*** Machine power off.  (Not implemented) ***\n");
+       while (1) {
+               if (cpu_wait)
+                       cpu_wait();
+       }
 }
index 64246c9c875c51d09e5c3861ca0e6f1096d50ac5..43cb3945fdbfffb8b355789e237a9b27df21abef 100644 (file)
@@ -44,7 +44,6 @@
 extern void __init board_setup(void);
 extern void pnx8550_machine_restart(char *);
 extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 extern char *prom_getcmdline(void);
@@ -100,7 +99,7 @@ void __init plat_mem_setup(void)
 
         _machine_restart = pnx8550_machine_restart;
         _machine_halt = pnx8550_machine_halt;
-        pm_power_off = pnx8550_machine_power_off;
+        pm_power_off = pnx8550_machine_halt;
 
        /* Clear the Global 2 Register, PCI Inta Output Enable Registers
           Bit 1:Enable DAC Powerdown
index 444b9f918fdf8f2d5dec64b9827d8d746bb1ade1..7c2a2f7f8dc143889b74605d2741f5707ad330e4 100644 (file)
@@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration"
 config MN10300
        def_bool y
        select HAVE_OPROFILE
-       select HAVE_ARCH_TRACEHOOK
 
 config AM33
        def_bool y
index ff80e86b9bd2d2305d34a731685d94fe5d3f3491..ce83c74b3fd714abf68fca4a4d2beef024545c83 100644 (file)
@@ -101,7 +101,7 @@ config GDBSTUB_DEBUG_BREAKPOINT
 
 choice
        prompt "GDB stub port"
-       default GDBSTUB_TTYSM0
+       default GDBSTUB_ON_TTYSM0
        depends on GDBSTUB
        help
          Select the serial port used for GDB-stub.
index f49ac49e09adc079adaabdd9893258ae9b795b7f..3f50e966107641f21f346a38e50cca97d2eda24b 100644 (file)
@@ -229,9 +229,9 @@ int ffs(int x)
 #include <asm-generic/bitops/hweight.h>
 
 #define ext2_set_bit_atomic(lock, nr, addr) \
-       test_and_set_bit((nr) ^ 0x18, (addr))
+       test_and_set_bit((nr), (addr))
 #define ext2_clear_bit_atomic(lock, nr, addr) \
-       test_and_clear_bit((nr) ^ 0x18, (addr))
+       test_and_clear_bit((nr), (addr))
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/minix-le.h>
index 7e891fce2370028acea4a56497aafa74c443c0be..1865d72a86ff7cc6823a7be07dbbb0f3907e2518 100644 (file)
@@ -78,7 +78,7 @@ typedef unsigned long sigset_t;
 
 /* These should not be considered constants from userland.  */
 #define SIGRTMIN       32
-#define SIGRTMAX       (_NSIG-1)
+#define SIGRTMAX       _NSIG
 
 /*
  * SA_FLAGS values:
index 9d49073e827a26429335b54cc51cff3304433ac7..db509dd80565b9e91c2b661c08c5fd64bc52e8d4 100644 (file)
@@ -156,17 +156,17 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = {
        ._intr          = &SC0ICR,
        ._rxb           = &SC0RXB,
        ._txb           = &SC0TXB,
-       .rx_name        = "ttySM0/Rx",
-       .tx_name        = "ttySM0/Tx",
+       .rx_name        = "ttySM0:Rx",
+       .tx_name        = "ttySM0:Tx",
 #ifdef CONFIG_MN10300_TTYSM0_TIMER8
-       .tm_name        = "ttySM0/Timer8",
+       .tm_name        = "ttySM0:Timer8",
        ._tmxmd         = &TM8MD,
        ._tmxbr         = &TM8BR,
        ._tmicr         = &TM8ICR,
        .tm_irq         = TM8IRQ,
        .div_timer      = MNSCx_DIV_TIMER_16BIT,
 #else /* CONFIG_MN10300_TTYSM0_TIMER2 */
-       .tm_name        = "ttySM0/Timer2",
+       .tm_name        = "ttySM0:Timer2",
        ._tmxmd         = &TM2MD,
        ._tmxbr         = (volatile u16 *) &TM2BR,
        ._tmicr         = &TM2ICR,
@@ -209,17 +209,17 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = {
        ._intr          = &SC1ICR,
        ._rxb           = &SC1RXB,
        ._txb           = &SC1TXB,
-       .rx_name        = "ttySM1/Rx",
-       .tx_name        = "ttySM1/Tx",
+       .rx_name        = "ttySM1:Rx",
+       .tx_name        = "ttySM1:Tx",
 #ifdef CONFIG_MN10300_TTYSM1_TIMER9
-       .tm_name        = "ttySM1/Timer9",
+       .tm_name        = "ttySM1:Timer9",
        ._tmxmd         = &TM9MD,
        ._tmxbr         = &TM9BR,
        ._tmicr         = &TM9ICR,
        .tm_irq         = TM9IRQ,
        .div_timer      = MNSCx_DIV_TIMER_16BIT,
 #else /* CONFIG_MN10300_TTYSM1_TIMER3 */
-       .tm_name        = "ttySM1/Timer3",
+       .tm_name        = "ttySM1:Timer3",
        ._tmxmd         = &TM3MD,
        ._tmxbr         = (volatile u16 *) &TM3BR,
        ._tmicr         = &TM3ICR,
@@ -260,9 +260,9 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = {
        .uart.lock      =
        __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock),
        .name           = "ttySM2",
-       .rx_name        = "ttySM2/Rx",
-       .tx_name        = "ttySM2/Tx",
-       .tm_name        = "ttySM2/Timer10",
+       .rx_name        = "ttySM2:Rx",
+       .tx_name        = "ttySM2:Tx",
+       .tm_name        = "ttySM2:Timer10",
        ._iobase        = &SC2CTR,
        ._control       = &SC2CTR,
        ._status        = &SC2STR,
index 6aea7fd76993b931f31f2dda76e72aecc1e31b4d..196a111e2e2937b134217356991c0ca2f68bda05 100644 (file)
@@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
 {
-       return module_bug_finalize(hdr, sechdrs, me);
+       return 0;
 }
 
 /*
@@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr,
  */
 void module_arch_cleanup(struct module *mod)
 {
-       module_bug_cleanup(mod);
 }
index 717db14c2cc32d8905a45e6cfae4bf2a00d38abd..d4de05ab786464cd585e7f1f0e6ed1652ad3de1c 100644 (file)
@@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig,
                old_sigset_t mask;
                if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+                   __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+                   __get_user(mask, &act->sa_mask))
                        return -EFAULT;
-               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               __get_user(mask, &act->sa_mask);
                siginitset(&new_ka.sa.sa_mask, mask);
        }
 
@@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig,
        if (!ret && oact) {
                if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+                   __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+                   __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
                        return -EFAULT;
-               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
        }
 
        return ret;
@@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs,
 {
        unsigned int err = 0;
 
+       /* Always make any pending restarted system calls return -EINTR */
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
        if (is_using_fpu(current))
                fpu_kill_state(current);
 
@@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
        regs->d0 = sig;
        regs->d1 = (unsigned long) &frame->sc;
 
-       set_fs(USER_DS);
-
        /* the tracer may want to single-step inside the handler */
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
@@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
        return 0;
 
 give_sigsegv:
-       force_sig(SIGSEGV, current);
+       force_sigsegv(sig, current);
        return -EFAULT;
 }
 
@@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->d0 = sig;
        regs->d1 = (long) &frame->info;
 
-       set_fs(USER_DS);
-
        /* the tracer may want to single-step inside the handler */
        if (test_thread_flag(TIF_SINGLESTEP))
                ptrace_notify(SIGTRAP);
@@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        return 0;
 
 give_sigsegv:
-       force_sig(SIGSEGV, current);
+       force_sigsegv(sig, current);
        return -EFAULT;
 }
 
+static inline void stepback(struct pt_regs *regs)
+{
+       regs->pc -= 2;
+       regs->orig_d0 = -1;
+}
+
 /*
  * handle the actual delivery of a signal to userspace
  */
@@ -459,7 +464,7 @@ static int handle_signal(int sig,
                        /* fallthrough */
                case -ERESTARTNOINTR:
                        regs->d0 = regs->orig_d0;
-                       regs->pc -= 2;
+                       stepback(regs);
                }
        }
 
@@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs)
                case -ERESTARTSYS:
                case -ERESTARTNOINTR:
                        regs->d0 = regs->orig_d0;
-                       regs->pc -= 2;
+                       stepback(regs);
                        break;
 
                case -ERESTART_RESTARTBLOCK:
                        regs->d0 = __NR_restart_syscall;
-                       regs->pc -= 2;
+                       stepback(regs);
                        break;
                }
        }
index 28b9d983db0cb280c07dcd76921d695892e11c48..1557277fbc5c03962c56f39b7d1a5687bdea80bd 100644 (file)
@@ -2,13 +2,11 @@
 # Makefile for the MN10300-specific memory management code
 #
 
+cacheflush-y   := cache.o cache-mn10300.o
+cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o
+
+cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o
+
 obj-y := \
        init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \
-       misalignment.o dma-alloc.o
-
-ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y)
-obj-y  += cache.o cache-mn10300.o
-ifeq ($(CONFIG_MN10300_CACHE_WBACK),y)
-obj-y  += cache-flush-mn10300.o
-endif
-endif
+       misalignment.o dma-alloc.o $(cacheflush-y)
diff --git a/arch/mn10300/mm/cache-disabled.c b/arch/mn10300/mm/cache-disabled.c
new file mode 100644 (file)
index 0000000..f669ea4
--- /dev/null
@@ -0,0 +1,21 @@
+/* Handle the cache being disabled
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#include <linux/mm.h>
+
+/*
+ * allow userspace to flush the instruction cache
+ */
+asmlinkage long sys_cacheflush(unsigned long start, unsigned long end)
+{
+       if (end < start)
+               return -EINVAL;
+       return 0;
+}
index 1b76719ec1c37b1686a648cd07f8c5e7baaf9ce1..9261217e8d2c5741bb500b829bbd7663859b5541 100644 (file)
@@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page);
 void flush_icache_range(unsigned long start, unsigned long end)
 {
 #ifdef CONFIG_MN10300_CACHE_WBACK
-       unsigned long addr, size, off;
+       unsigned long addr, size, base, off;
        struct page *page;
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *ppte, pte;
 
+       if (end > 0x80000000UL) {
+               /* addresses above 0xa0000000 do not go through the cache */
+               if (end > 0xa0000000UL) {
+                       end = 0xa0000000UL;
+                       if (start >= end)
+                               return;
+               }
+
+               /* kernel addresses between 0x80000000 and 0x9fffffff do not
+                * require page tables, so we just map such addresses directly */
+               base = (start >= 0x80000000UL) ? start : 0x80000000UL;
+               mn10300_dcache_flush_range(base, end);
+               if (base == start)
+                       goto invalidate;
+               end = base;
+       }
+
        for (; start < end; start += size) {
                /* work out how much of the page to flush */
                off = start & (PAGE_SIZE - 1);
@@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end)
        }
 #endif
 
+invalidate:
        mn10300_icache_inv();
 }
 EXPORT_SYMBOL(flush_icache_range);
index 02b77baa5da69f04729013cd9b6402ffc2dc3c39..efa0b60c63fe683f22629ddd540ed036495cd896 100644 (file)
@@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static __inline__ void __user *compat_alloc_user_space(long len)
+static __inline__ void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = &current->thread.regs;
        return (void __user *)regs->gr[30];
index 159a2b81e90c630db82eb9834c2096df7eb66896..6e81bb596e5b476e598e4a7309e4aba80ba0a322 100644 (file)
@@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr,
        nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
        DEBUGP("NEW num_symtab %lu\n", nsyms);
        symhdr->sh_size = nsyms * sizeof(Elf_Sym);
-       return module_bug_finalize(hdr, sechdrs, me);
+       return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
        deregister_unwind_table(mod);
-       module_bug_cleanup(mod);
 }
index 396d21a800587f0c8a740714a3277a743d2618cc..a11d4eac4f97f369f48866a7475696879b8be5d3 100644 (file)
@@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = current->thread.regs;
        unsigned long usp = regs->gpr[1];
index 477c663e014043a5c08fbaf51e82853005391344..49cee9df225be8bfc6b06a429ee9243d10484439 100644 (file)
@@ -63,11 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr,
                const Elf_Shdr *sechdrs, struct module *me)
 {
        const Elf_Shdr *sect;
-       int err;
-
-       err = module_bug_finalize(hdr, sechdrs, me);
-       if (err)
-               return err;
 
        /* Apply feature fixups */
        sect = find_section(hdr, sechdrs, "__ftr_fixup");
@@ -101,5 +96,4 @@ int module_finalize(const Elf_Ehdr *hdr,
 
 void module_arch_cleanup(struct module *mod)
 {
-       module_bug_cleanup(mod);
 }
index 7109f5b1baa87bd63e36aa18910c7d0bdfa40b12..2300426e531a096239b0620f9ec29f71e70b6daf 100644 (file)
@@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
                        ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
                        sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
                }
+               regs->trap = 0;
                return 0;               /* no signals delivered */
        }
 
@@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
                ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
        }
 
+       regs->trap = 0;
        if (ret) {
                spin_lock_irq(&current->sighand->siglock);
                sigorsets(&current->blocked, &current->blocked,
index 266610119f664970c66b72832ebb571eb842b1bc..b96a3a010c26859ab93f8cca5ec74cd4905dd16b 100644 (file)
@@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs,
        if (!sig)
                save_r2 = (unsigned int)regs->gpr[2];
        err = restore_general_regs(regs, sr);
+       regs->trap = 0;
        err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
        if (!sig)
                regs->gpr[2] = (unsigned long) save_r2;
@@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
        regs->nip = (unsigned long) ka->sa.sa_handler;
        /* enter the signal handler in big-endian mode */
        regs->msr &= ~MSR_LE;
-       regs->trap = 0;
        return 1;
 
 badframe:
@@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
        regs->nip = (unsigned long) ka->sa.sa_handler;
        /* enter the signal handler in big-endian mode */
        regs->msr &= ~MSR_LE;
-       regs->trap = 0;
 
        return 1;
 
index 2fe6fc64b614ef9d1b935a472487eaf161967fd9..27c4a4584f805b83fbcf09c5478e7ec9fa7f5e7c 100644 (file)
@@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
        err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
        err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
        /* skip SOFTE */
-       err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
+       regs->trap = 0;
        err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
        err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
        err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
index 5b243bd3eb3b699ee6a0712340c9df51db2ed948..3dc2a8d262b8731aa4995b6c4b20621f06742fef 100644 (file)
@@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
        int id_match = 0;
 
        if (dev == NULL || id == NULL)
-               return NULL;
+               return clk;
 
        mutex_lock(&clocks_mutex);
        list_for_each_entry(p, &clocks, node) {
index 45c0cb9b67e6774958c621b6e3c8055d43e46163..18c10482019811fd4fa25cbf1b0972ef87d4d0c7 100644 (file)
@@ -99,7 +99,7 @@ static void __init efika_pcisetup(void)
        if (bus_range == NULL || len < 2 * sizeof(int)) {
                printk(KERN_WARNING EFIKA_PLATFORM_NAME
                       ": Can't get bus-range for %s\n", pcictrl->full_name);
-               return;
+               goto out_put;
        }
 
        if (bus_range[1] == bus_range[0])
@@ -111,12 +111,12 @@ static void __init efika_pcisetup(void)
        printk(" controlled by %s\n", pcictrl->full_name);
        printk("\n");
 
-       hose = pcibios_alloc_controller(of_node_get(pcictrl));
+       hose = pcibios_alloc_controller(pcictrl);
        if (!hose) {
                printk(KERN_WARNING EFIKA_PLATFORM_NAME
                       ": Can't allocate PCI controller structure for %s\n",
                       pcictrl->full_name);
-               return;
+               goto out_put;
        }
 
        hose->first_busno = bus_range[0];
@@ -124,6 +124,9 @@ static void __init efika_pcisetup(void)
        hose->ops = &rtas_pci_ops;
 
        pci_process_bridge_OF_ranges(hose, pcictrl, 0);
+       return;
+out_put:
+       of_node_put(pcictrl);
 }
 
 #else
index 6e905314ad5d66035daf38a514adbfaa2aa60dfa..41f3a7eda1def670c1c12864de488788fc27ff98 100644 (file)
@@ -325,12 +325,16 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number)
        clrbits32(&simple_gpio->simple_dvo, sync | out);
        clrbits8(&wkup_gpio->wkup_dvo, reset);
 
-       /* wait at lease 1 us */
-       udelay(2);
+       /* wait for 1 us */
+       udelay(1);
 
        /* Deassert reset */
        setbits8(&wkup_gpio->wkup_dvo, reset);
 
+       /* wait at least 200ns */
+       /* 7 ~= (200ns * timebase) / ns2sec */
+       __delay(7);
+
        /* Restore pin-muxing */
        out_be32(&simple_gpio->port_config, mux);
 
index 104f2007f097720b339e469d37b7732c120c8168..a875c2f542e1070a120b484c96a0d2fc10fc55cb 100644 (file)
@@ -181,7 +181,7 @@ static inline int is_compat_task(void)
 
 #endif
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        unsigned long stack;
 
index 22cfd634c35531b7f8a1d4057f92b4af72e20d1a..f7167ee4604cf7033e30eb3845aa8f9ba9fd538b 100644 (file)
@@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr,
 {
        vfree(me->arch.syminfo);
        me->arch.syminfo = NULL;
-       return module_bug_finalize(hdr, sechdrs, me);
+       return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
-       module_bug_cleanup(mod);
 }
index 43adddfe4c04b6d2eee9acfa8cad99a7788dfcc4..ae0be697a89e4b220f527a2bdb34f4da7ec7d318 100644 (file)
@@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr,
        int ret = 0;
 
        ret |= module_dwarf_finalize(hdr, sechdrs, me);
-       ret |= module_bug_finalize(hdr, sechdrs, me);
 
        return ret;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
-       module_bug_cleanup(mod);
        module_dwarf_cleanup(mod);
 }
index 5016f76ea98a6f38510d3dc5a8593a1d871d4f53..6f57325bb883c5553b4781691cd699952bb90ff8 100644 (file)
@@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = current_thread_info()->kregs;
        unsigned long usp = regs->u_regs[UREG_I6];
index 357ced3c33ffac87a992e01b6820a77084cfb8de..6318e622cfb065d9da81e40b766c12dc0a6e2e7b 100644 (file)
@@ -1038,6 +1038,7 @@ static int __hw_perf_event_init(struct perf_event *event)
        if (atomic_read(&nmi_active) < 0)
                return -ENODEV;
 
+       pmap = NULL;
        if (attr->type == PERF_TYPE_HARDWARE) {
                if (attr->config >= sparc_pmu->max_events)
                        return -EINVAL;
@@ -1046,9 +1047,18 @@ static int __hw_perf_event_init(struct perf_event *event)
                pmap = sparc_map_cache_event(attr->config);
                if (IS_ERR(pmap))
                        return PTR_ERR(pmap);
-       } else
+       } else if (attr->type != PERF_TYPE_RAW)
                return -EOPNOTSUPP;
 
+       if (pmap) {
+               hwc->event_base = perf_event_encode(pmap);
+       } else {
+               /* User gives us "(encoding << 16) | pic_mask" for
+                * PERF_TYPE_RAW events.
+                */
+               hwc->event_base = attr->config;
+       }
+
        /* We save the enable bits in the config_base.  */
        hwc->config_base = sparc_pmu->irq_bit;
        if (!attr->exclude_user)
@@ -1058,8 +1068,6 @@ static int __hw_perf_event_init(struct perf_event *event)
        if (!attr->exclude_hv)
                hwc->config_base |= sparc_pmu->hv_bit;
 
-       hwc->event_base = perf_event_encode(pmap);
-
        n = 0;
        if (event->group_leader != event) {
                n = collect_events(event->group_leader,
index ea22cd373c64f4bc371478d2b7be14f71cd32560..75fad425e249bc40559f98d14ead5699839bbbb8 100644 (file)
@@ -453,8 +453,66 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
        return err;
 }
 
-static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-                         int signo, sigset_t *oldset)
+/* The I-cache flush instruction only works in the primary ASI, which
+ * right now is the nucleus, aka. kernel space.
+ *
+ * Therefore we have to kick the instructions out using the kernel
+ * side linear mapping of the physical address backing the user
+ * instructions.
+ */
+static void flush_signal_insns(unsigned long address)
+{
+       unsigned long pstate, paddr;
+       pte_t *ptep, pte;
+       pgd_t *pgdp;
+       pud_t *pudp;
+       pmd_t *pmdp;
+
+       /* Commit all stores of the instructions we are about to flush.  */
+       wmb();
+
+       /* Disable cross-call reception.  In this way even a very wide
+        * munmap() on another cpu can't tear down the page table
+        * hierarchy from underneath us, since that can't complete
+        * until the IPI tlb flush returns.
+        */
+
+       __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+       __asm__ __volatile__("wrpr %0, %1, %%pstate"
+                               : : "r" (pstate), "i" (PSTATE_IE));
+
+       pgdp = pgd_offset(current->mm, address);
+       if (pgd_none(*pgdp))
+               goto out_irqs_on;
+       pudp = pud_offset(pgdp, address);
+       if (pud_none(*pudp))
+               goto out_irqs_on;
+       pmdp = pmd_offset(pudp, address);
+       if (pmd_none(*pmdp))
+               goto out_irqs_on;
+
+       ptep = pte_offset_map(pmdp, address);
+       pte = *ptep;
+       if (!pte_present(pte))
+               goto out_unmap;
+
+       paddr = (unsigned long) page_address(pte_page(pte));
+
+       __asm__ __volatile__("flush     %0 + %1"
+                            : /* no outputs */
+                            : "r" (paddr),
+                              "r" (address & (PAGE_SIZE - 1))
+                            : "memory");
+
+out_unmap:
+       pte_unmap(ptep);
+out_irqs_on:
+       __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
+
+}
+
+static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+                        int signo, sigset_t *oldset)
 {
        struct signal_frame32 __user *sf;
        int sigframe_size;
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        if (ka->ka_restorer) {
                regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
        } else {
-               /* Flush instruction space. */
                unsigned long address = ((unsigned long)&(sf->insns[0]));
-               pgd_t *pgdp = pgd_offset(current->mm, address);
-               pud_t *pudp = pud_offset(pgdp, address);
-               pmd_t *pmdp = pmd_offset(pudp, address);
-               pte_t *ptep;
-               pte_t pte;
 
                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
        
@@ -562,34 +614,22 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                if (err)
                        goto sigsegv;
 
-               preempt_disable();
-               ptep = pte_offset_map(pmdp, address);
-               pte = *ptep;
-               if (pte_present(pte)) {
-                       unsigned long page = (unsigned long)
-                               page_address(pte_page(pte));
-
-                       wmb();
-                       __asm__ __volatile__("flush     %0 + %1"
-                                            : /* no outputs */
-                                            : "r" (page),
-                                              "r" (address & (PAGE_SIZE - 1))
-                                            : "memory");
-               }
-               pte_unmap(ptep);
-               preempt_enable();
+               flush_signal_insns(address);
        }
-       return;
+       return 0;
 
 sigill:
        do_exit(SIGILL);
+       return -EINVAL;
+
 sigsegv:
        force_sigsegv(signo, current);
+       return -EFAULT;
 }
 
-static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-                            unsigned long signr, sigset_t *oldset,
-                            siginfo_t *info)
+static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+                           unsigned long signr, sigset_t *oldset,
+                           siginfo_t *info)
 {
        struct rt_signal_frame32 __user *sf;
        int sigframe_size;
@@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        if (ka->ka_restorer)
                regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
        else {
-               /* Flush instruction space. */
                unsigned long address = ((unsigned long)&(sf->insns[0]));
-               pgd_t *pgdp = pgd_offset(current->mm, address);
-               pud_t *pudp = pud_offset(pgdp, address);
-               pmd_t *pmdp = pmd_offset(pudp, address);
-               pte_t *ptep;
 
                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
        
@@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                if (err)
                        goto sigsegv;
 
-               preempt_disable();
-               ptep = pte_offset_map(pmdp, address);
-               if (pte_present(*ptep)) {
-                       unsigned long page = (unsigned long)
-                               page_address(pte_page(*ptep));
-
-                       wmb();
-                       __asm__ __volatile__("flush     %0 + %1"
-                                            : /* no outputs */
-                                            : "r" (page),
-                                              "r" (address & (PAGE_SIZE - 1))
-                                            : "memory");
-               }
-               pte_unmap(ptep);
-               preempt_enable();
+               flush_signal_insns(address);
        }
-       return;
+       return 0;
 
 sigill:
        do_exit(SIGILL);
+       return -EINVAL;
+
 sigsegv:
        force_sigsegv(signr, current);
+       return -EFAULT;
 }
 
-static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
-                                  siginfo_t *info,
-                                  sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
+                                 siginfo_t *info,
+                                 sigset_t *oldset, struct pt_regs *regs)
 {
+       int err;
+
        if (ka->sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame32(ka, regs, signr, oldset, info);
+               err = setup_rt_frame32(ka, regs, signr, oldset, info);
        else
-               setup_frame32(ka, regs, signr, oldset);
+               err = setup_frame32(ka, regs, signr, oldset);
+
+       if (err)
+               return err;
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
                sigaddset(&current->blocked,signr);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+
+       tracehook_signal_handler(signr, info, ka, regs, 0);
+
+       return 0;
 }
 
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
        if (signr > 0) {
                if (restart_syscall)
                        syscall_restart32(orig_i0, regs, &ka.sa);
-               handle_signal32(signr, &ka, &info, oldset, regs);
-
-               /* A signal was successfully delivered; the saved
-                * sigmask will have been stored in the signal frame,
-                * and will be restored by sigreturn, so we can simply
-                * clear the TS_RESTORE_SIGMASK flag.
-                */
-               current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
-               tracehook_signal_handler(signr, &info, &ka, regs, 0);
+               if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
+                       /* A signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TS_RESTORE_SIGMASK flag.
+                        */
+                       current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+               }
                return;
        }
        if (restart_syscall &&
@@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
                regs->u_regs[UREG_I0] = orig_i0;
                regs->tpc -= 4;
                regs->tnpc -= 4;
+               pt_regs_clear_syscall(regs);
        }
        if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->tpc -= 4;
                regs->tnpc -= 4;
+               pt_regs_clear_syscall(regs);
        }
 
        /* If there's no signal to deliver, we just put the saved sigmask
index 9882df92ba0a2c8b8da4639f7e181214930c8ed6..5e5c5fd03783c997f5c344025e8f4784182a0ddc 100644 (file)
@@ -315,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
        return err;
 }
 
-static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
-                       int signo, sigset_t *oldset)
+static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
+                      int signo, sigset_t *oldset)
 {
        struct signal_frame __user *sf;
        int sigframe_size, err;
@@ -384,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
                /* Flush instruction space. */
                flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
        }
-       return;
+       return 0;
 
 sigill_and_return:
        do_exit(SIGILL);
+       return -EINVAL;
+
 sigsegv:
        force_sigsegv(signo, current);
+       return -EFAULT;
 }
 
-static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
-                          int signo, sigset_t *oldset, siginfo_t *info)
+static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
+                         int signo, sigset_t *oldset, siginfo_t *info)
 {
        struct rt_signal_frame __user *sf;
        int sigframe_size;
@@ -466,22 +469,30 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
                /* Flush instruction space. */
                flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
        }
-       return;
+       return 0;
 
 sigill:
        do_exit(SIGILL);
+       return -EINVAL;
+
 sigsegv:
        force_sigsegv(signo, current);
+       return -EFAULT;
 }
 
-static inline void
+static inline int
 handle_signal(unsigned long signr, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
+       int err;
+
        if (ka->sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame(ka, regs, signr, oldset, info);
+               err = setup_rt_frame(ka, regs, signr, oldset, info);
        else
-               setup_frame(ka, regs, signr, oldset);
+               err = setup_frame(ka, regs, signr, oldset);
+
+       if (err)
+               return err;
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -489,6 +500,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
                sigaddset(&current->blocked, signr);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+
+       tracehook_signal_handler(signr, info, ka, regs, 0);
+
+       return 0;
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -546,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        if (signr > 0) {
                if (restart_syscall)
                        syscall_restart(orig_i0, regs, &ka.sa);
-               handle_signal(signr, &ka, &info, oldset, regs);
-
-               /* a signal was successfully delivered; the saved
-                * sigmask will have been stored in the signal frame,
-                * and will be restored by sigreturn, so we can simply
-                * clear the TIF_RESTORE_SIGMASK flag.
-                */
-               if (test_thread_flag(TIF_RESTORE_SIGMASK))
-                       clear_thread_flag(TIF_RESTORE_SIGMASK);
-
-               tracehook_signal_handler(signr, &info, &ka, regs, 0);
+               if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+                       /* a signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TIF_RESTORE_SIGMASK flag.
+                        */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               }
                return;
        }
        if (restart_syscall &&
@@ -567,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
                regs->u_regs[UREG_I0] = orig_i0;
                regs->pc -= 4;
                regs->npc -= 4;
+               pt_regs_clear_syscall(regs);
        }
        if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->pc -= 4;
                regs->npc -= 4;
+               pt_regs_clear_syscall(regs);
        }
 
        /* if there's no signal to deliver, we just put the saved sigmask
index 9fa48c30037e5356c2f686be695ea8bcfb3613f3..006fe4515886dc6ae2a7a8e6cc9b6df9c16fda46 100644 (file)
@@ -409,7 +409,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *
        return (void __user *) sp;
 }
 
-static inline void
+static inline int
 setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
               int signo, sigset_t *oldset, siginfo_t *info)
 {
@@ -483,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        }
        /* 4. return to kernel instructions */
        regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
-       return;
+       return 0;
 
 sigill:
        do_exit(SIGILL);
+       return -EINVAL;
+
 sigsegv:
        force_sigsegv(signo, current);
+       return -EFAULT;
 }
 
-static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
-                                siginfo_t *info,
-                                sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
+                               siginfo_t *info,
+                               sigset_t *oldset, struct pt_regs *regs)
 {
-       setup_rt_frame(ka, regs, signr, oldset,
-                      (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+       int err;
+
+       err = setup_rt_frame(ka, regs, signr, oldset,
+                            (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+       if (err)
+               return err;
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
        if (!(ka->sa.sa_flags & SA_NOMASK))
                sigaddset(&current->blocked,signr);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+
+       tracehook_signal_handler(signr, info, ka, regs, 0);
+
+       return 0;
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -571,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        if (signr > 0) {
                if (restart_syscall)
                        syscall_restart(orig_i0, regs, &ka.sa);
-               handle_signal(signr, &ka, &info, oldset, regs);
-
-               /* A signal was successfully delivered; the saved
-                * sigmask will have been stored in the signal frame,
-                * and will be restored by sigreturn, so we can simply
-                * clear the TS_RESTORE_SIGMASK flag.
-                */
-               current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
-               tracehook_signal_handler(signr, &info, &ka, regs, 0);
+               if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+                       /* A signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TS_RESTORE_SIGMASK flag.
+                        */
+                       current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+               }
                return;
        }
        if (restart_syscall &&
@@ -591,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
                regs->u_regs[UREG_I0] = orig_i0;
                regs->tpc -= 4;
                regs->tnpc -= 4;
+               pt_regs_clear_syscall(regs);
        }
        if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->tpc -= 4;
                regs->tnpc -= 4;
+               pt_regs_clear_syscall(regs);
        }
 
        /* If there's no signal to deliver, we just put the saved sigmask
index 1246573be59ee78b872ed5d8fa5d583cf16860ac..261aaba092d4bb424d336caa645b222a1fdb1068 100644 (file)
 /** Is the PROC_STATUS SPR supported? */
 #define CHIP_HAS_PROC_STATUS_SPR() 0
 
+/** Is the DSTREAM_PF SPR supported? */
+#define CHIP_HAS_DSTREAM_PF() 0
+
 /** Log of the number of mshims we have. */
 #define CHIP_LOG_NUM_MSHIMS() 2
 
index e864c47fc89cce6cd7c366784e8d76d22a43e280..70017699a74ce0e37e30d0c7c8e62865e9577e3b 100644 (file)
 /** Is the PROC_STATUS SPR supported? */
 #define CHIP_HAS_PROC_STATUS_SPR() 1
 
+/** Is the DSTREAM_PF SPR supported? */
+#define CHIP_HAS_DSTREAM_PF() 0
+
 /** Log of the number of mshims we have. */
 #define CHIP_LOG_NUM_MSHIMS() 2
 
index 5a34da6cdd79a18802d437056393c41d6e2f6fba..8b60ec8b2d194f6e352df18eba598e3a61ef52f3 100644 (file)
@@ -195,7 +195,7 @@ static inline unsigned long ptr_to_compat_reg(void __user *uptr)
        return (long)(int)(long __force)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = task_pt_regs(current);
        return (void __user *)regs->sp - len;
@@ -214,8 +214,9 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
 struct compat_sigaction;
 struct compat_siginfo;
 struct compat_sigaltstack;
-long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
-                      compat_uptr_t __user *envp);
+long compat_sys_execve(const char __user *path,
+                      const compat_uptr_t __user *argv,
+                      const compat_uptr_t __user *envp);
 long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
                             struct compat_sigaction __user *oact,
                             size_t sigsetsize);
index 8c95bef3fa45a185a1ec5610bc7a1c21e6f96c13..ee43328713abf2ace9f76e885e9e26ce7b615b3a 100644 (file)
@@ -164,22 +164,22 @@ static inline void _tile_writeq(u64 val, unsigned long addr)
 #define iowrite32 writel
 #define iowrite64 writeq
 
-static inline void *memcpy_fromio(void *dst, void *src, int len)
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
+                                size_t len)
 {
        int x;
        BUG_ON((unsigned long)src & 0x3);
        for (x = 0; x < len; x += 4)
                *(u32 *)(dst + x) = readl(src + x);
-       return dst;
 }
 
-static inline void *memcpy_toio(void *dst, void *src, int len)
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
+                               size_t len)
 {
        int x;
        BUG_ON((unsigned long)dst & 0x3);
        for (x = 0; x < len; x += 4)
                writel(*(u32 *)(src + x), dst + x);
-       return dst;
 }
 
 /*
index d942d09b252e4012d251d6d09eaa1af6c7df7c3f..ccd5f84256886c7526edd78bc58ab621f14ef2ac 100644 (file)
@@ -103,6 +103,18 @@ struct thread_struct {
        /* Any other miscellaneous processor state bits */
        unsigned long proc_status;
 #endif
+#if !CHIP_HAS_FIXED_INTVEC_BASE()
+       /* Interrupt base for PL0 interrupts */
+       unsigned long interrupt_vector_base;
+#endif
+#if CHIP_HAS_TILE_RTF_HWM()
+       /* Tile cache retry fifo high-water mark */
+       unsigned long tile_rtf_hwm;
+#endif
+#if CHIP_HAS_DSTREAM_PF()
+       /* Data stream prefetch control */
+       unsigned long dstream_pf;
+#endif
 #ifdef CONFIG_HARDWALL
        /* Is this task tied to an activated hardwall? */
        struct hardwall_info *hardwall;
index acdae814e0161b967f6289e265f6aad1516b2aac..4a02bb07397993a2eb025ae7cd79caf618ae03d6 100644 (file)
@@ -51,10 +51,7 @@ typedef uint_reg_t pt_reg_t;
 
 /*
  * This struct defines the way the registers are stored on the stack during a
- * system call/exception.  It should be a multiple of 8 bytes to preserve
- * normal stack alignment rules.
- *
- * Must track <sys/ucontext.h> and <sys/procfs.h>
+ * system call or exception.  "struct sigcontext" has the same shape.
  */
 struct pt_regs {
        /* Saved main processor registers; 56..63 are special. */
@@ -80,11 +77,6 @@ struct pt_regs {
 
 #endif /* __ASSEMBLY__ */
 
-/* Flag bits in pt_regs.flags */
-#define PT_FLAGS_DISABLE_IRQ    1  /* on return to kernel, disable irqs */
-#define PT_FLAGS_CALLER_SAVES   2  /* caller-save registers are valid */
-#define PT_FLAGS_RESTORE_REGS   4  /* restore callee-save regs on return */
-
 #define PTRACE_GETREGS         12
 #define PTRACE_SETREGS         13
 #define PTRACE_GETFPREGS       14
@@ -101,6 +93,11 @@ struct pt_regs {
 
 #ifdef __KERNEL__
 
+/* Flag bits in pt_regs.flags */
+#define PT_FLAGS_DISABLE_IRQ    1  /* on return to kernel, disable irqs */
+#define PT_FLAGS_CALLER_SAVES   2  /* caller-save registers are valid */
+#define PT_FLAGS_RESTORE_REGS   4  /* restore callee-save regs on return */
+
 #ifndef __ASSEMBLY__
 
 #define instruction_pointer(regs) ((regs)->pc)
index 7cd7672e3ad4043072a6b6ac9c393491426f08a1..5e2d03336f5335ae99151a383a855e5db7cae6b0 100644 (file)
 #ifndef _ASM_TILE_SIGCONTEXT_H
 #define _ASM_TILE_SIGCONTEXT_H
 
-/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
-#include <asm/ptrace.h>
-
-/* Must track <sys/ucontext.h> */
+#include <arch/abi.h>
 
+/*
+ * struct sigcontext has the same shape as struct pt_regs,
+ * but is simplified since we know the fault is from userspace.
+ */
 struct sigcontext {
-       struct pt_regs regs;
+       uint_reg_t gregs[53];   /* General-purpose registers.  */
+       uint_reg_t tp;          /* Aliases gregs[TREG_TP].  */
+       uint_reg_t sp;          /* Aliases gregs[TREG_SP].  */
+       uint_reg_t lr;          /* Aliases gregs[TREG_LR].  */
+       uint_reg_t pc;          /* Program counter.  */
+       uint_reg_t ics;         /* In Interrupt Critical Section?  */
+       uint_reg_t faultnum;    /* Fault number.  */
+       uint_reg_t pad[5];
 };
 
 #endif /* _ASM_TILE_SIGCONTEXT_H */
index eb0253f32202c0b52b65012b7c4a8c839aae47dc..c1ee1d61d44ca8a07c504b9af425df3a9c7185c7 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm-generic/signal.h>
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+struct pt_regs;
 int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
 int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
 void do_signal(struct pt_regs *regs);
index af165a74537f84ff1f377ce22951848bba58d9e0..ce99ffefeacff351c5523d574581e1092d57ca06 100644 (file)
@@ -62,10 +62,12 @@ long sys_fork(void);
 long _sys_fork(struct pt_regs *regs);
 long sys_vfork(void);
 long _sys_vfork(struct pt_regs *regs);
-long sys_execve(char __user *filename, char __user * __user *argv,
-               char __user * __user *envp);
-long _sys_execve(char __user *filename, char __user * __user *argv,
-                char __user * __user *envp, struct pt_regs *regs);
+long sys_execve(const char __user *filename,
+               const char __user *const __user *argv,
+               const char __user *const __user *envp);
+long _sys_execve(const char __user *filename,
+                const char __user *const __user *argv,
+                const char __user *const __user *envp, struct pt_regs *regs);
 
 /* kernel/signal.c */
 long sys_sigaltstack(const stack_t __user *, stack_t __user *);
@@ -86,10 +88,13 @@ int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
 #endif
 
 #ifdef CONFIG_COMPAT
-long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
-                      compat_uptr_t __user *envp);
-long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
-                       compat_uptr_t __user *envp, struct pt_regs *regs);
+long compat_sys_execve(const char __user *path,
+                      const compat_uptr_t __user *argv,
+                      const compat_uptr_t __user *envp);
+long _compat_sys_execve(const char __user *path,
+                       const compat_uptr_t __user *argv,
+                       const compat_uptr_t __user *envp,
+                       struct pt_regs *regs);
 long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
                            struct compat_sigaltstack __user *uoss_ptr);
 long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
index 84f296ca9e63c85da528ee9a8d403cc8362c4097..8f58bdff20d7f7dd9b77d16a6901eb9db82f056b 100644 (file)
@@ -1506,13 +1506,6 @@ handle_ill:
        }
        STD_ENDPROC(handle_ill)
 
-       .pushsection .rodata, "a"
-       .align  8
-bpt_code:
-       bpt
-       ENDPROC(bpt_code)
-       .popsection
-
 /* Various stub interrupt handlers and syscall handlers */
 
 STD_ENTRY_LOCAL(_kernel_double_fault)
index 985cc28c74c5696f91adcf82d6347439999bfa41..84c29111756c2212f02cd5bc841691c1cc0a0fd9 100644 (file)
@@ -408,6 +408,15 @@ static void save_arch_state(struct thread_struct *t)
 #if CHIP_HAS_PROC_STATUS_SPR()
        t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
 #endif
+#if !CHIP_HAS_FIXED_INTVEC_BASE()
+       t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0);
+#endif
+#if CHIP_HAS_TILE_RTF_HWM()
+       t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM);
+#endif
+#if CHIP_HAS_DSTREAM_PF()
+       t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
+#endif
 }
 
 static void restore_arch_state(const struct thread_struct *t)
@@ -428,14 +437,14 @@ static void restore_arch_state(const struct thread_struct *t)
 #if CHIP_HAS_PROC_STATUS_SPR()
        __insn_mtspr(SPR_PROC_STATUS, t->proc_status);
 #endif
+#if !CHIP_HAS_FIXED_INTVEC_BASE()
+       __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base);
+#endif
 #if CHIP_HAS_TILE_RTF_HWM()
-       /*
-        * Clear this whenever we switch back to a process in case
-        * the previous process was monkeying with it.  Even if enabled
-        * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a
-        * performance hint, so isn't worth a full save/restore.
-        */
-       __insn_mtspr(SPR_TILE_RTF_HWM, 0);
+       __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm);
+#endif
+#if CHIP_HAS_DSTREAM_PF()
+       __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf);
 #endif
 }
 
@@ -561,8 +570,9 @@ out:
 }
 
 #ifdef CONFIG_COMPAT
-long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
-                       compat_uptr_t __user *envp, struct pt_regs *regs)
+long _compat_sys_execve(const char __user *path,
+                       const compat_uptr_t __user *argv,
+                       const compat_uptr_t __user *envp, struct pt_regs *regs)
 {
        long error;
        char *filename;
@@ -657,7 +667,7 @@ void show_regs(struct pt_regs *regs)
               regs->regs[51], regs->regs[52], regs->tp);
        pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
 #else
-       for (i = 0; i < 52; i += 3)
+       for (i = 0; i < 52; i += 4)
                pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
                       " r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
                       i, regs->regs[i], i+1, regs->regs[i+1],
index 45b66a3c991ffbc79a7f93e3f00543e50b20de8a..ce183aa1492c7abfaadfca95d54ec76bddc11455 100644 (file)
@@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs,
        /* Always make any pending restarted system calls return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
+       /*
+        * Enforce that sigcontext is like pt_regs, and doesn't mess
+        * up our stack alignment rules.
+        */
+       BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs));
+       BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0);
+
        for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
-               err |= __get_user(((long *)regs)[i],
-                                 &((long __user *)(&sc->regs))[i]);
+               err |= __get_user(regs->regs[i], &sc->gregs[i]);
 
        regs->faultnum = INT_SWINT_1_SIGRETURN;
 
-       err |= __get_user(*pr0, &sc->regs.regs[0]);
+       err |= __get_user(*pr0, &sc->gregs[0]);
        return err;
 }
 
@@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
        int i, err = 0;
 
        for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
-               err |= __put_user(((long *)regs)[i],
-                                 &((long __user *)(&sc->regs))[i]);
+               err |= __put_user(regs->regs[i], &sc->gregs[i]);
 
        return err;
 }
@@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         * Set up registers for signal handler.
         * Registers that we don't modify keep the value they had from
         * user-space at the time we took the signal.
+        * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
+        * since some things rely on this (e.g. glibc's debug/segfault.c).
         */
        regs->pc = (unsigned long) ka->sa.sa_handler;
        regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
        regs->sp = (unsigned long) frame;
        regs->lr = restorer;
        regs->regs[0] = (unsigned long) usig;
-
-       if (ka->sa.sa_flags & SA_SIGINFO) {
-               /* Need extra arguments, so mark to restore caller-saves. */
-               regs->regs[1] = (unsigned long) &frame->info;
-               regs->regs[2] = (unsigned long) &frame->uc;
-               regs->flags |= PT_FLAGS_CALLER_SAVES;
-       }
+       regs->regs[1] = (unsigned long) &frame->info;
+       regs->regs[2] = (unsigned long) &frame->uc;
+       regs->flags |= PT_FLAGS_CALLER_SAVES;
 
        /*
         * Notify any tracer that was single-stepping it.
index 38a68b0b45813474a791f18aabaa35eb33b8a38a..ea2e0ce28380a2d3fa59391cfc02cb4ca0022f1e 100644 (file)
@@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
                        pr_err("  <received signal %d>\n",
                               frame->info.si_signo);
                }
-               return &frame->uc.uc_mcontext.regs;
+               return (struct pt_regs *)&frame->uc.uc_mcontext;
        }
        return NULL;
 }
index 2ab233ba32c1564f8323884017108b0d53978366..47d0c37897d5874d0bfb95d3d2b87441bd2df6a0 100644 (file)
@@ -255,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-static int uml_net_set_mac(struct net_device *dev, void *addr)
-{
-       struct uml_net_private *lp = netdev_priv(dev);
-       struct sockaddr *hwaddr = addr;
-
-       spin_lock_irq(&lp->lock);
-       eth_mac_addr(dev, hwaddr->sa_data);
-       spin_unlock_irq(&lp->lock);
-
-       return 0;
-}
-
 static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
 {
        dev->mtu = new_mtu;
@@ -373,7 +361,7 @@ static const struct net_device_ops uml_netdev_ops = {
        .ndo_start_xmit         = uml_net_start_xmit,
        .ndo_set_multicast_list = uml_net_set_multicast_list,
        .ndo_tx_timeout         = uml_net_tx_timeout,
-       .ndo_set_mac_address    = uml_net_set_mac,
+       .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = uml_net_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
 };
@@ -472,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac,
            ((*transport->user->init)(&lp->user, dev) != 0))
                goto out_unregister;
 
-       eth_mac_addr(dev, device->mac);
+       /* don't use eth_mac_addr, it will not work here */
+       memcpy(dev->dev_addr, device->mac, ETH_ALEN);
        dev->mtu = transport->user->mtu;
        dev->netdev_ops = &uml_netdev_ops;
        dev->ethtool_ops = &uml_net_ethtool_ops;
index cd145eda357950b66b1ad2f05f55bd0094df6006..49b5e1eb32622abbdab4b3631207460bc80a1e14 100644 (file)
@@ -62,7 +62,7 @@ static long execve1(const char *file,
        return error;
 }
 
-long um_execve(const char *file, char __user *__user *argv, char __user *__user *env)
+long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
 {
        long err;
 
@@ -72,8 +72,8 @@ long um_execve(const char *file, char __user *__user *argv, char __user *__user
        return err;
 }
 
-long sys_execve(const char __user *file, char __user *__user *argv,
-               char __user *__user *env)
+long sys_execve(const char __user *file, const char __user *const __user *argv,
+               const char __user *const __user *env)
 {
        long error;
        char *filename;
index 1303a105fe91dc5aabca314e4e94faf8573b9c65..5bf97db24a046283f8704e2f7e0ee91e7b4d4844 100644 (file)
@@ -1 +1 @@
-extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env);
+extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env);
index 5ddb246626dbb87afe7484b87c0c495c8643de8f..f958cb876ee3d3e47ddff71094e8026c0a110f5d 100644 (file)
@@ -60,8 +60,8 @@ int kernel_execve(const char *filename,
 
        fs = get_fs();
        set_fs(KERNEL_DS);
-       ret = um_execve(filename, (char __user *__user *)argv,
-                       (char __user *__user *) envp);
+       ret = um_execve(filename, (const char __user *const __user *)argv,
+                       (const char __user *const __user *) envp);
        set_fs(fs);
 
        return ret;
index 8aa1b59b9074586e1fe9930b85d0cf945f14a695..e8c8881351b3a5a0b17429851732e0b12405d7c6 100644 (file)
@@ -74,7 +74,7 @@ endif
 
 ifdef CONFIG_CC_STACKPROTECTOR
        cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
-        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
+        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
                 stackp-y := -fstack-protector
                 KBUILD_CFLAGS += $(stackp-y)
         else
index 030f4b93e255ac00c9cd646a733eda26733a5324..5df2869c874baced33de00a78a7b693f3237ea0f 100644 (file)
@@ -58,7 +58,19 @@ static void parse_earlyprintk(void)
                if (arg[pos] == ',')
                        pos++;
 
-               if (!strncmp(arg, "ttyS", 4)) {
+               /*
+                * make sure we have
+                *      "serial,0x3f8,115200"
+                *      "serial,ttyS0,115200"
+                *      "ttyS0,115200"
+                */
+               if (pos == 7 && !strncmp(arg + pos, "0x", 2)) {
+                       port = simple_strtoull(arg + pos, &e, 16);
+                       if (port == 0 || arg + pos == e)
+                               port = DEFAULT_SERIAL_PORT;
+                       else
+                               pos = e - arg;
+               } else if (!strncmp(arg + pos, "ttyS", 4)) {
                        static const int bases[] = { 0x3f8, 0x2f8 };
                        int idx = 0;
 
index 0350311906ae731ca91e9ecedbc3e7acbaa668d0..2d93bdbc9ac026f2c0ef1e3fcd9c9a208b609787 100644 (file)
@@ -34,7 +34,7 @@
 #include <asm/ia32.h>
 
 #undef WARN_OLD
-#undef CORE_DUMP /* probably broken */
+#undef CORE_DUMP /* definitely broken */
 
 static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs);
 static int load_aout_library(struct file *);
@@ -131,21 +131,15 @@ static void set_brk(unsigned long start, unsigned long end)
  * macros to write out all the necessary info.
  */
 
-static int dump_write(struct file *file, const void *addr, int nr)
-{
-       return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
+#include <linux/coredump.h>
 
 #define DUMP_WRITE(addr, nr)                        \
        if (!dump_write(file, (void *)(addr), (nr))) \
                goto end_coredump;
 
-#define DUMP_SEEK(offset)                                              \
-       if (file->f_op->llseek) {                                       \
-               if (file->f_op->llseek(file, (offset), 0) != (offset))  \
-                       goto end_coredump;                              \
-       } else                                                          \
-               file->f_pos = (offset)
+#define DUMP_SEEK(offset)              \
+       if (!dump_seek(file, offset))   \
+               goto end_coredump;
 
 #define START_DATA()   (u.u_tsize << PAGE_SHIFT)
 #define START_STACK(u) (u.start_stack)
@@ -217,12 +211,6 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file,
                dump_size = dump.u_ssize << PAGE_SHIFT;
                DUMP_WRITE(dump_start, dump_size);
        }
-       /*
-        * Finally dump the task struct.  Not be used by gdb, but
-        * could be useful
-        */
-       set_fs(KERNEL_DS);
-       DUMP_WRITE(current, sizeof(*current));
 end_coredump:
        set_fs(fs);
        return has_dumped;
index b86feabed69bfe8e74f81f179c91fbe3a4b799d8..518bb99c339480820fc3995b1456d29704d67f07 100644 (file)
        /*
         * Reload arg registers from stack in case ptrace changed them.
         * We don't reload %eax because syscall_trace_enter() returned
-        * the value it wants us to use in the table lookup.
+        * the %rax value we should see.  Instead, we just truncate that
+        * value to 32 bits again as we did on entry from user mode.
+        * If it's a new value set by user_regset during entry tracing,
+        * this matches the normal truncation of the user-mode value.
+        * If it's -1 to make us punt the syscall, then (u32)-1 is still
+        * an appropriately invalid value.
         */
        .macro LOAD_ARGS32 offset, _r9=0
        .if \_r9
@@ -60,6 +65,7 @@
        movl \offset+48(%rsp),%edx
        movl \offset+56(%rsp),%esi
        movl \offset+64(%rsp),%edi
+       movl %eax,%eax                  /* zero extension */
        .endm
        
        .macro CFI_STARTPROC32 simple
@@ -153,7 +159,7 @@ ENTRY(ia32_sysenter_target)
        testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        CFI_REMEMBER_STATE
        jnz  sysenter_tracesys
-       cmpl    $(IA32_NR_syscalls-1),%eax
+       cmpq    $(IA32_NR_syscalls-1),%rax
        ja      ia32_badsys
 sysenter_do_call:
        IA32_ARG_FIXUP
@@ -195,7 +201,7 @@ sysexit_from_sys_call:
        movl $AUDIT_ARCH_I386,%edi      /* 1st arg: audit arch */
        call audit_syscall_entry
        movl RAX-ARGOFFSET(%rsp),%eax   /* reload syscall number */
-       cmpl $(IA32_NR_syscalls-1),%eax
+       cmpq $(IA32_NR_syscalls-1),%rax
        ja ia32_badsys
        movl %ebx,%edi                  /* reload 1st syscall arg */
        movl RCX-ARGOFFSET(%rsp),%esi   /* reload 2nd syscall arg */
@@ -248,7 +254,7 @@ sysenter_tracesys:
        call    syscall_trace_enter
        LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
-       cmpl    $(IA32_NR_syscalls-1),%eax
+       cmpq    $(IA32_NR_syscalls-1),%rax
        ja      int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
        jmp     sysenter_do_call
        CFI_ENDPROC
@@ -314,7 +320,7 @@ ENTRY(ia32_cstar_target)
        testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        CFI_REMEMBER_STATE
        jnz   cstar_tracesys
-       cmpl $IA32_NR_syscalls-1,%eax
+       cmpq $IA32_NR_syscalls-1,%rax
        ja  ia32_badsys
 cstar_do_call:
        IA32_ARG_FIXUP 1
@@ -367,7 +373,7 @@ cstar_tracesys:
        LOAD_ARGS32 ARGOFFSET, 1  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
        xchgl %ebp,%r9d
-       cmpl $(IA32_NR_syscalls-1),%eax
+       cmpq $(IA32_NR_syscalls-1),%rax
        ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
        jmp cstar_do_call
 END(ia32_cstar_target)
@@ -425,7 +431,7 @@ ENTRY(ia32_syscall)
        orl   $TS_COMPAT,TI_status(%r10)
        testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        jnz ia32_tracesys
-       cmpl $(IA32_NR_syscalls-1),%eax
+       cmpq $(IA32_NR_syscalls-1),%rax
        ja ia32_badsys
 ia32_do_call:
        IA32_ARG_FIXUP
@@ -444,7 +450,7 @@ ia32_tracesys:
        call syscall_trace_enter
        LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
-       cmpl $(IA32_NR_syscalls-1),%eax
+       cmpq $(IA32_NR_syscalls-1),%rax
        ja  int_ret_from_sys_call       /* ia32_tracesys has set RAX(%rsp) */
        jmp ia32_do_call
 END(ia32_syscall)
index d2544f1d705d3eb9cad310ac3486f94c2358b51d..cb030374b90aeb526ad7f985527def42643bc1a9 100644 (file)
@@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(void) { }
 
 #endif /* !CONFIG_AMD_IOMMU_STATS */
 
+static inline bool is_rd890_iommu(struct pci_dev *pdev)
+{
+       return (pdev->vendor == PCI_VENDOR_ID_ATI) &&
+              (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
+}
+
 #endif /* _ASM_X86_AMD_IOMMU_PROTO_H  */
index 7014e88bc7798af33f681724ff90cf09eda52af5..08616180deaf5b1e94bfe9ad0079cec7e9c619a3 100644 (file)
@@ -368,6 +368,9 @@ struct amd_iommu {
        /* capabilities of that IOMMU read from ACPI */
        u32 cap;
 
+       /* flags read from acpi table */
+       u8 acpi_flags;
+
        /*
         * Capability pointer. There could be more than one IOMMU per PCI
         * device function if there are more than one AMD IOMMU capability
@@ -411,6 +414,15 @@ struct amd_iommu {
 
        /* default dma_ops domain for that IOMMU */
        struct dma_ops_domain *default_dom;
+
+       /*
+        * This array is required to work around a potential BIOS bug.
+        * The BIOS may miss to restore parts of the PCI configuration
+        * space when the system resumes from S3. The result is that the
+        * IOMMU does not execute commands anymore which leads to system
+        * failure.
+        */
+       u32 cache_cfg[4];
 };
 
 /*
index 545776efeb164c72d523f2c78f2c501e1535344c..bafd80defa4328ed2f49e808daee7a624434345d 100644 (file)
@@ -309,7 +309,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
 {
        return ((1UL << (nr % BITS_PER_LONG)) &
-               (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+               (addr[nr / BITS_PER_LONG])) != 0;
 }
 
 static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
index 306160e58b48772ccef1f65c803a3a3813ff5d1e..1d9cd27c2920a326e5ac2440ebdbd998d0b925c0 100644 (file)
@@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = task_pt_regs(current);
        return (void __user *)regs->sp - len;
index 781a50b29a4917545e71c3e74bdcbbda7faa383d..3f76523589afa8b9f30abcb6841962b6344d603e 100644 (file)
 #define X86_FEATURE_XSAVEOPT   (7*32+ 4) /* Optimized Xsave */
 #define X86_FEATURE_PLN                (7*32+ 5) /* Intel Power Limit Notification */
 #define X86_FEATURE_PTS                (7*32+ 6) /* Intel Package Thermal Status */
+#define X86_FEATURE_DTS                (7*32+ 7) /* Digital Thermal Sensor */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
@@ -296,6 +297,7 @@ extern const char * const x86_power_flags[32];
 
 #endif /* CONFIG_X86_64 */
 
+#if __GNUC__ >= 4
 /*
  * Static testing of CPU features.  Used the same as boot_cpu_has().
  * These are only valid after alternatives have run, but will statically
@@ -304,7 +306,7 @@ extern const char * const x86_power_flags[32];
  */
 static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
                asm goto("1: jmp %l[t_no]\n"
                         "2:\n"
                         ".section .altinstructions,\"a\"\n"
@@ -345,7 +347,6 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
 #endif
 }
 
-#if __GNUC__ >= 4
 #define static_cpu_has(bit)                                    \
 (                                                              \
        __builtin_constant_p(boot_cpu_has(bit)) ?               \
index 004e6e25e91301dd8a6d188d84a9c9ee795a7100..1d5c08a1bdfdb5b61c72cb286dfb0ac382c17e76 100644 (file)
@@ -68,7 +68,6 @@ extern unsigned long force_hpet_address;
 extern u8 hpet_blockid;
 extern int hpet_force_user;
 extern u8 hpet_msi_disable;
-extern u8 hpet_readback_cmp;
 extern int is_hpet_enabled(void);
 extern int hpet_enable(void);
 extern void hpet_disable(void);
index 528a11e8d3e35f64fea90202d6f196d77d48e708..824ca07860d012cdcc9c46886500d056fdb2aeed 100644 (file)
@@ -20,7 +20,7 @@ struct arch_hw_breakpoint {
 #include <linux/list.h>
 
 /* Available HW breakpoint length encodings */
-#define X86_BREAKPOINT_LEN_X           0x00
+#define X86_BREAKPOINT_LEN_X           0x40
 #define X86_BREAKPOINT_LEN_1           0x40
 #define X86_BREAKPOINT_LEN_2           0x44
 #define X86_BREAKPOINT_LEN_4           0x4c
index 0925676266bdbc9cbcf03811916b9f8b9b9e627e..fedf32a8c3ecdd7a1aaed41b2884d2c9b10bf033 100644 (file)
@@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
 CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
+CFLAGS_REMOVE_pvclock.o = -pg
+CFLAGS_REMOVE_kvmclock.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 endif
index fb7a5f052e2b8766d11115e3f7fc174fadf6ac2f..fb16f17e59bea7dcde91e6ad6275c7bad5bbdfb8 100644 (file)
@@ -61,7 +61,7 @@ struct cstate_entry {
                unsigned int ecx;
        } states[ACPI_PROCESSOR_MAX_POWER];
 };
-static struct cstate_entry *cpu_cstate_entry;  /* per CPU ptr */
+static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */
 
 static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
 
index fa044e1e30a2ed081175480dccec352a7e381392..679b6450382b9c8bafa2d71e2677fcd5ae075b95 100644 (file)
@@ -1953,6 +1953,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
                           size_t size,
                           int dir)
 {
+       dma_addr_t flush_addr;
        dma_addr_t i, start;
        unsigned int pages;
 
@@ -1960,6 +1961,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
            (dma_addr + size > dma_dom->aperture_size))
                return;
 
+       flush_addr = dma_addr;
        pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
        dma_addr &= PAGE_MASK;
        start = dma_addr;
@@ -1974,7 +1976,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
        dma_ops_free_addresses(dma_dom, dma_addr, pages);
 
        if (amd_iommu_unmap_flush || dma_dom->need_flush) {
-               iommu_flush_pages(&dma_dom->domain, dma_addr, size);
+               iommu_flush_pages(&dma_dom->domain, flush_addr, size);
                dma_dom->need_flush = false;
        }
 }
index 3cc63e2b8dd4c4acc4ee7f77c3ad432d97beb169..5a170cbbbed86aa1376eb19336a5329aacc96e91 100644 (file)
@@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
        iommu->last_device = calc_devid(MMIO_GET_BUS(range),
                                        MMIO_GET_LD(range));
        iommu->evt_msi_num = MMIO_MSI_NUM(misc);
+
+       if (is_rd890_iommu(iommu->dev)) {
+               pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
+               pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
+               pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
+               pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
+       }
 }
 
 /*
@@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
        struct ivhd_entry *e;
 
        /*
-        * First set the recommended feature enable bits from ACPI
-        * into the IOMMU control registers
+        * First save the recommended feature enable bits from ACPI
         */
-       h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
-               iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
-               iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
-
-       h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
-               iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
-               iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
-
-       h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
-               iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
-               iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
-
-       h->flags & IVHD_FLAG_ISOC_EN_MASK ?
-               iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
-               iommu_feature_disable(iommu, CONTROL_ISOC_EN);
-
-       /*
-        * make IOMMU memory accesses cache coherent
-        */
-       iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+       iommu->acpi_flags = h->flags;
 
        /*
         * Done. Now parse the device entries
@@ -1116,6 +1103,40 @@ static void init_device_table(void)
        }
 }
 
+static void iommu_init_flags(struct amd_iommu *iommu)
+{
+       iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
+               iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
+               iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
+
+       iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
+               iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
+               iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
+
+       iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
+               iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
+               iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
+
+       iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
+               iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
+               iommu_feature_disable(iommu, CONTROL_ISOC_EN);
+
+       /*
+        * make IOMMU memory accesses cache coherent
+        */
+       iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+}
+
+static void iommu_apply_quirks(struct amd_iommu *iommu)
+{
+       if (is_rd890_iommu(iommu->dev)) {
+               pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
+               pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
+               pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
+               pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
+       }
+}
+
 /*
  * This function finally enables all IOMMUs found in the system after
  * they have been initialized
@@ -1126,6 +1147,8 @@ static void enable_iommus(void)
 
        for_each_iommu(iommu) {
                iommu_disable(iommu);
+               iommu_apply_quirks(iommu);
+               iommu_init_flags(iommu);
                iommu_set_device_table(iommu);
                iommu_enable_command_buffer(iommu);
                iommu_enable_event_buffer(iommu);
index f1efebaf55105fa835ac7938c1654295fdd81562..5c5b8f3dddb58686ba4afc8b314237c0c318370b 100644 (file)
@@ -306,14 +306,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc,
 
        old_cfg = old_desc->chip_data;
 
-       memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
+       cfg->vector = old_cfg->vector;
+       cfg->move_in_progress = old_cfg->move_in_progress;
+       cpumask_copy(cfg->domain, old_cfg->domain);
+       cpumask_copy(cfg->old_domain, old_cfg->old_domain);
 
        init_copy_irq_2_pin(old_cfg, cfg, node);
 }
 
-static void free_irq_cfg(struct irq_cfg *old_cfg)
+static void free_irq_cfg(struct irq_cfg *cfg)
 {
-       kfree(old_cfg);
+       free_cpumask_var(cfg->domain);
+       free_cpumask_var(cfg->old_domain);
+       kfree(cfg);
 }
 
 void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
index 7b598b84c902e62f9f852d78c896acb03d4ba318..f744f54cb248e7ac0cd6defaa84a8e673468b30a 100644 (file)
@@ -698,9 +698,11 @@ void __init uv_system_init(void)
                for (j = 0; j < 64; j++) {
                        if (!test_bit(j, &present))
                                continue;
-                       uv_blade_info[blade].pnode = (i * 64 + j);
+                       pnode = (i * 64 + j);
+                       uv_blade_info[blade].pnode = pnode;
                        uv_blade_info[blade].nr_possible_cpus = 0;
                        uv_blade_info[blade].nr_online_cpus = 0;
+                       max_pnode = max(pnode, max_pnode);
                        blade++;
                }
        }
@@ -738,7 +740,6 @@ void __init uv_system_init(void)
                uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
                uv_node_to_blade[nid] = blade;
                uv_cpu_to_blade[cpu] = blade;
-               max_pnode = max(pnode, max_pnode);
        }
 
        /* Add blade/pnode info for nodes without cpus */
@@ -750,7 +751,6 @@ void __init uv_system_init(void)
                pnode = (paddr >> m_val) & pnode_mask;
                blade = boot_pnode_to_blade(pnode);
                uv_node_to_blade[nid] = blade;
-               max_pnode = max(pnode, max_pnode);
        }
 
        map_gru_high(max_pnode);
index 490dac63c2d21e90ab3af70c543b012f1c3f43b5..f2f9ac7da25ccfba6d5ba7ea44b63899ba672e97 100644 (file)
@@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c)
        }
 }
 
-static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
 {
        u32 tfms, xlvl;
        u32 ebx;
index 3624e8a0f71bf72e4c3cd86abcedfbb1c53d9b4d..f668bb1f7d432811bc3f773d777ca2596b6f6e33 100644 (file)
@@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[],
                            *const __x86_cpu_dev_end[];
 
 extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
+extern void get_cpu_cap(struct cpuinfo_x86 *c);
 
 #endif
index 994230d4dc4e545986a8c982629589905f0f224d..4f6f679f27990198640f9a1e139ea3a838b05eb8 100644 (file)
@@ -368,16 +368,22 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
                return -ENODEV;
 
        out_obj = output.pointer;
-       if (out_obj->type != ACPI_TYPE_BUFFER)
-               return -ENODEV;
+       if (out_obj->type != ACPI_TYPE_BUFFER) {
+               ret = -ENODEV;
+               goto out_free;
+       }
 
        errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
-       if (errors)
-               return -ENODEV;
+       if (errors) {
+               ret = -ENODEV;
+               goto out_free;
+       }
 
        supported = *((u32 *)(out_obj->buffer.pointer + 4));
-       if (!(supported & 0x1))
-               return -ENODEV;
+       if (!(supported & 0x1)) {
+               ret = -ENODEV;
+               goto out_free;
+       }
 
 out_free:
        kfree(output.pointer);
index 85f69cdeae1020a18e1c9097c8da276a8e50b992..b4389441efbbd8e791289aa936369e5e73917c18 100644 (file)
@@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
                        misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
                        wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
                        c->cpuid_level = cpuid_eax(0);
+                       get_cpu_cap(c);
                }
        }
 
index 5e975298fa819ff3ca648e647f531700edb1f408..39aaee5c1ab23f742dd749500ca09834e0d39bc4 100644 (file)
@@ -141,6 +141,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
                                address = (low & MASK_BLKPTR_LO) >> 21;
                                if (!address)
                                        break;
+
                                address += MCG_XBLK_ADDR;
                        } else
                                ++address;
@@ -148,12 +149,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
                        if (rdmsr_safe(address, &low, &high))
                                break;
 
-                       if (!(high & MASK_VALID_HI)) {
-                               if (block)
-                                       continue;
-                               else
-                                       break;
-                       }
+                       if (!(high & MASK_VALID_HI))
+                               continue;
 
                        if (!(high & MASK_CNTP_HI)  ||
                             (high & MASK_LOCKED_HI))
index d9368eeda3090eb9f53482704e000e600b6237e3..169d8804a9f8eed37faf06503e1b8243a566cb37 100644 (file)
@@ -216,7 +216,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
                err = sysfs_add_file_to_group(&sys_dev->kobj,
                                              &attr_core_power_limit_count.attr,
                                              thermal_attr_group.name);
-       if (cpu_has(c, X86_FEATURE_PTS))
+       if (cpu_has(c, X86_FEATURE_PTS)) {
                err = sysfs_add_file_to_group(&sys_dev->kobj,
                                              &attr_package_throttle_count.attr,
                                              thermal_attr_group.name);
@@ -224,6 +224,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
                        err = sysfs_add_file_to_group(&sys_dev->kobj,
                                        &attr_package_power_limit_count.attr,
                                        thermal_attr_group.name);
+       }
 
        return err;
 }
index 3efdf2870a3572263add749326aa5925df7c461f..03a5b0385ad6c4402d2192b42aa14e9bfaccc80e 100644 (file)
@@ -102,6 +102,7 @@ struct cpu_hw_events {
         */
        struct perf_event       *events[X86_PMC_IDX_MAX]; /* in counter order */
        unsigned long           active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+       unsigned long           running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
        int                     enabled;
 
        int                     n_events;
@@ -1010,6 +1011,7 @@ static int x86_pmu_start(struct perf_event *event)
        x86_perf_event_set_period(event);
        cpuc->events[idx] = event;
        __set_bit(idx, cpuc->active_mask);
+       __set_bit(idx, cpuc->running);
        x86_pmu.enable(event);
        perf_event_update_userpage(event);
 
@@ -1141,8 +1143,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
        cpuc = &__get_cpu_var(cpu_hw_events);
 
        for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-               if (!test_bit(idx, cpuc->active_mask))
+               if (!test_bit(idx, cpuc->active_mask)) {
+                       /*
+                        * Though we deactivated the counter some cpus
+                        * might still deliver spurious interrupts still
+                        * in flight. Catch them:
+                        */
+                       if (__test_and_clear_bit(idx, cpuc->running))
+                               handled++;
                        continue;
+               }
 
                event = cpuc->events[idx];
                hwc = &event->hw;
index b560db3305be16ff954fc416137d17b17189b5e7..2490151739921e074085a5d4a39a6cfb783f7187 100644 (file)
@@ -660,8 +660,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs)
        for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                int overflow;
 
-               if (!test_bit(idx, cpuc->active_mask))
+               if (!test_bit(idx, cpuc->active_mask)) {
+                       /* catch in-flight IRQs */
+                       if (__test_and_clear_bit(idx, cpuc->running))
+                               handled++;
                        continue;
+               }
 
                event = cpuc->events[idx];
                hwc = &event->hw;
index 34b4dad6f0b8e35a0fe80d01f8708c230592144d..d49079515122a6f47d2731cb1d2ac2f03efaf6e0 100644 (file)
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
        const struct cpuid_bit *cb;
 
        static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
+               { X86_FEATURE_DTS,              CR_EAX, 0, 0x00000006, 0 },
                { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006, 0 },
                { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006, 0 },
                { X86_FEATURE_PLN,              CR_EAX, 4, 0x00000006, 0 },
index e5cc7e82e60ddbf1bd1ca2871fdb7d7fc7628e34..ebdb85cf2686fa36702cd4d50b657f22de85b3bd 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/apic.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
-#include <asm/hpet.h>
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
@@ -192,21 +191,6 @@ static void __init ati_bugs_contd(int num, int slot, int func)
 }
 #endif
 
-/*
- * Force the read back of the CMP register in hpet_next_event()
- * to work around the problem that the CMP register write seems to be
- * delayed. See hpet_next_event() for details.
- *
- * We do this on all SMBUS incarnations for now until we have more
- * information about the affected chipsets.
- */
-static void __init ati_hpet_bugs(int num, int slot, int func)
-{
-#ifdef CONFIG_HPET_TIMER
-       hpet_readback_cmp = 1;
-#endif
-}
-
 #define QFLAG_APPLY_ONCE       0x1
 #define QFLAG_APPLIED          0x2
 #define QFLAG_DONE             (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -236,8 +220,6 @@ static struct chipset early_qrk[] __initdata = {
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
-       { PCI_VENDOR_ID_ATI, PCI_ANY_ID,
-         PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_hpet_bugs },
        {}
 };
 
index 351f9c0fea1f20714321d01260003173faf548dc..7494999141b3ae9c9ab67302481a2e6c15e969e6 100644 (file)
@@ -35,7 +35,6 @@
 unsigned long                          hpet_address;
 u8                                     hpet_blockid; /* OS timer block num */
 u8                                     hpet_msi_disable;
-u8                                     hpet_readback_cmp;
 
 #ifdef CONFIG_PCI_MSI
 static unsigned long                   hpet_num_timers;
@@ -395,23 +394,27 @@ static int hpet_next_event(unsigned long delta,
         * at that point and we would wait for the next hpet interrupt
         * forever. We found out that reading the CMP register back
         * forces the transfer so we can rely on the comparison with
-        * the counter register below.
+        * the counter register below. If the read back from the
+        * compare register does not match the value we programmed
+        * then we might have a real hardware problem. We can not do
+        * much about it here, but at least alert the user/admin with
+        * a prominent warning.
         *
-        * That works fine on those ATI chipsets, but on newer Intel
-        * chipsets (ICH9...) this triggers due to an erratum: Reading
-        * the comparator immediately following a write is returning
-        * the old value.
+        * An erratum on some chipsets (ICH9,..), results in
+        * comparator read immediately following a write returning old
+        * value. Workaround for this is to read this value second
+        * time, when first read returns old value.
         *
-        * We restrict the read back to the affected ATI chipsets (set
-        * by quirks) and also run it with hpet=verbose for debugging
-        * purposes.
+        * In fact the write to the comparator register is delayed up
+        * to two HPET cycles so the workaround we tried to restrict
+        * the readback to those known to be borked ATI chipsets
+        * failed miserably. So we give up on optimizations forever
+        * and penalize all HPET incarnations unconditionally.
         */
-       if (hpet_readback_cmp || hpet_verbose) {
-               u32 cmp = hpet_readl(HPET_Tn_CMP(timer));
-
-               if (cmp != cnt)
+       if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+               if (hpet_readl(HPET_Tn_CMP(timer)) != cnt)
                        printk_once(KERN_WARNING
-                           "hpet: compare register read back failed.\n");
+                               "hpet: compare register read back failed.\n");
        }
 
        return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
@@ -503,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev)
 {
        unsigned int irq;
 
-       irq = create_irq();
+       irq = create_irq_nr(0, -1);
        if (!irq)
                return -EINVAL;
 
index a474ec37c32f84df372d39eac5730532d60d0228..ff15c9dcc25de8be8144fd4d15f1dfd3069314e4 100644 (file)
@@ -206,11 +206,27 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp)
 int arch_bp_generic_fields(int x86_len, int x86_type,
                           int *gen_len, int *gen_type)
 {
-       /* Len */
-       switch (x86_len) {
-       case X86_BREAKPOINT_LEN_X:
+       /* Type */
+       switch (x86_type) {
+       case X86_BREAKPOINT_EXECUTE:
+               if (x86_len != X86_BREAKPOINT_LEN_X)
+                       return -EINVAL;
+
+               *gen_type = HW_BREAKPOINT_X;
                *gen_len = sizeof(long);
+               return 0;
+       case X86_BREAKPOINT_WRITE:
+               *gen_type = HW_BREAKPOINT_W;
                break;
+       case X86_BREAKPOINT_RW:
+               *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Len */
+       switch (x86_len) {
        case X86_BREAKPOINT_LEN_1:
                *gen_len = HW_BREAKPOINT_LEN_1;
                break;
@@ -229,21 +245,6 @@ int arch_bp_generic_fields(int x86_len, int x86_type,
                return -EINVAL;
        }
 
-       /* Type */
-       switch (x86_type) {
-       case X86_BREAKPOINT_EXECUTE:
-               *gen_type = HW_BREAKPOINT_X;
-               break;
-       case X86_BREAKPOINT_WRITE:
-               *gen_type = HW_BREAKPOINT_W;
-               break;
-       case X86_BREAKPOINT_RW:
-               *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        return 0;
 }
 
@@ -316,9 +317,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
        ret = -EINVAL;
 
        switch (info->len) {
-       case X86_BREAKPOINT_LEN_X:
-               align = sizeof(long) -1;
-               break;
        case X86_BREAKPOINT_LEN_1:
                align = 0;
                break;
index e0bc186d7501f123265ae288ae071e772016e89b..1c355c550960ab75279c644b52269cd5a368239a 100644 (file)
@@ -239,11 +239,10 @@ int module_finalize(const Elf_Ehdr *hdr,
                apply_paravirt(pseg, pseg + para->sh_size);
        }
 
-       return module_bug_finalize(hdr, sechdrs, me);
+       return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
        alternatives_smp_module_del(mod);
-       module_bug_cleanup(mod);
 }
index bc5b9b8d4a33117259882835bfb884f4f8f37656..81ed28cb36e692eb4413c294408d5498bee876e8 100644 (file)
@@ -766,7 +766,6 @@ static void init_vmcb(struct vcpu_svm *svm)
 
        control->iopm_base_pa = iopm_base;
        control->msrpm_base_pa = __pa(svm->msrpm);
-       control->tsc_offset = 0;
        control->int_ctl = V_INTR_MASKING_MASK;
 
        init_seg(&save->es);
@@ -902,6 +901,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
        svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
        svm->asid_generation = 0;
        init_vmcb(svm);
+       svm->vmcb->control.tsc_offset = 0-native_read_tsc();
 
        err = fx_init(&svm->vcpu);
        if (err)
index 9257510b4836837eb4cdff719000b716ff3bdd63..9d5f5584845587acbf5f544d7405e260a5e16b95 100644 (file)
@@ -324,9 +324,8 @@ static void lguest_load_gdt(const struct desc_ptr *desc)
 }
 
 /*
- * For a single GDT entry which changes, we do the lazy thing: alter our GDT,
- * then tell the Host to reload the entire thing.  This operation is so rare
- * that this naive implementation is reasonable.
+ * For a single GDT entry which changes, we simply change our copy and
+ * then tell the host about it.
  */
 static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
                                   const void *desc, int type)
@@ -338,9 +337,13 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
 }
 
 /*
- * OK, I lied.  There are three "thread local storage" GDT entries which change
+ * There are three "thread local storage" GDT entries which change
  * on every context switch (these three entries are how glibc implements
- * __thread variables).  So we have a hypercall specifically for this case.
+ * __thread variables).  As an optimization, we have a hypercall
+ * specifically for this case.
+ *
+ * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall
+ * which took a range of entries?
  */
 static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
 {
index f9897f7a9ef1e25cfa81e9190a3449bec9e35f70..9c0d0d399c307678a09668155d9067139ab30416 100644 (file)
@@ -420,9 +420,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
                return -1;
        }
 
-       for_each_node_mask(i, nodes_parsed)
-               e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
-                                               nodes[i].end >> PAGE_SHIFT);
+       for (i = 0; i < num_node_memblks; i++)
+               e820_register_active_regions(memblk_nodeid[i],
+                               node_memblk_range[i].start >> PAGE_SHIFT,
+                               node_memblk_range[i].end >> PAGE_SHIFT);
+
        /* for out of order entries in SRAT */
        sort_node_map();
        if (!nodes_cover_memory(nodes)) {
index cfe4faabb0f6792aebfb8330dd55f02406b148dc..f1575c9a2572074cad464ae2f9c51ee88e63bce3 100644 (file)
@@ -671,7 +671,10 @@ static int __init ppro_init(char **cpu_type)
        case 14:
                *cpu_type = "i386/core";
                break;
-       case 15: case 23:
+       case 0x0f:
+       case 0x16:
+       case 0x17:
+       case 0x1d:
                *cpu_type = "i386/core_2";
                break;
        case 0x1a:
index 1a5353a753fcd10e1330c03d1af43a6fe9c5a5b7..b2bb5aa3b0540e42847a7664aa529cf5d2c0fb83 100644 (file)
@@ -489,8 +489,9 @@ static void xen_hvm_setup_cpu_clockevents(void)
 __init void xen_hvm_init_time_ops(void)
 {
        /* vector callback is needed otherwise we cannot receive interrupts
-        * on cpu > 0 */
-       if (!xen_have_vector_callback && num_present_cpus() > 1)
+        * on cpu > 0 and at this point we don't know how many cpus are
+        * available */
+       if (!xen_have_vector_callback)
                return;
        if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
                printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
index c65d7593f7f1deba5511347ceeb6dd5c881e5b3c..ade0a08c9099afdc487916924c0fe6718185536d 100644 (file)
@@ -307,7 +307,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
                return PTR_ERR(bio);
 
        if (rq_data_dir(rq) == WRITE)
-               bio->bi_rw |= (1 << REQ_WRITE);
+               bio->bi_rw |= REQ_WRITE;
 
        if (do_copy)
                rq->cmd_flags |= REQ_COPY_USER;
index 3b0cd4249671d9826b42ea10473a11486c403368..eafc94f68d79f2ceb1c0a89fce8e449c3a5ff3f6 100644 (file)
@@ -361,6 +361,18 @@ static int attempt_merge(struct request_queue *q, struct request *req,
        if (!rq_mergeable(req) || !rq_mergeable(next))
                return 0;
 
+       /*
+        * Don't merge file system requests and discard requests
+        */
+       if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
+               return 0;
+
+       /*
+        * Don't merge discard requests and secure discard requests
+        */
+       if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
+               return 0;
+
        /*
         * not contiguous
         */
index f65c6f01c47580b7e24e7fc6bda1764668cf4d21..9eba291eb6fd23854aee14d8a35b5b1108fc0629 100644 (file)
@@ -1019,10 +1019,20 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
         */
        atomic_set(&cfqg->ref, 1);
 
-       /* Add group onto cgroup list */
-       sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
-       cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
+       /*
+        * Add group onto cgroup list. It might happen that bdi->dev is
+        * not initiliazed yet. Initialize this new group without major
+        * and minor info and this info will be filled in once a new thread
+        * comes for IO. See code above.
+        */
+       if (bdi->dev) {
+               sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+               cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
                                        MKDEV(major, minor));
+       } else
+               cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
+                                       0);
+
        cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev);
 
        /* Add group on cfqd list */
index 205b09a5bd9ead9e64d7bcfb60cec924f1a22cbd..4e11559aa2b02d78c4d90c104e81e7a2e84aa05d 100644 (file)
@@ -938,6 +938,7 @@ int elv_register_queue(struct request_queue *q)
                        }
                }
                kobject_uevent(&e->kobj, KOBJ_ADD);
+               e->registered = 1;
        }
        return error;
 }
@@ -947,6 +948,7 @@ static void __elv_unregister_queue(struct elevator_queue *e)
 {
        kobject_uevent(&e->kobj, KOBJ_REMOVE);
        kobject_del(&e->kobj);
+       e->registered = 0;
 }
 
 void elv_unregister_queue(struct request_queue *q)
@@ -1042,11 +1044,13 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
 
        spin_unlock_irq(q->queue_lock);
 
-       __elv_unregister_queue(old_elevator);
+       if (old_elevator->registered) {
+               __elv_unregister_queue(old_elevator);
 
-       err = elv_register_queue(q);
-       if (err)
-               goto fail_register;
+               err = elv_register_queue(q);
+               if (err)
+                       goto fail_register;
+       }
 
        /*
         * finally exit old elevator and turn off BYPASS.
index ae473445ad6daf11254ee269c3194c9ed03e0cb1..a2aea53a75ed9fdf99058f9676429c84104c2f27 100644 (file)
@@ -50,7 +50,7 @@ obj-$(CONFIG_SPI)             += spi/
 obj-y                          += net/
 obj-$(CONFIG_ATM)              += atm/
 obj-$(CONFIG_FUSION)           += message/
-obj-$(CONFIG_FIREWIRE)         += firewire/
+obj-y                          += firewire/
 obj-y                          += ieee1394/
 obj-$(CONFIG_UIO)              += uio/
 obj-y                          += cdrom/
index b811f2173f6f167c84700040fe2720bafb43156f..88681aca88c581891399e18b056d9a6df94a9e01 100644 (file)
@@ -105,7 +105,7 @@ config ACPI_EC_DEBUGFS
 
          Be aware that using this interface can confuse your Embedded
          Controller in a way that a normal reboot is not enough. You then
-         have to power of your system, and remove the laptop battery for
+         have to power off your system, and remove the laptop battery for
          some seconds.
          An Embedded Controller typically is available on laptops and reads
          sensor values like battery state and temperature.
index b76848c80be34729c56bd20d04f75f9f534cbb36..6b115f6c43133c211acd79c68a83785506a4357a 100644 (file)
@@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device)
        device_remove_file(&device->dev, &dev_attr_rrtime);
 }
 
-/* Query firmware how many CPUs should be idle */
-static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
+/*
+ * Query firmware how many CPUs should be idle
+ * return -1 on failure
+ */
+static int acpi_pad_pur(acpi_handle handle)
 {
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        union acpi_object *package;
-       int rev, num, ret = -EINVAL;
+       int num = -1;
 
        if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
-               return -EINVAL;
+               return num;
 
        if (!buffer.length || !buffer.pointer)
-               return -EINVAL;
+               return num;
 
        package = buffer.pointer;
-       if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
-               goto out;
-       rev = package->package.elements[0].integer.value;
-       num = package->package.elements[1].integer.value;
-       if (rev != 1 || num < 0)
-               goto out;
-       *num_cpus = num;
-       ret = 0;
-out:
+
+       if (package->type == ACPI_TYPE_PACKAGE &&
+               package->package.count == 2 &&
+               package->package.elements[0].integer.value == 1) /* rev 1 */
+
+               num = package->package.elements[1].integer.value;
+
        kfree(buffer.pointer);
-       return ret;
+       return num;
 }
 
 /* Notify firmware how many CPUs are idle */
@@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle)
        uint32_t idle_cpus;
 
        mutex_lock(&isolated_cpus_lock);
-       if (acpi_pad_pur(handle, &num_cpus)) {
+       num_cpus = acpi_pad_pur(handle);
+       if (num_cpus < 0) {
                mutex_unlock(&isolated_cpus_lock);
                return;
        }
index df85b53a674fc33105fa1434b3800db7ab26a423..7dad9160f20998112cc302d0a239c9fa27fcd429 100644 (file)
@@ -854,6 +854,7 @@ struct acpi_bit_register_info {
        ACPI_BITMASK_POWER_BUTTON_STATUS   | \
        ACPI_BITMASK_SLEEP_BUTTON_STATUS   | \
        ACPI_BITMASK_RT_CLOCK_STATUS       | \
+       ACPI_BITMASK_PCIEXP_WAKE_DISABLE   | \
        ACPI_BITMASK_WAKE_STATUS)
 
 #define ACPI_BITMASK_TIMER_ENABLE               0x0001
index 74c24d517f81768a6a00418db71c9f93be335b2e..4093522eed45692012b5da617c57187ef20c4458 100644 (file)
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void)
  *
  * DESCRIPTION: Reacquire the interpreter execution region from within the
  *              interpreter code. Failure to enter the interpreter region is a
- *              fatal system error. Used in  conjuction with
+ *              fatal system error. Used in  conjunction with
  *              relinquish_interpreter
  *
  ******************************************************************************/
index 22cfcfbd9fff77cd4cd5bb77be80c244461b2df5..491191e6cf692bffe1811a22674a0eb0720c3771 100644 (file)
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
 
                        /*
                         * 16-, 32-, and 64-bit cases must use the move macros that perform
-                        * endian conversion and/or accomodate hardware that cannot perform
+                        * endian conversion and/or accommodate hardware that cannot perform
                         * misaligned memory transfers
                         */
                case ACPI_RSC_MOVE16:
index 907e350f1c7df58370cb0e68a399b91d903ec466..fca34ccfd294a782e3f05312d99d5b5fdef5bfb4 100644 (file)
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG
        depends on ACPI_APEI
        help
          ERST is a way provided by APEI to save and retrieve hardware
-         error infomation to and from a persistent store. Enable this
+         error information to and from a persistent store. Enable this
          if you want to debugging and testing the ERST kernel support
          and firmware implementation.
index 73fd0c7487c1ae0b1311f4d7e1c048ddc809153a..4a904a4bf05f83a1b952ec2365811f8c5db931e1 100644 (file)
@@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub);
 int apei_resources_request(struct apei_resources *resources,
                           const char *desc)
 {
-       struct apei_res *res, *res_bak;
+       struct apei_res *res, *res_bak = NULL;
        struct resource *r;
+       int rc;
 
-       apei_resources_sub(resources, &apei_resources_all);
+       rc = apei_resources_sub(resources, &apei_resources_all);
+       if (rc)
+               return rc;
 
+       rc = -EINVAL;
        list_for_each_entry(res, &resources->iomem, list) {
                r = request_mem_region(res->start, res->end - res->start,
                                       desc);
@@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources,
                }
        }
 
-       apei_resources_merge(&apei_resources_all, resources);
+       rc = apei_resources_merge(&apei_resources_all, resources);
+       if (rc) {
+               pr_err(APEI_PFX "Fail to merge resources!\n");
+               goto err_unmap_ioport;
+       }
 
        return 0;
 err_unmap_ioport:
@@ -491,12 +499,13 @@ err_unmap_iomem:
                        break;
                release_mem_region(res->start, res->end - res->start);
        }
-       return -EINVAL;
+       return rc;
 }
 EXPORT_SYMBOL_GPL(apei_resources_request);
 
 void apei_resources_release(struct apei_resources *resources)
 {
+       int rc;
        struct apei_res *res;
 
        list_for_each_entry(res, &resources->iomem, list)
@@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources)
        list_for_each_entry(res, &resources->ioport, list)
                release_region(res->start, res->end - res->start);
 
-       apei_resources_sub(&apei_resources_all, resources);
+       rc = apei_resources_sub(&apei_resources_all, resources);
+       if (rc)
+               pr_err(APEI_PFX "Fail to sub resources!\n");
 }
 EXPORT_SYMBOL_GPL(apei_resources_release);
 
index 465c885938ee89a45db10f1f39d1ceb8cba41cf9..cf29df69380b8dd32585a074c53efc7af7a65471 100644 (file)
@@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL,
 
 static int einj_check_table(struct acpi_table_einj *einj_tab)
 {
-       if (einj_tab->header_length != sizeof(struct acpi_table_einj))
+       if ((einj_tab->header_length !=
+            (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
+           && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
                return -EINVAL;
        if (einj_tab->header.length < sizeof(struct acpi_table_einj))
                return -EINVAL;
index 5281ddda2777c99c40f0830c1d4e5022cc5b37aa..da1228a9a544f026bab6c549e65892d439367266 100644 (file)
@@ -2,7 +2,7 @@
  * APEI Error Record Serialization Table debug support
  *
  * ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store. This file provide the
+ * information to and from a persistent store. This file provide the
  * debugging/testing support for ERST kernel support and firmware
  * implementation.
  *
@@ -111,11 +111,13 @@ retry:
                goto out;
        }
        if (len > erst_dbg_buf_len) {
-               kfree(erst_dbg_buf);
+               void *p;
                rc = -ENOMEM;
-               erst_dbg_buf = kmalloc(len, GFP_KERNEL);
-               if (!erst_dbg_buf)
+               p = kmalloc(len, GFP_KERNEL);
+               if (!p)
                        goto out;
+               kfree(erst_dbg_buf);
+               erst_dbg_buf = p;
                erst_dbg_buf_len = len;
                goto retry;
        }
@@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf,
        if (mutex_lock_interruptible(&erst_dbg_mutex))
                return -EINTR;
        if (usize > erst_dbg_buf_len) {
-               kfree(erst_dbg_buf);
+               void *p;
                rc = -ENOMEM;
-               erst_dbg_buf = kmalloc(usize, GFP_KERNEL);
-               if (!erst_dbg_buf)
+               p = kmalloc(usize, GFP_KERNEL);
+               if (!p)
                        goto out;
+               kfree(erst_dbg_buf);
+               erst_dbg_buf = p;
                erst_dbg_buf_len = usize;
        }
        rc = copy_from_user(erst_dbg_buf, ubuf, usize);
index 18645f4e83cdd2f22d526276b320dac631be8940..1211c03149e8c7c258fee89dd1109e1e6b901c26 100644 (file)
@@ -2,7 +2,7 @@
  * APEI Error Record Serialization Table support
  *
  * ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store.
+ * information to and from a persistent store.
  *
  * For more information about ERST, please refer to ACPI Specification
  * version 4.0, section 17.4.
@@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx,
 {
        int rc;
        u64 offset;
+       void *src, *dst;
+
+       /* ioremap does not work in interrupt context */
+       if (in_interrupt()) {
+               pr_warning(ERST_PFX
+                          "MOVE_DATA can not be used in interrupt context");
+               return -EBUSY;
+       }
 
        rc = __apei_exec_read_register(entry, &offset);
        if (rc)
                return rc;
-       memmove((void *)ctx->dst_base + offset,
-               (void *)ctx->src_base + offset,
-               ctx->var2);
+
+       src = ioremap(ctx->src_base + offset, ctx->var2);
+       if (!src)
+               return -ENOMEM;
+       dst = ioremap(ctx->dst_base + offset, ctx->var2);
+       if (!dst)
+               return -ENOMEM;
+
+       memmove(dst, src, ctx->var2);
+
+       iounmap(src);
+       iounmap(dst);
 
        return 0;
 }
@@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable);
 
 static int erst_check_table(struct acpi_table_erst *erst_tab)
 {
-       if (erst_tab->header_length != sizeof(struct acpi_table_erst))
+       if ((erst_tab->header_length !=
+            (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header)))
+           && (erst_tab->header_length != sizeof(struct acpi_table_einj)))
                return -EINVAL;
        if (erst_tab->header.length < sizeof(struct acpi_table_erst))
                return -EINVAL;
index 385a6059714a72dd32256685a2606586b92d771e..0d505e59214df73dfb40b67b7d5fc45a2d48e127 100644 (file)
@@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
        struct ghes *ghes = NULL;
        int rc = -EINVAL;
 
-       generic = ghes_dev->dev.platform_data;
+       generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
        if (!generic->enabled)
                return -ENODEV;
 
index 343168d1826626c202171c3a53c5b5e4c2090a65..1a3508a7fe03f157c2e0144727bbeb5c244d2a46 100644 (file)
@@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
 
 static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
 {
-       struct acpi_hest_generic *generic;
        struct platform_device *ghes_dev;
        struct ghes_arr *ghes_arr = data;
        int rc;
 
        if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR)
                return 0;
-       generic = (struct acpi_hest_generic *)hest_hdr;
-       if (!generic->enabled)
+
+       if (!((struct acpi_hest_generic *)hest_hdr)->enabled)
                return 0;
        ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id);
        if (!ghes_dev)
                return -ENOMEM;
-       ghes_dev->dev.platform_data = generic;
+
+       rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *));
+       if (rc)
+               goto err;
+
        rc = platform_device_add(ghes_dev);
        if (rc)
                goto err;
index 8f8bd736d4ff11919656e79d2ef9442b037fafff..542e5390389120de7ecd7da4cb7bd059baa18b01 100644 (file)
@@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr,
        list_add_tail_rcu(&map->list, &acpi_iomaps);
        spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
 
-       return vaddr + (paddr - pg_off);
+       return map->vaddr + (paddr - map->paddr);
 err_unmap:
        iounmap(vaddr);
        return NULL;
index dc58402b0a177a4e03e8dc54e7a094804edc1d36..98417201e9ce3881257354e7c2a360ee019a4e39 100644 (file)
@@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = {
        POWER_SUPPLY_PROP_CYCLE_COUNT,
        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
-       POWER_SUPPLY_PROP_CURRENT_NOW,
        POWER_SUPPLY_PROP_POWER_NOW,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
index 2bb28b9d91c4c2643106ed0d63069ae85799d136..af308d03f49235a6da0b30791e6857c824e8e32f 100644 (file)
@@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
 {
        printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
        acpi_osi_setup("!Windows 2006");
+       acpi_osi_setup("!Windows 2006 SP1");
+       acpi_osi_setup("!Windows 2006 SP2");
        return 0;
 }
 static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
@@ -202,6 +204,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                },
        },
        {
+       /*
+        * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
+        * driver (e.g. nouveau) when user press brightness hotkey.
+        * Currently, nouveau driver didn't do the job and it causes there
+        * have a infinite while loop in DSDT when user press hotkey.
+        * We add MSI GX723's dmi information to this table for workaround
+        * this issue.
+        * Will remove MSI GX723 from the table after nouveau grows support.
+        */
+       .callback = dmi_disable_osi_vista,
+       .ident = "MSI GX723",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
+               },
+       },
+       {
        .callback = dmi_disable_osi_vista,
        .ident = "Sony VGN-NS10J_S",
        .matches = {
@@ -226,6 +245,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                },
        },
        {
+       .callback = dmi_disable_osi_vista,
+       .ident = "Toshiba Satellite L355",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                    DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
+               },
+       },
+       {
        .callback = dmi_disable_osi_win7,
        .ident = "ASUS K50IJ",
        .matches = {
@@ -233,6 +260,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
                },
        },
+       {
+       .callback = dmi_disable_osi_vista,
+       .ident = "Toshiba P305D",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
+               },
+       },
 
        /*
         * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
index 5c221ab535d5b0a459516a16034f80a94a7d1bb4..310e3b9749cbbacdabb3c03d288a6b42874aa41b 100644 (file)
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir);
 static int set_power_nocheck(const struct dmi_system_id *id)
 {
        printk(KERN_NOTICE PREFIX "%s detected - "
-               "disable power check in power transistion\n", id->ident);
+               "disable power check in power transition\n", id->ident);
        acpi_power_nocheck = 1;
        return 0;
 }
@@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id)
 
 static struct dmi_system_id dsdt_dmi_table[] __initdata = {
        /*
-        * Insyde BIOS on some TOSHIBA machines corrupt the DSDT.
+        * Invoke DSDT corruption work-around on all Toshiba Satellite.
         * https://bugzilla.kernel.org/show_bug.cgi?id=14679
         */
        {
         .callback = set_copy_dsdt,
-        .ident = "TOSHIBA Satellite A505",
+        .ident = "TOSHIBA Satellite",
         .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"),
-               },
-       },
-       {
-        .callback = set_copy_dsdt,
-        .ident = "TOSHIBA Satellite L505D",
-        .matches = {
-               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
                },
        },
        {}
@@ -1027,7 +1019,7 @@ static int __init acpi_init(void)
 
        /*
         * If the laptop falls into the DMI check table, the power state check
-        * will be disabled in the course of device power transistion.
+        * will be disabled in the course of device power transition.
         */
        dmi_check_system(power_nocheck_dmi_table);
 
index 8a3b840c0bb268d0580cd5550c41986bf3c09662..d94d2953c9740f34675eeb576e00e74ee621bfd2 100644 (file)
@@ -369,7 +369,9 @@ static void __exit acpi_fan_exit(void)
 
        acpi_bus_unregister_driver(&acpi_fan_driver);
 
+#ifdef CONFIG_ACPI_PROCFS
        remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
+#endif
 
        return;
 }
index e9699aaed1092874b0f275d2ca86a8142850db1c..bec561c14bebee3a77817bdce8fa09b939f85ac0 100644 (file)
@@ -28,12 +28,6 @@ static int set_no_mwait(const struct dmi_system_id *id)
 }
 
 static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
-       {
-       set_no_mwait, "IFL91 board", {
-       DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
-       DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
-       DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
-       DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
        {
        set_no_mwait, "Extensa 5220", {
        DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -352,4 +346,5 @@ void __init acpi_early_processor_set_pdc(void)
        acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
                            ACPI_UINT32_MAX,
                            early_init_pdc, NULL, NULL, NULL);
+       acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL);
 }
index 15602189238942cc9db03b9d9f25c18823128ea0..347eb21b235302d44d0c5e2d768ce3a8870142f2 100644 (file)
@@ -850,7 +850,7 @@ static int __init acpi_processor_init(void)
                printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
                        acpi_idle_driver.name);
        } else {
-               printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s",
+               printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n",
                        cpuidle_get_driver()->name);
        }
 
index ba1bd263d903094692c3683c9557e8b919d1d985..3a73a93596e88a29c1e66fabec91dd2d0db96f6c 100644 (file)
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module)
        if (!try_module_get(calling_module))
                return -EINVAL;
 
-       /* is_done is set to negative if an error occured,
-        * and to postitive if _no_ error occured, but SMM
+       /* is_done is set to negative if an error occurred,
+        * and to postitive if _no_ error occurred, but SMM
         * was already notified. This avoids double notification
         * which might lead to unexpected results...
         */
index cf82989ae7568c3c54ded69d16829a2851119d80..4754ff6e70e6daa25b13df6f115745eb7bfb7e55 100644 (file)
@@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
        return 0;
 }
 
+static int __init init_nvs_nosave(const struct dmi_system_id *d)
+{
+       acpi_nvs_nosave();
+       return 0;
+}
+
 static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        {
        .callback = init_old_suspend_ordering,
@@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
                },
        },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-SR11M",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Everex StepNote Series",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 68e2e4582fa2f18968058c8125704a23f151cb62..f8588f81048ac989d6af1d727693a234f54bc27b 100644 (file)
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
        ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
 };
 
-static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
+static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
 {
        int result = 0;
        int i;
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
        return result;
 }
 
-static int param_get_debug_level(char *buffer, struct kernel_param *kp)
+static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
 {
        int result = 0;
        int i;
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp)
        return result;
 }
 
-module_param_call(debug_layer, param_set_uint, param_get_debug_layer,
-                 &acpi_dbg_layer, 0644);
-module_param_call(debug_level, param_set_uint, param_get_debug_level,
-                 &acpi_dbg_level, 0644);
+static struct kernel_param_ops param_ops_debug_layer = {
+       .set = param_set_uint,
+       .get = param_get_debug_layer,
+};
+
+static struct kernel_param_ops param_ops_debug_level = {
+       .set = param_set_uint,
+       .get = param_get_debug_level,
+};
+
+module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644);
+module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644);
 
 static char trace_method_name[6];
 module_param_string(trace_method_name, trace_method_name, 6, 0644);
index c5fef01b3c9591701fb03ae86290a6b5b643c32a..b836761265988590cea46dbcffc39d30ea3c5578 100644 (file)
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
                                  "support\n"));
                *cap |= ACPI_VIDEO_BACKLIGHT;
                if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
-                       printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
-                                       "control misses _BQC function\n");
+                       printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
+                               "cannot determine initial brightness\n");
                /* We have backlight support, no need to scan further */
                return AE_CTRL_TERMINATE;
        }
index ff1c945fba98e39de55b42ce46a5e9af26b34c45..99d0e5a511482215a7b3c59ffaed9f0827cfa2b1 100644 (file)
@@ -90,6 +90,10 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int ahci_pci_device_resume(struct pci_dev *pdev);
 #endif
 
+static struct scsi_host_template ahci_sht = {
+       AHCI_SHT("ahci"),
+};
+
 static struct ata_port_operations ahci_vt8251_ops = {
        .inherits               = &ahci_ops,
        .hardreset              = ahci_vt8251_hardreset,
index 474427b6f99f47a8dd997042cc9f2d271a743228..e5fdeebf9ef0610d6f43999baefc4fd06fcd354b 100644 (file)
@@ -298,7 +298,17 @@ struct ahci_host_priv {
 
 extern int ahci_ignore_sss;
 
-extern struct scsi_host_template ahci_sht;
+extern struct device_attribute *ahci_shost_attrs[];
+extern struct device_attribute *ahci_sdev_attrs[];
+
+#define AHCI_SHT(drv_name)                                             \
+       ATA_NCQ_SHT(drv_name),                                          \
+       .can_queue              = AHCI_MAX_CMDS - 1,                    \
+       .sg_tablesize           = AHCI_MAX_SG,                          \
+       .dma_boundary           = AHCI_DMA_BOUNDARY,                    \
+       .shost_attrs            = ahci_shost_attrs,                     \
+       .sdev_attrs             = ahci_sdev_attrs
+
 extern struct ata_port_operations ahci_ops;
 
 void ahci_save_initial_config(struct device *dev,
index 4e97f33cca4406212b9769c6c13fc11afc02bc4a..84b643270e7af5c49d8a73db78f6e6230ceabf7b 100644 (file)
 #include <linux/ahci_platform.h>
 #include "ahci.h"
 
+static struct scsi_host_template ahci_platform_sht = {
+       AHCI_SHT("ahci_platform"),
+};
+
 static int __init ahci_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -145,7 +149,7 @@ static int __init ahci_probe(struct platform_device *pdev)
        ahci_print_info(host, "platform");
 
        rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-                              &ahci_sht);
+                              &ahci_platform_sht);
        if (rc)
                goto err0;
 
index 68dc6785472f86932f769029ae6046a0dffeec47..8eea309ea21231fcb50ff0498a366ff8a8a1dcf7 100644 (file)
@@ -121,7 +121,7 @@ static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
 static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
                   ahci_read_em_buffer, ahci_store_em_buffer);
 
-static struct device_attribute *ahci_shost_attrs[] = {
+struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_link_power_management_policy,
        &dev_attr_em_message_type,
        &dev_attr_em_message,
@@ -132,22 +132,14 @@ static struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_em_buffer,
        NULL
 };
+EXPORT_SYMBOL_GPL(ahci_shost_attrs);
 
-static struct device_attribute *ahci_sdev_attrs[] = {
+struct device_attribute *ahci_sdev_attrs[] = {
        &dev_attr_sw_activity,
        &dev_attr_unload_heads,
        NULL
 };
-
-struct scsi_host_template ahci_sht = {
-       ATA_NCQ_SHT("ahci"),
-       .can_queue              = AHCI_MAX_CMDS - 1,
-       .sg_tablesize           = AHCI_MAX_SG,
-       .dma_boundary           = AHCI_DMA_BOUNDARY,
-       .shost_attrs            = ahci_shost_attrs,
-       .sdev_attrs             = ahci_sdev_attrs,
-};
-EXPORT_SYMBOL_GPL(ahci_sht);
+EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
 
 struct ata_port_operations ahci_ops = {
        .inherits               = &sata_pmp_port_ops,
index ee9ddeb53417c7da782d252f7d9e4f8113ee44b4..8cb0347dec2848e4d6c33f5276b9ba986a9f3fac 100644 (file)
@@ -3156,7 +3156,6 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
 {  
        struct atm_dev *dev;  
        IADEV *iadev;  
-        unsigned long flags;
        int ret;
 
        iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
@@ -3188,19 +3187,14 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
        ia_dev[iadev_count] = iadev;
        _ia_dev[iadev_count] = dev;
        iadev_count++;
-       spin_lock_init(&iadev->misc_lock);
-       /* First fixes first. I don't want to think about this now. */
-       spin_lock_irqsave(&iadev->misc_lock, flags); 
        if (ia_init(dev) || ia_start(dev)) {  
                IF_INIT(printk("IA register failed!\n");)
                iadev_count--;
                ia_dev[iadev_count] = NULL;
                _ia_dev[iadev_count] = NULL;
-               spin_unlock_irqrestore(&iadev->misc_lock, flags); 
                ret = -EINVAL;
                goto err_out_deregister_dev;
        }
-       spin_unlock_irqrestore(&iadev->misc_lock, flags); 
        IF_EVENT(printk("iadev_count = %d\n", iadev_count);)
 
        iadev->next_board = ia_boards;  
index b2cd20f549cb4d474edb0a2a9a2f419d40d5072b..077735e0e04bfdd1d12f048ac8006f8a598832f8 100644 (file)
@@ -1022,7 +1022,7 @@ typedef struct iadev_t {
        struct dle_q rx_dle_q;  
        struct free_desc_q *rx_free_desc_qhead;  
        struct sk_buff_head rx_dma_q;  
-        spinlock_t rx_lock, misc_lock;
+       spinlock_t rx_lock;
        struct atm_vcc **rx_open;       /* list of all open VCs */  
         u16 num_rx_desc, rx_buf_sz, rxing;
         u32 rx_pkt_ram, rx_tmp_cnt;
index f916ddf63938a03444c2ad6e4d8a6b63c46212aa..f46138ab38b6c310fffc589681f727840a05c646 100644 (file)
@@ -444,6 +444,7 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr,
        struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
        struct solos_card *card = atmdev->dev_data;
        struct sk_buff *skb;
+       unsigned int len;
 
        spin_lock(&card->cli_queue_lock);
        skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]);
@@ -451,11 +452,12 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr,
        if(skb == NULL)
                return sprintf(buf, "No data.\n");
 
-       memcpy(buf, skb->data, skb->len);
-       dev_dbg(&card->dev->dev, "len: %d\n", skb->len);
+       len = skb->len;
+       memcpy(buf, skb->data, len);
+       dev_dbg(&card->dev->dev, "len: %d\n", len);
 
        kfree_skb(skb);
-       return skb->len;
+       return len;
 }
 
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size)
index 6124c2fd2d33440f022aa45b369bd7fb7a850c8a..5e4fadcdece979b76571462210f60195a6531f27 100644 (file)
@@ -4792,7 +4792,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 clean4:
        kfree(h->cmd_pool_bits);
        /* Free up sg elements */
-       for (k = 0; k < h->nr_cmds; k++)
+       for (k-- ; k >= 0; k--)
                kfree(h->scatter_list[k]);
        kfree(h->scatter_list);
        cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
index b1cbeb59bb7622e61f75bc58f373cadf1e822218..37a2bb5950761fcfa6cd5ea16f30b5c74dc51a1e 100644 (file)
@@ -2369,7 +2369,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
        pkt_shrink_pktlist(pd);
 }
 
-static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
+static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor)
 {
        if (dev_minor >= MAX_WRITERS)
                return NULL;
index 2aafafca2b1374b11714546fb3c063044ed9200c..1101e251a629343b0715b4b02a9b664828e1ef3e 100644 (file)
@@ -202,6 +202,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
        struct virtio_blk *vblk = disk->private_data;
        struct request *req;
        struct bio *bio;
+       int err;
 
        bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES,
                           GFP_KERNEL);
@@ -215,7 +216,10 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
        }
 
        req->cmd_type = REQ_TYPE_SPECIAL;
-       return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
+       err = blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
+       blk_put_request(req);
+
+       return err;
 }
 
 static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode,
index eab58db5f91cd9cfd6ffa5302761780ac8b3f373..cd18493c952795317904229197016e40d7c408cd 100644 (file)
@@ -806,6 +806,8 @@ static const struct intel_driver_description {
            "G45/G43", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG,
            "B43", NULL, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG,
+           "B43", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG,
            "G41", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG,
index ee189c74d345ea98062ddbb914c87cb206691c59..d09b1ab7e8abeac5bbdf0cc8a8dd5f333f9c22a3 100644 (file)
 #define PCI_DEVICE_ID_INTEL_Q33_IG          0x29D2
 #define PCI_DEVICE_ID_INTEL_B43_HB          0x2E40
 #define PCI_DEVICE_ID_INTEL_B43_IG          0x2E42
+#define PCI_DEVICE_ID_INTEL_B43_1_HB        0x2E90
+#define PCI_DEVICE_ID_INTEL_B43_1_IG        0x2E92
 #define PCI_DEVICE_ID_INTEL_GM45_HB         0x2A40
 #define PCI_DEVICE_ID_INTEL_GM45_IG         0x2A42
 #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB        0x2E00
index 3822b4f49c84a360145a085e329fe0b76df4d47c..7bd7c45b53efc849225f7f0a604c41f2f0a4fded 100644 (file)
@@ -305,6 +305,9 @@ static int num_force_kipmid;
 #ifdef CONFIG_PCI
 static int pci_registered;
 #endif
+#ifdef CONFIG_ACPI
+static int pnp_registered;
+#endif
 #ifdef CONFIG_PPC_OF
 static int of_registered;
 #endif
@@ -2126,7 +2129,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
 {
        struct acpi_device *acpi_dev;
        struct smi_info *info;
-       struct resource *res;
+       struct resource *res, *res_second;
        acpi_handle handle;
        acpi_status status;
        unsigned long long tmp;
@@ -2182,13 +2185,13 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
        info->io.addr_data = res->start;
 
        info->io.regspacing = DEFAULT_REGSPACING;
-       res = pnp_get_resource(dev,
+       res_second = pnp_get_resource(dev,
                               (info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
                                        IORESOURCE_IO : IORESOURCE_MEM,
                               1);
-       if (res) {
-               if (res->start > info->io.addr_data)
-                       info->io.regspacing = res->start - info->io.addr_data;
+       if (res_second) {
+               if (res_second->start > info->io.addr_data)
+                       info->io.regspacing = res_second->start - info->io.addr_data;
        }
        info->io.regsize = DEFAULT_REGSPACING;
        info->io.regshift = 0;
@@ -3359,6 +3362,7 @@ static __devinit int init_ipmi_si(void)
 
 #ifdef CONFIG_ACPI
        pnp_register_driver(&ipmi_pnp_driver);
+       pnp_registered = 1;
 #endif
 
 #ifdef CONFIG_DMI
@@ -3526,7 +3530,8 @@ static __exit void cleanup_ipmi_si(void)
                pci_unregister_driver(&ipmi_pci_driver);
 #endif
 #ifdef CONFIG_ACPI
-       pnp_unregister_driver(&ipmi_pnp_driver);
+       if (pnp_registered)
+               pnp_unregister_driver(&ipmi_pnp_driver);
 #endif
 
 #ifdef CONFIG_PPC_OF
index a398ecdbd758058104e81223f1cbdfe7057e9a4b..1f528fad3516827754270806a4c6afdee505c9d0 100644 (file)
@@ -788,10 +788,11 @@ static const struct file_operations zero_fops = {
 /*
  * capabilities for /dev/zero
  * - permits private mappings, "copies" are taken of the source of zeros
+ * - no writeback happens
  */
 static struct backing_dev_info zero_bdi = {
        .name           = "char/mem",
-       .capabilities   = BDI_CAP_MAP_COPY,
+       .capabilities   = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK,
 };
 
 static const struct file_operations full_fops = {
index 942a9826bd23ed64b83095fcdeb65ed059c9ce02..c810481a5bc23ae3ca57127729c83e454d681534 100644 (file)
@@ -596,6 +596,10 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
        ssize_t ret;
        bool nonblock;
 
+       /* Userspace could be out to fool us */
+       if (!count)
+               return 0;
+
        port = filp->private_data;
 
        nonblock = filp->f_flags & O_NONBLOCK;
@@ -642,7 +646,7 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
        poll_wait(filp, &port->waitqueue, wait);
 
        ret = 0;
-       if (port->inbuf)
+       if (!will_read_block(port))
                ret |= POLLIN | POLLRDNORM;
        if (!will_write_block(port))
                ret |= POLLOUT;
index c2408bbe9c2eed3521f4eb21a86c1e9671774534..f508690eb95859ef80e217f68db827daba606f29 100644 (file)
@@ -80,7 +80,7 @@
  * Limiting Performance Impact
  * ---------------------------
  * C states, especially those with large exit latencies, can have a real
- * noticable impact on workloads, which is not acceptable for most sysadmins,
+ * noticeable impact on workloads, which is not acceptable for most sysadmins,
  * and in addition, less performance has a power price of its own.
  *
  * As a general rule of thumb, menu assumes that the following heuristic
index 8661c84a105d86751e1990636f6dbcdeb4962cf3..b98c67664ae72b7638bdf06365fd0789eb76245e 100644 (file)
@@ -39,6 +39,10 @@ static DEFINE_SPINLOCK(dca_lock);
 
 static LIST_HEAD(dca_domains);
 
+static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
+
+static int dca_providers_blocked;
+
 static struct pci_bus *dca_pci_rc_from_dev(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
@@ -70,6 +74,60 @@ static void dca_free_domain(struct dca_domain *domain)
        kfree(domain);
 }
 
+static int dca_provider_ioat_ver_3_0(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       return ((pdev->vendor == PCI_VENDOR_ID_INTEL) &&
+               ((pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG0) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG1) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG2) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG3) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG4) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG5) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG6) ||
+               (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG7)));
+}
+
+static void unregister_dca_providers(void)
+{
+       struct dca_provider *dca, *_dca;
+       struct list_head unregistered_providers;
+       struct dca_domain *domain;
+       unsigned long flags;
+
+       blocking_notifier_call_chain(&dca_provider_chain,
+                                    DCA_PROVIDER_REMOVE, NULL);
+
+       INIT_LIST_HEAD(&unregistered_providers);
+
+       spin_lock_irqsave(&dca_lock, flags);
+
+       if (list_empty(&dca_domains)) {
+               spin_unlock_irqrestore(&dca_lock, flags);
+               return;
+       }
+
+       /* at this point only one domain in the list is expected */
+       domain = list_first_entry(&dca_domains, struct dca_domain, node);
+       if (!domain)
+               return;
+
+       list_for_each_entry_safe(dca, _dca, &domain->dca_providers, node) {
+               list_del(&dca->node);
+               list_add(&dca->node, &unregistered_providers);
+       }
+
+       dca_free_domain(domain);
+
+       spin_unlock_irqrestore(&dca_lock, flags);
+
+       list_for_each_entry_safe(dca, _dca, &unregistered_providers, node) {
+               dca_sysfs_remove_provider(dca);
+               list_del(&dca->node);
+       }
+}
+
 static struct dca_domain *dca_find_domain(struct pci_bus *rc)
 {
        struct dca_domain *domain;
@@ -90,9 +148,13 @@ static struct dca_domain *dca_get_domain(struct device *dev)
        domain = dca_find_domain(rc);
 
        if (!domain) {
-               domain = dca_allocate_domain(rc);
-               if (domain)
-                       list_add(&domain->node, &dca_domains);
+               if (dca_provider_ioat_ver_3_0(dev) && !list_empty(&dca_domains)) {
+                       dca_providers_blocked = 1;
+               } else {
+                       domain = dca_allocate_domain(rc);
+                       if (domain)
+                               list_add(&domain->node, &dca_domains);
+               }
        }
 
        return domain;
@@ -293,8 +355,6 @@ void free_dca_provider(struct dca_provider *dca)
 }
 EXPORT_SYMBOL_GPL(free_dca_provider);
 
-static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
-
 /**
  * register_dca_provider - register a dca provider
  * @dca - struct created by alloc_dca_provider()
@@ -306,6 +366,13 @@ int register_dca_provider(struct dca_provider *dca, struct device *dev)
        unsigned long flags;
        struct dca_domain *domain;
 
+       spin_lock_irqsave(&dca_lock, flags);
+       if (dca_providers_blocked) {
+               spin_unlock_irqrestore(&dca_lock, flags);
+               return -ENODEV;
+       }
+       spin_unlock_irqrestore(&dca_lock, flags);
+
        err = dca_sysfs_add_provider(dca, dev);
        if (err)
                return err;
@@ -313,7 +380,13 @@ int register_dca_provider(struct dca_provider *dca, struct device *dev)
        spin_lock_irqsave(&dca_lock, flags);
        domain = dca_get_domain(dev);
        if (!domain) {
-               spin_unlock_irqrestore(&dca_lock, flags);
+               if (dca_providers_blocked) {
+                       spin_unlock_irqrestore(&dca_lock, flags);
+                       dca_sysfs_remove_provider(dca);
+                       unregister_dca_providers();
+               } else {
+                       spin_unlock_irqrestore(&dca_lock, flags);
+               }
                return -ENODEV;
        }
        list_add(&dca->node, &domain->dca_providers);
index 216f9d383b5b7b1b0a4d2062c388518a7270de55..effd140fc042b827617bebce013dae190c7b4d76 100644 (file)
@@ -879,7 +879,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca)
        dma->device_issue_pending = ioat2_issue_pending;
        dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
        dma->device_free_chan_resources = ioat2_free_chan_resources;
-       dma->device_tx_status = ioat_tx_status;
+       dma->device_tx_status = ioat_dma_tx_status;
 
        err = ioat_probe(device);
        if (err)
index 86c5ae9fde34d3cf0f3f372a33739ccb4286fdf3..411d5bf50fc43cab437dff34d3d9f25dd9928fe0 100644 (file)
@@ -162,7 +162,7 @@ static int mv_is_err_intr(u32 intr_cause)
 
 static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
 {
-       u32 val = (1 << (1 + (chan->idx * 16)));
+       u32 val = ~(1 << (chan->idx * 16));
        dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val);
        __raw_writel(val, XOR_INTR_CAUSE(chan));
 }
index fb64cf36ba61d0e786ecfeb802f43909ade4f2f2..eb6b54dbb8064a9a5d2e71eb3261132195ff6f8d 100644 (file)
@@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
 
        sh_chan = to_sh_chan(chan);
        param = chan->private;
-       slave_addr = param->config->addr;
 
        /* Someone calling slave DMA on a public channel? */
        if (!param || !sg_len) {
@@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
                return NULL;
        }
 
+       slave_addr = param->config->addr;
+
        /*
         * if (param != NULL), this is a successfully requested slave channel,
         * therefore param->config != NULL too.
index 3630308e7b811a66f398193eae71cc12f5d7383f..6b21e25f7a84cc99ad6ea710b788745992d1170f 100644 (file)
@@ -339,6 +339,9 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci)
 {
        int status;
 
+       if (mci->op_state != OP_RUNNING_POLL)
+               return;
+
        status = cancel_delayed_work(&mci->work);
        if (status == 0) {
                debugf0("%s() not canceled, flush the queue\n",
index e0187d16dd7c53fd240b58d62005e4c17df14bc4..0fd5b85a0f756745bd1074ae673e89d6c81a237a 100644 (file)
@@ -1140,6 +1140,7 @@ static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = {
        ATTR_COUNTER(0),
        ATTR_COUNTER(1),
        ATTR_COUNTER(2),
+       { .attr = { .name = NULL } }
 };
 
 static struct mcidev_sysfs_group i7core_udimm_counters = {
index be29b0bb247101442a63fa623467e98ad7b77524..1b05896648bce47cff20ed04acbf5d1ee6175a8b 100644 (file)
@@ -263,6 +263,7 @@ static const struct {
        {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
        {PCI_VENDOR_ID_NEC,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
        {PCI_VENDOR_ID_VIA,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
+       {PCI_VENDOR_ID_RICOH,   PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
        {PCI_VENDOR_ID_APPLE,   PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
 };
 
index 55d03ed050006c3de3a2b7470c4ededeafbc8871..529a0dbe9fc65960e62bc7840320754fb61393e8 100644 (file)
@@ -98,8 +98,8 @@ EXPORT_SYMBOL(drm_buffer_alloc);
  *   user_data: A pointer the data that is copied to the buffer.
  *   size: The Number of bytes to copy.
  */
-extern int drm_buffer_copy_from_user(struct drm_buffer *buf,
-               void __user *user_data, int size)
+int drm_buffer_copy_from_user(struct drm_buffer *buf,
+                             void __user *user_data, int size)
 {
        int nr_pages = size / PAGE_SIZE + 1;
        int idx;
@@ -163,7 +163,7 @@ void *drm_buffer_read_object(struct drm_buffer *buf,
 {
        int idx = drm_buffer_index(buf);
        int page = drm_buffer_page(buf);
-       void *obj = 0;
+       void *obj = NULL;
 
        if (idx + objsize <= PAGE_SIZE) {
                obj = &buf->data[page][idx];
index d2ab01e90a96315fee72015f4a76f194211d4a81..dcbeb98f195a7addf665e0134af9ee799280a279 100644 (file)
@@ -103,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                if (connector->funcs->force)
                        connector->funcs->force(connector);
        } else {
-               connector->status = connector->funcs->detect(connector);
-               drm_helper_hpd_irq_event(dev);
+               connector->status = connector->funcs->detect(connector, true);
+               drm_kms_helper_poll_enable(dev);
        }
 
        if (connector->status == connector_status_disconnected) {
@@ -637,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                mode_changed = true;
 
        if (mode_changed) {
-               old_fb = set->crtc->fb;
-               set->crtc->fb = set->fb;
                set->crtc->enabled = (set->mode != NULL);
                if (set->mode != NULL) {
                        DRM_DEBUG_KMS("attempting to set mode from"
                                        " userspace\n");
                        drm_mode_debug_printmodeline(set->mode);
+                       old_fb = set->crtc->fb;
+                       set->crtc->fb = set->fb;
                        if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
                                                      set->x, set->y,
                                                      old_fb)) {
@@ -866,7 +866,7 @@ static void output_poll_execute(struct work_struct *work)
                    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
                        continue;
 
-               status = connector->funcs->detect(connector);
+               status = connector->funcs->detect(connector, false);
                if (old_status != status)
                        changed = true;
        }
index bf92d07510df740d856c173e7dcce292659fe6f7..5663d2719063de9231ca6cc153b63b30422e17aa 100644 (file)
@@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev,
                return -ENOMEM;
 
        kref_init(&obj->refcount);
-       kref_init(&obj->handlecount);
+       atomic_set(&obj->handle_count, 0);
        obj->size = size;
 
        atomic_inc(&dev->object_count);
@@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref)
 }
 EXPORT_SYMBOL(drm_gem_object_free);
 
-/**
- * Called after the last reference to the object has been lost.
- * Must be called without holding struct_mutex
- *
- * Frees the object
- */
-void
-drm_gem_object_free_unlocked(struct kref *kref)
-{
-       struct drm_gem_object *obj = (struct drm_gem_object *) kref;
-       struct drm_device *dev = obj->dev;
-
-       if (dev->driver->gem_free_object_unlocked != NULL)
-               dev->driver->gem_free_object_unlocked(obj);
-       else if (dev->driver->gem_free_object != NULL) {
-               mutex_lock(&dev->struct_mutex);
-               dev->driver->gem_free_object(obj);
-               mutex_unlock(&dev->struct_mutex);
-       }
-}
-EXPORT_SYMBOL(drm_gem_object_free_unlocked);
-
 static void drm_gem_object_ref_bug(struct kref *list_kref)
 {
        BUG();
@@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref)
  * called before drm_gem_object_free or we'll be touching
  * freed memory
  */
-void
-drm_gem_object_handle_free(struct kref *kref)
+void drm_gem_object_handle_free(struct drm_gem_object *obj)
 {
-       struct drm_gem_object *obj = container_of(kref,
-                                                 struct drm_gem_object,
-                                                 handlecount);
        struct drm_device *dev = obj->dev;
 
        /* Remove any name for this object */
@@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma)
        struct drm_gem_object *obj = vma->vm_private_data;
 
        drm_gem_object_reference(obj);
+
+       mutex_lock(&obj->dev->struct_mutex);
+       drm_vm_open_locked(vma);
+       mutex_unlock(&obj->dev->struct_mutex);
 }
 EXPORT_SYMBOL(drm_gem_vm_open);
 
@@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma)
 {
        struct drm_gem_object *obj = vma->vm_private_data;
 
-       drm_gem_object_unreference_unlocked(obj);
+       mutex_lock(&obj->dev->struct_mutex);
+       drm_vm_close_locked(vma);
+       drm_gem_object_unreference(obj);
+       mutex_unlock(&obj->dev->struct_mutex);
 }
 EXPORT_SYMBOL(drm_gem_vm_close);
 
index 2ef2c78272434dcb6b32dc17fd96e34dd7a8d959..974e970ce3f81ce014170b90ad1b8adc8a1dd5a9 100644 (file)
@@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data)
 
        seq_printf(m, "%6d %8zd %7d %8d\n",
                   obj->name, obj->size,
-                  atomic_read(&obj->handlecount.refcount),
+                  atomic_read(&obj->handle_count),
                   atomic_read(&obj->refcount.refcount));
        return 0;
 }
index e20f78b542a756644a29693c8da5927dd72f5a7d..f5bd9e590c801b50b0d3629ddbadd6c54a69923a 100644 (file)
@@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
        dev->hose = pdev->sysdata;
 #endif
 
+       mutex_lock(&drm_global_mutex);
+
        if ((ret = drm_fill_in_dev(dev, ent, driver))) {
                printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
                goto err_g2;
@@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                 driver->name, driver->major, driver->minor, driver->patchlevel,
                 driver->date, pci_name(pdev), dev->primary->index);
 
+       mutex_unlock(&drm_global_mutex);
        return 0;
 
 err_g4:
@@ -210,6 +213,7 @@ err_g2:
        pci_disable_device(pdev);
 err_g1:
        kfree(dev);
+       mutex_unlock(&drm_global_mutex);
        return ret;
 }
 EXPORT_SYMBOL(drm_get_pci_dev);
index 460e9a3afa8d4bd43ac752cbf2e1bae3e0f2b832..92d1d0fb7b7581821756ebcdf01089f55037198c 100644 (file)
@@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev,
        dev->platformdev = platdev;
        dev->dev = &platdev->dev;
 
+       mutex_lock(&drm_global_mutex);
+
        ret = drm_fill_in_dev(dev, NULL, driver);
 
        if (ret) {
@@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev,
 
        list_add_tail(&dev->driver_item, &driver->device_list);
 
+       mutex_unlock(&drm_global_mutex);
+
        DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
                 driver->name, driver->major, driver->minor, driver->patchlevel,
                 driver->date, dev->primary->index);
@@ -100,6 +104,7 @@ err_g2:
                drm_put_minor(&dev->control);
 err_g1:
        kfree(dev);
+       mutex_unlock(&drm_global_mutex);
        return ret;
 }
 EXPORT_SYMBOL(drm_get_platform_dev);
index 86118a742231b42fd711f18b64deb182a8d60d3a..85da4c40694cc8a99c2b3224e31af548b76e198a 100644 (file)
@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device,
        struct drm_connector *connector = to_drm_connector(device);
        enum drm_connector_status status;
 
-       status = connector->funcs->detect(connector);
+       status = connector->funcs->detect(connector, true);
        return snprintf(buf, PAGE_SIZE, "%s\n",
                        drm_get_connector_status_name(status));
 }
index fda67468e603b6169393b92bc4922afef8b4d8ce..5df450683aab8649511aaa96aaa759452b022fc0 100644 (file)
@@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma)
        mutex_unlock(&dev->struct_mutex);
 }
 
-/**
- * \c close method for all virtual memory types.
- *
- * \param vma virtual memory area.
- *
- * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
- * free it.
- */
-static void drm_vm_close(struct vm_area_struct *vma)
+void drm_vm_close_locked(struct vm_area_struct *vma)
 {
        struct drm_file *priv = vma->vm_file->private_data;
        struct drm_device *dev = priv->minor->dev;
@@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma)
                  vma->vm_start, vma->vm_end - vma->vm_start);
        atomic_dec(&dev->vma_count);
 
-       mutex_lock(&dev->struct_mutex);
        list_for_each_entry_safe(pt, temp, &dev->vmalist, head) {
                if (pt->vma == vma) {
                        list_del(&pt->head);
@@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma)
                        break;
                }
        }
+}
+
+/**
+ * \c close method for all virtual memory types.
+ *
+ * \param vma virtual memory area.
+ *
+ * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
+ * free it.
+ */
+static void drm_vm_close(struct vm_area_struct *vma)
+{
+       struct drm_file *priv = vma->vm_file->private_data;
+       struct drm_device *dev = priv->minor->dev;
+
+       mutex_lock(&dev->struct_mutex);
+       drm_vm_close_locked(vma);
        mutex_unlock(&dev->struct_mutex);
 }
 
index 61b4caf220fa83bd15815ea0f82b627f2d773727..fb07e73581e84467ab59ebe744e21ff6f712d2ce 100644 (file)
@@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
 static const struct file_operations i810_buffer_fops = {
        .open = drm_open,
        .release = drm_release,
-       .unlocked_ioctl = drm_ioctl,
+       .unlocked_ioctl = i810_ioctl,
        .mmap = i810_mmap_buffers,
        .fasync = drm_fasync,
 };
index 671aa18415ac52d17164e79b4c2a9f287b02da0d..cc92c7e6236fbdffb86078290b5b93dffad2cbad 100644 (file)
@@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
 static const struct file_operations i830_buffer_fops = {
        .open = drm_open,
        .release = drm_release,
-       .unlocked_ioctl = drm_ioctl,
+       .unlocked_ioctl = i830_ioctl,
        .mmap = i830_mmap_buffers,
        .fasync = drm_fasync,
 };
index 9d67b485303005771a090ea7a3c1e1c6f8b74e9e..2dd2c93ebfa35dace7916b38c6df18c835161978 100644 (file)
@@ -1787,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
                }
        }
 
-       div_u64(diff, diff1);
+       diff = div_u64(diff, diff1);
        ret = ((m * diff) + c);
-       div_u64(ret, 10);
+       ret = div_u64(ret, 10);
 
        dev_priv->last_count1 = total_count;
        dev_priv->last_time1 = now;
@@ -1858,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv)
 
        /* More magic constants... */
        diff = diff * 1181;
-       div_u64(diff, diffms * 10);
+       diff = div_u64(diff, diffms * 10);
        dev_priv->gfx_power = diff;
 }
 
@@ -2231,6 +2231,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        dev_priv->mchdev_lock = &mchdev_lock;
        spin_unlock(&mchdev_lock);
 
+       /* XXX Prevent module unload due to memory corruption bugs. */
+       __module_get(THIS_MODULE);
+
        return 0;
 
 out_workqueue_free:
index 216deb579785eb93e27e2ba57a0556471a13daf2..6dbe14cc4f7474aa57221c46fa59286caf362b9f 100644 (file)
@@ -170,6 +170,7 @@ static const struct pci_device_id pciidlist[] = {           /* aka */
        INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),              /* G45_G */
        INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),              /* G41_G */
        INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),              /* B43_G */
+       INTEL_VGA_DEVICE(0x2e92, &intel_g45_info),              /* B43_G.1 */
        INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
        INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
        INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
index 16fca1d1799a4211474a91e7fc52b605eceafbfc..90b1d6753b9d493d3ed8d2c45153bf2047b54d8f 100644 (file)
@@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
                return -ENOMEM;
 
        ret = drm_gem_handle_create(file_priv, obj, &handle);
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_unreference_unlocked(obj);
        if (ret) {
-               drm_gem_object_unreference_unlocked(obj);
                return ret;
        }
 
-       /* Sink the floating reference from kref_init(handlecount) */
-       drm_gem_object_handle_unreference_unlocked(obj);
-
        args->handle = handle;
        return 0;
 }
@@ -471,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
                return -ENOENT;
        obj_priv = to_intel_bo(obj);
 
-       /* Bounds check source.
-        *
-        * XXX: This could use review for overflow issues...
-        */
-       if (args->offset > obj->size || args->size > obj->size ||
-           args->offset + args->size > obj->size) {
-               drm_gem_object_unreference_unlocked(obj);
-               return -EINVAL;
+       /* Bounds check source.  */
+       if (args->offset > obj->size || args->size > obj->size - args->offset) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (!access_ok(VERIFY_WRITE,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size)) {
+               ret = -EFAULT;
+               goto err;
        }
 
        if (i915_gem_object_needs_bit17_swizzle(obj)) {
@@ -490,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
                                                        file_priv);
        }
 
+err:
        drm_gem_object_unreference_unlocked(obj);
-
        return ret;
 }
 
@@ -580,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
 
        user_data = (char __user *) (uintptr_t) args->data_ptr;
        remain = args->size;
-       if (!access_ok(VERIFY_READ, user_data, remain))
-               return -EFAULT;
 
 
        mutex_lock(&dev->struct_mutex);
@@ -934,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
                return -ENOENT;
        obj_priv = to_intel_bo(obj);
 
-       /* Bounds check destination.
-        *
-        * XXX: This could use review for overflow issues...
-        */
-       if (args->offset > obj->size || args->size > obj->size ||
-           args->offset + args->size > obj->size) {
-               drm_gem_object_unreference_unlocked(obj);
-               return -EINVAL;
+       /* Bounds check destination. */
+       if (args->offset > obj->size || args->size > obj->size - args->offset) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (!access_ok(VERIFY_READ,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size)) {
+               ret = -EFAULT;
+               goto err;
        }
 
        /* We can only do the GTT pwrite on untiled buffers, as otherwise
@@ -975,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
                DRM_INFO("pwrite failed %d\n", ret);
 #endif
 
+err:
        drm_gem_object_unreference_unlocked(obj);
-
        return ret;
 }
 
@@ -2351,14 +2353,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 
        reg->obj = obj;
 
-       if (IS_GEN6(dev))
+       switch (INTEL_INFO(dev)->gen) {
+       case 6:
                sandybridge_write_fence_reg(reg);
-       else if (IS_I965G(dev))
+               break;
+       case 5:
+       case 4:
                i965_write_fence_reg(reg);
-       else if (IS_I9XX(dev))
+               break;
+       case 3:
                i915_write_fence_reg(reg);
-       else
+               break;
+       case 2:
                i830_write_fence_reg(reg);
+               break;
+       }
 
        trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
                        obj_priv->tiling_mode);
@@ -2381,22 +2390,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_i915_fence_reg *reg =
                &dev_priv->fence_regs[obj_priv->fence_reg];
+       uint32_t fence_reg;
 
-       if (IS_GEN6(dev)) {
+       switch (INTEL_INFO(dev)->gen) {
+       case 6:
                I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
                             (obj_priv->fence_reg * 8), 0);
-       } else if (IS_I965G(dev)) {
+               break;
+       case 5:
+       case 4:
                I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
-       } else {
-               uint32_t fence_reg;
-
-               if (obj_priv->fence_reg < 8)
-                       fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
+               break;
+       case 3:
+               if (obj_priv->fence_reg >= 8)
+                       fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4;
                else
-                       fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg -
-                                                      8) * 4;
+       case 2:
+                       fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
 
                I915_WRITE(fence_reg, 0);
+               break;
        }
 
        reg->obj = NULL;
@@ -3247,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                                  (int) reloc->offset,
                                  reloc->read_domains,
                                  reloc->write_domain);
+                       drm_gem_object_unreference(target_obj);
+                       i915_gem_object_unpin(obj);
                        return -EINVAL;
                }
                if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
index 72cae3cccad8802641d973542ab6c440445b81db..5c428fa3e0b34049e94786184b646a98ee87c06d 100644 (file)
@@ -79,6 +79,7 @@ mark_free(struct drm_i915_gem_object *obj_priv,
           struct list_head *unwind)
 {
        list_add(&obj_priv->evict_list, unwind);
+       drm_gem_object_reference(&obj_priv->base);
        return drm_mm_scan_add_block(obj_priv->gtt_space);
 }
 
@@ -92,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct list_head eviction_list, unwind_list;
-       struct drm_i915_gem_object *obj_priv, *tmp_obj_priv;
+       struct drm_i915_gem_object *obj_priv;
        struct list_head *render_iter, *bsd_iter;
        int ret = 0;
 
@@ -165,6 +166,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
        list_for_each_entry(obj_priv, &unwind_list, evict_list) {
                ret = drm_mm_scan_remove_block(obj_priv->gtt_space);
                BUG_ON(ret);
+               drm_gem_object_unreference(&obj_priv->base);
        }
 
        /* We expect the caller to unpin, evict all and try again, or give up.
@@ -173,36 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
        return -ENOSPC;
 
 found:
+       /* drm_mm doesn't allow any other other operations while
+        * scanning, therefore store to be evicted objects on a
+        * temporary list. */
        INIT_LIST_HEAD(&eviction_list);
-       list_for_each_entry_safe(obj_priv, tmp_obj_priv,
-                                &unwind_list, evict_list) {
+       while (!list_empty(&unwind_list)) {
+               obj_priv = list_first_entry(&unwind_list,
+                                           struct drm_i915_gem_object,
+                                           evict_list);
                if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
-                       /* drm_mm doesn't allow any other other operations while
-                        * scanning, therefore store to be evicted objects on a
-                        * temporary list. */
                        list_move(&obj_priv->evict_list, &eviction_list);
+                       continue;
                }
+               list_del(&obj_priv->evict_list);
+               drm_gem_object_unreference(&obj_priv->base);
        }
 
        /* Unbinding will emit any required flushes */
-       list_for_each_entry_safe(obj_priv, tmp_obj_priv,
-                                &eviction_list, evict_list) {
-#if WATCH_LRU
-               DRM_INFO("%s: evicting %p\n", __func__, obj);
-#endif
-               ret = i915_gem_object_unbind(&obj_priv->base);
-               if (ret)
-                       return ret;
+       while (!list_empty(&eviction_list)) {
+               obj_priv = list_first_entry(&eviction_list,
+                                           struct drm_i915_gem_object,
+                                           evict_list);
+               if (ret == 0)
+                       ret = i915_gem_object_unbind(&obj_priv->base);
+               list_del(&obj_priv->evict_list);
+               drm_gem_object_unreference(&obj_priv->base);
        }
 
-       /* The just created free hole should be on the top of the free stack
-        * maintained by drm_mm, so this BUG_ON actually executes in O(1).
-        * Furthermore all accessed data has just recently been used, so it
-        * should be really fast, too. */
-       BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size,
-                                  alignment, 0));
-
-       return 0;
+       return ret;
 }
 
 int
index 2c6b98f2440eff4fdee79ba3c7c95a5bbdf07c4a..31f08581e93a46dbdc2ca1cfa563faec31e9ffc5 100644 (file)
@@ -789,16 +789,25 @@ int i915_save_state(struct drm_device *dev)
                dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
 
        /* Fences */
-       if (IS_I965G(dev)) {
+       switch (INTEL_INFO(dev)->gen) {
+       case 6:
+               for (i = 0; i < 16; i++)
+                       dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
+               break;
+       case 5:
+       case 4:
                for (i = 0; i < 16; i++)
                        dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
-       } else {
-               for (i = 0; i < 8; i++)
-                       dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
-
+               break;
+       case 3:
                if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
                        for (i = 0; i < 8; i++)
                                dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
+       case 2:
+               for (i = 0; i < 8; i++)
+                       dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
+               break;
+
        }
 
        return 0;
@@ -815,15 +824,24 @@ int i915_restore_state(struct drm_device *dev)
        I915_WRITE(HWS_PGA, dev_priv->saveHWS);
 
        /* Fences */
-       if (IS_I965G(dev)) {
+       switch (INTEL_INFO(dev)->gen) {
+       case 6:
+               for (i = 0; i < 16; i++)
+                       I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
+               break;
+       case 5:
+       case 4:
                for (i = 0; i < 16; i++)
                        I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
-       } else {
-               for (i = 0; i < 8; i++)
-                       I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+               break;
+       case 3:
+       case 2:
                if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
                        for (i = 0; i < 8; i++)
                                I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
+               for (i = 0; i < 8; i++)
+                       I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+               break;
        }
 
        i915_restore_display(dev);
index 4b7735196cd5a516eb3bb34b9a843450da3f1fe4..197d4f32585a59b5b336328b470fa038bc922781 100644 (file)
@@ -188,7 +188,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 
        if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
                     1000, 1))
-               DRM_ERROR("timed out waiting for FORCE_TRIGGER");
+               DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
 
        if (turn_off_dac) {
                I915_WRITE(PCH_ADPA, temp);
@@ -245,7 +245,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
                if (wait_for((I915_READ(PORT_HOTPLUG_EN) &
                              CRT_HOTPLUG_FORCE_DETECT) == 0,
                             1000, 1))
-                       DRM_ERROR("timed out waiting for FORCE_DETECT to go off");
+                       DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off");
        }
 
        stat = I915_READ(PORT_HOTPLUG_STAT);
@@ -400,7 +400,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
        return status;
 }
 
-static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
+static enum drm_connector_status
+intel_crt_detect(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
        struct drm_encoder *encoder = intel_attached_encoder(connector);
@@ -419,6 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
        if (intel_crt_detect_ddc(encoder))
                return connector_status_connected;
 
+       if (!force)
+               return connector->status;
+
        /* for pre-945g platforms use load detect */
        if (encoder->crtc && encoder->crtc->enabled) {
                status = intel_crt_load_detect(encoder->crtc, intel_encoder);
index 19daead5b525d5d3d653e156ce2bfe532479bd9e..979228594599a28ac7737762679f1c97fd5981bf 100644 (file)
@@ -1013,8 +1013,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
                DRM_DEBUG_KMS("vblank wait timed out\n");
 }
 
-/**
- * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
+/*
+ * intel_wait_for_pipe_off - wait for pipe to turn off
  * @dev: drm device
  * @pipe: pipe to wait for
  *
@@ -1022,25 +1022,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
  * spinning on the vblank interrupt status bit, since we won't actually
  * see an interrupt when the pipe is disabled.
  *
- * So this function waits for the display line value to settle (it
- * usually ends up stopping at the start of the next frame).
+ * On Gen4 and above:
+ *   wait for the pipe register state bit to turn off
+ *
+ * Otherwise:
+ *   wait for the display line value to settle (it usually
+ *   ends up stopping at the start of the next frame).
+ *  
  */
-void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
+static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
-       unsigned long timeout = jiffies + msecs_to_jiffies(100);
-       u32 last_line;
-
-       /* Wait for the display line to settle */
-       do {
-               last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
-               mdelay(5);
-       } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
-                time_after(timeout, jiffies));
-
-       if (time_after(jiffies, timeout))
-               DRM_DEBUG_KMS("vblank wait timed out\n");
+
+       if (INTEL_INFO(dev)->gen >= 4) {
+               int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF);
+
+               /* Wait for the Pipe State to go off */
+               if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0,
+                            100, 0))
+                       DRM_DEBUG_KMS("pipe_off wait timed out\n");
+       } else {
+               u32 last_line;
+               int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
+               unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+               /* Wait for the display line to settle */
+               do {
+                       last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
+                       mdelay(5);
+               } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
+                        time_after(timeout, jiffies));
+               if (time_after(jiffies, timeout))
+                       DRM_DEBUG_KMS("pipe_off wait timed out\n");
+       }
 }
 
 /* Parameters have changed, update FBC info */
@@ -2328,13 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
                        I915_READ(dspbase_reg);
                }
 
-               /* Wait for vblank for the disable to take effect */
-               intel_wait_for_vblank_off(dev, pipe);
-
                /* Don't disable pipe A or pipe A PLLs if needed */
                if (pipeconf_reg == PIPEACONF &&
-                   (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+                   (dev_priv->quirks & QUIRK_PIPEA_FORCE)) {
+                       /* Wait for vblank for the disable to take effect */
+                       intel_wait_for_vblank(dev, pipe);
                        goto skip_pipe_off;
+               }
 
                /* Next, disable display pipes */
                temp = I915_READ(pipeconf_reg);
@@ -2343,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
                        I915_READ(pipeconf_reg);
                }
 
-               /* Wait for vblank for the disable to take effect. */
-               intel_wait_for_vblank_off(dev, pipe);
+               /* Wait for the pipe to turn off */
+               intel_wait_for_pipe_off(dev, pipe);
 
                temp = I915_READ(dpll_reg);
                if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -2463,11 +2477,19 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
                                  struct drm_display_mode *adjusted_mode)
 {
        struct drm_device *dev = crtc->dev;
+
        if (HAS_PCH_SPLIT(dev)) {
                /* FDI link clock is fixed at 2.7G */
                if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
                        return false;
        }
+
+       /* XXX some encoders set the crtcinfo, others don't.
+        * Obviously we need some form of conflict resolution here...
+        */
+       if (adjusted_mode->crtc_htotal == 0)
+               drm_mode_set_crtcinfo(adjusted_mode, 0);
+
        return true;
 }
 
index 51d142939a26e9abe76fdfe8a90aa94ff0f3b612..9ab8708ac6ba1370cea75680d6a660daa5f9b147 100644 (file)
@@ -1138,18 +1138,14 @@ static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
                        uint32_t dp_reg_value,
                        uint8_t dp_train_pat,
-                       uint8_t train_set[4],
-                       bool first)
+                       uint8_t train_set[4])
 {
        struct drm_device *dev = intel_dp->base.enc.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
        int ret;
 
        I915_WRITE(intel_dp->output_reg, dp_reg_value);
        POSTING_READ(intel_dp->output_reg);
-       if (first)
-               intel_wait_for_vblank(dev, intel_crtc->pipe);
 
        intel_dp_aux_native_write_1(intel_dp,
                                    DP_TRAINING_PATTERN_SET,
@@ -1174,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp)
        uint8_t voltage;
        bool clock_recovery = false;
        bool channel_eq = false;
-       bool first = true;
        int tries;
        u32 reg;
        uint32_t DP = intel_dp->DP;
+       struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
+
+       /* Enable output, wait for it to become active */
+       I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+       POSTING_READ(intel_dp->output_reg);
+       intel_wait_for_vblank(dev, intel_crtc->pipe);
 
        /* Write the link configuration data */
        intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
@@ -1210,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp)
                        reg = DP | DP_LINK_TRAIN_PAT_1;
 
                if (!intel_dp_set_link_train(intel_dp, reg,
-                                            DP_TRAINING_PATTERN_1, train_set, first))
+                                            DP_TRAINING_PATTERN_1, train_set))
                        break;
-               first = false;
                /* Set training pattern 1 */
 
                udelay(100);
@@ -1266,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp)
 
                /* channel eq pattern */
                if (!intel_dp_set_link_train(intel_dp, reg,
-                                            DP_TRAINING_PATTERN_2, train_set,
-                                            false))
+                                            DP_TRAINING_PATTERN_2, train_set))
                        break;
 
                udelay(400);
@@ -1386,7 +1385,7 @@ ironlake_dp_detect(struct drm_connector *connector)
  * \return false if DP port is disconnected.
  */
 static enum drm_connector_status
-intel_dp_detect(struct drm_connector *connector)
+intel_dp_detect(struct drm_connector *connector, bool force)
 {
        struct drm_encoder *encoder = intel_attached_encoder(connector);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
index ad312ca6b3e570125732168b3c2f670467264beb..8828b3ac6414eabff93134e34a41ae5c38d1cd34 100644 (file)
@@ -229,7 +229,6 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
                                                    struct drm_crtc *crtc);
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
-extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
 extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
 extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
index a399f4b2c1c526cdfd64aa2d476f6b97c3fd69d2..7c9ec1472d46ab3cbb08f6bffc8257af952a64b0 100644 (file)
@@ -221,7 +221,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
  *
  * Unimplemented.
  */
-static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
+static enum drm_connector_status
+intel_dvo_detect(struct drm_connector *connector, bool force)
 {
        struct drm_encoder *encoder = intel_attached_encoder(connector);
        struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
index 7bdc96256bf55b6e87d102377b428a871792be91..b61966c126d3e3839d33be6c8df2c0170c5d1376 100644 (file)
@@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev,
        drm_fb_helper_fini(&ifbdev->helper);
 
        drm_framebuffer_cleanup(&ifb->base);
-       if (ifb->obj)
+       if (ifb->obj) {
                drm_gem_object_unreference(ifb->obj);
+               ifb->obj = NULL;
+       }
 
        return 0;
 }
index ccd4c97e652492f19d85abf532d56aafcab6968a..926934a482ec085c63256567e27f0309b51b24cf 100644 (file)
@@ -139,7 +139,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 }
 
 static enum drm_connector_status
-intel_hdmi_detect(struct drm_connector *connector)
+intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
        struct drm_encoder *encoder = intel_attached_encoder(connector);
        struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
index 4fbb0165b26f06a24cdbd8eef71f3c3d8e9845a2..6ec39a86ed06d2bd6e716611f3ab4d384d950636 100644 (file)
@@ -445,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
  * connected and closed means disconnected.  We also send hotplug events as
  * needed, using lid status notification from the input layer.
  */
-static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
+static enum drm_connector_status
+intel_lvds_detect(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
        enum drm_connector_status status = connector_status_connected;
@@ -540,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
         * the LID nofication event.
         */
        if (connector)
-               connector->status = connector->funcs->detect(connector);
+               connector->status = connector->funcs->detect(connector,
+                                                            false);
+
        /* Don't force modeset on machines where it causes a GPU lockup */
        if (dmi_check_system(intel_no_modeset_on_lid))
                return NOTIFY_OK;
index e3b7a7ee39cb97b390048c1a5ce9187b94b6e51d..ee73e428a84a800dd8d70a1747457033f7e8da8e 100644 (file)
@@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev)
        if (!analog_connector)
                return false;
 
-       if (analog_connector->funcs->detect(analog_connector) ==
+       if (analog_connector->funcs->detect(analog_connector, false) ==
                        connector_status_disconnected)
                return false;
 
@@ -1486,7 +1486,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
        return status;
 }
 
-static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
+static enum drm_connector_status
+intel_sdvo_detect(struct drm_connector *connector, bool force)
 {
        uint16_t response;
        struct drm_encoder *encoder = intel_attached_encoder(connector);
@@ -2169,8 +2170,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
         return true;
 
 err:
-       intel_sdvo_destroy_enhance_property(connector);
-       kfree(intel_sdvo_connector);
+       intel_sdvo_destroy(connector);
        return false;
 }
 
@@ -2242,8 +2242,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
        return true;
 
 err:
-       intel_sdvo_destroy_enhance_property(connector);
-       kfree(intel_sdvo_connector);
+       intel_sdvo_destroy(connector);
        return false;
 }
 
@@ -2521,11 +2520,10 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
                uint16_t response;
        } enhancements;
 
-       if (!intel_sdvo_get_value(intel_sdvo,
-                                 SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
-                                 &enhancements, sizeof(enhancements)))
-               return false;
-
+       enhancements.response = 0;
+       intel_sdvo_get_value(intel_sdvo,
+                            SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+                            &enhancements, sizeof(enhancements));
        if (enhancements.response == 0) {
                DRM_DEBUG_KMS("No enhancement is supported\n");
                return true;
index c671f60ce80bac917a61c1c60cdb02e692afcb85..4a117e318a73a0a44c7ae4cc0be3447d11a403da 100644 (file)
@@ -1341,7 +1341,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
  * we have a pipe programmed in order to probe the TV.
  */
 static enum drm_connector_status
-intel_tv_detect(struct drm_connector *connector)
+intel_tv_detect(struct drm_connector *connector, bool force)
 {
        struct drm_display_mode mode;
        struct drm_encoder *encoder = intel_attached_encoder(connector);
@@ -1353,7 +1353,7 @@ intel_tv_detect(struct drm_connector *connector)
 
        if (encoder->crtc && encoder->crtc->enabled) {
                type = intel_tv_detect_type(intel_tv);
-       } else {
+       } else if (force) {
                struct drm_crtc *crtc;
                int dpms_mode;
 
@@ -1364,10 +1364,9 @@ intel_tv_detect(struct drm_connector *connector)
                        intel_release_load_detect_pipe(&intel_tv->base, connector,
                                                       dpms_mode);
                } else
-                       type = -1;
-       }
-
-       intel_tv->type = type;
+                       return connector_status_unknown;
+       } else
+               return connector->status;
 
        if (type < 0)
                return connector_status_disconnected;
index a1473fff06ac2d61bd3f629dcc9527be5975f165..fc737037f751c3690dfb09239e3439df1fa4191c 100644 (file)
@@ -168,7 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
 }
 
 static enum drm_connector_status
-nouveau_connector_detect(struct drm_connector *connector)
+nouveau_connector_detect(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
@@ -246,7 +246,7 @@ detect_analog:
 }
 
 static enum drm_connector_status
-nouveau_connector_detect_lvds(struct drm_connector *connector)
+nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -267,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector)
 
        /* Try retrieving EDID via DDC */
        if (!dev_priv->vbios.fp_no_ddc) {
-               status = nouveau_connector_detect(connector);
+               status = nouveau_connector_detect(connector, force);
                if (status == connector_status_connected)
                        goto out;
        }
@@ -558,8 +558,10 @@ nouveau_connector_get_modes(struct drm_connector *connector)
        if (nv_encoder->dcb->type == OUTPUT_LVDS &&
            (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
             dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
-               nv_connector->native_mode = drm_mode_create(dev);
-               nouveau_bios_fp_mode(dev, nv_connector->native_mode);
+               struct drm_display_mode mode;
+
+               nouveau_bios_fp_mode(dev, &mode);
+               nv_connector->native_mode = drm_mode_duplicate(dev, &mode);
        }
 
        /* Find the native mode if this is a digital panel, if we didn't
index ead7b8fc53fcbcd473dbdc7a97d893a3e2e9c454..19620a6709f55c00e97efd5d2f816705788420f8 100644 (file)
@@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
                goto out;
 
        ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_unreference_unlocked(nvbo->gem);
 out:
-       drm_gem_object_handle_unreference_unlocked(nvbo->gem);
-
-       if (ret)
-               drm_gem_object_unreference_unlocked(nvbo->gem);
        return ret;
 }
 
index 1bc72c3190a9dcfe9b8f70f16087a231560d9b08..fe359a239df343437cce0b0c79d2692c559ffb9e 100644 (file)
@@ -4999,7 +4999,7 @@ typedef struct _SW_I2C_IO_DATA_PARAMETERS
 #define SW_I2C_CNTL_WRITE1BIT 6
 
 //==============================VESA definition Portion===============================
-#define VESA_OEM_PRODUCT_REV                               '01.00'
+#define VESA_OEM_PRODUCT_REV                               "01.00"
 #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT            0xBB       //refer to VBE spec p.32, no TTY support
 #define VESA_MODE_WIN_ATTRIBUTE                                                     7
 #define VESA_WIN_SIZE                                                                                       64
index 464a81a1990f6f274d46bd0535283bb315680305..cd0290f946cff51e8aa8c702dda5e650ec5f9af0 100644 (file)
@@ -539,14 +539,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                        pll->algo = PLL_ALGO_LEGACY;
                                        pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
                                }
-                               /* There is some evidence (often anecdotal) that RV515 LVDS
+                               /* There is some evidence (often anecdotal) that RV515/RV620 LVDS
                                 * (on some boards at least) prefers the legacy algo.  I'm not
                                 * sure whether this should handled generically or on a
                                 * case-by-case quirk basis.  Both algos should work fine in the
                                 * majority of cases.
                                 */
                                if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
-                                   (rdev->family == CHIP_RV515)) {
+                                   ((rdev->family == CHIP_RV515) ||
+                                    (rdev->family == CHIP_RV620))) {
                                        /* allow the user to overrride just in case */
                                        if (radeon_new_pll == 1)
                                                pll->algo = PLL_ALGO_NEW;
index b8b7f010b25f8df49e20329932c1735482c03ecf..2f93d46ae69ad58dfb90ea5db02021a402506ae5 100644 (file)
@@ -1137,7 +1137,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 
                WREG32(RCU_IND_INDEX, 0x203);
                efuse_straps_3 = RREG32(RCU_IND_DATA);
-               efuse_box_bit_127_124 = (u8)(efuse_straps_3 & 0xF0000000) >> 28;
+               efuse_box_bit_127_124 = (u8)((efuse_straps_3 & 0xF0000000) >> 28);
 
                switch(efuse_box_bit_127_124) {
                case 0x0:
@@ -1160,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                                                                        EVERGREEN_MAX_BACKENDS_MASK));
                        break;
                }
-       } else
-               gb_backend_map =
-                       evergreen_get_tile_pipe_to_backend_map(rdev,
-                                                              rdev->config.evergreen.max_tile_pipes,
-                                                              rdev->config.evergreen.max_backends,
-                                                              ((EVERGREEN_MAX_BACKENDS_MASK <<
-                                                                rdev->config.evergreen.max_backends) &
-                                                               EVERGREEN_MAX_BACKENDS_MASK));
+       } else {
+               switch (rdev->family) {
+               case CHIP_CYPRESS:
+               case CHIP_HEMLOCK:
+                       gb_backend_map = 0x66442200;
+                       break;
+               case CHIP_JUNIPER:
+                       gb_backend_map = 0x00006420;
+                       break;
+               default:
+                       gb_backend_map =
+                               evergreen_get_tile_pipe_to_backend_map(rdev,
+                                                                      rdev->config.evergreen.max_tile_pipes,
+                                                                      rdev->config.evergreen.max_backends,
+                                                                      ((EVERGREEN_MAX_BACKENDS_MASK <<
+                                                                        rdev->config.evergreen.max_backends) &
+                                                                       EVERGREEN_MAX_BACKENDS_MASK));
+               }
+       }
 
        rdev->config.evergreen.tile_config = gb_addr_config;
        WREG32(GB_BACKEND_MAP, gb_backend_map);
@@ -1396,6 +1407,7 @@ int evergreen_mc_init(struct radeon_device *rdev)
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        r600_vram_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 
@@ -1509,7 +1521,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
 {
        u32 tmp;
 
-       WREG32(CP_INT_CNTL, 0);
+       WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
        WREG32(GRBM_INT_CNTL, 0);
        WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
        WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
index e817a0bb5eb4a71550d0c9f6f8697cd80c31914e..e59422320bb6df9873fbf88f9e29d34fdc412110 100644 (file)
@@ -1030,6 +1030,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
                return r;
        }
        rdev->cp.ready = true;
+       rdev->mc.active_vram_size = rdev->mc.real_vram_size;
        return 0;
 }
 
@@ -1047,6 +1048,7 @@ void r100_cp_fini(struct radeon_device *rdev)
 void r100_cp_disable(struct radeon_device *rdev)
 {
        /* Disable ring */
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        rdev->cp.ready = false;
        WREG32(RADEON_CP_CSQ_MODE, 0);
        WREG32(RADEON_CP_CSQ_CNTL, 0);
@@ -2020,18 +2022,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l
                return false;
        }
        elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies);
-       if (elapsed >= 3000) {
-               /* very likely the improbable case where current
-                * rptr is equal to last recorded, a while ago, rptr
-                * this is more likely a false positive update tracking
-                * information which should force us to be recall at
-                * latter point
-                */
-               lockup->last_cp_rptr = cp->rptr;
-               lockup->last_jiffies = jiffies;
-               return false;
-       }
-       if (elapsed >= 1000) {
+       if (elapsed >= 10000) {
                dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed);
                return true;
        }
@@ -2306,6 +2297,7 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
        /* FIXME we don't use the second aperture yet when we could use it */
        if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
                rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
        if (rdev->flags & RADEON_IS_IGP) {
                uint32_t tom;
@@ -3308,13 +3300,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
        unsigned long size;
        unsigned prim_walk;
        unsigned nverts;
+       unsigned num_cb = track->num_cb;
 
-       for (i = 0; i < track->num_cb; i++) {
+       if (!track->zb_cb_clear && !track->color_channel_mask &&
+           !track->blend_read_enable)
+               num_cb = 0;
+
+       for (i = 0; i < num_cb; i++) {
                if (track->cb[i].robj == NULL) {
-                       if (!(track->zb_cb_clear || track->color_channel_mask ||
-                             track->blend_read_enable)) {
-                               continue;
-                       }
                        DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
                        return -EINVAL;
                }
index afc18d87fdca7409e4c7462fe3a1b03eeaa6d3ca..7b65e4efe8af61e2df5404ea52c468fe8ee564db 100644 (file)
@@ -1248,6 +1248,7 @@ int r600_mc_init(struct radeon_device *rdev)
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        r600_vram_gtt_location(rdev, &rdev->mc);
 
        if (rdev->flags & RADEON_IS_IGP) {
@@ -1917,6 +1918,7 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
  */
 void r600_cp_stop(struct radeon_device *rdev)
 {
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
 }
 
@@ -2729,7 +2731,7 @@ int r600_ib_test(struct radeon_device *rdev)
        if (i < rdev->usec_timeout) {
                DRM_INFO("ib test succeeded in %u usecs\n", i);
        } else {
-               DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
+               DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n",
                          scratch, tmp);
                r = -EINVAL;
        }
@@ -2910,7 +2912,7 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)
 {
        u32 tmp;
 
-       WREG32(CP_INT_CNTL, 0);
+       WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
        WREG32(GRBM_INT_CNTL, 0);
        WREG32(DxMODE_INT_MASK, 0);
        if (ASIC_IS_DCE3(rdev)) {
@@ -3528,7 +3530,8 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
        /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
         * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
         */
-       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+           rdev->vram_scratch.ptr) {
                void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
                u32 tmp;
 
index d13622ae74e9799d75045cd282d2797071a23d21..3473c00781ffaaac06cab0c520231a5a66a21111 100644 (file)
@@ -1,3 +1,28 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -507,6 +532,7 @@ int r600_blit_init(struct radeon_device *rdev)
        memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
        radeon_bo_kunmap(rdev->r600_blit.shader_obj);
        radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+       rdev->mc.active_vram_size = rdev->mc.real_vram_size;
        return 0;
 }
 
@@ -514,6 +540,7 @@ void r600_blit_fini(struct radeon_device *rdev)
 {
        int r;
 
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        if (rdev->r600_blit.shader_obj == NULL)
                return;
        /* If we can't reserve the bo, unref should be enough to destroy
index fdc3b378cbb0d78542987e111fc1693462dc2b1b..f437d36dd98c2f33d195f4fdaaae034c535be6e8 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
 
 #ifndef R600_BLIT_SHADERS_H
 #define R600_BLIT_SHADERS_H
index d8864949e387a30d838e59cb5eb6d95a4549b1e3..250a3a918193e9821aa6f5836d463553cf6f903d 100644 (file)
@@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
        /* using get ib will give us the offset into the mipmap bo */
        word0 = radeon_get_ib_value(p, idx + 3) << 8;
        if ((mipmap_size + word0) > radeon_bo_size(mipmap)) {
-               dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
-                       w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));
-               return -EINVAL;
+               /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
+                 w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/
        }
        return 0;
 }
index a168d644bf9e96724b5e717f2a8777bb8354f5e5..9ff38c99a6ea0e568f2567c0a7ad34b06e60e512 100644 (file)
@@ -344,6 +344,7 @@ struct radeon_mc {
         * about vram size near mc fb location */
        u64                     mc_vram_size;
        u64                     visible_vram_size;
+       u64                     active_vram_size;
        u64                     gtt_size;
        u64                     gtt_start;
        u64                     gtt_end;
index ebae14c4b768b4413990e84c1055782a72590009..8e43ddae70cc27d3c37d472561527432cc51dd53 100644 (file)
@@ -317,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
                        *connector_type = DRM_MODE_CONNECTOR_DVID;
        }
 
+       /* MSI K9A2GM V2/V3 board has no HDMI or DVI */
+       if ((dev->pdev->device == 0x796e) &&
+           (dev->pdev->subsystem_vendor == 0x1462) &&
+           (dev->pdev->subsystem_device == 0x7302)) {
+               if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) ||
+                   (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
+                       return false;
+       }
+
        /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
        if ((dev->pdev->device == 0x7941) &&
            (dev->pdev->subsystem_vendor == 0x147b) &&
@@ -1549,39 +1558,39 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)
                switch (tv_info->ucTV_BootUpDefaultStandard) {
                case ATOM_TV_NTSC:
                        tv_std = TV_STD_NTSC;
-                       DRM_INFO("Default TV standard: NTSC\n");
+                       DRM_DEBUG_KMS("Default TV standard: NTSC\n");
                        break;
                case ATOM_TV_NTSCJ:
                        tv_std = TV_STD_NTSC_J;
-                       DRM_INFO("Default TV standard: NTSC-J\n");
+                       DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
                        break;
                case ATOM_TV_PAL:
                        tv_std = TV_STD_PAL;
-                       DRM_INFO("Default TV standard: PAL\n");
+                       DRM_DEBUG_KMS("Default TV standard: PAL\n");
                        break;
                case ATOM_TV_PALM:
                        tv_std = TV_STD_PAL_M;
-                       DRM_INFO("Default TV standard: PAL-M\n");
+                       DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
                        break;
                case ATOM_TV_PALN:
                        tv_std = TV_STD_PAL_N;
-                       DRM_INFO("Default TV standard: PAL-N\n");
+                       DRM_DEBUG_KMS("Default TV standard: PAL-N\n");
                        break;
                case ATOM_TV_PALCN:
                        tv_std = TV_STD_PAL_CN;
-                       DRM_INFO("Default TV standard: PAL-CN\n");
+                       DRM_DEBUG_KMS("Default TV standard: PAL-CN\n");
                        break;
                case ATOM_TV_PAL60:
                        tv_std = TV_STD_PAL_60;
-                       DRM_INFO("Default TV standard: PAL-60\n");
+                       DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
                        break;
                case ATOM_TV_SECAM:
                        tv_std = TV_STD_SECAM;
-                       DRM_INFO("Default TV standard: SECAM\n");
+                       DRM_DEBUG_KMS("Default TV standard: SECAM\n");
                        break;
                default:
                        tv_std = TV_STD_NTSC;
-                       DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
+                       DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n");
                        break;
                }
        }
index bd74e428bd147d0df444cc64858f28acbed0d8ed..7b7ea269549ccef95c1e6c343083071774e7e9de 100644 (file)
@@ -913,47 +913,47 @@ radeon_combios_get_tv_info(struct radeon_device *rdev)
                        switch (RBIOS8(tv_info + 7) & 0xf) {
                        case 1:
                                tv_std = TV_STD_NTSC;
-                               DRM_INFO("Default TV standard: NTSC\n");
+                               DRM_DEBUG_KMS("Default TV standard: NTSC\n");
                                break;
                        case 2:
                                tv_std = TV_STD_PAL;
-                               DRM_INFO("Default TV standard: PAL\n");
+                               DRM_DEBUG_KMS("Default TV standard: PAL\n");
                                break;
                        case 3:
                                tv_std = TV_STD_PAL_M;
-                               DRM_INFO("Default TV standard: PAL-M\n");
+                               DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
                                break;
                        case 4:
                                tv_std = TV_STD_PAL_60;
-                               DRM_INFO("Default TV standard: PAL-60\n");
+                               DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
                                break;
                        case 5:
                                tv_std = TV_STD_NTSC_J;
-                               DRM_INFO("Default TV standard: NTSC-J\n");
+                               DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
                                break;
                        case 6:
                                tv_std = TV_STD_SCART_PAL;
-                               DRM_INFO("Default TV standard: SCART-PAL\n");
+                               DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n");
                                break;
                        default:
                                tv_std = TV_STD_NTSC;
-                               DRM_INFO
+                               DRM_DEBUG_KMS
                                    ("Unknown TV standard; defaulting to NTSC\n");
                                break;
                        }
 
                        switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) {
                        case 0:
-                               DRM_INFO("29.498928713 MHz TV ref clk\n");
+                               DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n");
                                break;
                        case 1:
-                               DRM_INFO("28.636360000 MHz TV ref clk\n");
+                               DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n");
                                break;
                        case 2:
-                               DRM_INFO("14.318180000 MHz TV ref clk\n");
+                               DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n");
                                break;
                        case 3:
-                               DRM_INFO("27.000000000 MHz TV ref clk\n");
+                               DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n");
                                break;
                        default:
                                break;
@@ -1324,7 +1324,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
 
        if (tmds_info) {
                ver = RBIOS8(tmds_info);
-               DRM_INFO("DFP table revision: %d\n", ver);
+               DRM_DEBUG_KMS("DFP table revision: %d\n", ver);
                if (ver == 3) {
                        n = RBIOS8(tmds_info + 5) + 1;
                        if (n > 4)
@@ -1408,7 +1408,7 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder
                offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
                if (offset) {
                        ver = RBIOS8(offset);
-                       DRM_INFO("External TMDS Table revision: %d\n", ver);
+                       DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver);
                        tmds->slave_addr = RBIOS8(offset + 4 + 2);
                        tmds->slave_addr >>= 1; /* 7 bit addressing */
                        gpio = RBIOS8(offset + 4 + 3);
@@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                        /* PowerMac8,1 ? */
                        /* imac g5 isight */
                        rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
+               } else if ((rdev->pdev->device == 0x4a48) &&
+                          (rdev->pdev->subsystem_vendor == 0x1002) &&
+                          (rdev->pdev->subsystem_device == 0x4a48)) {
+                       /* Mac X800 */
+                       rdev->mode_info.connector_table = CT_MAC_X800;
                } else
 #endif /* CONFIG_PPC_PMAC */
 #ifdef CONFIG_PPC64
@@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            CONNECTOR_OBJECT_ID_VGA,
                                            &hpd);
                break;
+       case CT_MAC_X800:
+               DRM_INFO("Connector Table: %d (mac x800)\n",
+                        rdev->mode_info.connector_table);
+               /* DVI - primary dac, internal tmds */
+               ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
+               hpd.hpd = RADEON_HPD_1; /* ??? */
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_DFP1_SUPPORT,
+                                                                 0),
+                                         ATOM_DEVICE_DFP1_SUPPORT);
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_CRT1_SUPPORT,
+                                                                 1),
+                                         ATOM_DEVICE_CRT1_SUPPORT);
+               radeon_add_legacy_connector(dev, 0,
+                                           ATOM_DEVICE_DFP1_SUPPORT |
+                                           ATOM_DEVICE_CRT1_SUPPORT,
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
+               /* DVI - tv dac, dvo */
+               ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
+               hpd.hpd = RADEON_HPD_2; /* ??? */
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_DFP2_SUPPORT,
+                                                                 0),
+                                         ATOM_DEVICE_DFP2_SUPPORT);
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_CRT2_SUPPORT,
+                                                                 2),
+                                         ATOM_DEVICE_CRT2_SUPPORT);
+               radeon_add_legacy_connector(dev, 1,
+                                           ATOM_DEVICE_DFP2_SUPPORT |
+                                           ATOM_DEVICE_CRT2_SUPPORT,
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
+                                           &hpd);
+               break;
        default:
                DRM_INFO("Connector table: %d (invalid)\n",
                         rdev->mode_info.connector_table);
index a9dd7847d96ed673e4548efc343e9112390e7c75..ecc1a8fafbfd3eb3c12c0c4d45b4b091a1bee03b 100644 (file)
@@ -481,7 +481,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
+static enum drm_connector_status
+radeon_lvds_detect(struct drm_connector *connector, bool force)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct drm_encoder *encoder = radeon_best_single_encoder(connector);
@@ -594,7 +595,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
+static enum drm_connector_status
+radeon_vga_detect(struct drm_connector *connector, bool force)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct drm_encoder *encoder;
@@ -691,7 +693,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
+static enum drm_connector_status
+radeon_tv_detect(struct drm_connector *connector, bool force)
 {
        struct drm_encoder *encoder;
        struct drm_encoder_helper_funcs *encoder_funcs;
@@ -748,7 +751,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector)
  * we have to check if this analog encoder is shared with anyone else (TV)
  * if its shared we have to set the other connector to disconnected.
  */
-static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
+static enum drm_connector_status
+radeon_dvi_detect(struct drm_connector *connector, bool force)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct drm_encoder *encoder = NULL;
@@ -972,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
        return ret;
 }
 
-static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
+static enum drm_connector_status
+radeon_dp_detect(struct drm_connector *connector, bool force)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        enum drm_connector_status ret = connector_status_disconnected;
index 6dd434ad2429b9d9689ed861d33a2b1c0b09f092..b92d2f2fcbed6a8bd472ce9f4b936aa82f309278 100644 (file)
@@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev)
                                        DRM_INFO("    DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
                                if (devices & ATOM_DEVICE_DFP5_SUPPORT)
                                        DRM_INFO("    DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
+                               if (devices & ATOM_DEVICE_DFP6_SUPPORT)
+                                       DRM_INFO("    DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]);
                                if (devices & ATOM_DEVICE_TV1_SUPPORT)
                                        DRM_INFO("    TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
                                if (devices & ATOM_DEVICE_CV_SUPPORT)
@@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
        struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
 
-       if (radeon_fb->obj)
+       if (radeon_fb->obj) {
                drm_gem_object_unreference_unlocked(radeon_fb->obj);
+       }
        drm_framebuffer_cleanup(fb);
        kfree(radeon_fb);
 }
@@ -1140,17 +1143,18 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                                radeon_crtc->rmx_type = radeon_encoder->rmx_type;
                        else
                                radeon_crtc->rmx_type = RMX_OFF;
-                       src_v = crtc->mode.vdisplay;
-                       dst_v = radeon_crtc->native_mode.vdisplay;
-                       src_h = crtc->mode.hdisplay;
-                       dst_h = radeon_crtc->native_mode.vdisplay;
                        /* copy native mode */
                        memcpy(&radeon_crtc->native_mode,
                               &radeon_encoder->native_mode,
                                sizeof(struct drm_display_mode));
+                       src_v = crtc->mode.vdisplay;
+                       dst_v = radeon_crtc->native_mode.vdisplay;
+                       src_h = crtc->mode.hdisplay;
+                       dst_h = radeon_crtc->native_mode.hdisplay;
 
                        /* fix up for overscan on hdmi */
                        if (ASIC_IS_AVIVO(rdev) &&
+                           (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
                            ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
                             ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
                              drm_detect_hdmi_monitor(radeon_connector->edid) &&
index c74a8b20d9413e921bc6a03cd92578146a9ee8ef..40b0c087b5921384d46bf7f745cf93f2b391015b 100644 (file)
@@ -94,6 +94,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
        ret = radeon_bo_reserve(rbo, false);
        if (likely(ret == 0)) {
                radeon_bo_kunmap(rbo);
+               radeon_bo_unpin(rbo);
                radeon_bo_unreserve(rbo);
        }
        drm_gem_object_unreference_unlocked(gobj);
@@ -325,8 +326,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
 {
        struct fb_info *info;
        struct radeon_framebuffer *rfb = &rfbdev->rfb;
-       struct radeon_bo *rbo;
-       int r;
 
        if (rfbdev->helper.fbdev) {
                info = rfbdev->helper.fbdev;
@@ -338,14 +337,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
        }
 
        if (rfb->obj) {
-               rbo = rfb->obj->driver_private;
-               r = radeon_bo_reserve(rbo, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rbo);
-                       radeon_bo_unpin(rbo);
-                       radeon_bo_unreserve(rbo);
-               }
-               drm_gem_object_unreference_unlocked(rfb->obj);
+               radeonfb_destroy_pinned_object(rfb->obj);
+               rfb->obj = NULL;
        }
        drm_fb_helper_fini(&rfbdev->helper);
        drm_framebuffer_cleanup(&rfb->base);
index c578f265b24cefc6dce21734783b01c1aed1ce27..d1e595d9172396b8104d19c7a1d0a87d3b14b772 100644 (file)
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
                return r;
        }
        r = drm_gem_handle_create(filp, gobj, &handle);
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_unreference_unlocked(gobj);
        if (r) {
-               drm_gem_object_unreference_unlocked(gobj);
                return r;
        }
-       drm_gem_object_handle_unreference_unlocked(gobj);
        args->handle = handle;
        return 0;
 }
index 5eee3c41d124bf49fbd5dfbc7264fb062699e961..8fbbe1c6ebbda854f7bf9dc9f76ae1c4eefdafc5 100644 (file)
@@ -203,6 +203,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
  */
 int radeon_driver_firstopen_kms(struct drm_device *dev)
 {
+       struct radeon_device *rdev = dev->dev_private;
+
+       if (rdev->powered_down)
+               return -EINVAL;
        return 0;
 }
 
index efbe975312dc42342c2add89c417b753b0e92791..17a6602b5885786fecd6dd3231940a7b5d3c4261 100644 (file)
@@ -204,7 +204,7 @@ struct radeon_i2c_chan {
 
 /* mostly for macs, but really any system without connector tables */
 enum radeon_connector_table {
-       CT_NONE,
+       CT_NONE = 0,
        CT_GENERIC,
        CT_IBOOK,
        CT_POWERBOOK_EXTERNAL,
@@ -215,6 +215,7 @@ enum radeon_connector_table {
        CT_IMAC_G5_ISIGHT,
        CT_EMAC,
        CT_RN50_POWER,
+       CT_MAC_X800,
 };
 
 enum radeon_dvo_chip {
index 0afd1e62347dcfb9670d20e13a818d8d7a99b59c..b3b5306bb578bf88547e4078fe48f59d9e0ea720 100644 (file)
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
        u32 c = 0;
 
        rbo->placement.fpfn = 0;
-       rbo->placement.lpfn = 0;
+       rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
        rbo->placement.placement = rbo->placements;
        rbo->placement.busy_placement = rbo->placements;
        if (domain & RADEON_GEM_DOMAIN_VRAM)
index 353998dc2c03b12992cd244ff116d01e45db2b96..3481bc7f6f582b08a0c2a9ff079fa9787defb6cd 100644 (file)
@@ -124,11 +124,8 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
        int r;
 
        r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
-       if (unlikely(r != 0)) {
-               if (r != -ERESTARTSYS)
-                       dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
+       if (unlikely(r != 0))
                return r;
-       }
        spin_lock(&bo->tbo.lock);
        if (mem_type)
                *mem_type = bo->tbo.mem.mem_type;
index cc05b230d7effbbae88524da0d698dace6228ccf..51d5f7b5ab21b40a6e34d2fd286f28da91e4f0b0 100644 (file)
@@ -693,6 +693,7 @@ void rs600_mc_init(struct radeon_device *rdev)
        rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
        rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        base = RREG32_MC(R_000004_MC_FB_LOCATION);
        base = G_000004_MC_FB_START(base) << 16;
index 3e3f75718be3e83ab156465dc80a11f604b58a64..4dc2a87ea68018f0292cc0724d6ef4868c00e8ac 100644 (file)
@@ -157,6 +157,7 @@ void rs690_mc_init(struct radeon_device *rdev)
        rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
        rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
        base = G_000100_MC_FB_START(base) << 16;
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
index bfa59db374d23d3c4a06877a6e9a37aec59904e0..9490da700749487c00fe9c57671ec89727653136 100644 (file)
@@ -267,6 +267,7 @@ static void rv770_mc_program(struct radeon_device *rdev)
  */
 void r700_cp_stop(struct radeon_device *rdev)
 {
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
 }
 
@@ -992,6 +993,7 @@ int rv770_mc_init(struct radeon_device *rdev)
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        r600_vram_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 
index cb4cf7ef4d1eee9bc726c4d4ee34f8962526b316..db809e034cc48b6d8c246cba1ede0660113e30de 100644 (file)
@@ -441,6 +441,43 @@ out_err:
        return ret;
 }
 
+/**
+ * Call bo::reserved and with the lru lock held.
+ * Will release GPU memory type usage on destruction.
+ * This is the place to put in driver specific hooks.
+ * Will release the bo::reserved lock and the
+ * lru lock on exit.
+ */
+
+static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
+{
+       struct ttm_bo_global *glob = bo->glob;
+
+       if (bo->ttm) {
+
+               /**
+                * Release the lru_lock, since we don't want to have
+                * an atomic requirement on ttm_tt[unbind|destroy].
+                */
+
+               spin_unlock(&glob->lru_lock);
+               ttm_tt_unbind(bo->ttm);
+               ttm_tt_destroy(bo->ttm);
+               bo->ttm = NULL;
+               spin_lock(&glob->lru_lock);
+       }
+
+       if (bo->mem.mm_node) {
+               drm_mm_put_block(bo->mem.mm_node);
+               bo->mem.mm_node = NULL;
+       }
+
+       atomic_set(&bo->reserved, 0);
+       wake_up_all(&bo->event_queue);
+       spin_unlock(&glob->lru_lock);
+}
+
+
 /**
  * If bo idle, remove from delayed- and lru lists, and unref.
  * If not idle, and already on delayed list, do nothing.
@@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
        int ret;
 
        spin_lock(&bo->lock);
+retry:
        (void) ttm_bo_wait(bo, false, false, !remove_all);
 
        if (!bo->sync_obj) {
@@ -464,31 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
                spin_unlock(&bo->lock);
 
                spin_lock(&glob->lru_lock);
-               put_count = ttm_bo_del_from_lru(bo);
+               ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0);
+
+               /**
+                * Someone else has the object reserved. Bail and retry.
+                */
 
-               ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
-               BUG_ON(ret);
-               if (bo->ttm)
-                       ttm_tt_unbind(bo->ttm);
+               if (unlikely(ret == -EBUSY)) {
+                       spin_unlock(&glob->lru_lock);
+                       spin_lock(&bo->lock);
+                       goto requeue;
+               }
+
+               /**
+                * We can re-check for sync object without taking
+                * the bo::lock since setting the sync object requires
+                * also bo::reserved. A busy object at this point may
+                * be caused by another thread starting an accelerated
+                * eviction.
+                */
+
+               if (unlikely(bo->sync_obj)) {
+                       atomic_set(&bo->reserved, 0);
+                       wake_up_all(&bo->event_queue);
+                       spin_unlock(&glob->lru_lock);
+                       spin_lock(&bo->lock);
+                       if (remove_all)
+                               goto retry;
+                       else
+                               goto requeue;
+               }
+
+               put_count = ttm_bo_del_from_lru(bo);
 
                if (!list_empty(&bo->ddestroy)) {
                        list_del_init(&bo->ddestroy);
                        ++put_count;
                }
-               if (bo->mem.mm_node) {
-                       drm_mm_put_block(bo->mem.mm_node);
-                       bo->mem.mm_node = NULL;
-               }
-               spin_unlock(&glob->lru_lock);
 
-               atomic_set(&bo->reserved, 0);
+               ttm_bo_cleanup_memtype_use(bo);
 
                while (put_count--)
                        kref_put(&bo->list_kref, ttm_bo_ref_bug);
 
                return 0;
        }
-
+requeue:
        spin_lock(&glob->lru_lock);
        if (list_empty(&bo->ddestroy)) {
                void *sync_obj = bo->sync_obj;
index 7cffb3e0423249ec4f78f7c7cbdc72b6df921e50..3451a82adba76c31672ee96f086146f5da1ab12b 100644 (file)
@@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        INIT_LIST_HEAD(&fbo->lru);
        INIT_LIST_HEAD(&fbo->swap);
        fbo->vm_node = NULL;
+       atomic_set(&fbo->cpu_writers, 0);
 
        fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
        kref_init(&fbo->list_kref);
index ca904799f018a6e3ae23c80933bd1e007aec8f7f..b1e02fffd3ccdebf256d38bb55bed9a37ea1c8d7 100644 (file)
@@ -69,7 +69,7 @@ struct ttm_page_pool {
        spinlock_t              lock;
        bool                    fill_lock;
        struct list_head        list;
-       int                     gfp_flags;
+       gfp_t                   gfp_flags;
        unsigned                npages;
        char                    *name;
        unsigned long           nfrees;
@@ -475,7 +475,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages,
  * This function is reentrant if caller updates count depending on number of
  * pages returned in pages array.
  */
-static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags,
+static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags,
                int ttm_flags, enum ttm_caching_state cstate, unsigned count)
 {
        struct page **caching_array;
@@ -666,7 +666,7 @@ int ttm_get_pages(struct list_head *pages, int flags,
 {
        struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
        struct page *p = NULL;
-       int gfp_flags = GFP_USER;
+       gfp_t gfp_flags = GFP_USER;
        int r;
 
        /* set zero flag for page allocation if required */
@@ -818,7 +818,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
        return 0;
 }
 
-void ttm_page_alloc_fini()
+void ttm_page_alloc_fini(void)
 {
        int i;
 
index 72ec2e2b6e9787196ca1de65f28e4c6a0f090051..a96ed6d9d010b82cfc58ed41ec6240f99d5a9103 100644 (file)
@@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = {
        {0, 0, 0}
 };
 
-static char *vmw_devname = "vmwgfx";
+static int enable_fbdev;
 
 static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
 static void vmw_master_init(struct vmw_master *);
 static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
                              void *ptr);
 
+MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
+module_param_named(enable_fbdev, enable_fbdev, int, 0600);
+
 static void vmw_print_capabilities(uint32_t capabilities)
 {
        DRM_INFO("Capabilities:\n");
@@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv)
 {
        int ret;
 
-       vmw_kms_save_vga(dev_priv);
-
        ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Unable to initialize FIFO.\n");
@@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv)
 static void vmw_release_device(struct vmw_private *dev_priv)
 {
        vmw_fifo_release(dev_priv, &dev_priv->fifo);
-       vmw_kms_restore_vga(dev_priv);
 }
 
+int vmw_3d_resource_inc(struct vmw_private *dev_priv)
+{
+       int ret = 0;
+
+       mutex_lock(&dev_priv->release_mutex);
+       if (unlikely(dev_priv->num_3d_resources++ == 0)) {
+               ret = vmw_request_device(dev_priv);
+               if (unlikely(ret != 0))
+                       --dev_priv->num_3d_resources;
+       }
+       mutex_unlock(&dev_priv->release_mutex);
+       return ret;
+}
+
+
+void vmw_3d_resource_dec(struct vmw_private *dev_priv)
+{
+       int32_t n3d;
+
+       mutex_lock(&dev_priv->release_mutex);
+       if (unlikely(--dev_priv->num_3d_resources == 0))
+               vmw_release_device(dev_priv);
+       n3d = (int32_t) dev_priv->num_3d_resources;
+       mutex_unlock(&dev_priv->release_mutex);
+
+       BUG_ON(n3d < 0);
+}
 
 static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 {
@@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
        dev_priv->last_read_sequence = (uint32_t) -100;
        mutex_init(&dev_priv->hw_mutex);
        mutex_init(&dev_priv->cmdbuf_mutex);
+       mutex_init(&dev_priv->release_mutex);
        rwlock_init(&dev_priv->resource_lock);
        idr_init(&dev_priv->context_idr);
        idr_init(&dev_priv->surface_idr);
@@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
        dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
        dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
 
+       dev_priv->enable_fb = enable_fbdev;
+
        mutex_lock(&dev_priv->hw_mutex);
 
        vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
@@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 
        dev->dev_private = dev_priv;
 
-       if (!dev->devname)
-               dev->devname = vmw_devname;
-
-       if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
-               ret = drm_irq_install(dev);
-               if (unlikely(ret != 0)) {
-                       DRM_ERROR("Failed installing irq: %d\n", ret);
-                       goto out_no_irq;
-               }
-       }
-
        ret = pci_request_regions(dev->pdev, "vmwgfx probe");
        dev_priv->stealth = (ret != 0);
        if (dev_priv->stealth) {
@@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
                        goto out_no_device;
                }
        }
-       ret = vmw_request_device(dev_priv);
+       ret = vmw_kms_init(dev_priv);
        if (unlikely(ret != 0))
-               goto out_no_device;
-       vmw_kms_init(dev_priv);
+               goto out_no_kms;
        vmw_overlay_init(dev_priv);
-       vmw_fb_init(dev_priv);
+       if (dev_priv->enable_fb) {
+               ret = vmw_3d_resource_inc(dev_priv);
+               if (unlikely(ret != 0))
+                       goto out_no_fifo;
+               vmw_kms_save_vga(dev_priv);
+               vmw_fb_init(dev_priv);
+               DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ?
+                        "Detected device 3D availability.\n" :
+                        "Detected no device 3D availability.\n");
+       } else {
+               DRM_INFO("Delayed 3D detection since we're not "
+                        "running the device in SVGA mode yet.\n");
+       }
+
+       if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
+               ret = drm_irq_install(dev);
+               if (unlikely(ret != 0)) {
+                       DRM_ERROR("Failed installing irq: %d\n", ret);
+                       goto out_no_irq;
+               }
+       }
 
        dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
        register_pm_notifier(&dev_priv->pm_nb);
 
-       DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
-
        return 0;
 
-out_no_device:
-       if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
-               drm_irq_uninstall(dev_priv->dev);
-       if (dev->devname == vmw_devname)
-               dev->devname = NULL;
 out_no_irq:
+       if (dev_priv->enable_fb) {
+               vmw_fb_close(dev_priv);
+               vmw_kms_restore_vga(dev_priv);
+               vmw_3d_resource_dec(dev_priv);
+       }
+out_no_fifo:
+       vmw_overlay_close(dev_priv);
+       vmw_kms_close(dev_priv);
+out_no_kms:
+       if (dev_priv->stealth)
+               pci_release_region(dev->pdev, 2);
+       else
+               pci_release_regions(dev->pdev);
+out_no_device:
        ttm_object_device_release(&dev_priv->tdev);
 out_err4:
        iounmap(dev_priv->mmio_virt);
@@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev)
 
        unregister_pm_notifier(&dev_priv->pm_nb);
 
-       vmw_fb_close(dev_priv);
+       if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
+               drm_irq_uninstall(dev_priv->dev);
+       if (dev_priv->enable_fb) {
+               vmw_fb_close(dev_priv);
+               vmw_kms_restore_vga(dev_priv);
+               vmw_3d_resource_dec(dev_priv);
+       }
        vmw_kms_close(dev_priv);
        vmw_overlay_close(dev_priv);
-       vmw_release_device(dev_priv);
        if (dev_priv->stealth)
                pci_release_region(dev->pdev, 2);
        else
                pci_release_regions(dev->pdev);
 
-       if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
-               drm_irq_uninstall(dev_priv->dev);
-       if (dev->devname == vmw_devname)
-               dev->devname = NULL;
        ttm_object_device_release(&dev_priv->tdev);
        iounmap(dev_priv->mmio_virt);
        drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
@@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
                struct drm_ioctl_desc *ioctl =
                    &vmw_ioctls[nr - DRM_COMMAND_BASE];
 
-               if (unlikely(ioctl->cmd != cmd)) {
+               if (unlikely(ioctl->cmd_drv != cmd)) {
                        DRM_ERROR("Invalid command format, ioctl %d\n",
                                  nr - DRM_COMMAND_BASE);
                        return -EINVAL;
@@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev,
        struct vmw_master *vmaster = vmw_master(file_priv->master);
        int ret = 0;
 
+       if (!dev_priv->enable_fb) {
+               ret = vmw_3d_resource_inc(dev_priv);
+               if (unlikely(ret != 0))
+                       return ret;
+               vmw_kms_save_vga(dev_priv);
+               mutex_lock(&dev_priv->hw_mutex);
+               vmw_write(dev_priv, SVGA_REG_TRACES, 0);
+               mutex_unlock(&dev_priv->hw_mutex);
+       }
+
        if (active) {
                BUG_ON(active != &dev_priv->fbdev_master);
                ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
@@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev,
        return 0;
 
 out_no_active_lock:
-       vmw_release_device(dev_priv);
+       if (!dev_priv->enable_fb) {
+               mutex_lock(&dev_priv->hw_mutex);
+               vmw_write(dev_priv, SVGA_REG_TRACES, 1);
+               mutex_unlock(&dev_priv->hw_mutex);
+               vmw_kms_restore_vga(dev_priv);
+               vmw_3d_resource_dec(dev_priv);
+       }
        return ret;
 }
 
@@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev,
 
        ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
 
+       if (!dev_priv->enable_fb) {
+               ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
+               if (unlikely(ret != 0))
+                       DRM_ERROR("Unable to clean VRAM on master drop.\n");
+               mutex_lock(&dev_priv->hw_mutex);
+               vmw_write(dev_priv, SVGA_REG_TRACES, 1);
+               mutex_unlock(&dev_priv->hw_mutex);
+               vmw_kms_restore_vga(dev_priv);
+               vmw_3d_resource_dec(dev_priv);
+       }
+
        dev_priv->active_master = &dev_priv->fbdev_master;
        ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
        ttm_vt_unlock(&dev_priv->fbdev_master.lock);
 
-       vmw_fb_on(dev_priv);
+       if (dev_priv->enable_fb)
+               vmw_fb_on(dev_priv);
 }
 
 
@@ -722,6 +796,7 @@ static struct drm_driver driver = {
        .irq_postinstall = vmw_irq_postinstall,
        .irq_uninstall = vmw_irq_uninstall,
        .irq_handler = vmw_irq_handler,
+       .get_vblank_counter = vmw_get_vblank_counter,
        .reclaim_buffers_locked = NULL,
        .get_map_ofs = drm_core_get_map_ofs,
        .get_reg_ofs = drm_core_get_reg_ofs,
index 429f917b60bf4b30ecdfd0946f9f1f0978bd5c58..58de6393f611dd79fbbebeab81102dcf0f4abfcb 100644 (file)
@@ -277,6 +277,7 @@ struct vmw_private {
 
        bool stealth;
        bool is_opened;
+       bool enable_fb;
 
        /**
         * Master management.
@@ -285,6 +286,9 @@ struct vmw_private {
        struct vmw_master *active_master;
        struct vmw_master fbdev_master;
        struct notifier_block pm_nb;
+
+       struct mutex release_mutex;
+       uint32_t num_3d_resources;
 };
 
 static inline struct vmw_private *vmw_priv(struct drm_device *dev)
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv,
        return val;
 }
 
+int vmw_3d_resource_inc(struct vmw_private *dev_priv);
+void vmw_3d_resource_dec(struct vmw_private *dev_priv);
+
 /**
  * GMR utilities - vmwgfx_gmr.c
  */
@@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv,
                        unsigned bbp, unsigned depth);
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
+u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
 
 /**
  * Overlay control - vmwgfx_overlay.c
index 870967a97c15d52eb3f380323e6038d32ed6e76f..409e172f4abfe94502be96502e251b5d6b2e54c9 100644 (file)
@@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
        if (unlikely(ret != 0))
                goto err_unlock;
 
+       if (bo->mem.mem_type == TTM_PL_VRAM &&
+           bo->mem.mm_node->start < bo->num_pages)
+               (void) ttm_bo_validate(bo, &vmw_sys_placement, false,
+                                      false, false);
+
        ret = ttm_bo_validate(bo, &ne_placement, false, false, false);
 
        /* Could probably bug on */
index e6a1eb7ea95498f00e65d123adeae79160af8fa8..0fe31766e4cf5f11e6025e5a85f96baa5936408f 100644 (file)
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
        mutex_lock(&dev_priv->hw_mutex);
        dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
        dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
+       dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
        vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
 
        min = 4;
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
                  dev_priv->config_done_state);
        vmw_write(dev_priv, SVGA_REG_ENABLE,
                  dev_priv->enable_state);
+       vmw_write(dev_priv, SVGA_REG_TRACES,
+                 dev_priv->traces_state);
 
        mutex_unlock(&dev_priv->hw_mutex);
        vmw_fence_queue_takedown(&fifo->fence_queue);
index 64d7f47df8683ef49cfbb3c83eb449026949af03..e882ba099f0c33dab30f12f7b9328b3b628ac712 100644 (file)
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv)
                save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
                save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
                vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+               if (i == 0 && vmw_priv->num_displays == 1 &&
+                   save->width == 0 && save->height == 0) {
+
+                       /*
+                        * It should be fairly safe to assume that these
+                        * values are uninitialized.
+                        */
+
+                       save->width = vmw_priv->vga_width - save->pos_x;
+                       save->height = vmw_priv->vga_height - save->pos_y;
+               }
        }
+
        return 0;
 }
 
@@ -984,3 +996,8 @@ out_unlock:
        ttm_read_unlock(&vmaster->lock);
        return ret;
 }
+
+u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+       return 0;
+}
index 2ff5cf78235f35379cf409b3ec659774124a0757..11cb39e3accbfa9581801095ab0398952d2313f1 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "vmwgfx_kms.h"
 
+#define VMWGFX_LDU_NUM_DU 8
+
 #define vmw_crtc_to_ldu(x) \
        container_of(x, struct vmw_legacy_display_unit, base.crtc)
 #define vmw_encoder_to_ldu(x) \
@@ -335,7 +337,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
 }
 
 static enum drm_connector_status
-       vmw_ldu_connector_detect(struct drm_connector *connector)
+       vmw_ldu_connector_detect(struct drm_connector *connector,
+                                bool force)
 {
        if (vmw_connector_to_ldu(connector)->pref_active)
                return connector_status_connected;
@@ -516,7 +519,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 
        drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
-       connector->status = vmw_ldu_connector_detect(connector);
+       connector->status = vmw_ldu_connector_detect(connector, true);
 
        drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
                         DRM_MODE_ENCODER_LVDS);
@@ -535,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 
 int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
 {
+       struct drm_device *dev = dev_priv->dev;
+       int i;
+       int ret;
+
        if (dev_priv->ldu_priv) {
                DRM_INFO("ldu system already on\n");
                return -EINVAL;
@@ -552,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
 
        drm_mode_create_dirty_info_property(dev_priv->dev);
 
-       vmw_ldu_init(dev_priv, 0);
-       /* for old hardware without multimon only enable one display */
        if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
-               vmw_ldu_init(dev_priv, 1);
-               vmw_ldu_init(dev_priv, 2);
-               vmw_ldu_init(dev_priv, 3);
-               vmw_ldu_init(dev_priv, 4);
-               vmw_ldu_init(dev_priv, 5);
-               vmw_ldu_init(dev_priv, 6);
-               vmw_ldu_init(dev_priv, 7);
+               for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i)
+                       vmw_ldu_init(dev_priv, i);
+               ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU);
+       } else {
+               /* for old hardware without multimon only enable one display */
+               vmw_ldu_init(dev_priv, 0);
+               ret = drm_vblank_init(dev, 1);
        }
 
-       return 0;
+       return ret;
 }
 
 int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
 {
+       struct drm_device *dev = dev_priv->dev;
+
+       drm_vblank_cleanup(dev);
        if (!dev_priv->ldu_priv)
                return -ENOSYS;
 
@@ -610,7 +618,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
                        ldu->pref_height = 600;
                        ldu->pref_active = false;
                }
-               con->status = vmw_ldu_connector_detect(con);
+               con->status = vmw_ldu_connector_detect(con, true);
        }
 
        mutex_unlock(&dev->mode_config.mutex);
index 5f2d5df01e5c370acbc1be99772701626419daf5..c8c40e9979dbd21442a5d87cf6ac4cdcad08cfad 100644 (file)
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
        cmd->body.cid = cpu_to_le32(res->id);
 
        vmw_fifo_commit(dev_priv, sizeof(*cmd));
+       vmw_3d_resource_dec(dev_priv);
 }
 
 static int vmw_context_init(struct vmw_private *dev_priv,
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv,
        cmd->body.cid = cpu_to_le32(res->id);
 
        vmw_fifo_commit(dev_priv, sizeof(*cmd));
+       (void) vmw_3d_resource_inc(dev_priv);
        vmw_resource_activate(res, vmw_hw_context_destroy);
        return 0;
 }
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
        cmd->body.sid = cpu_to_le32(res->id);
 
        vmw_fifo_commit(dev_priv, sizeof(*cmd));
+       vmw_3d_resource_dec(dev_priv);
 }
 
 void vmw_surface_res_free(struct vmw_resource *res)
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv,
        }
 
        vmw_fifo_commit(dev_priv, submit_size);
+       (void) vmw_3d_resource_inc(dev_priv);
        vmw_resource_activate(res, vmw_hw_surface_destroy);
        return 0;
 }
index b87569e96b163c04fb35790ef8c457999480e3f3..f366f968155a3ed913ce770a60ca30cbf2f97981 100644 (file)
@@ -598,7 +598,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
        pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count);
 }
 
-void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
+static void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
 {
        struct vga_device *vgadev;
        unsigned long flags;
index 0c52899be9643d85af5c7ac6be8c87bc67d6e6ce..3f7292486024b8feace0b72775c03a2ae122e8fc 100644 (file)
@@ -1285,8 +1285,11 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
@@ -1578,7 +1581,6 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) },
        { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)},
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)},
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)},
        { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
index 85c6d13c9ffa9369fca613eda828133b2b69a3e2..765a4f53eb5cb663fd319d0a71386ae1a9ee0fa5 100644 (file)
 
 #define USB_VENDOR_ID_ASUS             0x0486
 #define USB_DEVICE_ID_ASUS_T91MT       0x0185
+#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO   0x0186
 
 #define USB_VENDOR_ID_ASUSTEK          0x0b05
 #define USB_DEVICE_ID_ASUSTEK_LCM      0x1726
 
 #define USB_VENDOR_ID_BTC              0x046e
 #define USB_DEVICE_ID_BTC_EMPREX_REMOTE        0x5578
+#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2      0x5577
 
 #define USB_VENDOR_ID_CANDO            0x2087
 #define USB_DEVICE_ID_CANDO_MULTI_TOUCH        0x0a01
 
 #define USB_VENDOR_ID_CHICONY          0x04f2
 #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD     0x0418
+#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH      0xb19d
 
 #define USB_VENDOR_ID_CIDC             0x1677
 
 #define USB_VENDOR_ID_UCLOGIC          0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209    0x0042
 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U   0x0003
+#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5      0x6001
 
 #define USB_VENDOR_ID_VERNIER          0x08f7
 #define USB_DEVICE_ID_VERNIER_LABPRO   0x0001
index e91437c189061cf7c862a74b3b6054f369528af7..ac5421d568f151cd6937f33244740d9f9759fedb 100644 (file)
@@ -239,6 +239,7 @@ static void mosart_remove(struct hid_device *hdev)
 
 static const struct hid_device_id mosart_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, mosart_devices);
index 5771f851f85693a46bd581085e25e09775fbcae5..956ed9ac19d4dee7fc3b259b1453662ec0bd8146 100644 (file)
@@ -64,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 static const struct hid_device_id ts_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
        { }
 };
index b729c02866798c00ae4d2c77eadba097a79d7f73..599041a7f670a9f105e00da3272d79642aefb78c 100644 (file)
@@ -828,6 +828,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
                }
        } else {
                int skipped_report_id = 0;
+               int report_id = buf[0];
                if (buf[0] == 0x0) {
                        /* Don't send the Report ID */
                        buf++;
@@ -837,7 +838,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
                ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                        HID_REQ_SET_REPORT,
                        USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-                       ((report_type + 1) << 8) | *buf,
+                       ((report_type + 1) << 8) | report_id,
                        interface->desc.bInterfaceNumber, buf, count,
                        USB_CTRL_SET_TIMEOUT);
                /* count also the report id, if this was a numbered report. */
@@ -1445,6 +1446,11 @@ static const struct hid_device_id hid_usb_table[] = {
        { }
 };
 
+struct usb_interface *usbhid_find_interface(int minor)
+{
+       return usb_find_interface(&hid_driver, minor);
+}
+
 static struct hid_driver hid_usb_driver = {
        .name = "generic-usb",
        .id_table = hid_usb_table,
index 2643d31476213cd41f5d1b39042e83d5a70a63a4..70da3181c8a0467663c15abd324dd6fbe801ea51 100644 (file)
@@ -33,6 +33,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+       { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
        { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -69,6 +70,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
@@ -77,6 +79,8 @@ static const struct hid_blacklist {
 
        { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
 
+       { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
+
        { 0, 0 }
 };
 
index 0a29c51114aaf0d36c64f6c8c25195db5e2f3747..681e620eb95b166ed43ac48c082960ba0f39e211 100644 (file)
@@ -270,7 +270,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
        struct hiddev *hiddev;
        int res;
 
-       intf = usb_find_interface(&hiddev_driver, iminor(inode));
+       intf = usbhid_find_interface(iminor(inode));
        if (!intf)
                return -ENODEV;
        hid = usb_get_intfdata(intf);
index 693fd3e720df41c8ded8ccf15f9575648de77c96..89d2e847dcc671b65f15484b3df34f6c4a6c288d 100644 (file)
@@ -42,6 +42,7 @@ void usbhid_submit_report
 (struct hid_device *hid, struct hid_report *report, unsigned char dir);
 int usbhid_get_power(struct hid_device *hid);
 void usbhid_put_power(struct hid_device *hid);
+struct usb_interface *usbhid_find_interface(int minor);
 
 /* iofl flags */
 #define HID_CTRL_RUNNING       1
index 4d4d09bdec0a7a7cb043725b2fb94dc1fff23dc7..97499d00615aacbddcf5963bcfa08b5f4733a1bb 100644 (file)
@@ -409,7 +409,7 @@ config SENSORS_CORETEMP
 
 config SENSORS_PKGTEMP
        tristate "Intel processor package temperature sensor"
-       depends on X86 && PCI && EXPERIMENTAL
+       depends on X86 && EXPERIMENTAL
        help
          If you say yes here you get support for the package level temperature
          sensor inside your CPU. Check documentation/driver for details.
index 15c1a9616af33ba13ae8a79823cb7d30729c42fe..0683e6be662cfe28e803cac2b6ddd6501f06ef29 100644 (file)
@@ -79,7 +79,7 @@ struct adm1031_data {
        int chip_type;
        char valid;             /* !=0 if following fields are valid */
        unsigned long last_updated;     /* In jiffies */
-       unsigned int update_rate;       /* In milliseconds */
+       unsigned int update_interval;   /* In milliseconds */
        /* The chan_select_table contains the possible configurations for
         * auto fan control.
         */
@@ -743,23 +743,23 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12);
 static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13);
 static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14);
 
-/* Update Rate */
-static const unsigned int update_rates[] = {
+/* Update Interval */
+static const unsigned int update_intervals[] = {
        16000, 8000, 4000, 2000, 1000, 500, 250, 125,
 };
 
-static ssize_t show_update_rate(struct device *dev,
-                               struct device_attribute *attr, char *buf)
+static ssize_t show_update_interval(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct adm1031_data *data = i2c_get_clientdata(client);
 
-       return sprintf(buf, "%u\n", data->update_rate);
+       return sprintf(buf, "%u\n", data->update_interval);
 }
 
-static ssize_t set_update_rate(struct device *dev,
-                              struct device_attribute *attr,
-                              const char *buf, size_t count)
+static ssize_t set_update_interval(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct adm1031_data *data = i2c_get_clientdata(client);
@@ -771,12 +771,15 @@ static ssize_t set_update_rate(struct device *dev,
        if (err)
                return err;
 
-       /* find the nearest update rate from the table */
-       for (i = 0; i < ARRAY_SIZE(update_rates) - 1; i++) {
-               if (val >= update_rates[i])
+       /*
+        * Find the nearest update interval from the table.
+        * Use it to determine the matching update rate.
+        */
+       for (i = 0; i < ARRAY_SIZE(update_intervals) - 1; i++) {
+               if (val >= update_intervals[i])
                        break;
        }
-       /* if not found, we point to the last entry (lowest update rate) */
+       /* if not found, we point to the last entry (lowest update interval) */
 
        /* set the new update rate while preserving other settings */
        reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
@@ -785,14 +788,14 @@ static ssize_t set_update_rate(struct device *dev,
        adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg);
 
        mutex_lock(&data->update_lock);
-       data->update_rate = update_rates[i];
+       data->update_interval = update_intervals[i];
        mutex_unlock(&data->update_lock);
 
        return count;
 }
 
-static DEVICE_ATTR(update_rate, S_IRUGO | S_IWUSR, show_update_rate,
-                  set_update_rate);
+static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval,
+                  set_update_interval);
 
 static struct attribute *adm1031_attributes[] = {
        &sensor_dev_attr_fan1_input.dev_attr.attr,
@@ -830,7 +833,7 @@ static struct attribute *adm1031_attributes[] = {
 
        &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr,
 
-       &dev_attr_update_rate.attr,
+       &dev_attr_update_interval.attr,
        &dev_attr_alarms.attr,
 
        NULL
@@ -981,7 +984,8 @@ static void adm1031_init_client(struct i2c_client *client)
        mask = ADM1031_UPDATE_RATE_MASK;
        read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
        i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT;
-       data->update_rate = update_rates[i];
+       /* Save it as update interval */
+       data->update_interval = update_intervals[i];
 }
 
 static struct adm1031_data *adm1031_update_device(struct device *dev)
@@ -993,7 +997,8 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
 
        mutex_lock(&data->update_lock);
 
-       next_update = data->last_updated + msecs_to_jiffies(data->update_rate);
+       next_update = data->last_updated
+         + msecs_to_jiffies(data->update_interval);
        if (time_after(jiffies, next_update) || !data->valid) {
 
                dev_dbg(&client->dev, "Starting adm1031 update\n");
index de8111114f469ec21567a5781349bb0d7f7cbc98..a23b17a78ace8f42cb114b30f593b9019a24a982 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/smp.h>
 
 #define DRVNAME        "coretemp"
 
@@ -423,9 +424,18 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
        int err;
        struct platform_device *pdev;
        struct pdev_entry *pdev_entry;
-#ifdef CONFIG_SMP
        struct cpuinfo_x86 *c = &cpu_data(cpu);
-#endif
+
+       /*
+        * CPUID.06H.EAX[0] indicates whether the CPU has thermal
+        * sensors. We check this bit only, all the early CPUs
+        * without thermal sensors will be filtered out.
+        */
+       if (!cpu_has(c, X86_FEATURE_DTS)) {
+               printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
+                      " has no thermal sensor.\n", c->x86_model);
+               return 0;
+       }
 
        mutex_lock(&pdev_list_mutex);
 
@@ -482,14 +492,22 @@ exit:
 
 static void coretemp_device_remove(unsigned int cpu)
 {
-       struct pdev_entry *p, *n;
+       struct pdev_entry *p;
+       unsigned int i;
+
        mutex_lock(&pdev_list_mutex);
-       list_for_each_entry_safe(p, n, &pdev_list, list) {
-               if (p->cpu == cpu) {
-                       platform_device_unregister(p->pdev);
-                       list_del(&p->list);
-                       kfree(p);
-               }
+       list_for_each_entry(p, &pdev_list, list) {
+               if (p->cpu != cpu)
+                       continue;
+
+               platform_device_unregister(p->pdev);
+               list_del(&p->list);
+               mutex_unlock(&pdev_list_mutex);
+               kfree(p);
+               for_each_cpu(i, cpu_sibling_mask(cpu))
+                       if (i != cpu && !coretemp_device_add(i))
+                               break;
+               return;
        }
        mutex_unlock(&pdev_list_mutex);
 }
@@ -527,30 +545,21 @@ static int __init coretemp_init(void)
        if (err)
                goto exit;
 
-       for_each_online_cpu(i) {
-               struct cpuinfo_x86 *c = &cpu_data(i);
-               /*
-                * CPUID.06H.EAX[0] indicates whether the CPU has thermal
-                * sensors. We check this bit only, all the early CPUs
-                * without thermal sensors will be filtered out.
-                */
-               if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01))
-                       coretemp_device_add(i);
-               else {
-                       printk(KERN_INFO DRVNAME ": CPU (model=0x%x)"
-                               " has no thermal sensor.\n", c->x86_model);
-               }
-       }
+       for_each_online_cpu(i)
+               coretemp_device_add(i);
+
+#ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
                err = -ENODEV;
                goto exit_driver_unreg;
        }
+#endif
 
        register_hotcpu_notifier(&coretemp_cpu_notifier);
        return 0;
 
-exit_driver_unreg:
 #ifndef CONFIG_HOTPLUG_CPU
+exit_driver_unreg:
        platform_driver_unregister(&coretemp_driver);
 #endif
 exit:
index 5b58b20dead1fa92b79af5c05036d45de8bf88ca..8dee3f38fdfb27e1c80a9fb36add60e414aeb805 100644 (file)
@@ -308,7 +308,6 @@ static int emc1403_probe(struct i2c_client *client,
        res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr);
        if (res) {
                dev_warn(&client->dev, "create group failed\n");
-               hwmon_device_unregister(data->hwmon_dev);
                goto thermal_error1;
        }
        data->hwmon_dev = hwmon_device_register(&client->dev);
index 537841ef44b99d179318f7510dbf28dddedb0ed8..75afb3b0e0763c184a1b22cdc163ef32d10d2969 100644 (file)
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg)
        return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+       /* Don't step on other drivers' I/O space by accident */
+       if (!request_muxed_region(base, 2, DRVNAME)) {
+               printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+                               base);
+               return -EBUSY;
+       }
+
        /* according to the datasheet the key must be send twice! */
        outb(SIO_UNLOCK_KEY, base);
        outb(SIO_UNLOCK_KEY, base);
+
+       return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
        outb(SIO_LOCK_KEY, base);
+       release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
        struct f71882fg_sio_data *sio_data)
 {
-       int err = -ENODEV;
        u16 devid;
-
-       /* Don't step on other drivers' I/O space by accident */
-       if (!request_region(sioaddr, 2, DRVNAME)) {
-               printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-                               (int)sioaddr);
-               return -EBUSY;
-       }
-
-       superio_enter(sioaddr);
+       int err = superio_enter(sioaddr);
+       if (err)
+               return err;
 
        devid = superio_inw(sioaddr, SIO_REG_MANID);
        if (devid != SIO_FINTEK_ID) {
                pr_debug(DRVNAME ": Not a Fintek device\n");
+               err = -ENODEV;
                goto exit;
        }
 
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
        default:
                printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
                       (unsigned int)devid);
+               err = -ENODEV;
                goto exit;
        }
 
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
        if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
                printk(KERN_WARNING DRVNAME ": Device not activated\n");
+               err = -ENODEV;
                goto exit;
        }
 
        *address = superio_inw(sioaddr, SIO_REG_ADDR);
        if (*address == 0) {
                printk(KERN_WARNING DRVNAME ": Base address not set\n");
+               err = -ENODEV;
                goto exit;
        }
        *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
                (int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
        superio_exit(sioaddr);
-       release_region(sioaddr, 2);
        return err;
 }
 
index 0f58ecc5334d941cb4114a3681e2e5a44893280e..9638d58f99fdb0e56f15832f824dc6096d99d3ea 100644 (file)
@@ -79,7 +79,7 @@ enum chips { f75373, f75375 };
 #define F75375_REG_PWM2_DROP_DUTY      0x6C
 
 #define FAN_CTRL_LINEAR(nr)            (4 + nr)
-#define FAN_CTRL_MODE(nr)              (5 + ((nr) * 2))
+#define FAN_CTRL_MODE(nr)              (4 + ((nr) * 2))
 
 /*
  * Data structures and manipulation thereof
@@ -298,7 +298,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
                return -EINVAL;
 
        fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
-       fanmode = ~(3 << FAN_CTRL_MODE(nr));
+       fanmode &= ~(3 << FAN_CTRL_MODE(nr));
 
        switch (val) {
        case 0: /* Full speed */
@@ -350,7 +350,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
 
        mutex_lock(&data->update_lock);
        conf = f75375_read8(client, F75375_REG_CONFIG1);
-       conf = ~(1 << FAN_CTRL_LINEAR(nr));
+       conf &= ~(1 << FAN_CTRL_LINEAR(nr));
 
        if (val == 0)
                conf |= (1 << FAN_CTRL_LINEAR(nr)) ;
index 6138f036b159956dbc4eec8282636db794485527..fc591ae53107da8481a2ab5e02f53117ac6e2471 100644 (file)
@@ -277,7 +277,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
        wake_up_interruptible(&lis3_dev.misc_wait);
        kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
 out:
-       if (lis3_dev.whoami == WAI_8B && lis3_dev.idev &&
+       if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev &&
            lis3_dev.idev->input->users)
                return IRQ_WAKE_THREAD;
        return IRQ_HANDLED;
@@ -718,7 +718,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
         * io-apic is not configurable (and generates a warning) but I keep it
         * in case of support for other hardware.
         */
-       if (dev->whoami == WAI_8B)
+       if (dev->pdata && dev->whoami == WAI_8B)
                thread_fn = lis302dl_interrupt_thread1_8b;
        else
                thread_fn = NULL;
index dc1f5402c1d7ddcdaf4396fe177a689550b9ac2b..8e5933b72d1956c2a931ea7176b1c589e3066968 100644 (file)
@@ -121,7 +121,7 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
 {
        struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
-       if (!lis3->pdata->wakeup_flags)
+       if (!lis3->pdata || !lis3->pdata->wakeup_flags)
                lis3lv02d_poweroff(lis3);
        return 0;
 }
@@ -130,7 +130,7 @@ static int lis3lv02d_i2c_resume(struct i2c_client *client)
 {
        struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
-       if (!lis3->pdata->wakeup_flags)
+       if (!lis3->pdata || !lis3->pdata->wakeup_flags)
                lis3lv02d_poweron(lis3);
        return 0;
 }
index 82b16808a274c1e0045692fcfc32dcfdb641ec31..b9be5e3a22b3825bc640d9c038c8c724e888c5b4 100644 (file)
@@ -92,7 +92,7 @@ static int lis3lv02d_spi_suspend(struct spi_device *spi, pm_message_t mesg)
 {
        struct lis3lv02d *lis3 = spi_get_drvdata(spi);
 
-       if (!lis3->pdata->wakeup_flags)
+       if (!lis3->pdata || !lis3->pdata->wakeup_flags)
                lis3lv02d_poweroff(&lis3_dev);
 
        return 0;
@@ -102,7 +102,7 @@ static int lis3lv02d_spi_resume(struct spi_device *spi)
 {
        struct lis3lv02d *lis3 = spi_get_drvdata(spi);
 
-       if (!lis3->pdata->wakeup_flags)
+       if (!lis3->pdata || !lis3->pdata->wakeup_flags)
                lis3lv02d_poweron(lis3);
 
        return 0;
index 94741d42112da02ca902b2e87beacbe96aab3cd3..464340f25496402dd15a69e2d59281544e267c37 100644 (file)
@@ -91,7 +91,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev);
 struct lm95241_data {
        struct device *hwmon_dev;
        struct mutex update_lock;
-       unsigned long last_updated, rate; /* in jiffies */
+       unsigned long last_updated, interval; /* in jiffies */
        char valid; /* zero until following fields are valid */
        /* registers values */
        u8 local_h, local_l; /* local */
@@ -114,23 +114,23 @@ show_temp(local);
 show_temp(remote1);
 show_temp(remote2);
 
-static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
+static ssize_t show_interval(struct device *dev, struct device_attribute *attr,
                         char *buf)
 {
        struct lm95241_data *data = lm95241_update_device(dev);
 
-       snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
+       snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval / HZ);
        return strlen(buf);
 }
 
-static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
+static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct lm95241_data *data = i2c_get_clientdata(client);
 
-       strict_strtol(buf, 10, &data->rate);
-       data->rate = data->rate * HZ / 1000;
+       strict_strtol(buf, 10, &data->interval);
+       data->interval = data->interval * HZ / 1000;
 
        return count;
 }
@@ -286,7 +286,8 @@ static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
 static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
 static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
 static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
-static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
+static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval,
+                  set_interval);
 
 static struct attribute *lm95241_attributes[] = {
        &dev_attr_temp1_input.attr,
@@ -298,7 +299,7 @@ static struct attribute *lm95241_attributes[] = {
        &dev_attr_temp3_min.attr,
        &dev_attr_temp2_max.attr,
        &dev_attr_temp3_max.attr,
-       &dev_attr_rate.attr,
+       &dev_attr_update_interval.attr,
        NULL
 };
 
@@ -376,7 +377,7 @@ static void lm95241_init_client(struct i2c_client *client)
 {
        struct lm95241_data *data = i2c_get_clientdata(client);
 
-       data->rate = HZ;    /* 1 sec default */
+       data->interval = HZ;    /* 1 sec default */
        data->valid = 0;
        data->config = CFG_CR0076;
        data->model = 0;
@@ -410,7 +411,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev)
 
        mutex_lock(&data->update_lock);
 
-       if (time_after(jiffies, data->last_updated + data->rate) ||
+       if (time_after(jiffies, data->last_updated + data->interval) ||
            !data->valid) {
                dev_dbg(&client->dev, "Updating lm95241 data.\n");
                data->local_h =
index 74157fcda6edf4bc569469db4ae1de9efa5b882d..f11903936c8b3a51c3f8dddcb20318185952fa79 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/cpu.h>
-#include <linux/pci.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
 
@@ -224,7 +223,7 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev)
 
        err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group);
        if (err)
-               goto exit_free;
+               goto exit_dev;
 
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -238,6 +237,8 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev)
 
 exit_class:
        sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+exit_dev:
+       device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
 exit_free:
        kfree(data);
 exit:
@@ -250,6 +251,7 @@ static int __devexit pkgtemp_remove(struct platform_device *pdev)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
+       device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
        platform_set_drvdata(pdev, NULL);
        kfree(data);
        return 0;
@@ -281,9 +283,10 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu)
        int err;
        struct platform_device *pdev;
        struct pdev_entry *pdev_entry;
-#ifdef CONFIG_SMP
        struct cpuinfo_x86 *c = &cpu_data(cpu);
-#endif
+
+       if (!cpu_has(c, X86_FEATURE_PTS))
+               return 0;
 
        mutex_lock(&pdev_list_mutex);
 
@@ -339,17 +342,18 @@ exit:
 #ifdef CONFIG_HOTPLUG_CPU
 static void pkgtemp_device_remove(unsigned int cpu)
 {
-       struct pdev_entry *p, *n;
+       struct pdev_entry *p;
        unsigned int i;
        int err;
 
        mutex_lock(&pdev_list_mutex);
-       list_for_each_entry_safe(p, n, &pdev_list, list) {
+       list_for_each_entry(p, &pdev_list, list) {
                if (p->cpu != cpu)
                        continue;
 
                platform_device_unregister(p->pdev);
                list_del(&p->list);
+               mutex_unlock(&pdev_list_mutex);
                kfree(p);
                for_each_cpu(i, cpu_core_mask(cpu)) {
                        if (i != cpu) {
@@ -358,7 +362,7 @@ static void pkgtemp_device_remove(unsigned int cpu)
                                        break;
                        }
                }
-               break;
+               return;
        }
        mutex_unlock(&pdev_list_mutex);
 }
@@ -399,11 +403,6 @@ static int __init pkgtemp_init(void)
                goto exit;
 
        for_each_online_cpu(i) {
-               struct cpuinfo_x86 *c = &cpu_data(i);
-
-               if (!cpu_has(c, X86_FEATURE_PTS))
-                       continue;
-
                err = pkgtemp_device_add(i);
                if (err)
                        goto exit_devices_unreg;
index e96e69dd36fb4b4faba43ffad13b53815d06bc65..072c58008a633b713e1f68fd3a522572a41842d1 100644 (file)
@@ -127,6 +127,7 @@ superio_enter(int ioreg)
 static inline void
 superio_exit(int ioreg)
 {
+       outb(0xaa, ioreg);
        outb(0x02, ioreg);
        outb(0x02, ioreg + 1);
 }
index f7bd2613ceccbc69e4d04b69432fdc40638b2555..f2de3be35df36265cdfca5d899097b161ef10171 100644 (file)
@@ -677,6 +677,11 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev,
        dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
                cpm->adap.name);
 
+       /*
+        * register OF I2C devices
+        */
+       of_i2c_register_devices(&cpm->adap);
+
        return 0;
 out_shut:
        cpm_i2c_shutdown(cpm);
index 2222c87876b97bc711b6d739fd4a82deef7db330..b8feac5f2ef4f6f4be4d410ec7a5a2ce2a6d4946 100644 (file)
@@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 
        dev->terminate = 0;
 
-       /* write the data into mode register */
-       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
        /*
         * First byte should be set here, not after interrupt,
         * because transmit-data-ready interrupt can come before
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
                dev->buf_len--;
        }
 
+       /* write the data into mode register; start transmitting */
+       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
        r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
                                                      dev->adapter.timeout);
        if (r == 0) {
index 43ca32fddde2b77309c92533f9c2c50e44719879..89eedf45d30ed877e6abbc76c66507372c4a3f83 100644 (file)
@@ -761,6 +761,9 @@ static int __devinit iic_probe(struct platform_device *ofdev,
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
+       /* Now register all the child nodes */
+       of_i2c_register_devices(adap);
+
        return 0;
 
 error_cleanup:
index a1c419a716af8d24f4a84a680cc93123b6c8bff9..b74e6dc6886c71ed5ebe3e02f219a68f8f0a2df8 100644 (file)
@@ -632,6 +632,7 @@ static int __devinit fsl_i2c_probe(struct platform_device *op,
                dev_err(i2c->dev, "failed to add adapter\n");
                goto fail_add;
        }
+       of_i2c_register_devices(&i2c->adap);
 
        return result;
 
index 0e9f85d0a835718dac97ecd52ff270f327d84136..56dbe54e88118a3fb7b112da16e11ccd5bdbc9fb 100644 (file)
@@ -218,7 +218,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)
                return result;
        } else if (result == 0) {
                dev_dbg(i2c->dev, "%s: timeout\n", __func__);
-               result = -ETIMEDOUT;
+               return -ETIMEDOUT;
        }
 
        return 0;
index 7674efb553786e4e2a639c5a5b263362564b626b..b33c78586bfccf815d9322df1d561b7bec5797b5 100644 (file)
@@ -680,6 +680,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
        if (r == 0)
                r = num;
+
+       omap_i2c_wait_for_bb(dev);
 out:
        omap_i2c_idle(dev);
        return r;
index bbd77603a4173b8f29aa1353ef1e47376c594196..29933f87d8fa8fdc31ffdd38c4ff905fddd7774d 100644 (file)
@@ -71,8 +71,8 @@ static int pca_isa_readbyte(void *pd, int reg)
 
 static int pca_isa_waitforcompletion(void *pd)
 {
-       long ret = ~0;
        unsigned long timeout;
+       long ret;
 
        if (irq > -1) {
                ret = wait_event_timeout(pca_wait,
@@ -81,11 +81,15 @@ static int pca_isa_waitforcompletion(void *pd)
        } else {
                /* Do polling */
                timeout = jiffies + pca_isa_ops.timeout;
-               while (((pca_isa_readbyte(pd, I2C_PCA_CON)
-                               & I2C_PCA_CON_SI) == 0)
-                               && (ret = time_before(jiffies, timeout)))
+               do {
+                       ret = time_before(jiffies, timeout);
+                       if (pca_isa_readbyte(pd, I2C_PCA_CON)
+                                       & I2C_PCA_CON_SI)
+                               break;
                        udelay(100);
+               } while (ret);
        }
+
        return ret > 0;
 }
 
index ef5c78487eb779c36fd5b98f3fd8d0727c34494e..5f6d7f89e2252d1a4806a3be9e6368c212ceed48 100644 (file)
@@ -80,8 +80,8 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
 static int i2c_pca_pf_waitforcompletion(void *pd)
 {
        struct i2c_pca_pf_data *i2c = pd;
-       long ret = ~0;
        unsigned long timeout;
+       long ret;
 
        if (i2c->irq) {
                ret = wait_event_timeout(i2c->wait,
@@ -90,10 +90,13 @@ static int i2c_pca_pf_waitforcompletion(void *pd)
        } else {
                /* Do polling */
                timeout = jiffies + i2c->adap.timeout;
-               while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
-                               & I2C_PCA_CON_SI) == 0)
-                               && (ret = time_before(jiffies, timeout)))
+               do {
+                       ret = time_before(jiffies, timeout);
+                       if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+                                       & I2C_PCA_CON_SI)
+                               break;
                        udelay(100);
+               } while (ret);
        }
 
        return ret > 0;
index 72902e0bbfa79a48caaf2193420d4b8712af1e18..bf831bf8158741a9f857eb541afc1f3a48d38e52 100644 (file)
@@ -662,8 +662,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
                unsigned long sda_delay;
 
                if (pdata->sda_delay) {
-                       sda_delay = (freq / 1000) * pdata->sda_delay;
-                       sda_delay /= 1000000;
+                       sda_delay = clkin * pdata->sda_delay;
+                       sda_delay = DIV_ROUND_UP(sda_delay, 1000000);
                        sda_delay = DIV_ROUND_UP(sda_delay, 5);
                        if (sda_delay > 3)
                                sda_delay = 3;
index 6649176de940572a317b2744bd1d4e393c4bbd04..bea4c5021d26cb5b4c92e9b58cabeda2b882023c 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
@@ -197,11 +196,12 @@ static int i2c_device_pm_suspend(struct device *dev)
 {
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-       if (pm_runtime_suspended(dev))
-               return 0;
-
-       if (pm)
-               return pm->suspend ? pm->suspend(dev) : 0;
+       if (pm) {
+               if (pm_runtime_suspended(dev))
+                       return 0;
+               else
+                       return pm->suspend ? pm->suspend(dev) : 0;
+       }
 
        return i2c_legacy_suspend(dev, PMSG_SUSPEND);
 }
@@ -216,12 +216,6 @@ static int i2c_device_pm_resume(struct device *dev)
        else
                ret = i2c_legacy_resume(dev);
 
-       if (!ret) {
-               pm_runtime_disable(dev);
-               pm_runtime_set_active(dev);
-               pm_runtime_enable(dev);
-       }
-
        return ret;
 }
 
@@ -229,11 +223,12 @@ static int i2c_device_pm_freeze(struct device *dev)
 {
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-       if (pm_runtime_suspended(dev))
-               return 0;
-
-       if (pm)
-               return pm->freeze ? pm->freeze(dev) : 0;
+       if (pm) {
+               if (pm_runtime_suspended(dev))
+                       return 0;
+               else
+                       return pm->freeze ? pm->freeze(dev) : 0;
+       }
 
        return i2c_legacy_suspend(dev, PMSG_FREEZE);
 }
@@ -242,11 +237,12 @@ static int i2c_device_pm_thaw(struct device *dev)
 {
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-       if (pm_runtime_suspended(dev))
-               return 0;
-
-       if (pm)
-               return pm->thaw ? pm->thaw(dev) : 0;
+       if (pm) {
+               if (pm_runtime_suspended(dev))
+                       return 0;
+               else
+                       return pm->thaw ? pm->thaw(dev) : 0;
+       }
 
        return i2c_legacy_resume(dev);
 }
@@ -255,11 +251,12 @@ static int i2c_device_pm_poweroff(struct device *dev)
 {
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-       if (pm_runtime_suspended(dev))
-               return 0;
-
-       if (pm)
-               return pm->poweroff ? pm->poweroff(dev) : 0;
+       if (pm) {
+               if (pm_runtime_suspended(dev))
+                       return 0;
+               else
+                       return pm->poweroff ? pm->poweroff(dev) : 0;
+       }
 
        return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
 }
@@ -876,9 +873,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
 
-       /* Register devices from the device tree */
-       of_i2c_register_devices(adap);
-
        /* Notify drivers */
        mutex_lock(&core_lock);
        bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
index 4c3d1bfec0c5b450fbbe68014e1c15fe9e29c454..068cef0a987aa672566d986eb7353670d533fdd6 100644 (file)
@@ -1444,14 +1444,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        ide_acpi_port_init_devices(hwif);
        }
 
-       ide_host_for_each_port(i, hwif, host) {
-               if (hwif == NULL)
-                       continue;
-
-               if (hwif->present)
-                       hwif_register_devices(hwif);
-       }
-
        ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
@@ -1459,8 +1451,10 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                ide_sysfs_register_port(hwif);
                ide_proc_register_port(hwif);
 
-               if (hwif->present)
+               if (hwif->present) {
                        ide_proc_port_register_devices(hwif);
+                       hwif_register_devices(hwif);
+               }
        }
 
        return j ? 0 : -1;
old mode 100755 (executable)
new mode 100644 (file)
index a10152b..c37ef64
@@ -83,7 +83,7 @@ static unsigned int mwait_substates;
 /* Reliable LAPIC Timer States, bit 1 for C1 etc.  */
 static unsigned int lapic_timer_reliable_states;
 
-static struct cpuidle_device *intel_idle_cpuidle_devices;
+static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
 static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
 
 static struct cpuidle_state *cpuidle_state_table;
@@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
                .name = "NHM-C3",
                .desc = "MWAIT 0x10",
                .driver_data = (void *) 0x10,
-               .flags = CPUIDLE_FLAG_TIME_VALID,
+               .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 20,
                .power_usage = 500,
                .target_residency = 80,
@@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
                .name = "NHM-C6",
                .desc = "MWAIT 0x20",
                .driver_data = (void *) 0x20,
-               .flags = CPUIDLE_FLAG_TIME_VALID,
+               .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 200,
                .power_usage = 350,
                .target_residency = 800,
@@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
                .name = "ATM-C4",
                .desc = "MWAIT 0x30",
                .driver_data = (void *) 0x30,
-               .flags = CPUIDLE_FLAG_TIME_VALID,
+               .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 100,
                .power_usage = 250,
                .target_residency = 400,
@@ -157,13 +157,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C5 */ },
        { /* MWAIT C6 */
                .name = "ATM-C6",
-               .desc = "MWAIT 0x40",
-               .driver_data = (void *) 0x40,
-               .flags = CPUIDLE_FLAG_TIME_VALID,
-               .exit_latency = 200,
+               .desc = "MWAIT 0x52",
+               .driver_data = (void *) 0x52,
+               .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
+               .exit_latency = 140,
                .power_usage = 150,
-               .target_residency = 800,
-               .enter = NULL },        /* disabled */
+               .target_residency = 560,
+               .enter = &intel_idle },
 };
 
 /**
@@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
 
        local_irq_disable();
 
+       /*
+        * If the state flag indicates that the TLB will be flushed or if this
+        * is the deepest c-state supported, do a voluntary leave mm to avoid
+        * costly and mostly unnecessary wakeups for flushing the user TLB's
+        * associated with the active mm.
+        */
+       if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED ||
+           (&dev->states[dev->state_count - 1] == state))
+               leave_mm(cpu);
+
        if (!(lapic_timer_reliable_states & (1 << (cstate))))
                clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 
index d88077a219944ec49e2f594de780d0f216f9201f..13c88871dc3b90f564a52b4651aa371a4cd15633 100644 (file)
@@ -463,7 +463,8 @@ static int send_connect(struct iwch_ep *ep)
            V_MSS_IDX(mtu_idx) |
            V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx);
        opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10);
-       opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor);
+       opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) |
+              V_CONG_CONTROL_FLAVOR(cong_flavor);
        skb->priority = CPL_PRIORITY_SETUP;
        set_arp_failure_handler(skb, act_open_req_arp_failure);
 
@@ -1280,7 +1281,8 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb)
            V_MSS_IDX(mtu_idx) |
            V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx);
        opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10);
-       opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor);
+       opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) |
+              V_CONG_CONTROL_FLAVOR(cong_flavor);
 
        rpl = cplhdr(skb);
        rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
index d85bd8a7967d2ee26aff8e5313c67a0cd7290532..22239e9884988139df3228a50db421f337818355 100644 (file)
@@ -483,6 +483,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
 
        memcpy(joydev->abspam, abspam, len);
 
+       for (i = 0; i < joydev->nabs; i++)
+               joydev->absmap[joydev->abspam[i]] = i;
+
  out:
        kfree(abspam);
        return retval;
index 9cc488d2149019626101d3c5f76d0b2bdab0fe57..aa037fec2f86122500cbd5d14cfca0c59e614804 100644 (file)
@@ -338,7 +338,7 @@ config KEYBOARD_OPENCORES
 
 config KEYBOARD_PXA27x
        tristate "PXA27x/PXA3xx keypad support"
-       depends on PXA27x || PXA3xx
+       depends on PXA27x || PXA3xx || ARCH_MMP
        help
          Enable support for PXA27x/PXA3xx keypad controller.
 
index f32404f991893ef4584ab5540d213945cbb0c738..4b0ec35259a17f70357df965ae4f9b698bf4e01a 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <mach/pxa27x_keypad.h>
+#include <plat/pxa27x_keypad.h>
 /*
  * Keypad Controller registers
  */
@@ -330,11 +330,21 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
        keypad->direct_key_state = new_state;
 }
 
+static void clear_wakeup_event(struct pxa27x_keypad *keypad)
+{
+       struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+
+       if (pdata->clear_wakeup_event)
+               (pdata->clear_wakeup_event)();
+}
+
 static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
 {
        struct pxa27x_keypad *keypad = dev_id;
        unsigned long kpc = keypad_readl(KPC);
 
+       clear_wakeup_event(keypad);
+
        if (kpc & KPC_DI)
                pxa27x_keypad_scan_direct(keypad);
 
index 0d4266a533a524564adcc85cc546736248753628..360698553eb55d2d1f1b84f912dbc6984eb606bd 100644 (file)
@@ -404,6 +404,13 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
                retval = uinput_validate_absbits(dev);
                if (retval < 0)
                        goto exit;
+               if (test_bit(ABS_MT_SLOT, dev->absbit)) {
+                       int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
+                       input_mt_create_slots(dev, nslot);
+                       input_set_events_per_packet(dev, 6 * nslot);
+               } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
+                       input_set_events_per_packet(dev, 60);
+               }
        }
 
        udev->state = UIST_SETUP_COMPLETE;
index 42ba3691d908bc1fc8c370da5ada4287ceb21115..b35876ee6908c7328f29e2505fd29a94a61b2d61 100644 (file)
@@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb)
 static int wacom_open(struct input_dev *dev)
 {
        struct wacom *wacom = input_get_drvdata(dev);
+       int retval = 0;
 
-       mutex_lock(&wacom->lock);
-
-       wacom->irq->dev = wacom->usbdev;
-
-       if (usb_autopm_get_interface(wacom->intf) < 0) {
-               mutex_unlock(&wacom->lock);
+       if (usb_autopm_get_interface(wacom->intf) < 0)
                return -EIO;
-       }
+
+       mutex_lock(&wacom->lock);
 
        if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
-               usb_autopm_put_interface(wacom->intf);
-               mutex_unlock(&wacom->lock);
-               return -EIO;
+               retval = -EIO;
+               goto out;
        }
 
        wacom->open = true;
        wacom->intf->needs_remote_wakeup = 1;
 
+out:
        mutex_unlock(&wacom->lock);
-       return 0;
+       if (retval)
+               usb_autopm_put_interface(wacom->intf);
+       return retval;
 }
 
 static void wacom_close(struct input_dev *dev)
@@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev)
        wacom->open = false;
        wacom->intf->needs_remote_wakeup = 0;
        mutex_unlock(&wacom->lock);
+
+       usb_autopm_put_interface(wacom->intf);
 }
 
 static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
index 6e29badb969e44192be85080caf801851c3d06fa..47fd7a041c52e1898a8727c5386569fb3caed45c 100644 (file)
@@ -442,8 +442,10 @@ static void wacom_intuos_general(struct wacom_wac *wacom)
        /* general pen packet */
        if ((data[1] & 0xb8) == 0xa0) {
                t = (data[6] << 2) | ((data[7] >> 6) & 3);
-               if (features->type >= INTUOS4S && features->type <= INTUOS4L)
+               if ((features->type >= INTUOS4S && features->type <= INTUOS4L) ||
+                   features->type == WACOM_21UX2) {
                        t = (t << 1) | (data[1] & 1);
+               }
                input_report_abs(input, ABS_PRESSURE, t);
                input_report_abs(input, ABS_TILT_X,
                                ((data[7] << 1) & 0x7e) | (data[8] >> 7));
index 485be8b1e1b33bef2bd7e3af8fab2066d3687ec3..f0225bc0f2670ce2f0fde9b5d276f26151c6a046 100644 (file)
@@ -112,11 +112,19 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
                        }
                        else if(callid>=0x0000 && callid<=0x7FFF)
                        {
+                               int len;
+
                                pr_debug("%s: Got Incoming Call\n",
                                                sc_adapter[card]->devicename);
-                               strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4]));
-                               strcpy(setup.eazmsn,
-                                       sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn);
+                               len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]),
+                                               sizeof(setup.phone));
+                               if (len >= sizeof(setup.phone))
+                                       continue;
+                               len = strlcpy(setup.eazmsn,
+                                               sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
+                                               sizeof(setup.eazmsn));
+                               if (len >= sizeof(setup.eazmsn))
+                                       continue;
                                setup.si1 = 7;
                                setup.si2 = 0;
                                setup.plan = 0;
@@ -176,7 +184,9 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
                 * Handle a GetMyNumber Rsp
                 */
                if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){
-                       strcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array);
+                       strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
+                               rcvmsg.msg_data.byte_array,
+                               sizeof(rcvmsg.msg_data.byte_array));
                        continue;
                }
                        
index e4112622e5a25e7eb90b615bcc93475bcfd054a7..cc2a88d5192fbb359f3027082c0843ad34055d97 100644 (file)
@@ -304,13 +304,22 @@ config LEDS_MC13783
 
 config LEDS_NS2
        tristate "LED support for Network Space v2 GPIO LEDs"
-       depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2
+       depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
        default y
        help
          This option enable support for the dual-GPIO LED found on the
          Network Space v2 board (and parents). This include Internet Space v2,
          Network Space (Max) v2 and d2 Network v2 boards.
 
+config LEDS_NETXBIG
+       tristate "LED support for Big Network series LEDs"
+       depends on MACH_NET2BIG_V2 || MACH_NET5BIG_V2
+       default y
+       help
+         This option enable support for LEDs found on the LaCie 2Big
+         and 5Big Network v2 boards. The LEDs are wired to a CPLD and are
+         controlled through a GPIO extension bus.
+
 config LEDS_TRIGGERS
        bool "LED Trigger support"
        help
index 7d6b95831f8eb5da86fad02ab6eedf680c437e3c..9c96db40ef6d7d3a12f776ab4d764371a71026a5 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_LEDS_ADP5520)            += leds-adp5520.o
 obj-$(CONFIG_LEDS_DELL_NETBOOKS)       += dell-led.o
 obj-$(CONFIG_LEDS_MC13783)             += leds-mc13783.o
 obj-$(CONFIG_LEDS_NS2)                 += leds-ns2.o
+obj-$(CONFIG_LEDS_NETXBIG)             += leds-netxbig.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
new file mode 100644 (file)
index 0000000..f2e51c1
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs
+ *
+ * Copyright (C) 2010 LaCie
+ *
+ * Author: Simon Guinot <sguinot@lacie.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <mach/leds-netxbig.h>
+
+/*
+ * GPIO extension bus.
+ */
+
+static DEFINE_SPINLOCK(gpio_ext_lock);
+
+static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
+{
+       int pin;
+
+       for (pin = 0; pin < gpio_ext->num_addr; pin++)
+               gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1);
+}
+
+static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data)
+{
+       int pin;
+
+       for (pin = 0; pin < gpio_ext->num_data; pin++)
+               gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1);
+}
+
+static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext)
+{
+       /* Enable select is done on the raising edge. */
+       gpio_set_value(gpio_ext->enable, 0);
+       gpio_set_value(gpio_ext->enable, 1);
+}
+
+static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
+                              int addr, int value)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_ext_lock, flags);
+       gpio_ext_set_addr(gpio_ext, addr);
+       gpio_ext_set_data(gpio_ext, value);
+       gpio_ext_enable_select(gpio_ext);
+       spin_unlock_irqrestore(&gpio_ext_lock, flags);
+}
+
+static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
+{
+       int err;
+       int i;
+
+       if (unlikely(!gpio_ext))
+               return -EINVAL;
+
+       /* Configure address GPIOs. */
+       for (i = 0; i < gpio_ext->num_addr; i++) {
+               err = gpio_request(gpio_ext->addr[i], "GPIO extension addr");
+               if (err)
+                       goto err_free_addr;
+               err = gpio_direction_output(gpio_ext->addr[i], 0);
+               if (err) {
+                       gpio_free(gpio_ext->addr[i]);
+                       goto err_free_addr;
+               }
+       }
+       /* Configure data GPIOs. */
+       for (i = 0; i < gpio_ext->num_data; i++) {
+               err = gpio_request(gpio_ext->data[i], "GPIO extension data");
+               if (err)
+                       goto err_free_data;
+               err = gpio_direction_output(gpio_ext->data[i], 0);
+               if (err) {
+                       gpio_free(gpio_ext->data[i]);
+                       goto err_free_data;
+               }
+       }
+       /* Configure "enable select" GPIO. */
+       err = gpio_request(gpio_ext->enable, "GPIO extension enable");
+       if (err)
+               goto err_free_data;
+       err = gpio_direction_output(gpio_ext->enable, 0);
+       if (err) {
+               gpio_free(gpio_ext->enable);
+               goto err_free_data;
+       }
+
+       return 0;
+
+err_free_data:
+       for (i = i - 1; i >= 0; i--)
+               gpio_free(gpio_ext->data[i]);
+       i = gpio_ext->num_addr;
+err_free_addr:
+       for (i = i - 1; i >= 0; i--)
+               gpio_free(gpio_ext->addr[i]);
+
+       return err;
+}
+
+static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
+{
+       int i;
+
+       gpio_free(gpio_ext->enable);
+       for (i = gpio_ext->num_addr - 1; i >= 0; i--)
+               gpio_free(gpio_ext->addr[i]);
+       for (i = gpio_ext->num_data - 1; i >= 0; i--)
+               gpio_free(gpio_ext->data[i]);
+}
+
+/*
+ * Class LED driver.
+ */
+
+struct netxbig_led_data {
+       struct netxbig_gpio_ext *gpio_ext;
+       struct led_classdev     cdev;
+       int                     mode_addr;
+       int                     *mode_val;
+       int                     bright_addr;
+       int                     bright_max;
+       struct                  netxbig_led_timer *timer;
+       int                     num_timer;
+       enum netxbig_led_mode   mode;
+       int                     sata;
+       spinlock_t              lock;
+};
+
+static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode,
+                                     unsigned long delay_on,
+                                     unsigned long delay_off,
+                                     struct netxbig_led_timer *timer,
+                                     int num_timer)
+{
+       int i;
+
+       for (i = 0; i < num_timer; i++) {
+               if (timer[i].delay_on == delay_on &&
+                   timer[i].delay_off == delay_off) {
+                       *mode = timer[i].mode;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static int netxbig_led_blink_set(struct led_classdev *led_cdev,
+                                unsigned long *delay_on,
+                                unsigned long *delay_off)
+{
+       struct netxbig_led_data *led_dat =
+               container_of(led_cdev, struct netxbig_led_data, cdev);
+       enum netxbig_led_mode mode;
+       int mode_val;
+       int ret;
+
+       /* Look for a LED mode with the requested timer frequency. */
+       ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off,
+                                        led_dat->timer, led_dat->num_timer);
+       if (ret < 0)
+               return ret;
+
+       mode_val = led_dat->mode_val[mode];
+       if (mode_val == NETXBIG_LED_INVALID_MODE)
+               return -EINVAL;
+
+       spin_lock_irq(&led_dat->lock);
+
+       gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+       led_dat->mode = mode;
+
+       spin_unlock_irq(&led_dat->lock);
+
+       return 0;
+}
+
+static void netxbig_led_set(struct led_classdev *led_cdev,
+                           enum led_brightness value)
+{
+       struct netxbig_led_data *led_dat =
+               container_of(led_cdev, struct netxbig_led_data, cdev);
+       enum netxbig_led_mode mode;
+       int mode_val, bright_val;
+       int set_brightness = 1;
+       unsigned long flags;
+
+       spin_lock_irqsave(&led_dat->lock, flags);
+
+       if (value == LED_OFF) {
+               mode = NETXBIG_LED_OFF;
+               set_brightness = 0;
+       } else {
+               if (led_dat->sata)
+                       mode = NETXBIG_LED_SATA;
+               else if (led_dat->mode == NETXBIG_LED_OFF)
+                       mode = NETXBIG_LED_ON;
+               else /* Keep 'timer' mode. */
+                       mode = led_dat->mode;
+       }
+       mode_val = led_dat->mode_val[mode];
+
+       gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+       led_dat->mode = mode;
+       /*
+        * Note that the brightness register is shared between all the
+        * SATA LEDs. So, change the brightness setting for a single
+        * SATA LED will affect all the others.
+        */
+       if (set_brightness) {
+               bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
+                                         LED_FULL);
+               gpio_ext_set_value(led_dat->gpio_ext,
+                                  led_dat->bright_addr, bright_val);
+       }
+
+       spin_unlock_irqrestore(&led_dat->lock, flags);
+}
+
+static ssize_t netxbig_led_sata_store(struct device *dev,
+                                     struct device_attribute *attr,
+                                     const char *buff, size_t count)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct netxbig_led_data *led_dat =
+               container_of(led_cdev, struct netxbig_led_data, cdev);
+       unsigned long enable;
+       enum netxbig_led_mode mode;
+       int mode_val;
+       int ret;
+
+       ret = strict_strtoul(buff, 10, &enable);
+       if (ret < 0)
+               return ret;
+
+       enable = !!enable;
+
+       spin_lock_irq(&led_dat->lock);
+
+       if (led_dat->sata == enable) {
+               ret = count;
+               goto exit_unlock;
+       }
+
+       if (led_dat->mode != NETXBIG_LED_ON &&
+           led_dat->mode != NETXBIG_LED_SATA)
+               mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */
+       else if (enable)
+               mode = NETXBIG_LED_SATA;
+       else
+               mode = NETXBIG_LED_ON;
+
+       mode_val = led_dat->mode_val[mode];
+       if (mode_val == NETXBIG_LED_INVALID_MODE) {
+               ret = -EINVAL;
+               goto exit_unlock;
+       }
+
+       gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
+       led_dat->mode = mode;
+       led_dat->sata = enable;
+
+       ret = count;
+
+exit_unlock:
+       spin_unlock_irq(&led_dat->lock);
+
+       return ret;
+}
+
+static ssize_t netxbig_led_sata_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct netxbig_led_data *led_dat =
+               container_of(led_cdev, struct netxbig_led_data, cdev);
+
+       return sprintf(buf, "%d\n", led_dat->sata);
+}
+
+static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
+
+static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat)
+{
+       if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
+               device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
+       led_classdev_unregister(&led_dat->cdev);
+}
+
+static int __devinit
+create_netxbig_led(struct platform_device *pdev,
+                  struct netxbig_led_data *led_dat,
+                  const struct netxbig_led *template)
+{
+       struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+       int ret;
+
+       spin_lock_init(&led_dat->lock);
+       led_dat->gpio_ext = pdata->gpio_ext;
+       led_dat->cdev.name = template->name;
+       led_dat->cdev.default_trigger = template->default_trigger;
+       led_dat->cdev.blink_set = netxbig_led_blink_set;
+       led_dat->cdev.brightness_set = netxbig_led_set;
+       /*
+        * Because the GPIO extension bus don't allow to read registers
+        * value, there is no way to probe the LED initial state.
+        * So, the initial sysfs LED value for the "brightness" and "sata"
+        * attributes are inconsistent.
+        *
+        * Note that the initial LED state can't be reconfigured.
+        * The reason is that the LED behaviour must stay uniform during
+        * the whole boot process (bootloader+linux).
+        */
+       led_dat->sata = 0;
+       led_dat->cdev.brightness = LED_OFF;
+       led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+       led_dat->mode_addr = template->mode_addr;
+       led_dat->mode_val = template->mode_val;
+       led_dat->bright_addr = template->bright_addr;
+       led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
+       led_dat->timer = pdata->timer;
+       led_dat->num_timer = pdata->num_timer;
+
+       ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * If available, expose the SATA activity blink capability through
+        * a "sata" sysfs attribute.
+        */
+       if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
+               ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
+               if (ret)
+                       led_classdev_unregister(&led_dat->cdev);
+       }
+
+       return ret;
+}
+
+static int __devinit netxbig_led_probe(struct platform_device *pdev)
+{
+       struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+       struct netxbig_led_data *leds_data;
+       int i;
+       int ret;
+
+       if (!pdata)
+               return -EINVAL;
+
+       leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds,
+                           GFP_KERNEL);
+       if (!leds_data)
+               return -ENOMEM;
+
+       ret = gpio_ext_init(pdata->gpio_ext);
+       if (ret < 0)
+               goto err_free_data;
+
+       for (i = 0; i < pdata->num_leds; i++) {
+               ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
+               if (ret < 0)
+                       goto err_free_leds;
+       }
+
+       platform_set_drvdata(pdev, leds_data);
+
+       return 0;
+
+err_free_leds:
+       for (i = i - 1; i >= 0; i--)
+               delete_netxbig_led(&leds_data[i]);
+
+       gpio_ext_free(pdata->gpio_ext);
+err_free_data:
+       kfree(leds_data);
+
+       return ret;
+}
+
+static int __devexit netxbig_led_remove(struct platform_device *pdev)
+{
+       struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
+       struct netxbig_led_data *leds_data;
+       int i;
+
+       leds_data = platform_get_drvdata(pdev);
+
+       for (i = 0; i < pdata->num_leds; i++)
+               delete_netxbig_led(&leds_data[i]);
+
+       gpio_ext_free(pdata->gpio_ext);
+       kfree(leds_data);
+
+       return 0;
+}
+
+static struct platform_driver netxbig_led_driver = {
+       .probe          = netxbig_led_probe,
+       .remove         = __devexit_p(netxbig_led_remove),
+       .driver         = {
+               .name   = "leds-netxbig",
+               .owner  = THIS_MODULE,
+       },
+};
+MODULE_ALIAS("platform:leds-netxbig");
+
+static int __init netxbig_led_init(void)
+{
+       return platform_driver_register(&netxbig_led_driver);
+}
+
+static void __exit netxbig_led_exit(void)
+{
+       platform_driver_unregister(&netxbig_led_driver);
+}
+
+module_init(netxbig_led_init);
+module_exit(netxbig_led_exit);
+
+MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
+MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
+MODULE_LICENSE("GPL");
index 74dce4ba0262560977ae88d69fbb2fbe7db62009..f77d48d0b3e484bea2d48fd76568f4aa42cce445 100644 (file)
@@ -81,7 +81,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat,
        int cmd_level;
        int slow_level;
 
-       read_lock(&led_dat->rw_lock);
+       read_lock_irq(&led_dat->rw_lock);
 
        cmd_level = gpio_get_value(led_dat->cmd);
        slow_level = gpio_get_value(led_dat->slow);
@@ -95,7 +95,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat,
                }
        }
 
-       read_unlock(&led_dat->rw_lock);
+       read_unlock_irq(&led_dat->rw_lock);
 
        return ret;
 }
@@ -104,8 +104,9 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat,
                             enum ns2_led_modes mode)
 {
        int i;
+       unsigned long flags;
 
-       write_lock(&led_dat->rw_lock);
+       write_lock_irqsave(&led_dat->rw_lock, flags);
 
        for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
                if (mode == ns2_led_modval[i].mode) {
@@ -116,7 +117,7 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat,
                }
        }
 
-       write_unlock(&led_dat->rw_lock);
+       write_unlock_irqrestore(&led_dat->rw_lock, flags);
 }
 
 static void ns2_led_set(struct led_classdev *led_cdev,
@@ -140,10 +141,12 @@ static ssize_t ns2_led_sata_store(struct device *dev,
                                  struct device_attribute *attr,
                                  const char *buff, size_t count)
 {
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct ns2_led_data *led_dat =
+               container_of(led_cdev, struct ns2_led_data, cdev);
        int ret;
        unsigned long enable;
        enum ns2_led_modes mode;
-       struct ns2_led_data *led_dat = dev_get_drvdata(dev);
 
        ret = strict_strtoul(buff, 10, &enable);
        if (ret < 0)
@@ -171,7 +174,9 @@ static ssize_t ns2_led_sata_store(struct device *dev,
 static ssize_t ns2_led_sata_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
 {
-       struct ns2_led_data *led_dat = dev_get_drvdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct ns2_led_data *led_dat =
+               container_of(led_cdev, struct ns2_led_data, cdev);
 
        return sprintf(buf, "%d\n", led_dat->sata);
 }
@@ -233,7 +238,6 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
        if (ret < 0)
                goto err_free_slow;
 
-       dev_set_drvdata(led_dat->cdev.dev, led_dat);
        ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
        if (ret < 0)
                goto err_free_cdev;
index ed4900ade93a4d80b84784e76aafc406689020b2..e4fb58db5454d4bfc5cc5257bb74435907b3b3f2 100644 (file)
@@ -1000,10 +1000,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
                                page = bitmap->sb_page;
                                offset = sizeof(bitmap_super_t);
                                if (!file)
-                                       read_sb_page(bitmap->mddev,
-                                                    bitmap->mddev->bitmap_info.offset,
-                                                    page,
-                                                    index, count);
+                                       page = read_sb_page(
+                                               bitmap->mddev,
+                                               bitmap->mddev->bitmap_info.offset,
+                                               page,
+                                               index, count);
                        } else if (file) {
                                page = read_page(file, index, bitmap, count);
                                offset = 0;
index 43cf9cc9c1df3650c228ce01920645fb474f105a..f20d13e717d55e0a04de747f62384d2ce4b0b310 100644 (file)
@@ -1643,7 +1643,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
                bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1;
                if (rdev->sb_size & bmask)
                        rdev->sb_size = (rdev->sb_size | bmask) + 1;
-       }
+       } else
+               max_dev = le32_to_cpu(sb->max_dev);
+
        for (i=0; i<max_dev;i++)
                sb->dev_roles[i] = cpu_to_le16(0xfffe);
        
@@ -7069,7 +7071,7 @@ void md_check_recovery(mddev_t *mddev)
        if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
                return;
        if ( ! (
-               (mddev->flags && !mddev->external) ||
+               (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
                test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
                test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
                (mddev->external == 0 && mddev->safemode == 1) ||
index ad83a4dcadc3ed7cafa914d2e4dcb7ef1a939fdf..0b830bbe1d8b6323bac02106c2ccc4d806e1e390 100644 (file)
@@ -1839,7 +1839,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
 
                /* take from bio_init */
                bio->bi_next = NULL;
+               bio->bi_flags &= ~(BIO_POOL_MASK-1);
                bio->bi_flags |= 1 << BIO_UPTODATE;
+               bio->bi_comp_cpu = -1;
                bio->bi_rw = READ;
                bio->bi_vcnt = 0;
                bio->bi_idx = 0;
@@ -1912,7 +1914,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                            !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
                                break;
                        BUG_ON(sync_blocks < (PAGE_SIZE>>9));
-                       if (len > (sync_blocks<<9))
+                       if ((len >> 9) > sync_blocks)
                                len = sync_blocks<<9;
                }
 
index 7e82a9df726b51ab6d90f00fc1b1fa22998c8862..7961d59f5cace91b18fc6a67fef4caea09f08265 100644 (file)
@@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie)
         * a keyup event might follow immediately after the keydown.
         */
        spin_lock_irqsave(&ir->keylock, flags);
-       if (time_is_after_eq_jiffies(ir->keyup_jiffies))
+       if (time_is_before_eq_jiffies(ir->keyup_jiffies))
                ir_keyup(ir);
        spin_unlock_irqrestore(&ir->keylock, flags);
 }
@@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev,
                   (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
                        " in raw mode" : "");
 
+       /*
+        * Default delay of 250ms is too short for some protocols, expecially
+        * since the timeout is currently set to 250ms. Increase it to 500ms,
+        * to avoid wrong repetition of the keycodes.
+        */
+       input_dev->rep[REP_DELAY] = 500;
+
        return 0;
 
 out_event:
index 77b5946413c0203739d9bdcecb129e218f194356..e63f757d5d72ca0ba6c1b4e206914c7d7625112a 100644 (file)
@@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev)
                        features |= LIRC_CAN_SET_SEND_CARRIER;
 
                if (ir_dev->props->s_tx_duty_cycle)
-                       features |= LIRC_CAN_SET_REC_DUTY_CYCLE;
+                       features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
        }
 
        if (ir_dev->props->s_rx_carrier_range)
index 43094e7eccfa92ba6213115ecdab06d88b1387ec..8e0e1b1f8c87ef9f83f05ab6a564e30ddd78aa4c 100644 (file)
@@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev)
                        "rc%u",  (unsigned int)ir->devno);
 
        if (IS_ERR(ir->raw->thread)) {
+               int ret = PTR_ERR(ir->raw->thread);
+
                kfree(ir->raw);
                ir->raw = NULL;
-               return PTR_ERR(ir->raw->thread);
+               return ret;
        }
 
        mutex_lock(&ir_raw_handler_lock);
index 96dafc425c8e61495cd662bf7f4c11182d674e79..46d42467f9b43010739895f165ed7bfe93793137 100644 (file)
@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d,
        char *tmp = buf;
        int i;
 
-       if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+       if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
                enabled = ir_dev->rc_tab.ir_type;
                allowed = ir_dev->props->allowed_protos;
-       } else {
+       } else if (ir_dev->raw) {
                enabled = ir_dev->raw->enabled_protocols;
                allowed = ir_raw_get_allowed_protocols();
-       }
+       } else
+               return sprintf(tmp, "[builtin]\n");
 
        IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
                   (long long)allowed,
@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d,
        int rc, i, count = 0;
        unsigned long flags;
 
-       if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
+       if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
                type = ir_dev->rc_tab.ir_type;
-       else
+       else if (ir_dev->raw)
                type = ir_dev->raw->enabled_protocols;
+       else {
+               IR_dprintk(1, "Protocol switching not supported\n");
+               return -EINVAL;
+       }
 
        while ((tmp = strsep((char **) &data, " \n")) != NULL) {
                if (!*tmp)
@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d,
                }
        }
 
-       if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+       if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
                spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
                ir_dev->rc_tab.ir_type = type;
                spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
index 64264f7f838f29a0be7861f872f8e852bf376669..39557ad401b63fce5a892e5245fe7d6f42b83ee1 100644 (file)
@@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = {
 
        { 0x800f0416, KEY_PLAY },
        { 0x800f0418, KEY_PAUSE },
+       { 0x800f046e, KEY_PLAYPAUSE },
        { 0x800f0419, KEY_STOP },
        { 0x800f0417, KEY_RECORD },
 
@@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = {
        { 0x800f0411, KEY_VOLUMEDOWN },
        { 0x800f0412, KEY_CHANNELUP },
        { 0x800f0413, KEY_CHANNELDOWN },
+       { 0x800f043a, KEY_BRIGHTNESSUP },
+       { 0x800f0480, KEY_BRIGHTNESSDOWN },
 
        { 0x800f0401, KEY_NUMERIC_1 },
        { 0x800f0402, KEY_NUMERIC_2 },
index ac6bb2c01a4810446451d2651df53936b57d104c..bc620e10ef77e46149f57bdf278cc8bf79d150b3 100644 (file)
@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = {
        { USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
        /* Philips eHome Infrared Transceiver */
        { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
+       /* Philips/Spinel plus IR transceiver for ASUS */
+       { USB_DEVICE(VENDOR_PHILIPS, 0x206c) },
+       /* Philips/Spinel plus IR transceiver for ASUS */
+       { USB_DEVICE(VENDOR_PHILIPS, 0x2088) },
        /* Realtek MCE IR Receiver */
        { USB_DEVICE(VENDOR_REALTEK, 0x0161) },
        /* SMK/Toshiba G83C0004D410 */
index fe818348b8a36450357f2b19571b000afdcd873f..48397f103d326264b261506539bc1c4cee9a343d 100644 (file)
@@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf,
                        else
                                dev->props.rc.core.bulk_mode = false;
 
-                       /* Need a higher delay, to avoid wrong repeat */
-                       dev->rc_input_dev->rep[REP_DELAY] = 500;
-
                        dib0700_rc_setup(dev);
 
                        return 0;
index f634d2e784b2ce24a005b0593372b505b903e1c3..e06acd1fecb61b9f3bf2676f0a16375f9101e907 100644 (file)
@@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
        return adap->fe == NULL ? -ENODEV : 0;
 }
 
+/* STK7770P */
+static struct dib7000p_config dib7770p_dib7000p_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &dib7070_agc_config,
+       .bw  = &dib7070_bw_config_12_mhz,
+       .tuner_is_baseband = 1,
+       .spur_protect = 1,
+
+       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+       .enable_current_mirror = 1,
+       .disable_sample_and_hold = 0,
+};
+
+static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+       if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
+           p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       else
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                    &dib7770p_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                   __func__);
+               return -ENODEV;
+       }
+
+       adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+               &dib7770p_dib7000p_config);
+       return adap->fe == NULL ? -ENODEV : 0;
+}
+
 /* DIB807x generic */
 static struct dibx000_agc_config dib807x_agc_config[2] = {
        {
@@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
 /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
-       { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
+       { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
        { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
 /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
@@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                .pid_filter_count = 32,
                                .pid_filter       = stk70x0p_pid_filter,
                                .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070p_frontend_attach,
+                               .frontend_attach  = stk7770p_frontend_attach,
                                .tuner_attach     = dib7770p_tuner_attach,
 
                                DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
index 6b22ec64ab0cc69d7124bc16421309d3e9c070cd..f896337b453518e603419beedd5093a9a5f1fb16 100644 (file)
@@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev,
                }
        }
        kfree(p);
-       if (fw) {
-               release_firmware(fw);
-       }
+       release_firmware(fw);
        return ret;
 }
 
index 2e28b973dfd3cbb1743ac48d3fb931c9d2600063..3aed0d43392152688bbe4176ebc8ee68712ab724 100644 (file)
@@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
 
 //     dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 
+       reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
+       reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
+
        dib7000p_write_word(state, 908, reg_908);
        dib7000p_write_word(state, 909, reg_909);
 }
@@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
                default:
                case GUARD_INTERVAL_1_32: value *= 1; break;
        }
-       state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
+       if (state->cfg.diversity_delay == 0)
+               state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
+       else
+               state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo
 
        /* deactive the possibility of diversity reception if extended interleaver */
        state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
index 805dd13a97ee347d3b06e517e266d2bb1de9e4d3..da17345bf5bdd66002ea64080e2c4456bfde1ca3 100644 (file)
@@ -33,6 +33,11 @@ struct dib7000p_config {
        int (*agc_control) (struct dvb_frontend *, u8 before);
 
        u8 output_mode;
+       u8 disable_sample_and_hold : 1;
+
+       u8 enable_current_mirror : 1;
+       u8 diversity_delay;
+
 };
 
 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
index d93468cd3a85e1a5a3d8eee586c7ec29b69d3051..ff3b0fa901b39f00e23250e20dda2502fbb42e04 100644 (file)
@@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
  *
  * @return pointer to descriptor on success, NULL on error.
  */
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+
+struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
 {
        struct smscore_buffer_t *cb = NULL;
        unsigned long flags;
 
-       DEFINE_WAIT(wait);
-
        spin_lock_irqsave(&coredev->bufferslock, flags);
-
-       /* This function must return a valid buffer, since the buffer list is
-        * finite, we check that there is an available buffer, if not, we wait
-        * until such buffer become available.
-        */
-
-       prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
-       if (list_empty(&coredev->buffers)) {
-               spin_unlock_irqrestore(&coredev->bufferslock, flags);
-               schedule();
-               spin_lock_irqsave(&coredev->bufferslock, flags);
+       if (!list_empty(&coredev->buffers)) {
+               cb = (struct smscore_buffer_t *) coredev->buffers.next;
+               list_del(&cb->entry);
        }
+       spin_unlock_irqrestore(&coredev->bufferslock, flags);
+       return cb;
+}
 
-       finish_wait(&coredev->buffer_mng_waitq, &wait);
-
-       cb = (struct smscore_buffer_t *) coredev->buffers.next;
-       list_del(&cb->entry);
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb = NULL;
 
-       spin_unlock_irqrestore(&coredev->bufferslock, flags);
+       wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
 
        return cb;
 }
index 67a4ec8768a6145ecfd6fb1d44095bfb51f29fdc..4ce541a5eb47558f5b26dc9bd14523e937c5cfaf 100644 (file)
@@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
        radio->registers[POWERCFG] = POWERCFG_ENABLE;
        if (si470x_set_register(radio, POWERCFG) < 0) {
                retval = -EIO;
-               goto err_all;
+               goto err_video;
        }
        msleep(110);
 
index 755dd0ce65ff724f2fd479f502e314e0cabf236e..6f2b57384488b3bb8124eed072217ef8ecf3194b 100644 (file)
@@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
 
index 6bdc0ef18119716dadc5facc2347f22fda5c6192..f2a4900014bc5c1dace49615b123cb86184ba814 100644 (file)
@@ -32,6 +32,7 @@
 #include <media/v4l2-chip-ident.h>
 
 #include <media/cx25840.h>
+#include "dvb-usb-ids.h"
 #include "xc5000.h"
 
 #include "cx231xx.h"
@@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = {
         .driver_info = CX231XX_BOARD_CNXT_RDE_250},
        {USB_DEVICE(0x0572, 0x58A1),
         .driver_info = CX231XX_BOARD_CNXT_RDU_250},
+       {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
+        .driver_info = CX231XX_BOARD_UNKNOWN},
        {},
 };
 
@@ -226,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev)
                     dev->board.name, dev->model);
 
        /* set the direction for GPIO pins */
-       cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
-       cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
-       cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
+       if (dev->board.tuner_gpio) {
+               cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
+               cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
+               cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
 
-       /* request some modules if any required */
+               /* request some modules if any required */
 
-       /* reset the Tuner */
-       cx231xx_gpio_set(dev, dev->board.tuner_gpio);
+               /* reset the Tuner */
+               cx231xx_gpio_set(dev, dev->board.tuner_gpio);
+       }
 
        /* set the mode to Analog mode initially */
        cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
index 86ca8c2359dd8bb409cadd434dc951a17ff170a9..f5a3e74c3c7cc0e6e52ebec222b28604e7cf53ef 100644 (file)
@@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client,
 
                state->volume = v4l2_ctrl_new_std(&state->hdl,
                        &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
-                       0, 65335, 65535 / 100, default_volume);
+                       0, 65535, 65535 / 100, default_volume);
                state->mute = v4l2_ctrl_new_std(&state->hdl,
                        &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
                        0, 1, 1, 0);
index 99dbae1175919befc55ae7e2e00a3a524f666053..0fa85cbefbb12ffbe1e5729581ce6544dbadcfce 100644 (file)
@@ -17,7 +17,7 @@ config VIDEO_CX88
 
 config VIDEO_CX88_ALSA
        tristate "Conexant 2388x DMA audio support"
-       depends on VIDEO_CX88 && SND && EXPERIMENTAL
+       depends on VIDEO_CX88 && SND
        select SND_PCM
        ---help---
          This is a video4linux driver for direct (DMA) audio on
index b9846106913eb4871f429924092dd27563f0f115..78abc1c1f9d52766704af26c0ec3769cd08f9198 100644 (file)
@@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
                usb_rcvintpipe(dev, ep->bEndpointAddress),
                buffer, buffer_len,
                int_irq, (void *)gspca_dev, interval);
+       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        gspca_dev->int_urb = urb;
        ret = usb_submit_urb(urb, GFP_KERNEL);
        if (ret < 0) {
index 83a718f0f3f9841b8412c34967f41476040398e0..9052d5702556539fbf77dbd8cf1da66e5d87bdc4 100644 (file)
@@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                            (data[33] << 10);
                avg_lum >>= 9;
                atomic_set(&sd->avg_lum, avg_lum);
-               gspca_frame_add(gspca_dev, LAST_PACKET,
-                               data, len);
+               gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
                return;
        }
        if (gspca_dev->last_packet_type == LAST_PACKET) {
index be03a712731c3b61a249d607927fb852f0517881..f0316d02f09f6df1297a6f3e5e6ed4e0c1b8ff1f 100644 (file)
@@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
                        struct fb_vblank vblank;
                        u32 trace;
 
+                       memset(&vblank, 0, sizeof(struct fb_vblank));
+
                        vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
                                        FB_VBLANK_HAVE_VSYNC;
                        trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
index 4525335f9bd416388484cbc5872ea0db3c3af768..a7210d981388e8c4724f524e3fd5c77bbd672dca 100644 (file)
@@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx,
                return -EFAULT;
        }
 
-       if (in_buf->vb.size < out_buf->vb.size) {
+       if (in_buf->vb.size > out_buf->vb.size) {
                v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
                return -EINVAL;
        }
@@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev)
        v4l2_m2m_release(dev->m2m_dev);
        del_timer_sync(&dev->timer);
        video_unregister_device(dev->vfd);
+       video_device_release(dev->vfd);
        v4l2_device_unregister(&dev->v4l2_dev);
        kfree(dev);
 
index 758a4db27d65651481eec16b970f755a9036f622..c71af4e0e517f61631b1cc936021104dbcd30f92 100644 (file)
@@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
                __func__, rect.left, rect.top, rect.width, rect.height);
 
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
        ret = mt9m111_make_rect(client, &rect);
        if (!ret)
                mt9m111->rect = rect;
@@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 
 static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
        a->bounds.left                  = MT9M111_MIN_DARK_COLS;
        a->bounds.top                   = MT9M111_MIN_DARK_ROWS;
        a->bounds.width                 = MT9M111_MAX_WIDTH;
        a->bounds.height                = MT9M111_MAX_HEIGHT;
        a->defrect                      = a->bounds;
-       a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        a->pixelaspect.numerator        = 1;
        a->pixelaspect.denominator      = 1;
 
@@ -487,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd,
        mf->width       = mt9m111->rect.width;
        mf->height      = mt9m111->rect.height;
        mf->code        = mt9m111->fmt->code;
+       mf->colorspace  = mt9m111->fmt->colorspace;
        mf->field       = V4L2_FIELD_NONE;
 
        return 0;
index e7cd23cd63941ecb3380243f623960cf91c8ea31..b48473c7896b4b31d6d816ac544be70e6a1ac3c7 100644 (file)
@@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
                if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
                        return -EINVAL;
                break;
-       case 0:
-               /* No format change, only geometry */
-               break;
        default:
                return -EINVAL;
        }
index 66ff174151b5f3d909022fbc096f8c432e6f65f4..b6ea67221d1d5fc64594348f49715539c19f9840 100644 (file)
@@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
 
        spin_lock_irqsave(&pcdev->lock, flags);
 
+       if (*fb_active == NULL)
+               goto out;
+
        vb = &(*fb_active)->vb;
        dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
@@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
 
        *fb_active = buf;
 
+out:
        spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
index 1b992b847198a486bc0eb62342d3d1b020c99919..55ea914c7fcd3e0a21a17671ef68294831b4a567 100644 (file)
@@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
                        if (ret >= 0) {
                                ret = pvr2_ctrl_range_check(cptr,*valptr);
                        }
-                       if (maskptr) *maskptr = ~0;
+                       *maskptr = ~0;
                } else if (cptr->info->type == pvr2_ctl_bool) {
                        ret = parse_token(ptr,len,valptr,boolNames,
                                          ARRAY_SIZE(boolNames));
@@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
                        } else if (ret == 0) {
                                *valptr = (*valptr & 1) ? !0 : 0;
                        }
-                       if (maskptr) *maskptr = 1;
+                       *maskptr = 1;
                } else if (cptr->info->type == pvr2_ctl_enum) {
                        ret = parse_token(
                                ptr,len,valptr,
@@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
                        if (ret >= 0) {
                                ret = pvr2_ctrl_range_check(cptr,*valptr);
                        }
-                       if (maskptr) *maskptr = ~0;
+                       *maskptr = ~0;
                } else if (cptr->info->type == pvr2_ctl_bitmask) {
                        ret = parse_tlist(
                                ptr,len,maskptr,valptr,
index b151c7be8a506b18ae1ff544de0ba604f7e05e8f..6961c55baf9b1140609dd470b4abc3e05eed86c3 100644 (file)
@@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
        dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
 }
 
+static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
+{
+       struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
+
+       f->dma_offset.y_h = f->offs_h;
+       if (!variant->pix_hoff)
+               f->dma_offset.y_h *= (f->fmt->depth >> 3);
+
+       f->dma_offset.y_v = f->offs_v;
+
+       f->dma_offset.cb_h = f->offs_h;
+       f->dma_offset.cb_v = f->offs_v;
+
+       f->dma_offset.cr_h = f->offs_h;
+       f->dma_offset.cr_v = f->offs_v;
+
+       if (!variant->pix_hoff) {
+               if (f->fmt->planes_cnt == 3) {
+                       f->dma_offset.cb_h >>= 1;
+                       f->dma_offset.cr_h >>= 1;
+               }
+               if (f->fmt->color == S5P_FIMC_YCBCR420) {
+                       f->dma_offset.cb_v >>= 1;
+                       f->dma_offset.cr_v >>= 1;
+               }
+       }
+
+       dbg("in_offset: color= %d, y_h= %d, y_v= %d",
+           f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
+}
+
 /**
  * fimc_prepare_config - check dimensions, operation and color mode
  *                      and pre-calculate offset and the scaling coefficients.
@@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
 {
        struct fimc_frame *s_frame, *d_frame;
        struct fimc_vid_buffer *buf = NULL;
-       struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
        int ret = 0;
 
        s_frame = &ctx->s_frame;
@@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
                        swap(d_frame->width, d_frame->height);
                }
 
-               /* Prepare the output offset ratios for scaler. */
-               d_frame->dma_offset.y_h = d_frame->offs_h;
-               if (!variant->pix_hoff)
-                       d_frame->dma_offset.y_h *= (d_frame->fmt->depth >> 3);
-
-               d_frame->dma_offset.y_v = d_frame->offs_v;
-
-               d_frame->dma_offset.cb_h = d_frame->offs_h;
-               d_frame->dma_offset.cb_v = d_frame->offs_v;
-
-               d_frame->dma_offset.cr_h = d_frame->offs_h;
-               d_frame->dma_offset.cr_v = d_frame->offs_v;
+               /* Prepare the DMA offset ratios for scaler. */
+               fimc_prepare_dma_offset(ctx, &ctx->s_frame);
+               fimc_prepare_dma_offset(ctx, &ctx->d_frame);
 
-               if (!variant->pix_hoff && d_frame->fmt->planes_cnt == 3) {
-                       d_frame->dma_offset.cb_h >>= 1;
-                       d_frame->dma_offset.cb_v >>= 1;
-                       d_frame->dma_offset.cr_h >>= 1;
-                       d_frame->dma_offset.cr_v >>= 1;
-               }
-
-               dbg("out offset: color= %d, y_h= %d, y_v= %d",
-                       d_frame->fmt->color,
-                       d_frame->dma_offset.y_h, d_frame->dma_offset.y_v);
-
-               /* Prepare the input offset ratios for scaler. */
-               s_frame->dma_offset.y_h = s_frame->offs_h;
-               if (!variant->pix_hoff)
-                       s_frame->dma_offset.y_h *= (s_frame->fmt->depth >> 3);
-               s_frame->dma_offset.y_v = s_frame->offs_v;
-
-               s_frame->dma_offset.cb_h = s_frame->offs_h;
-               s_frame->dma_offset.cb_v = s_frame->offs_v;
-
-               s_frame->dma_offset.cr_h = s_frame->offs_h;
-               s_frame->dma_offset.cr_v = s_frame->offs_v;
-
-               if (!variant->pix_hoff && s_frame->fmt->planes_cnt == 3) {
-                       s_frame->dma_offset.cb_h >>= 1;
-                       s_frame->dma_offset.cb_v >>= 1;
-                       s_frame->dma_offset.cr_h >>= 1;
-                       s_frame->dma_offset.cr_v >>= 1;
-               }
-
-               dbg("in offset: color= %d, y_h= %d, y_v= %d",
-                       s_frame->fmt->color, s_frame->dma_offset.y_h,
-                       s_frame->dma_offset.y_v);
-
-               fimc_set_yuv_order(ctx);
-
-               /* Check against the scaler ratio. */
                if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) ||
                    s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) {
                        err("out of scaler range");
                        return -EINVAL;
                }
+               fimc_set_yuv_order(ctx);
        }
 
        /* Input DMA mode is not allowed when the scaler is disabled. */
@@ -822,7 +807,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
        } else {
                v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
                         "Wrong buffer/video queue type (%d)\n", f->type);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto s_fmt_out;
        }
 
        pix = &f->fmt.pix;
@@ -1414,8 +1400,10 @@ static int fimc_probe(struct platform_device *pdev)
        }
 
        fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev));
-       if (!fimc->work_queue)
+       if (!fimc->work_queue) {
+               ret = -ENOMEM;
                goto err_irq;
+       }
 
        ret = fimc_register_m2m_device(fimc);
        if (ret)
@@ -1492,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = {
 };
 
 static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
+       .pix_hoff       = 1,
        .has_inp_rot    = 1,
        .has_out_rot    = 1,
        .min_inp_pixsize = 16,
@@ -1506,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
 };
 
 static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
+       .pix_hoff        = 1,
        .min_inp_pixsize = 16,
        .min_out_pixsize = 32,
 
index ec697fcd406ede6b23c9691ceb5d0fe1fc0134a4..bb8d83d8ddafbd79dd892e971e6d8152f5483a37 100644 (file)
@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = {
        },
        [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
                /*       Beholder Intl. Ltd. 2008      */
-               /*Dmitry Belimov <d.belimov@gmail.com> */
-               .name           = "Beholder BeholdTV Columbus TVFM",
+               /* Dmitry Belimov <d.belimov@gmail.com> */
+               .name           = "Beholder BeholdTV Columbus TV/FM",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_ALPS_TSBE5_PAL,
-               .radio_type     = UNSET,
-               .tuner_addr     = ADDR_UNSET,
-               .radio_addr     = ADDR_UNSET,
+               .radio_type     = TUNER_TEA5767,
+               .tuner_addr     = 0xc2 >> 1,
+               .radio_addr     = 0xc0 >> 1,
                .tda9887_conf   = TDA9887_PRESENT,
                .gpiomask       = 0x000A8004,
                .inputs         = {{
index 5713f3a4b76c952bf9b1db333bb547caf3e40376..ddd25d32723dc0436f2477a641afaa0d75d9f2d3 100644 (file)
@@ -136,10 +136,11 @@ ret:
 int saa7164_buffer_dealloc(struct saa7164_tsport *port,
        struct saa7164_buffer *buf)
 {
-       struct saa7164_dev *dev = port->dev;
+       struct saa7164_dev *dev;
 
-       if ((buf == 0) || (port == 0))
+       if (!buf || !port)
                return SAA_ERR_BAD_PARAMETER;
+       dev = port->dev;
 
        dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
 
index 8bdd940f32e689c5b51a94ec8975014567d9f00c..2ac85d8984f025cb0ec9933f87bf00e91bf656dd 100644 (file)
@@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev,
                            max(frame->dwFrameInterval[0],
                                frame->dwDefaultFrameInterval));
 
+               if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
+                       frame->bFrameIntervalType = 1;
+                       frame->dwFrameInterval[0] =
+                               frame->dwDefaultFrameInterval;
+               }
+
                uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n",
                        frame->wWidth, frame->wHeight,
                        10000000/frame->dwDefaultFrameInterval,
@@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VENDOR_SPEC,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0 },
+       /* Chicony CNF7129 (Asus EEE 100HE) */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x04f2,
+         .idProduct            = 0xb071,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_RESTRICT_FRAME_RATE },
        /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2091,6 +2106,15 @@ static struct usb_device_id uvc_ids[] = {
          .bInterfaceProtocol   = 0,
          .driver_info          = UVC_QUIRK_PROBE_MINMAX
                                | UVC_QUIRK_PROBE_DEF },
+       /* IMC Networks (Medion Akoya) */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x13d3,
+         .idProduct            = 0x5103,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_STREAM_NO_FID },
        /* Syntek (HP Spartan) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
index bdacf3beabf54fcbe1f9f901692a0134e6b48ed1..892e0e51916c31853d9e8fa681ecce27e75edc53 100644 (file)
@@ -182,6 +182,7 @@ struct uvc_xu_control {
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
 #define UVC_QUIRK_FIX_BANDWIDTH                0x00000080
 #define UVC_QUIRK_PROBE_DEF            0x00000100
+#define UVC_QUIRK_RESTRICT_FRAME_RATE  0x00000200
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED                0x00000001
index 372b87efcd0538ec6c91c1bb45749177294f7442..6ff9e4bac3ea14fd6248bf07e1dfc6109fe43d27 100644 (file)
@@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
        }
 
        /* read() method */
-       dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
-       mem->vaddr = NULL;
+       if (mem->vaddr) {
+               dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
+               mem->vaddr = NULL;
+       }
 }
 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
 
index 06f9a9c2a39add9256a58850d0cf5c4b0c52bf5b..2ad0bc252b0eaed1612ddaac477d21f6d7033b0c 100644 (file)
@@ -94,7 +94,7 @@ err:
  * must free the memory.
  */
 static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
-                                               int nr_pages, int offset)
+                                       int nr_pages, int offset, size_t size)
 {
        struct scatterlist *sglist;
        int i;
@@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
                /* DMA to highmem pages might not work */
                goto highmem;
        sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset);
+       size -= PAGE_SIZE - offset;
        for (i = 1; i < nr_pages; i++) {
                if (NULL == pages[i])
                        goto nopage;
                if (PageHighMem(pages[i]))
                        goto highmem;
-               sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0);
+               sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0);
+               size -= min(PAGE_SIZE, size);
        }
        return sglist;
 
@@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
 
        first = (data          & PAGE_MASK) >> PAGE_SHIFT;
        last  = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
-       dma->offset   = data & ~PAGE_MASK;
+       dma->offset = data & ~PAGE_MASK;
+       dma->size = size;
        dma->nr_pages = last-first+1;
        dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL);
        if (NULL == dma->pages)
@@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
 
        if (dma->pages) {
                dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
-                                                  dma->offset);
+                                                  dma->offset, dma->size);
        }
        if (dma->vaddr) {
                dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr,
index 04028a9ee082735278557b606840619ade7e29a9..428377a5a6f56fe94ca033730a49102f19164dd2 100644 (file)
@@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq)
        irq_tsc = cache_tsc;
        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
                irq_data = &max8925_irqs[i];
+               /* 1 -- disable, 0 -- enable */
                switch (irq_data->mask_reg) {
                case MAX8925_CHG_IRQ1_MASK:
-                       irq_chg[0] &= irq_data->enable;
+                       irq_chg[0] &= ~irq_data->enable;
                        break;
                case MAX8925_CHG_IRQ2_MASK:
-                       irq_chg[1] &= irq_data->enable;
+                       irq_chg[1] &= ~irq_data->enable;
                        break;
                case MAX8925_ON_OFF_IRQ1_MASK:
-                       irq_on[0] &= irq_data->enable;
+                       irq_on[0] &= ~irq_data->enable;
                        break;
                case MAX8925_ON_OFF_IRQ2_MASK:
-                       irq_on[1] &= irq_data->enable;
+                       irq_on[1] &= ~irq_data->enable;
                        break;
                case MAX8925_RTC_IRQ_MASK:
-                       irq_rtc &= irq_data->enable;
+                       irq_rtc &= ~irq_data->enable;
                        break;
                case MAX8925_TSC_IRQ_MASK:
-                       irq_tsc &= irq_data->enable;
+                       irq_tsc &= ~irq_data->enable;
                        break;
                default:
                        dev_err(chip->dev, "wrong IRQ\n");
index 7dabe4dbd3732e1d75c396b9b1e01bdeafafa57c..294183b6260b1facff3d26764eb3cea8c6d4b011 100644 (file)
@@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
 
        irq = irq - wm831x->irq_base;
 
-       if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11)
-               return -EINVAL;
+       if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
+               /* Ignore internal-only IRQs */
+               if (irq >= 0 && irq < WM831X_NUM_IRQS)
+                       return 0;
+               else
+                       return -EINVAL;
+       }
 
        switch (type) {
        case IRQ_TYPE_EDGE_BOTH:
index 0b591b658243a7675ac66d24b97e7ea1ceaa9781..b74331260744db8829a2a8712a0d08bf5d42f949 100644 (file)
@@ -368,7 +368,7 @@ config VMWARE_BALLOON
          If unsure, say N.
 
          To compile this driver as a module, choose M here: the
-         module will be called vmware_balloon.
+         module will be called vmw_balloon.
 
 config ARM_CHARLCD
        bool "ARM Ltd. Character LCD Driver"
index 255a80dc9d73267a115da07c5729e04aa1c8a8ee..42eab95cde2af49e8ae737036695a1093caa01d9 100644 (file)
@@ -33,5 +33,5 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_HMC6352)          += hmc6352.o
 obj-y                          += eeprom/
 obj-y                          += cb710/
-obj-$(CONFIG_VMWARE_BALLOON)   += vmware_balloon.o
+obj-$(CONFIG_VMWARE_BALLOON)   += vmw_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)      += arm-charlcd.o
index 714c6b487313a4ad7b360687591b75a6cddedc55..d5f3a3fd231931508948a9b0227aae2a3648a96f 100644 (file)
@@ -190,7 +190,6 @@ static int __devexit bh1780_remove(struct i2c_client *client)
 
        ddata = i2c_get_clientdata(client);
        sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group);
-       i2c_set_clientdata(client, NULL);
        kfree(ddata);
 
        return 0;
index 71ad4163b95e12b45aab7d41379c8022995d8ac4..aacb862ecc8a979f8022b8e0dd3428ed26c15baa 100644 (file)
@@ -241,8 +241,10 @@ static struct sdhci_ops sdhci_s3c_ops = {
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
 {
        struct sdhci_host *host = platform_get_drvdata(dev);
+       unsigned long flags;
+
        if (host) {
-               spin_lock(&host->lock);
+               spin_lock_irqsave(&host->lock, flags);
                if (state) {
                        dev_dbg(&dev->dev, "card inserted.\n");
                        host->flags &= ~SDHCI_DEVICE_DEAD;
@@ -253,7 +255,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
                        host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
                }
                tasklet_schedule(&host->card_tasklet);
-               spin_unlock(&host->lock);
+               spin_unlock_irqrestore(&host->lock, flags);
        }
 }
 
@@ -481,8 +483,10 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
        sdhci_remove_host(host, 1);
 
        for (ptr = 0; ptr < 3; ptr++) {
-               clk_disable(sc->clk_bus[ptr]);
-               clk_put(sc->clk_bus[ptr]);
+               if (sc->clk_bus[ptr]) {
+                       clk_disable(sc->clk_bus[ptr]);
+                       clk_put(sc->clk_bus[ptr]);
+               }
        }
        clk_disable(sc->clk_io);
        clk_put(sc->clk_io);
index a382e3dd0a5dc8cdcddc2fc5f0b993c3badadd33..6fbeefa3a7662fb5fb85e8bfdbb86e0c63307ab3 100644 (file)
@@ -682,7 +682,6 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
 static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
 {
        struct bf5xx_nand_info *info = to_nand_info(pdev);
-       struct mtd_info *mtd = NULL;
 
        platform_set_drvdata(pdev, NULL);
 
@@ -690,11 +689,7 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
         * and their partitions, then go through freeing the
         * resources used
         */
-       mtd = &info->mtd;
-       if (mtd) {
-               nand_release(mtd);
-               kfree(mtd);
-       }
+       nand_release(&info->mtd);
 
        peripheral_free_list(bfin_nfc_pin_req);
        bf5xx_nand_dma_remove(info);
@@ -710,7 +705,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd)
        struct nand_chip *chip = mtd->priv;
        int ret;
 
-       ret = nand_scan_ident(mtd, 1);
+       ret = nand_scan_ident(mtd, 1, NULL);
        if (ret)
                return ret;
 
index fcf8ceb277d44cd3e78b5c5e0249ec1b40d7ab33..b2828e84d24377fdbf2be2d9af3d2492ee7feea2 100644 (file)
@@ -67,7 +67,9 @@
 #define NFC_V1_V2_CONFIG1_BIG          (1 << 5)
 #define NFC_V1_V2_CONFIG1_RST          (1 << 6)
 #define NFC_V1_V2_CONFIG1_CE           (1 << 7)
-#define NFC_V1_V2_CONFIG1_ONE_CYCLE    (1 << 8)
+#define NFC_V2_CONFIG1_ONE_CYCLE       (1 << 8)
+#define NFC_V2_CONFIG1_PPB(x)          (((x) & 0x3) << 9)
+#define NFC_V2_CONFIG1_FP_INT          (1 << 11)
 
 #define NFC_V1_V2_CONFIG2_INT          (1 << 15)
 
@@ -402,16 +404,16 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
        /* Wait for operation to complete */
        wait_op_done(host, true);
 
+       memcpy(host->data_buf, host->main_area0, 16);
+
        if (this->options & NAND_BUSWIDTH_16) {
-               void __iomem *main_buf = host->main_area0;
                /* compress the ID info */
-               writeb(readb(main_buf + 2), main_buf + 1);
-               writeb(readb(main_buf + 4), main_buf + 2);
-               writeb(readb(main_buf + 6), main_buf + 3);
-               writeb(readb(main_buf + 8), main_buf + 4);
-               writeb(readb(main_buf + 10), main_buf + 5);
+               host->data_buf[1] = host->data_buf[2];
+               host->data_buf[2] = host->data_buf[4];
+               host->data_buf[3] = host->data_buf[6];
+               host->data_buf[4] = host->data_buf[8];
+               host->data_buf[5] = host->data_buf[10];
        }
-       memcpy(host->data_buf, host->main_area0, 16);
 }
 
 static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
@@ -729,27 +731,30 @@ static void preset_v1_v2(struct mtd_info *mtd)
 {
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
-       uint16_t tmp;
-
-       /* enable interrupt, disable spare enable */
-       tmp = readw(NFC_V1_V2_CONFIG1);
-       tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
-       tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
-       if (nand_chip->ecc.mode == NAND_ECC_HW) {
-               tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
-       } else {
-               tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
-       }
+       uint16_t config1 = 0;
+
+       if (nand_chip->ecc.mode == NAND_ECC_HW)
+               config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+
+       if (nfc_is_v21())
+               config1 |= NFC_V2_CONFIG1_FP_INT;
+
+       if (!cpu_is_mx21())
+               config1 |= NFC_V1_V2_CONFIG1_INT_MSK;
 
        if (nfc_is_v21() && mtd->writesize) {
+               uint16_t pages_per_block = mtd->erasesize / mtd->writesize;
+
                host->eccsize = get_eccsize(mtd);
                if (host->eccsize == 4)
-                       tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
+                       config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
+
+               config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6);
        } else {
                host->eccsize = 1;
        }
 
-       writew(tmp, NFC_V1_V2_CONFIG1);
+       writew(config1, NFC_V1_V2_CONFIG1);
        /* preset operation */
 
        /* Unlock the internal RAM Buffer */
index 133d51528f8dc0fb79eae4d12230e1a65bd7595e..513e0a76a4a73866d52bba8151e43556a3b30a54 100644 (file)
@@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
                prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT);
        } while (prefetch_status);
        /* disable and stop the PFPW engine */
-       gpmc_prefetch_reset();
+       gpmc_prefetch_reset(info->gpmc_cs);
 
        dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
        return 0;
index 4d89f37802075a26e602cf4ba6f42de54d07cfc8..4d01cda6884463daa844c02fde951970854e972a 100644 (file)
@@ -1320,6 +1320,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
                goto fail_free_irq;
        }
 
+#ifdef CONFIG_MTD_PARTITIONS
        if (mtd_has_cmdlinepart()) {
                static const char *probes[] = { "cmdlinepart", NULL };
                struct mtd_partition *parts;
@@ -1332,6 +1333,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
        }
 
        return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
+#else
+       return 0;
+#endif
 
 fail_free_irq:
        free_irq(irq, info);
@@ -1364,7 +1368,9 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        del_mtd_device(mtd);
+#ifdef CONFIG_MTD_PARTITIONS
        del_mtd_partitions(mtd);
+#endif
        irq = platform_get_irq(pdev, 0);
        if (irq >= 0)
                free_irq(irq, info);
index cb443af3d45feee407bb79e8440f439cbdba7bd1..a460f1b748c20fbcb29982925820b79e6a7bbd78 100644 (file)
@@ -554,14 +554,13 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
 
        do {
                status = readl(base + S5PC110_DMA_TRANS_STATUS);
+               if (status & S5PC110_DMA_TRANS_STATUS_TE) {
+                       writel(S5PC110_DMA_TRANS_CMD_TEC,
+                                       base + S5PC110_DMA_TRANS_CMD);
+                       return -EIO;
+               }
        } while (!(status & S5PC110_DMA_TRANS_STATUS_TD));
 
-       if (status & S5PC110_DMA_TRANS_STATUS_TE) {
-               writel(S5PC110_DMA_TRANS_CMD_TEC, base + S5PC110_DMA_TRANS_CMD);
-               writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
-               return -EIO;
-       }
-
        writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
 
        return 0;
@@ -571,13 +570,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
                unsigned char *buffer, int offset, size_t count)
 {
        struct onenand_chip *this = mtd->priv;
-       void __iomem *bufferram;
        void __iomem *p;
        void *buf = (void *) buffer;
        dma_addr_t dma_src, dma_dst;
        int err;
 
-       p = bufferram = this->base + area;
+       p = this->base + area;
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
                if (area == ONENAND_DATARAM)
                        p += this->writesize;
@@ -621,7 +619,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
 normal:
        if (count != mtd->writesize) {
                /* Copy the bufferram to memory to prevent unaligned access */
-               memcpy(this->page_buf, bufferram, mtd->writesize);
+               memcpy(this->page_buf, p, mtd->writesize);
                p = this->page_buf + offset;
        }
 
index 85671adae455dc59bd29405aa2b196e5b0ebd9c2..179871d9e71f9a1f111645f58c68b7fea55b0861 100644 (file)
@@ -635,6 +635,9 @@ struct vortex_private {
                must_free_region:1,                             /* Flag: if zero, Cardbus owns the I/O region */
                large_frames:1,                 /* accept large frames */
                handling_irq:1;                 /* private in_irq indicator */
+       /* {get|set}_wol operations are already serialized by rtnl.
+        * no additional locking is required for the enable_wol and acpi_set_WOL()
+        */
        int drv_flags;
        u16 status_enable;
        u16 intr_enable;
@@ -2939,28 +2942,31 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct vortex_private *vp = netdev_priv(dev);
 
-       spin_lock_irq(&vp->lock);
+       if (!VORTEX_PCI(vp))
+               return;
+
        wol->supported = WAKE_MAGIC;
 
        wol->wolopts = 0;
        if (vp->enable_wol)
                wol->wolopts |= WAKE_MAGIC;
-       spin_unlock_irq(&vp->lock);
 }
 
 static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct vortex_private *vp = netdev_priv(dev);
+
+       if (!VORTEX_PCI(vp))
+               return -EOPNOTSUPP;
+
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EINVAL;
 
-       spin_lock_irq(&vp->lock);
        if (wol->wolopts & WAKE_MAGIC)
                vp->enable_wol = 1;
        else
                vp->enable_wol = 0;
        acpi_set_WOL(dev);
-       spin_unlock_irq(&vp->lock);
 
        return 0;
 }
@@ -3202,6 +3208,9 @@ static void acpi_set_WOL(struct net_device *dev)
                        return;
                }
 
+               if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
+                       return;
+
                /* Change the power state to D3; RxEnable doesn't take effect. */
                pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
        }
index 2cc81a54cbf322a49ccbf474f5d41f654faf109d..77efe462b9215914dd1071c8875635ebabff6d09 100644 (file)
@@ -2,6 +2,9 @@
 # Network device configuration
 #
 
+config HAVE_NET_MACB
+       bool
+
 menuconfig NETDEVICES
        default y if UML
        depends on NET
@@ -221,7 +224,7 @@ config MII
 
 config MACB
        tristate "Atmel MACB support"
-       depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
+       depends on HAVE_NET_MACB
        select PHYLIB
        help
          The Atmel MACB ethernet interface is found on many AT32 and AT91
@@ -2428,7 +2431,7 @@ config UGETH_TX_ON_DEMAND
 
 config MV643XX_ETH
        tristate "Marvell Discovery (643XX) and Orion ethernet support"
-       depends on MV64X60 || PPC32 || PLAT_ORION
+       depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
        select INET_LRO
        select PHYLIB
        help
@@ -2803,7 +2806,7 @@ config NIU
 
 config PASEMI_MAC
        tristate "PA Semi 1/10Gbit MAC"
-       depends on PPC_PASEMI && PCI
+       depends on PPC_PASEMI && PCI && INET
        select PHYLIB
        select INET_LRO
        help
index 63b9ba0cc67e13c408686442f1e2fe984ee9b462..c73be2848319deecd38a3d6f5e8e45ed8637e6f9 100644 (file)
@@ -1251,6 +1251,12 @@ static void atl1_free_ring_resources(struct atl1_adapter *adapter)
 
        rrd_ring->desc = NULL;
        rrd_ring->dma = 0;
+
+       adapter->cmb.dma = 0;
+       adapter->cmb.cmb = NULL;
+
+       adapter->smb.dma = 0;
+       adapter->smb.smb = NULL;
 }
 
 static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
@@ -2847,10 +2853,11 @@ static int atl1_resume(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
        atl1_reset_hw(&adapter->hw);
-       adapter->cmb.cmb->int_stats = 0;
 
-       if (netif_running(netdev))
+       if (netif_running(netdev)) {
+               adapter->cmb.cmb->int_stats = 0;
                atl1_up(adapter);
+       }
        netif_device_attach(netdev);
 
        return 0;
index 1e620e287ae0cc9fbe9894a105fedbfdc9fbb6be..efeffdf9e5fab30d2bd97a07e5e866fec60ed595 100644 (file)
@@ -2170,8 +2170,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
        dev->irq = sdev->irq;
        SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
 
-       netif_carrier_off(dev);
-
        err = ssb_bus_powerup(sdev->bus, 0);
        if (err) {
                dev_err(sdev->dev,
@@ -2213,6 +2211,8 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
                goto err_out_powerdown;
        }
 
+       netif_carrier_off(dev);
+
        ssb_set_drvdata(sdev, dev);
 
        /* Chip reset provides power to the b44 MAC & PCI cores, which
index 822f586d72afa67d8abd5c606f38b11f60f0147d..0ddf4c66afe21aa99679a3fb31b1e932dc51612c 100644 (file)
@@ -2466,6 +2466,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
        if (!(dev->flags & IFF_MASTER))
                goto out;
 
+       if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
+               goto out;
+
        read_lock(&bond->lock);
        slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev),
                                        orig_dev);
index c746b331771d38f38771c89aa492ede20cbdf711..26bb118c45334074ef4c8a51deda39e4161fba44 100644 (file)
@@ -362,6 +362,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
                goto out;
        }
 
+       if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
+               goto out;
+
        if (skb->len < sizeof(struct arp_pkt)) {
                pr_debug("Packet is too small to be an ARP\n");
                goto out;
index 3b16f62d5606c741e97fb0a7c7b0b211c903157d..e953c6ad6e6d1ea3fd7e22fddc8f5f27ba1f8b38 100644 (file)
@@ -5164,6 +5164,15 @@ int bond_create(struct net *net, const char *name)
                res = dev_alloc_name(bond_dev, "bond%d");
                if (res < 0)
                        goto out;
+       } else {
+               /*
+                * If we're given a name to register
+                * we need to ensure that its not already
+                * registered
+                */
+               res = -EEXIST;
+               if (__dev_get_by_name(net, name) != NULL)
+                       goto out;
        }
 
        res = register_netdevice(bond_dev);
index ad19585d960be79c0ec350c312fce978afaf2a9b..f208712c0b90d6b675f1ef1179f5825ae9f9f911 100644 (file)
@@ -2296,6 +2296,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
        case CHELSIO_GET_QSET_NUM:{
                struct ch_reg edata;
 
+               memset(&edata, 0, sizeof(struct ch_reg));
+
                edata.cmd = CHELSIO_GET_QSET_NUM;
                edata.val = pi->nqsets;
                if (copy_to_user(useraddr, &edata, sizeof(edata)))
index 66ed08f726fb9bcdd13225086d05f3dcf437da6a..ba302a5c2c30e14c2be16333f38adb2a2668a89c 100644 (file)
@@ -57,6 +57,7 @@ enum e1e_registers {
        E1000_SCTL     = 0x00024, /* SerDes Control - RW */
        E1000_FCAL     = 0x00028, /* Flow Control Address Low - RW */
        E1000_FCAH     = 0x0002C, /* Flow Control Address High -RW */
+       E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */
        E1000_FEXTNVM  = 0x00028, /* Future Extended NVM - RW */
        E1000_FCT      = 0x00030, /* Flow Control Type - RW */
        E1000_VET      = 0x00038, /* VLAN Ether Type - RW */
index 63930d12711cf44ceb3334e5334fef5089ecb2e2..57b5435599ab1d61c58e393d04e0a2f3912d66fc 100644 (file)
 #define E1000_FEXTNVM_SW_CONFIG                1
 #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
 
+#define E1000_FEXTNVM4_BEACON_DURATION_MASK    0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_8USEC   0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_16USEC  0x3
+
 #define PCIE_ICH8_SNOOP_ALL            PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES          7
 
 /* SMBus Address Phy Register */
 #define HV_SMB_ADDR            PHY_REG(768, 26)
+#define HV_SMB_ADDR_MASK       0x007F
 #define HV_SMB_ADDR_PEC_EN     0x0200
 #define HV_SMB_ADDR_VALID      0x0080
 
@@ -237,6 +242,8 @@ static s32  e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -272,7 +279,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
 static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       u32 ctrl;
+       u32 ctrl, fwsm;
        s32 ret_val = 0;
 
        phy->addr                     = 1;
@@ -294,7 +301,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
         * disabled, then toggle the LANPHYPC Value bit to force
         * the interconnect to PCIe mode.
         */
-       if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+       fwsm = er32(FWSM);
+       if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
                ctrl = er32(CTRL);
                ctrl |=  E1000_CTRL_LANPHYPC_OVERRIDE;
                ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
@@ -303,6 +311,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
                ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
                ew32(CTRL, ctrl);
                msleep(50);
+
+               /*
+                * Gate automatic PHY configuration by hardware on
+                * non-managed 82579
+                */
+               if (hw->mac.type == e1000_pch2lan)
+                       e1000_gate_hw_phy_config_ich8lan(hw, true);
        }
 
        /*
@@ -315,6 +330,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
        if (ret_val)
                goto out;
 
+       /* Ungate automatic PHY configuration on non-managed 82579 */
+       if ((hw->mac.type == e1000_pch2lan)  &&
+           !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
+               msleep(10);
+               e1000_gate_hw_phy_config_ich8lan(hw, false);
+       }
+
        phy->id = e1000_phy_unknown;
        ret_val = e1000e_get_phy_id(hw);
        if (ret_val)
@@ -561,13 +583,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
        if (mac->type == e1000_ich8lan)
                e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
 
-       /* Disable PHY configuration by hardware, config by software */
-       if (mac->type == e1000_pch2lan) {
-               u32 extcnf_ctrl = er32(EXTCNF_CTRL);
-
-               extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
-               ew32(EXTCNF_CTRL, extcnf_ctrl);
-       }
+       /* Gate automatic PHY configuration by hardware on managed 82579 */
+       if ((mac->type == e1000_pch2lan) &&
+           (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+               e1000_gate_hw_phy_config_ich8lan(hw, true);
 
        return 0;
 }
@@ -652,6 +671,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                        goto out;
        }
 
+       if (hw->mac.type == e1000_pch2lan) {
+               ret_val = e1000_k1_workaround_lv(hw);
+               if (ret_val)
+                       goto out;
+       }
+
        /*
         * Check if there was DownShift, must be checked
         * immediately after link-up
@@ -894,6 +919,34 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
        return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET;
 }
 
+/**
+ *  e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states
+ *  @hw: pointer to the HW structure
+ *
+ *  Assumes semaphore already acquired.
+ *
+ **/
+static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
+{
+       u16 phy_data;
+       u32 strap = er32(STRAP);
+       s32 ret_val = 0;
+
+       strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;
+
+       ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data &= ~HV_SMB_ADDR_MASK;
+       phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
+       phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
+       ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
+
+out:
+       return ret_val;
+}
+
 /**
  *  e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
  *  @hw:   pointer to the HW structure
@@ -903,7 +956,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
  **/
 static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 {
-       struct e1000_adapter *adapter = hw->adapter;
        struct e1000_phy_info *phy = &hw->phy;
        u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
        s32 ret_val = 0;
@@ -921,7 +973,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
                if (phy->type != e1000_phy_igp_3)
                        return ret_val;
 
-               if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) {
+               if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
+                   (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
                        sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
                        break;
                }
@@ -961,21 +1014,16 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
        cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
        cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
 
-       if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
-           ((hw->mac.type == e1000_pchlan) ||
-            (hw->mac.type == e1000_pch2lan))) {
+       if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
+           (hw->mac.type == e1000_pchlan)) ||
+            (hw->mac.type == e1000_pch2lan)) {
                /*
                 * HW configures the SMBus address and LEDs when the
                 * OEM and LCD Write Enable bits are set in the NVM.
                 * When both NVM bits are cleared, SW will configure
                 * them instead.
                 */
-               data = er32(STRAP);
-               data &= E1000_STRAP_SMBUS_ADDRESS_MASK;
-               reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT;
-               reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
-               ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR,
-                                                       reg_data);
+               ret_val = e1000_write_smbus_addr(hw);
                if (ret_val)
                        goto out;
 
@@ -1440,10 +1488,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
                        goto out;
 
                /* Enable jumbo frame workaround in the PHY */
-               e1e_rphy(hw, PHY_REG(769, 20), &data);
-               ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
-               if (ret_val)
-                       goto out;
                e1e_rphy(hw, PHY_REG(769, 23), &data);
                data &= ~(0x7F << 5);
                data |= (0x37 << 5);
@@ -1452,7 +1496,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
                        goto out;
                e1e_rphy(hw, PHY_REG(769, 16), &data);
                data &= ~(1 << 13);
-               data |= (1 << 12);
                ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
                if (ret_val)
                        goto out;
@@ -1477,7 +1520,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 
                mac_reg = er32(RCTL);
                mac_reg &= ~E1000_RCTL_SECRC;
-               ew32(FFLT_DBG, mac_reg);
+               ew32(RCTL, mac_reg);
 
                ret_val = e1000e_read_kmrn_reg(hw,
                                                E1000_KMRNCTRLSTA_CTRL_OFFSET,
@@ -1503,17 +1546,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
                        goto out;
 
                /* Write PHY register values back to h/w defaults */
-               e1e_rphy(hw, PHY_REG(769, 20), &data);
-               ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
-               if (ret_val)
-                       goto out;
                e1e_rphy(hw, PHY_REG(769, 23), &data);
                data &= ~(0x7F << 5);
                ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
                if (ret_val)
                        goto out;
                e1e_rphy(hw, PHY_REG(769, 16), &data);
-               data &= ~(1 << 12);
                data |= (1 << 13);
                ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
                if (ret_val)
@@ -1558,6 +1596,69 @@ out:
        return ret_val;
 }
 
+/**
+ *  e1000_k1_gig_workaround_lv - K1 Si workaround
+ *  @hw:   pointer to the HW structure
+ *
+ *  Workaround to set the K1 beacon duration for 82579 parts
+ **/
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 status_reg = 0;
+       u32 mac_reg;
+
+       if (hw->mac.type != e1000_pch2lan)
+               goto out;
+
+       /* Set K1 beacon duration based on 1Gbps speed or otherwise */
+       ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
+       if (ret_val)
+               goto out;
+
+       if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
+           == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
+               mac_reg = er32(FEXTNVM4);
+               mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
+
+               if (status_reg & HV_M_STATUS_SPEED_1000)
+                       mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
+               else
+                       mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
+
+               ew32(FEXTNVM4, mac_reg);
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware
+ *  @hw:   pointer to the HW structure
+ *  @gate: boolean set to true to gate, false to ungate
+ *
+ *  Gate/ungate the automatic PHY configuration via hardware; perform
+ *  the configuration via software instead.
+ **/
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
+{
+       u32 extcnf_ctrl;
+
+       if (hw->mac.type != e1000_pch2lan)
+               return;
+
+       extcnf_ctrl = er32(EXTCNF_CTRL);
+
+       if (gate)
+               extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+       else
+               extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+
+       ew32(EXTCNF_CTRL, extcnf_ctrl);
+       return;
+}
+
 /**
  *  e1000_lan_init_done_ich8lan - Check for PHY config completion
  *  @hw: pointer to the HW structure
@@ -1602,6 +1703,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
        if (e1000_check_reset_block(hw))
                goto out;
 
+       /* Allow time for h/w to get to quiescent state after reset */
+       msleep(10);
+
        /* Perform any necessary post-reset workarounds */
        switch (hw->mac.type) {
        case e1000_pchlan:
@@ -1630,6 +1734,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
        /* Configure the LCD with the OEM bits in NVM */
        ret_val = e1000_oem_bits_config_ich8lan(hw, true);
 
+       /* Ungate automatic PHY configuration on non-managed 82579 */
+       if ((hw->mac.type == e1000_pch2lan) &&
+           !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+               msleep(10);
+               e1000_gate_hw_phy_config_ich8lan(hw, false);
+       }
+
 out:
        return ret_val;
 }
@@ -1646,6 +1757,11 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 {
        s32 ret_val = 0;
 
+       /* Gate automatic PHY configuration by hardware on non-managed 82579 */
+       if ((hw->mac.type == e1000_pch2lan) &&
+           !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+               e1000_gate_hw_phy_config_ich8lan(hw, true);
+
        ret_val = e1000e_phy_hw_reset_generic(hw);
        if (ret_val)
                goto out;
@@ -2910,6 +3026,14 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
                 * external PHY is reset.
                 */
                ctrl |= E1000_CTRL_PHY_RST;
+
+               /*
+                * Gate automatic PHY configuration by hardware on
+                * non-managed 82579
+                */
+               if ((hw->mac.type == e1000_pch2lan) &&
+                   !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+                       e1000_gate_hw_phy_config_ich8lan(hw, true);
        }
        ret_val = e1000_acquire_swflag_ich8lan(hw);
        e_dbg("Issuing a global reset to ich8lan\n");
@@ -3460,13 +3584,20 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
 void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
 {
        u32 phy_ctrl;
+       s32 ret_val;
 
        phy_ctrl = er32(PHY_CTRL);
        phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
        ew32(PHY_CTRL, phy_ctrl);
 
-       if (hw->mac.type >= e1000_pchlan)
-               e1000_phy_hw_reset_ich8lan(hw);
+       if (hw->mac.type >= e1000_pchlan) {
+               e1000_oem_bits_config_ich8lan(hw, true);
+               ret_val = hw->phy.ops.acquire(hw);
+               if (ret_val)
+                       return;
+               e1000_write_smbus_addr(hw);
+               hw->phy.ops.release(hw);
+       }
 }
 
 /**
index 2b8ef44bd2b1629c5d203206479a3b8bab510fab..e561d15c3eb161558f9a7da3825f3cc6c90840c7 100644 (file)
@@ -2704,6 +2704,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
        u32 psrctl = 0;
        u32 pages = 0;
 
+       /* Workaround Si errata on 82579 - configure jumbo frame flow */
+       if (hw->mac.type == e1000_pch2lan) {
+               s32 ret_val;
+
+               if (adapter->netdev->mtu > ETH_DATA_LEN)
+                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
+               else
+                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
+       }
+
        /* Program MC offset vector base */
        rctl = er32(RCTL);
        rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
@@ -2744,16 +2754,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                e1e_wphy(hw, 22, phy_data);
        }
 
-       /* Workaround Si errata on 82579 - configure jumbo frame flow */
-       if (hw->mac.type == e1000_pch2lan) {
-               s32 ret_val;
-
-               if (rctl & E1000_RCTL_LPE)
-                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
-               else
-                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
-       }
-
        /* Setup buffer sizes */
        rctl &= ~E1000_RCTL_SZ_4096;
        rctl |= E1000_RCTL_BSEX;
@@ -4833,6 +4833,15 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
                return -EINVAL;
        }
 
+       /* Jumbo frame workaround on 82579 requires CRC be stripped */
+       if ((adapter->hw.mac.type == e1000_pch2lan) &&
+           !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
+           (new_mtu > ETH_DATA_LEN)) {
+               e_err("Jumbo Frames not supported on 82579 when CRC "
+                     "stripping is disabled.\n");
+               return -EINVAL;
+       }
+
        /* 82573 Errata 17 */
        if (((adapter->hw.mac.type == e1000_82573) ||
             (adapter->hw.mac.type == e1000_82574)) &&
index a333b42111b8c2ba20b92eca94bf5648704c4f9a..6372610ed24093b8ed99fdf002e44442be49f696 100644 (file)
@@ -533,8 +533,15 @@ static inline void ehea_fill_skb(struct net_device *dev,
        int length = cqe->num_bytes_transfered - 4;     /*remove CRC */
 
        skb_put(skb, length);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
        skb->protocol = eth_type_trans(skb, dev);
+
+       /* The packet was not an IPV4 packet so a complemented checksum was
+          calculated. The value is found in the Internet Checksum field. */
+       if (cqe->status & EHEA_CQE_BLIND_CKSUM) {
+               skb->ip_summed = CHECKSUM_COMPLETE;
+               skb->csum = csum_unfold(~cqe->inet_checksum_value);
+       } else
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
 }
 
 static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array,
index f608a6c54af5845727494c9749e2b786390dfa78..38104734a3be82b0fb4480526295510a4769e8bf 100644 (file)
@@ -150,6 +150,7 @@ struct ehea_rwqe {
 #define EHEA_CQE_TYPE_RQ           0x60
 #define EHEA_CQE_STAT_ERR_MASK     0x700F
 #define EHEA_CQE_STAT_FAT_ERR_MASK 0xF
+#define EHEA_CQE_BLIND_CKSUM       0x8000
 #define EHEA_CQE_STAT_ERR_TCP      0x4000
 #define EHEA_CQE_STAT_ERR_IP       0x2000
 #define EHEA_CQE_STAT_ERR_CRC      0x1000
index dda2c7944da9a45872d55f626503d15c67c67641..0cb1cf9cf4b0c2c38abd69f964838f276c1a6ff9 100644 (file)
@@ -555,6 +555,8 @@ static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp)
        equalizer_t *eql;
        master_config_t mc;
 
+       memset(&mc, 0, sizeof(master_config_t));
+
        if (eql_is_master(dev)) {
                eql = netdev_priv(dev);
                mc.max_slaves = eql->max_slaves;
index 768b840aeb6b7b0bf2ceec87469bb0b4925b5d20..cce32d43175f5c3ed5f6e7ef2ebd56eede8e9139 100644 (file)
@@ -678,24 +678,37 @@ static int fec_enet_mii_probe(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
        struct phy_device *phy_dev = NULL;
-       int ret;
+       char mdio_bus_id[MII_BUS_ID_SIZE];
+       char phy_name[MII_BUS_ID_SIZE + 3];
+       int phy_id;
 
        fep->phy_dev = NULL;
 
-       /* find the first phy */
-       phy_dev = phy_find_first(fep->mii_bus);
-       if (!phy_dev) {
-               printk(KERN_ERR "%s: no PHY found\n", dev->name);
-               return -ENODEV;
+       /* check for attached phy */
+       for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
+               if ((fep->mii_bus->phy_mask & (1 << phy_id)))
+                       continue;
+               if (fep->mii_bus->phy_map[phy_id] == NULL)
+                       continue;
+               if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
+                       continue;
+               strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
+               break;
        }
 
-       /* attach the mac to the phy */
-       ret = phy_connect_direct(dev, phy_dev,
-                            &fec_enet_adjust_link, 0,
-                            PHY_INTERFACE_MODE_MII);
-       if (ret) {
-               printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-               return ret;
+       if (phy_id >= PHY_MAX_ADDR) {
+               printk(KERN_INFO "%s: no PHY, assuming direct connection "
+                       "to switch\n", dev->name);
+               strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE);
+               phy_id = 0;
+       }
+
+       snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+       phy_dev = phy_connect(dev, phy_name, &fec_enet_adjust_link, 0,
+               PHY_INTERFACE_MODE_MII);
+       if (IS_ERR(phy_dev)) {
+               printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
+               return PTR_ERR(phy_dev);
        }
 
        /* mask with MAC supported features */
@@ -738,7 +751,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
        fep->mii_bus->read = fec_enet_mdio_read;
        fep->mii_bus->write = fec_enet_mdio_write;
        fep->mii_bus->reset = fec_enet_mdio_reset;
-       snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
+       snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id + 1);
        fep->mii_bus->priv = fep;
        fep->mii_bus->parent = &pdev->dev;
 
@@ -1311,6 +1324,9 @@ fec_probe(struct platform_device *pdev)
        if (ret)
                goto failed_mii_init;
 
+       /* Carrier starts down, phylib will bring it up */
+       netif_carrier_off(ndev);
+
        ret = register_netdev(ndev);
        if (ret)
                goto failed_register;
index 3506fd6ad7263be467b9128938b248bbaf3dd054..519e19e23955a3c3a86d8e04f615b67daa7a996e 100644 (file)
@@ -2928,7 +2928,7 @@ static int __devinit emac_probe(struct platform_device *ofdev,
        if (dev->emac_irq != NO_IRQ)
                irq_dispose_mapping(dev->emac_irq);
  err_free:
-       kfree(ndev);
+       free_netdev(ndev);
  err_gone:
        /* if we were on the bootlist, remove us as we won't show up and
         * wake up all waiters to notify them in case they were waiting
@@ -2971,7 +2971,7 @@ static int __devexit emac_remove(struct platform_device *ofdev)
        if (dev->emac_irq != NO_IRQ)
                irq_dispose_mapping(dev->emac_irq);
 
-       kfree(dev->ndev);
+       free_netdev(dev->ndev);
 
        return 0;
 }
index bdf2149e529689b1135603904da6343fcbbbebc2..87f0a93b165c33478e1d59aa5e23942afaccc80f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/of_device.h>
 #include <linux/of_mdio.h>
 #include <linux/of_platform.h>
+#include <linux/of_address.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/tcp.h>      /* needed for sizeof(tcphdr) */
index 5ae28c975b384bf64ff7a7dc763a3d1766669b5a..8cf9d4f56bb2223893dd912e1d475a48fc30f683 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/phy.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/of_mdio.h>
 
index cabae7bb1fc6777d3366c5a8728feadcd53d0aa3..b075a35b85d4ef09cfab1b2df3b42be0313c2516 100644 (file)
@@ -1540,7 +1540,6 @@ netxen_process_rcv(struct netxen_adapter *adapter,
        if (pkt_offset)
                skb_pull(skb, pkt_offset);
 
-       skb->truesize = skb->len + sizeof(struct sk_buff);
        skb->protocol = eth_type_trans(skb, netdev);
 
        napi_gro_receive(&sds_ring->napi, skb);
@@ -1602,8 +1601,6 @@ netxen_process_lro(struct netxen_adapter *adapter,
 
        skb_put(skb, lro_length + data_offset);
 
-       skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
-
        skb_pull(skb, l2_hdr_offset);
        skb->protocol = eth_type_trans(skb, netdev);
 
index 49279b0ee526a54a534c6f8c04e7c48aa4aba0d0..f9b509a6b09a702d214ed2821d3bf6a79a671b49 100644 (file)
@@ -508,7 +508,8 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
                           unsigned int vcc,
                           void *priv_data)
 {
-       int *has_shmem = priv_data;
+       int *priv = priv_data;
+       int try = (*priv & 0x1);
        int i;
        cistpl_io_t *io = &cfg->io;
 
@@ -525,77 +526,103 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
                i = p_dev->resource[1]->end = 0;
        }
 
-       *has_shmem = ((cfg->mem.nwin == 1) &&
-                     (cfg->mem.win[0].len >= 0x4000));
+       *priv &= ((cfg->mem.nwin == 1) &&
+                 (cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10;
+
        p_dev->resource[0]->start = io->win[i].base;
        p_dev->resource[0]->end = io->win[i].len;
-       p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+       if (!try)
+               p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+       else
+               p_dev->io_lines = 16;
        if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
                return try_io_port(p_dev);
 
-       return 0;
+       return -EINVAL;
+}
+
+static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
+                                  int *has_shmem, int try)
+{
+       struct net_device *dev = link->priv;
+       hw_info_t *local_hw_info;
+       pcnet_dev_t *info = PRIV(dev);
+       int priv = try;
+       int ret;
+
+       ret = pcmcia_loop_config(link, pcnet_confcheck, &priv);
+       if (ret) {
+               dev_warn(&link->dev, "no useable port range found\n");
+               return NULL;
+       }
+       *has_shmem = (priv & 0x10);
+
+       if (!link->irq)
+               return NULL;
+
+       if (resource_size(link->resource[1]) == 8) {
+               link->conf.Attributes |= CONF_ENABLE_SPKR;
+               link->conf.Status = CCSR_AUDIO_ENA;
+       }
+       if ((link->manf_id == MANFID_IBM) &&
+           (link->card_id == PRODID_IBM_HOME_AND_AWAY))
+               link->conf.ConfigIndex |= 0x10;
+
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               return NULL;
+
+       dev->irq = link->irq;
+       dev->base_addr = link->resource[0]->start;
+
+       if (info->flags & HAS_MISC_REG) {
+               if ((if_port == 1) || (if_port == 2))
+                       dev->if_port = if_port;
+               else
+                       dev_notice(&link->dev, "invalid if_port requested\n");
+       } else
+               dev->if_port = 0;
+
+       if ((link->conf.ConfigBase == 0x03c0) &&
+           (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
+               dev_info(&link->dev,
+                       "this is an AX88190 card - use axnet_cs instead.\n");
+               return NULL;
+       }
+
+       local_hw_info = get_hwinfo(link);
+       if (!local_hw_info)
+               local_hw_info = get_prom(link);
+       if (!local_hw_info)
+               local_hw_info = get_dl10019(link);
+       if (!local_hw_info)
+               local_hw_info = get_ax88190(link);
+       if (!local_hw_info)
+               local_hw_info = get_hwired(link);
+
+       return local_hw_info;
 }
 
 static int pcnet_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     pcnet_dev_t *info = PRIV(dev);
-    int ret, start_pg, stop_pg, cm_offset;
+    int start_pg, stop_pg, cm_offset;
     int has_shmem = 0;
     hw_info_t *local_hw_info;
 
     dev_dbg(&link->dev, "pcnet_config\n");
 
-    ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
-    if (ret)
-       goto failed;
-
-    if (!link->irq)
-           goto failed;
-
-    if (resource_size(link->resource[1]) == 8) {
-       link->conf.Attributes |= CONF_ENABLE_SPKR;
-       link->conf.Status = CCSR_AUDIO_ENA;
-    }
-    if ((link->manf_id == MANFID_IBM) &&
-       (link->card_id == PRODID_IBM_HOME_AND_AWAY))
-       link->conf.ConfigIndex |= 0x10;
-
-    ret = pcmcia_request_configuration(link, &link->conf);
-    if (ret)
-           goto failed;
-    dev->irq = link->irq;
-    dev->base_addr = link->resource[0]->start;
-    if (info->flags & HAS_MISC_REG) {
-       if ((if_port == 1) || (if_port == 2))
-           dev->if_port = if_port;
-       else
-           printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
-    } else {
-       dev->if_port = 0;
-    }
-
-    if ((link->conf.ConfigBase == 0x03c0) &&
-       (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
-       printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
-       printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
-       goto failed;
-    }
-
-    local_hw_info = get_hwinfo(link);
-    if (local_hw_info == NULL)
-       local_hw_info = get_prom(link);
-    if (local_hw_info == NULL)
-       local_hw_info = get_dl10019(link);
-    if (local_hw_info == NULL)
-       local_hw_info = get_ax88190(link);
-    if (local_hw_info == NULL)
-       local_hw_info = get_hwired(link);
-
-    if (local_hw_info == NULL) {
-       printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
-              " address for io base %#3lx\n", dev->base_addr);
-       goto failed;
+    local_hw_info = pcnet_try_config(link, &has_shmem, 0);
+    if (!local_hw_info) {
+           /* check whether forcing io_lines to 16 helps... */
+           pcmcia_disable_device(link);
+           local_hw_info = pcnet_try_config(link, &has_shmem, 1);
+           if (local_hw_info == NULL) {
+                   dev_notice(&link->dev, "unable to read hardware net"
+                           " address for io base %#3lx\n", dev->base_addr);
+                   goto failed;
+           }
     }
 
     info->flags = local_hw_info->flags;
index 6a6b8199a0d6862467260384e32979584f24d95a..6c58da2b882c845e453ddd7b6bb0b544f4705b83 100644 (file)
@@ -308,7 +308,7 @@ static int mdio_bus_suspend(struct device *dev)
         * may call phy routines that try to grab the same lock, and that may
         * lead to a deadlock.
         */
-       if (phydev->attached_dev)
+       if (phydev->attached_dev && phydev->adjust_link)
                phy_stop_machine(phydev);
 
        if (!mdio_bus_phy_may_suspend(phydev))
@@ -331,7 +331,7 @@ static int mdio_bus_resume(struct device *dev)
                return ret;
 
 no_resume:
-       if (phydev->attached_dev)
+       if (phydev->attached_dev && phydev->adjust_link)
                phy_start_machine(phydev, NULL);
 
        return 0;
index 6695a51e09e9b86340aa0cee342f2fb8d99e1159..736b91703b3e11578eda930e7b119a06f96c0fc6 100644 (file)
@@ -1314,8 +1314,13 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
        hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
        i = 0;
        list_for_each_entry(pch, &ppp->channels, clist) {
-               navail += pch->avail = (pch->chan != NULL);
-               pch->speed = pch->chan->speed;
+               if (pch->chan) {
+                       pch->avail = 1;
+                       navail++;
+                       pch->speed = pch->chan->speed;
+               } else {
+                       pch->avail = 0;
+               }
                if (pch->avail) {
                        if (skb_queue_empty(&pch->file.xq) ||
                                !pch->had_frag) {
index 75ba744b173c89d0f598d1d61183fd5d9dca1675..2c7cf0b64811ed72d4d6368c02d46fa966e7de2f 100644 (file)
@@ -1316,7 +1316,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
                return -ENOMEM;
        }
 
-       skb_reserve(skb, 2);
+       skb_reserve(skb, NET_IP_ALIGN);
 
        dma = pci_map_single(pdev, skb->data,
                        rds_ring->dma_size, PCI_DMA_FROMDEVICE);
@@ -1404,7 +1404,6 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
        if (pkt_offset)
                skb_pull(skb, pkt_offset);
 
-       skb->truesize = skb->len + sizeof(struct sk_buff);
        skb->protocol = eth_type_trans(skb, netdev);
 
        napi_gro_receive(&sds_ring->napi, skb);
@@ -1466,8 +1465,6 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
 
        skb_put(skb, lro_length + data_offset);
 
-       skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
-
        skb_pull(skb, l2_hdr_offset);
        skb->protocol = eth_type_trans(skb, netdev);
 
@@ -1700,8 +1697,6 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
        if (pkt_offset)
                skb_pull(skb, pkt_offset);
 
-       skb->truesize = skb->len + sizeof(struct sk_buff);
-
        if (!qlcnic_check_loopback_buff(skb->data))
                adapter->diag_cnt++;
 
index 078bbf4e6f1933f3ee1e95e2c0dccfea92157088..992db2fa136e9c5e6f5130c053393aa662d4e5c9 100644 (file)
@@ -1212,7 +1212,8 @@ static void rtl8169_update_counters(struct net_device *dev)
        if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
                return;
 
-       counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
+       counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters),
+                                     &paddr, GFP_KERNEL);
        if (!counters)
                return;
 
@@ -1233,7 +1234,8 @@ static void rtl8169_update_counters(struct net_device *dev)
        RTL_W32(CounterAddrLow, 0);
        RTL_W32(CounterAddrHigh, 0);
 
-       pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
+       dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters,
+                         paddr);
 }
 
 static void rtl8169_get_ethtool_stats(struct net_device *dev,
@@ -2934,7 +2936,7 @@ static const struct rtl_cfg_info {
                .hw_start       = rtl_hw_start_8168,
                .region         = 2,
                .align          = 8,
-               .intr_event     = SYSErr | LinkChg | RxOverflow |
+               .intr_event     = SYSErr | RxFIFOOver | LinkChg | RxOverflow |
                                  TxErr | TxOK | RxOK | RxErr,
                .napi_event     = TxErr | TxOK | RxOK | RxOverflow,
                .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
@@ -3292,15 +3294,15 @@ static int rtl8169_open(struct net_device *dev)
 
        /*
         * Rx and Tx desscriptors needs 256 bytes alignment.
-        * pci_alloc_consistent provides more.
+        * dma_alloc_coherent provides more.
         */
-       tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
-                                              &tp->TxPhyAddr);
+       tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES,
+                                            &tp->TxPhyAddr, GFP_KERNEL);
        if (!tp->TxDescArray)
                goto err_pm_runtime_put;
 
-       tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
-                                              &tp->RxPhyAddr);
+       tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES,
+                                            &tp->RxPhyAddr, GFP_KERNEL);
        if (!tp->RxDescArray)
                goto err_free_tx_0;
 
@@ -3334,12 +3336,12 @@ out:
 err_release_ring_2:
        rtl8169_rx_clear(tp);
 err_free_rx_1:
-       pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
-                           tp->RxPhyAddr);
+       dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
+                         tp->RxPhyAddr);
        tp->RxDescArray = NULL;
 err_free_tx_0:
-       pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
-                           tp->TxPhyAddr);
+       dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
+                         tp->TxPhyAddr);
        tp->TxDescArray = NULL;
 err_pm_runtime_put:
        pm_runtime_put_noidle(&pdev->dev);
@@ -3975,7 +3977,7 @@ static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
 {
        struct pci_dev *pdev = tp->pci_dev;
 
-       pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
+       dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
                         PCI_DMA_FROMDEVICE);
        dev_kfree_skb(*sk_buff);
        *sk_buff = NULL;
@@ -4000,7 +4002,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
 static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
                                            struct net_device *dev,
                                            struct RxDesc *desc, int rx_buf_sz,
-                                           unsigned int align)
+                                           unsigned int align, gfp_t gfp)
 {
        struct sk_buff *skb;
        dma_addr_t mapping;
@@ -4008,13 +4010,13 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
 
        pad = align ? align : NET_IP_ALIGN;
 
-       skb = netdev_alloc_skb(dev, rx_buf_sz + pad);
+       skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp);
        if (!skb)
                goto err_out;
 
        skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
 
-       mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
+       mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz,
                                 PCI_DMA_FROMDEVICE);
 
        rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
@@ -4039,7 +4041,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp)
 }
 
 static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
-                          u32 start, u32 end)
+                          u32 start, u32 end, gfp_t gfp)
 {
        u32 cur;
 
@@ -4054,7 +4056,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
 
                skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
                                           tp->RxDescArray + i,
-                                          tp->rx_buf_sz, tp->align);
+                                          tp->rx_buf_sz, tp->align, gfp);
                if (!skb)
                        break;
 
@@ -4082,7 +4084,7 @@ static int rtl8169_init_ring(struct net_device *dev)
        memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
        memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
 
-       if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
+       if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC)
                goto err_out;
 
        rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
@@ -4099,7 +4101,8 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb,
 {
        unsigned int len = tx_skb->len;
 
-       pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
+       dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len,
+                        PCI_DMA_TODEVICE);
        desc->opts1 = 0x00;
        desc->opts2 = 0x00;
        desc->addr = 0x00;
@@ -4243,7 +4246,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
                txd = tp->TxDescArray + entry;
                len = frag->size;
                addr = ((void *) page_address(frag->page)) + frag->page_offset;
-               mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE);
+               mapping = dma_map_single(&tp->pci_dev->dev, addr, len,
+                                        PCI_DMA_TODEVICE);
 
                /* anti gcc 2.95.3 bugware (sic) */
                status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
@@ -4313,7 +4317,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
                tp->tx_skb[entry].skb = skb;
        }
 
-       mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
+       mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len,
+                                PCI_DMA_TODEVICE);
 
        tp->tx_skb[entry].len = len;
        txd->addr = cpu_to_le64(mapping);
@@ -4477,8 +4482,8 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
        if (!skb)
                goto out;
 
-       pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size,
-                                   PCI_DMA_FROMDEVICE);
+       dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size,
+                               PCI_DMA_FROMDEVICE);
        skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
        *sk_buff = skb;
        done = true;
@@ -4549,11 +4554,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                        rtl8169_rx_csum(skb, desc);
 
                        if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
-                               pci_dma_sync_single_for_device(pdev, addr,
+                               dma_sync_single_for_device(&pdev->dev, addr,
                                        pkt_size, PCI_DMA_FROMDEVICE);
                                rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
                        } else {
-                               pci_unmap_single(pdev, addr, tp->rx_buf_sz,
+                               dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz,
                                                 PCI_DMA_FROMDEVICE);
                                tp->Rx_skbuff[entry] = NULL;
                        }
@@ -4583,7 +4588,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
        count = cur_rx - tp->cur_rx;
        tp->cur_rx = cur_rx;
 
-       delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
+       delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC);
        if (!delta && count)
                netif_info(tp, intr, dev, "no Rx buffer allocated\n");
        tp->dirty_rx += delta;
@@ -4625,8 +4630,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                }
 
                /* Work around for rx fifo overflow */
-               if (unlikely(status & RxFIFOOver) &&
-               (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+               if (unlikely(status & RxFIFOOver)) {
                        netif_stop_queue(dev);
                        rtl8169_tx_timeout(dev);
                        break;
@@ -4770,10 +4774,10 @@ static int rtl8169_close(struct net_device *dev)
 
        free_irq(dev->irq, dev);
 
-       pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
-                           tp->RxPhyAddr);
-       pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
-                           tp->TxPhyAddr);
+       dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
+                         tp->RxPhyAddr);
+       dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
+                         tp->TxPhyAddr);
        tp->TxDescArray = NULL;
        tp->RxDescArray = NULL;
 
index 07eb884ff982405c3d15204a04d6188394e329f3..44150f2f7bfd6b206b17e0a64064d5996d0033ea 100644 (file)
@@ -384,7 +384,7 @@ static void rionet_remove(struct rio_dev *rdev)
        free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
                                        __ilog2(sizeof(void *)) + 4 : 0);
        unregister_netdev(ndev);
-       kfree(ndev);
+       free_netdev(ndev);
 
        list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
                list_del(&peer->node);
index cc4bd8c65f8b6a58846065430f8b89c1be6a4bc3..9265315baa0b29bdc2c7a9e20db20462dcf52ae5 100644 (file)
@@ -804,7 +804,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev)
 err_out_free_page:
        free_page((unsigned long) sp->srings);
 err_out_free_dev:
-       kfree(dev);
+       free_netdev(dev);
 
 err_out:
        return err;
index 40e5c46e7571ad46f1c7abf655d0235f89762bfd..465ae7e84507385b079c7922cb7360cec428a30f 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/seq_file.h>
 #include <linux/mii.h>
 #include <linux/slab.h>
+#include <linux/dmi.h>
 #include <asm/irq.h>
 
 #include "skge.h"
@@ -3868,6 +3869,8 @@ static void __devinit skge_show_addr(struct net_device *dev)
        netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr);
 }
 
+static int only_32bit_dma;
+
 static int __devinit skge_probe(struct pci_dev *pdev,
                                const struct pci_device_id *ent)
 {
@@ -3889,7 +3892,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
 
        pci_set_master(pdev);
 
-       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+       if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
                using_dac = 1;
                err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
        } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
@@ -4147,8 +4150,21 @@ static struct pci_driver skge_driver = {
        .shutdown =     skge_shutdown,
 };
 
+static struct dmi_system_id skge_32bit_dma_boards[] = {
+       {
+               .ident = "Gigabyte nForce boards",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"),
+                       DMI_MATCH(DMI_BOARD_NAME, "nForce"),
+               },
+       },
+       {}
+};
+
 static int __init skge_init_module(void)
 {
+       if (dmi_check_system(skge_32bit_dma_boards))
+               only_32bit_dma = 1;
        skge_debug_init();
        return pci_register_driver(&skge_driver);
 }
index 0909ae934ad0fcee52c5eb67101240e77fb70dde..8150ba1541161ab2e7781ade13be970540f835ec 100644 (file)
@@ -58,6 +58,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_VERSION(SMSC_DRV_VERSION);
+MODULE_ALIAS("platform:smsc911x");
 
 #if USE_DEBUG > 0
 static int debug = 16;
index bc3af78a869ff52881077b89cf6e5e544b6e8a91..1ec4b9e0239a8ff8c0d3cb18882ff517ef528881 100644 (file)
@@ -4666,7 +4666,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                                       desc_idx, *post_ptr);
                drop_it_no_recycle:
                        /* Other statistics kept track of by card. */
-                       tp->net_stats.rx_dropped++;
+                       tp->rx_dropped++;
                        goto next_pkt;
                }
 
@@ -4726,7 +4726,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                if (len > (tp->dev->mtu + ETH_HLEN) &&
                    skb->protocol != htons(ETH_P_8021Q)) {
                        dev_kfree_skb(skb);
-                       goto next_pkt;
+                       goto drop_it_no_recycle;
                }
 
                if (desc->type_flags & RXD_FLAG_VLAN &&
@@ -9240,6 +9240,8 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
        stats->rx_missed_errors = old_stats->rx_missed_errors +
                get_stat64(&hw_stats->rx_discards);
 
+       stats->rx_dropped = tp->rx_dropped;
+
        return stats;
 }
 
index 4937bd19096413bae1115b82cc63ce5123207536..be7ff138a7f98d58a4f4d4c8ff7fe70bb83911d9 100644 (file)
@@ -2759,7 +2759,7 @@ struct tg3 {
 
 
        /* begin "everything else" cacheline(s) section */
-       struct rtnl_link_stats64        net_stats;
+       unsigned long                   rx_dropped;
        struct rtnl_link_stats64        net_stats_prev;
        struct tg3_ethtool_stats        estats;
        struct tg3_ethtool_stats        estats_prev;
index 5efa57757a2c8507f5bcf0d0d7f3ac5d1b5a26c3..6888e3d41462081952c7320b501736f03230ba78 100644 (file)
@@ -243,6 +243,7 @@ enum {
        NWayState               = (1 << 14) | (1 << 13) | (1 << 12),
        NWayRestart             = (1 << 12),
        NonselPortActive        = (1 << 9),
+       SelPortActive           = (1 << 8),
        LinkFailStatus          = (1 << 2),
        NetCxnErr               = (1 << 1),
 };
@@ -363,7 +364,9 @@ static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, };
 
 /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/
 static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
-static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, };
+static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
+/* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */
+static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
 
 
@@ -1064,6 +1067,9 @@ static void de21041_media_timer (unsigned long data)
        unsigned int carrier;
        unsigned long flags;
 
+       /* clear port active bits */
+       dw32(SIAStatus, NonselPortActive | SelPortActive);
+
        carrier = (status & NetCxnErr) ? 0 : 1;
 
        if (carrier) {
@@ -1158,14 +1164,29 @@ no_link_yet:
 static void de_media_interrupt (struct de_private *de, u32 status)
 {
        if (status & LinkPass) {
+               /* Ignore if current media is AUI or BNC and we can't use TP */
+               if ((de->media_type == DE_MEDIA_AUI ||
+                    de->media_type == DE_MEDIA_BNC) &&
+                   (de->media_lock ||
+                    !de_ok_to_advertise(de, DE_MEDIA_TP_AUTO)))
+                       return;
+               /* If current media is not TP, change it to TP */
+               if ((de->media_type == DE_MEDIA_AUI ||
+                    de->media_type == DE_MEDIA_BNC)) {
+                       de->media_type = DE_MEDIA_TP_AUTO;
+                       de_stop_rxtx(de);
+                       de_set_media(de);
+                       de_start_rxtx(de);
+               }
                de_link_up(de);
                mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK);
                return;
        }
 
        BUG_ON(!(status & LinkFail));
-
-       if (netif_carrier_ok(de->dev)) {
+       /* Mark the link as down only if current media is TP */
+       if (netif_carrier_ok(de->dev) && de->media_type != DE_MEDIA_AUI &&
+           de->media_type != DE_MEDIA_BNC) {
                de_link_down(de);
                mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
        }
@@ -1229,6 +1250,7 @@ static void de_adapter_sleep (struct de_private *de)
        if (de->de21040)
                return;
 
+       dw32(CSR13, 0); /* Reset phy */
        pci_read_config_dword(de->pdev, PCIPM, &pmctl);
        pmctl |= PM_Sleep;
        pci_write_config_dword(de->pdev, PCIPM, pmctl);
@@ -1574,12 +1596,15 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
                return 0; /* nothing to change */
 
        de_link_down(de);
+       mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);
        de_stop_rxtx(de);
 
        de->media_type = new_media;
        de->media_lock = media_lock;
        de->media_advertise = ecmd->advertising;
        de_set_media(de);
+       if (netif_running(de->dev))
+               de_start_rxtx(de);
 
        return 0;
 }
@@ -1911,8 +1936,14 @@ fill_defaults:
        for (i = 0; i < DE_MAX_MEDIA; i++) {
                if (de->media[i].csr13 == 0xffff)
                        de->media[i].csr13 = t21041_csr13[i];
-               if (de->media[i].csr14 == 0xffff)
-                       de->media[i].csr14 = t21041_csr14[i];
+               if (de->media[i].csr14 == 0xffff) {
+                       /* autonegotiation is broken at least on some chip
+                          revisions - rev. 0x21 works, 0x11 does not */
+                       if (de->pdev->revision < 0x20)
+                               de->media[i].csr14 = t21041_csr14_brk[i];
+                       else
+                               de->media[i].csr14 = t21041_csr14[i];
+               }
                if (de->media[i].csr15 == 0xffff)
                        de->media[i].csr15 = t21041_csr15[i];
        }
@@ -2158,6 +2189,8 @@ static int de_resume (struct pci_dev *pdev)
                dev_err(&dev->dev, "pci_enable_device failed in resume\n");
                goto out;
        }
+       pci_set_master(pdev);
+       de_init_rings(de);
        de_init_hw(de);
 out_attach:
        netif_device_attach(dev);
index 6efca66b87663a84ec7f36529c190aa5a107d401..1cd752f9a6e1e8586f3eda9fcb854ac0226de67a 100644 (file)
@@ -1652,6 +1652,8 @@ static int hso_get_count(struct hso_serial *serial,
        struct uart_icount cnow;
        struct hso_tiocmget  *tiocmget = serial->tiocmget;
 
+       memset(&icount, 0, sizeof(struct serial_icounter_struct));
+
        if (!tiocmget)
                 return -ENOENT;
        spin_lock_irq(&serial->serial_lock);
index 8cc9e319f4356da8904cbf4e7a495d59eba94645..1737d1488b35704f3196975a76bcc919e943808b 100644 (file)
@@ -1244,16 +1244,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
        int i, result;
        struct device *dev = i2400m_dev(i2400m);
        const struct i2400m_msg_hdr *msg_hdr;
-       size_t pl_itr, pl_size, skb_len;
+       size_t pl_itr, pl_size;
        unsigned long flags;
-       unsigned num_pls, single_last;
+       unsigned num_pls, single_last, skb_len;
 
        skb_len = skb->len;
-       d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n",
+       d_fnstart(4, dev, "(i2400m %p skb %p [size %u])\n",
                  i2400m, skb, skb_len);
        result = -EIO;
        msg_hdr = (void *) skb->data;
-       result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb->len);
+       result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb_len);
        if (result < 0)
                goto error_msg_hdr_check;
        result = -EIO;
@@ -1261,10 +1261,10 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
        pl_itr = sizeof(*msg_hdr) +     /* Check payload descriptor(s) */
                num_pls * sizeof(msg_hdr->pld[0]);
        pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN);
-       if (pl_itr > skb->len) {        /* got all the payload descriptors? */
+       if (pl_itr > skb_len) { /* got all the payload descriptors? */
                dev_err(dev, "RX: HW BUG? message too short (%u bytes) for "
                        "%u payload descriptors (%zu each, total %zu)\n",
-                       skb->len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr);
+                       skb_len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr);
                goto error_pl_descr_short;
        }
        /* Walk each payload payload--check we really got it */
@@ -1272,7 +1272,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
                /* work around old gcc warnings */
                pl_size = i2400m_pld_size(&msg_hdr->pld[i]);
                result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i],
-                                                 pl_itr, skb->len);
+                                                 pl_itr, skb_len);
                if (result < 0)
                        goto error_pl_descr_check;
                single_last = num_pls == 1 || i == num_pls - 1;
@@ -1290,16 +1290,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
        if (i < i2400m->rx_pl_min)
                i2400m->rx_pl_min = i;
        i2400m->rx_num++;
-       i2400m->rx_size_acc += skb->len;
-       if (skb->len < i2400m->rx_size_min)
-               i2400m->rx_size_min = skb->len;
-       if (skb->len > i2400m->rx_size_max)
-               i2400m->rx_size_max = skb->len;
+       i2400m->rx_size_acc += skb_len;
+       if (skb_len < i2400m->rx_size_min)
+               i2400m->rx_size_min = skb_len;
+       if (skb_len > i2400m->rx_size_max)
+               i2400m->rx_size_max = skb_len;
        spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 error_pl_descr_check:
 error_pl_descr_short:
 error_msg_hdr_check:
-       d_fnend(4, dev, "(i2400m %p skb %p [size %zu]) = %d\n",
+       d_fnend(4, dev, "(i2400m %p skb %p [size %u]) = %d\n",
                i2400m, skb, skb_len, result);
        return result;
 }
index cc648b6ae31cef3b3a650ab7414b76fa061173e4..a3d95cca8f0c5be9a32c76d57082da1206cd44d1 100644 (file)
@@ -543,7 +543,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
        if (conf_is_ht40(conf))
                return clockrate * 2;
 
-       return clockrate * 2;
+       return clockrate;
 }
 
 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
index 9dd9e64c2b0b1a69f11a6d40a5e0e2cbc84d8b22..8fd00a6e512019075e966a038d2c5d09539ccf85 100644 (file)
@@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        clear_bit(STATUS_SCAN_HW, &priv->status);
        clear_bit(STATUS_SCANNING, &priv->status);
        /* inform mac80211 scan aborted */
-       queue_work(priv->workqueue, &priv->scan_completed);
+       queue_work(priv->workqueue, &priv->abort_scan);
 }
 
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
index 07dbc27964480eebedb67760029dcadab9584f84..e23c4060a0f093e966ca355af1d466880f65b0ee 100644 (file)
@@ -2613,6 +2613,11 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EINVAL;
 
+       if (test_bit(STATUS_SCANNING, &priv->status)) {
+               IWL_DEBUG_INFO(priv, "scan in progress.\n");
+               return -EINVAL;
+       }
+
        if (mode >= IWL_MAX_FORCE_RESET) {
                IWL_DEBUG_INFO(priv, "invalid reset request.\n");
                return -EINVAL;
index 59a308b02f95fdc077a84a7d12d71db7451b1816..d31661c1ce778259996b5428f9cff95b87f1a3db 100644 (file)
@@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        clear_bit(STATUS_SCANNING, &priv->status);
 
        /* inform mac80211 scan aborted */
-       queue_work(priv->workqueue, &priv->scan_completed);
+       queue_work(priv->workqueue, &priv->abort_scan);
 }
 
 static void iwl3945_bg_restart(struct work_struct *data)
index c3ceebb5be84168ae71b845bdc52b3c9a6b557b3..4789f8e8bf7ad91cae0b0a1043349ac96ea5fa64 100644 (file)
 #define DMA_32BIT_PFN          IOVA_PFN(DMA_BIT_MASK(32))
 #define DMA_64BIT_PFN          IOVA_PFN(DMA_BIT_MASK(64))
 
+/* page table handling */
+#define LEVEL_STRIDE           (9)
+#define LEVEL_MASK             (((u64)1 << LEVEL_STRIDE) - 1)
+
+static inline int agaw_to_level(int agaw)
+{
+       return agaw + 2;
+}
+
+static inline int agaw_to_width(int agaw)
+{
+       return 30 + agaw * LEVEL_STRIDE;
+}
+
+static inline int width_to_agaw(int width)
+{
+       return (width - 30) / LEVEL_STRIDE;
+}
+
+static inline unsigned int level_to_offset_bits(int level)
+{
+       return (level - 1) * LEVEL_STRIDE;
+}
+
+static inline int pfn_level_offset(unsigned long pfn, int level)
+{
+       return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
+}
+
+static inline unsigned long level_mask(int level)
+{
+       return -1UL << level_to_offset_bits(level);
+}
+
+static inline unsigned long level_size(int level)
+{
+       return 1UL << level_to_offset_bits(level);
+}
+
+static inline unsigned long align_to_level(unsigned long pfn, int level)
+{
+       return (pfn + level_size(level) - 1) & level_mask(level);
+}
 
 /* VT-d pages must always be _smaller_ than MM pages. Otherwise things
    are never going to work. */
@@ -434,8 +477,6 @@ void free_iova_mem(struct iova *iova)
 }
 
 
-static inline int width_to_agaw(int width);
-
 static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
 {
        unsigned long sagaw;
@@ -646,51 +687,6 @@ out:
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-/* page table handling */
-#define LEVEL_STRIDE           (9)
-#define LEVEL_MASK             (((u64)1 << LEVEL_STRIDE) - 1)
-
-static inline int agaw_to_level(int agaw)
-{
-       return agaw + 2;
-}
-
-static inline int agaw_to_width(int agaw)
-{
-       return 30 + agaw * LEVEL_STRIDE;
-
-}
-
-static inline int width_to_agaw(int width)
-{
-       return (width - 30) / LEVEL_STRIDE;
-}
-
-static inline unsigned int level_to_offset_bits(int level)
-{
-       return (level - 1) * LEVEL_STRIDE;
-}
-
-static inline int pfn_level_offset(unsigned long pfn, int level)
-{
-       return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
-}
-
-static inline unsigned long level_mask(int level)
-{
-       return -1UL << level_to_offset_bits(level);
-}
-
-static inline unsigned long level_size(int level)
-{
-       return 1UL << level_to_offset_bits(level);
-}
-
-static inline unsigned long align_to_level(unsigned long pfn, int level)
-{
-       return (pfn + level_size(level) - 1) & level_mask(level);
-}
-
 static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
                                      unsigned long pfn)
 {
@@ -3761,6 +3757,33 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
 
+#define GGC 0x52
+#define GGC_MEMORY_SIZE_MASK   (0xf << 8)
+#define GGC_MEMORY_SIZE_NONE   (0x0 << 8)
+#define GGC_MEMORY_SIZE_1M     (0x1 << 8)
+#define GGC_MEMORY_SIZE_2M     (0x3 << 8)
+#define GGC_MEMORY_VT_ENABLED  (0x8 << 8)
+#define GGC_MEMORY_SIZE_2M_VT  (0x9 << 8)
+#define GGC_MEMORY_SIZE_3M_VT  (0xa << 8)
+#define GGC_MEMORY_SIZE_4M_VT  (0xb << 8)
+
+static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
+{
+       unsigned short ggc;
+
+       if (pci_read_config_word(dev, GGC, &ggc))
+               return;
+
+       if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
+               printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
+               dmar_map_gfx = 0;
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
+
 /* On Tylersburg chipsets, some BIOSes have been known to enable the
    ISOCH DMAR unit for the Azalia sound device, but not give it any
    TLB entries, which causes it to deadlock. Check for that.  We do
index ce6a3666b3d9878f70be6fb65f3e1272fdf6b6b2..553d8ee55c1c4aa3c9f6567867642d3505cf89df 100644 (file)
@@ -608,7 +608,7 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno,
  * the VF BAR size multiplied by the number of VFs.  The alignment
  * is just the VF BAR size.
  */
-int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
 {
        struct resource tmp;
        enum pci_bar_type type;
index 7754a678ab15cc77445d396aa59409658bf8006f..6beb11b617a92973f7a32cc47a7343a759218d6e 100644 (file)
@@ -264,7 +264,8 @@ extern int pci_iov_init(struct pci_dev *dev);
 extern void pci_iov_release(struct pci_dev *dev);
 extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
                                enum pci_bar_type *type);
-extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
+extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev,
+                                                   int resno);
 extern void pci_restore_iov_state(struct pci_dev *dev);
 extern int pci_iov_bus_range(struct pci_bus *bus);
 
@@ -320,7 +321,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
 }
 #endif /* CONFIG_PCI_IOV */
 
-static inline int pci_resource_alignment(struct pci_dev *dev,
+static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
                                         struct resource *res)
 {
 #ifdef CONFIG_PCI_IOV
index 89ed181cd90cd9cd68506a212eb423ba60f9c8e2..857ae01734a66156c8abb92335be91cc674964a0 100644 (file)
@@ -162,6 +162,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1,       quirk_isa_d
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,     PCI_DEVICE_ID_NEC_CBUS_2,       quirk_isa_dma_hangs);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,     PCI_DEVICE_ID_NEC_CBUS_3,       quirk_isa_dma_hangs);
 
+/*
+ * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear
+ * for some HT machines to use C4 w/o hanging.
+ */
+static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev)
+{
+       u32 pmbase;
+       u16 pm1a;
+
+       pci_read_config_dword(dev, 0x40, &pmbase);
+       pmbase = pmbase & 0xff80;
+       pm1a = inw(pmbase);
+
+       if (pm1a & 0x10) {
+               dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+               outw(0x10, pmbase);
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts);
+
 /*
  *     Chipsets where PCI->PCI transfers vanish or hang
  */
index 54aa1c238cb34a5966a1d8ff6621835846514d87..9ba4dade69a4d67cd5b0efc1e4c55a70dbf349c1 100644 (file)
@@ -163,7 +163,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev,
        c = p_dev->function_config;
 
        if (!(c->state & CONFIG_LOCKED)) {
-               dev_dbg(&s->dev, "Configuration isnt't locked\n");
+               dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
                mutex_unlock(&s->ops_mutex);
                return -EACCES;
        }
@@ -220,7 +220,7 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
        s->win[w].card_start = offset;
        ret = s->ops->set_mem_map(s, &s->win[w]);
        if (ret)
-               dev_warn(&s->dev, "failed to set_mem_map\n");
+               dev_warn(&p_dev->dev, "failed to set_mem_map\n");
        mutex_unlock(&s->ops_mutex);
        return ret;
 } /* pcmcia_map_mem_page */
@@ -244,18 +244,18 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        c = p_dev->function_config;
 
        if (!(s->state & SOCKET_PRESENT)) {
-               dev_dbg(&s->dev, "No card present\n");
+               dev_dbg(&p_dev->dev, "No card present\n");
                ret = -ENODEV;
                goto unlock;
        }
        if (!(c->state & CONFIG_LOCKED)) {
-               dev_dbg(&s->dev, "Configuration isnt't locked\n");
+               dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
                ret = -EACCES;
                goto unlock;
        }
 
        if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) {
-               dev_dbg(&s->dev,
+               dev_dbg(&p_dev->dev,
                        "changing Vcc or IRQ is not allowed at this time\n");
                ret = -EINVAL;
                goto unlock;
@@ -265,20 +265,22 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
            (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                if (mod->Vpp1 != mod->Vpp2) {
-                       dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
+                       dev_dbg(&p_dev->dev,
+                               "Vpp1 and Vpp2 must be the same\n");
                        ret = -EINVAL;
                        goto unlock;
                }
                s->socket.Vpp = mod->Vpp1;
                if (s->ops->set_socket(s, &s->socket)) {
-                       dev_printk(KERN_WARNING, &s->dev,
+                       dev_printk(KERN_WARNING, &p_dev->dev,
                                   "Unable to set VPP\n");
                        ret = -EIO;
                        goto unlock;
                }
        } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
                   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
-               dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
+               dev_dbg(&p_dev->dev,
+                       "changing Vcc is not allowed at this time\n");
                ret = -EINVAL;
                goto unlock;
        }
@@ -401,7 +403,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
        win = &s->win[w];
 
        if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
-               dev_dbg(&s->dev, "not releasing unknown window\n");
+               dev_dbg(&p_dev->dev, "not releasing unknown window\n");
                mutex_unlock(&s->ops_mutex);
                return -EINVAL;
        }
@@ -439,7 +441,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
                return -ENODEV;
 
        if (req->IntType & INT_CARDBUS) {
-               dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
+               dev_dbg(&p_dev->dev, "IntType may not be INT_CARDBUS\n");
                return -EINVAL;
        }
 
@@ -447,7 +449,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
        c = p_dev->function_config;
        if (c->state & CONFIG_LOCKED) {
                mutex_unlock(&s->ops_mutex);
-               dev_dbg(&s->dev, "Configuration is locked\n");
+               dev_dbg(&p_dev->dev, "Configuration is locked\n");
                return -EACCES;
        }
 
@@ -455,7 +457,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
        s->socket.Vpp = req->Vpp;
        if (s->ops->set_socket(s, &s->socket)) {
                mutex_unlock(&s->ops_mutex);
-               dev_printk(KERN_WARNING, &s->dev,
+               dev_printk(KERN_WARNING, &p_dev->dev,
                           "Unable to set socket state\n");
                return -EINVAL;
        }
@@ -569,19 +571,20 @@ int pcmcia_request_io(struct pcmcia_device *p_dev)
        int ret = -EINVAL;
 
        mutex_lock(&s->ops_mutex);
-       dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]);
+       dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR",
+               &c->io[0], &c->io[1]);
 
        if (!(s->state & SOCKET_PRESENT)) {
-               dev_dbg(&s->dev, "pcmcia_request_io: No card present\n");
+               dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n");
                goto out;
        }
 
        if (c->state & CONFIG_LOCKED) {
-               dev_dbg(&s->dev, "Configuration is locked\n");
+               dev_dbg(&p_dev->dev, "Configuration is locked\n");
                goto out;
        }
        if (c->state & CONFIG_IO_REQ) {
-               dev_dbg(&s->dev, "IO already configured\n");
+               dev_dbg(&p_dev->dev, "IO already configured\n");
                goto out;
        }
 
@@ -592,7 +595,13 @@ int pcmcia_request_io(struct pcmcia_device *p_dev)
        if (c->io[1].end) {
                ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
                if (ret) {
+                       struct resource tmp = c->io[0];
+                       /* release the previously allocated resource */
                        release_io_space(s, &c->io[0]);
+                       /* but preserve the settings, for they worked... */
+                       c->io[0].end = resource_size(&tmp);
+                       c->io[0].start = tmp.start;
+                       c->io[0].flags = tmp.flags;
                        goto out;
                }
        } else
@@ -601,7 +610,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev)
        c->state |= CONFIG_IO_REQ;
        p_dev->_io = 1;
 
-       dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR",
+       dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR",
                &c->io[0], &c->io[1]);
 out:
        mutex_unlock(&s->ops_mutex);
@@ -800,7 +809,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        int w;
 
        if (!(s->state & SOCKET_PRESENT)) {
-               dev_dbg(&s->dev, "No card present\n");
+               dev_dbg(&p_dev->dev, "No card present\n");
                return -ENODEV;
        }
 
@@ -809,12 +818,12 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
                req->Size = s->map_size;
        align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size;
        if (req->Size & (s->map_size-1)) {
-               dev_dbg(&s->dev, "invalid map size\n");
+               dev_dbg(&p_dev->dev, "invalid map size\n");
                return -EINVAL;
        }
        if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
            (req->Base & (align-1))) {
-               dev_dbg(&s->dev, "invalid base address\n");
+               dev_dbg(&p_dev->dev, "invalid base address\n");
                return -EINVAL;
        }
        if (req->Base)
@@ -826,7 +835,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
                if (!(s->state & SOCKET_WIN_REQ(w)))
                        break;
        if (w == MAX_WIN) {
-               dev_dbg(&s->dev, "all windows are used already\n");
+               dev_dbg(&p_dev->dev, "all windows are used already\n");
                mutex_unlock(&s->ops_mutex);
                return -EINVAL;
        }
@@ -837,7 +846,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
                win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
                                                0, s);
                if (!win->res) {
-                       dev_dbg(&s->dev, "allocating mem region failed\n");
+                       dev_dbg(&p_dev->dev, "allocating mem region failed\n");
                        mutex_unlock(&s->ops_mutex);
                        return -EINVAL;
                }
@@ -851,7 +860,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        win->card_start = 0;
 
        if (s->ops->set_mem_map(s, win) != 0) {
-               dev_dbg(&s->dev, "failed to set memory mapping\n");
+               dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
                mutex_unlock(&s->ops_mutex);
                return -EIO;
        }
@@ -874,7 +883,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
        if (win->res)
                request_resource(&iomem_resource, res);
 
-       dev_dbg(&s->dev, "request_window results in %pR\n", res);
+       dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
 
        mutex_unlock(&s->ops_mutex);
        *wh = res;
index b8a869af0f4410dd25a3cb0b4b5ace093ea5d6a5..deef6656ab7b8e2015e382ed48b85e067c7503a5 100644 (file)
@@ -646,7 +646,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
        if (!pci_resource_start(dev, 0)) {
                dev_warn(&dev->dev, "refusing to load the driver as the "
                        "io_base is NULL.\n");
-               goto err_out_free_mem;
+               goto err_out_disable;
        }
 
        dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
index 9024480a82288ec071e26008f616fe2d9556c18b..c44a5e8b8b82da9d06706d9cd3a3ec0fcb2b883c 100644 (file)
@@ -51,7 +51,6 @@
  * TODO:
  *   - handle CPU hotplug
  *   - provide turbo enable/disable api
- *   - make sure we can write turbo enable/disable reg based on MISC_EN
  *
  * Related documents:
  *   - CDI 403777, 403778 - Auburndale EDS vol 1 & 2
 #define THM_TC2                0xac
 #define THM_DTV                0xb0
 #define THM_ITV                0xd8
-#define   ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */
+#define   ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */
 #define   ITV_ME_SEQNO_SHIFT (16)
 #define   ITV_MCH_TEMP_MASK 0x0000ff00
 #define   ITV_MCH_TEMP_SHIFT (8)
@@ -325,6 +324,7 @@ struct ips_driver {
        bool gpu_preferred;
        bool poll_turbo_status;
        bool second_cpu;
+       bool turbo_toggle_allowed;
        struct ips_mcp_limits *limits;
 
        /* Optional MCH interfaces for if i915 is in use */
@@ -415,7 +415,7 @@ static void ips_cpu_lower(struct ips_driver *ips)
        new_limit = cur_limit - 8; /* 1W decrease */
 
        /* Clamp to SKU TDP limit */
-       if (((new_limit * 10) / 8) < (ips->orig_turbo_limit & TURBO_TDP_MASK))
+       if (new_limit  < (ips->orig_turbo_limit & TURBO_TDP_MASK))
                new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK;
 
        thm_writew(THM_MPCPC, (new_limit * 10) / 8);
@@ -461,7 +461,8 @@ static void ips_enable_cpu_turbo(struct ips_driver *ips)
        if (ips->__cpu_turbo_on)
                return;
 
-       on_each_cpu(do_enable_cpu_turbo, ips, 1);
+       if (ips->turbo_toggle_allowed)
+               on_each_cpu(do_enable_cpu_turbo, ips, 1);
 
        ips->__cpu_turbo_on = true;
 }
@@ -498,7 +499,8 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips)
        if (!ips->__cpu_turbo_on)
                return;
 
-       on_each_cpu(do_disable_cpu_turbo, ips, 1);
+       if (ips->turbo_toggle_allowed)
+               on_each_cpu(do_disable_cpu_turbo, ips, 1);
 
        ips->__cpu_turbo_on = false;
 }
@@ -598,17 +600,29 @@ static bool mcp_exceeded(struct ips_driver *ips)
 {
        unsigned long flags;
        bool ret = false;
+       u32 temp_limit;
+       u32 avg_power;
+       const char *msg = "MCP limit exceeded: ";
 
        spin_lock_irqsave(&ips->turbo_status_lock, flags);
-       if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100))
-               ret = true;
-       if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit)
+
+       temp_limit = ips->mcp_temp_limit * 100;
+       if (ips->mcp_avg_temp > temp_limit) {
+               dev_info(&ips->dev->dev,
+                       "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp,
+                       temp_limit);
                ret = true;
-       spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
+       }
 
-       if (ret)
+       avg_power = ips->cpu_avg_power + ips->mch_avg_power;
+       if (avg_power > ips->mcp_power_limit) {
                dev_info(&ips->dev->dev,
-                        "MCP power or thermal limit exceeded\n");
+                       "%sAvg power %u, limit %u\n", msg, avg_power,
+                       ips->mcp_power_limit);
+               ret = true;
+       }
+
+       spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
 
        return ret;
 }
@@ -662,6 +676,27 @@ static bool mch_exceeded(struct ips_driver *ips)
        return ret;
 }
 
+/**
+ * verify_limits - verify BIOS provided limits
+ * @ips: IPS structure
+ *
+ * BIOS can optionally provide non-default limits for power and temp.  Check
+ * them here and use the defaults if the BIOS values are not provided or
+ * are otherwise unusable.
+ */
+static void verify_limits(struct ips_driver *ips)
+{
+       if (ips->mcp_power_limit < ips->limits->mcp_power_limit ||
+           ips->mcp_power_limit > 35000)
+               ips->mcp_power_limit = ips->limits->mcp_power_limit;
+
+       if (ips->mcp_temp_limit < ips->limits->core_temp_limit ||
+           ips->mcp_temp_limit < ips->limits->mch_temp_limit ||
+           ips->mcp_temp_limit > 150)
+               ips->mcp_temp_limit = min(ips->limits->core_temp_limit,
+                                         ips->limits->mch_temp_limit);
+}
+
 /**
  * update_turbo_limits - get various limits & settings from regs
  * @ips: IPS driver struct
@@ -680,12 +715,21 @@ static void update_turbo_limits(struct ips_driver *ips)
        u32 hts = thm_readl(THM_HTS);
 
        ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS);
-       ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS);
+       /* 
+        * Disable turbo for now, until we can figure out why the power figures
+        * are wrong
+        */
+       ips->cpu_turbo_enabled = false;
+
+       if (ips->gpu_busy)
+               ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS);
+
        ips->core_power_limit = thm_readw(THM_MPCPC);
        ips->mch_power_limit = thm_readw(THM_MMGPC);
        ips->mcp_temp_limit = thm_readw(THM_PTL);
        ips->mcp_power_limit = thm_readw(THM_MPPC);
 
+       verify_limits(ips);
        /* Ignore BIOS CPU vs GPU pref */
 }
 
@@ -858,7 +902,7 @@ static u32 get_cpu_power(struct ips_driver *ips, u32 *last, int period)
        ret = (ret * 1000) / 65535;
        *last = val;
 
-       return ret;
+       return 0;
 }
 
 static const u16 temp_decay_factor = 2;
@@ -940,7 +984,6 @@ static int ips_monitor(void *data)
                kfree(mch_samples);
                kfree(cpu_samples);
                kfree(mchp_samples);
-               kthread_stop(ips->adjust);
                return -ENOMEM;
        }
 
@@ -948,7 +991,7 @@ static int ips_monitor(void *data)
                ITV_ME_SEQNO_SHIFT;
        seqno_timestamp = get_jiffies_64();
 
-       old_cpu_power = thm_readl(THM_CEC) / 65535;
+       old_cpu_power = thm_readl(THM_CEC);
        schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD));
 
        /* Collect an initial average */
@@ -1150,11 +1193,18 @@ static irqreturn_t ips_irq_handler(int irq, void *arg)
                                STS_GPL_SHIFT;
                        /* ignore EC CPU vs GPU pref */
                        ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS);
-                       ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS);
+                       /* 
+                        * Disable turbo for now, until we can figure
+                        * out why the power figures are wrong
+                        */
+                       ips->cpu_turbo_enabled = false;
+                       if (ips->gpu_busy)
+                               ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS);
                        ips->mcp_temp_limit = (sts & STS_PTL_MASK) >>
                                STS_PTL_SHIFT;
                        ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >>
                                STS_PPL_SHIFT;
+                       verify_limits(ips);
                        spin_unlock(&ips->turbo_status_lock);
 
                        thm_writeb(THM_SEC, SEC_ACK);
@@ -1333,8 +1383,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
         * turbo manually or we'll get an illegal MSR access, even though
         * turbo will still be available.
         */
-       if (!(misc_en & IA32_MISC_TURBO_EN))
-               ; /* add turbo MSR write allowed flag if necessary */
+       if (misc_en & IA32_MISC_TURBO_EN)
+               ips->turbo_toggle_allowed = true;
+       else
+               ips->turbo_toggle_allowed = false;
 
        if (strstr(boot_cpu_data.x86_model_id, "CPU       M"))
                limits = &ips_sv_limits;
@@ -1351,9 +1403,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
        tdp = turbo_power & TURBO_TDP_MASK;
 
        /* Sanity check TDP against CPU */
-       if (limits->mcp_power_limit != (tdp / 8) * 1000) {
-               dev_warn(&ips->dev->dev, "Warning: CPU TDP doesn't match expected value (found %d, expected %d)\n",
-                        tdp / 8, limits->mcp_power_limit / 1000);
+       if (limits->core_power_limit != (tdp / 8) * 1000) {
+               dev_info(&ips->dev->dev, "CPU TDP doesn't match expected value (found %d, expected %d)\n",
+                        tdp / 8, limits->core_power_limit / 1000);
+               limits->core_power_limit = (tdp / 8) * 1000;
        }
 
 out:
@@ -1390,7 +1443,7 @@ static bool ips_get_i915_syms(struct ips_driver *ips)
        return true;
 
 out_put_busy:
-       symbol_put(i915_gpu_turbo_disable);
+       symbol_put(i915_gpu_busy);
 out_put_lower:
        symbol_put(i915_gpu_lower);
 out_put_raise:
@@ -1532,22 +1585,27 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
        /* Save turbo limits & ratios */
        rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit);
 
-       ips_enable_cpu_turbo(ips);
-       ips->cpu_turbo_enabled = true;
+       ips_disable_cpu_turbo(ips);
+       ips->cpu_turbo_enabled = false;
 
-       /* Set up the work queue and monitor/adjust threads */
-       ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor");
-       if (IS_ERR(ips->monitor)) {
+       /* Create thermal adjust thread */
+       ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust");
+       if (IS_ERR(ips->adjust)) {
                dev_err(&dev->dev,
-                       "failed to create thermal monitor thread, aborting\n");
+                       "failed to create thermal adjust thread, aborting\n");
                ret = -ENOMEM;
                goto error_free_irq;
+
        }
 
-       ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust");
-       if (IS_ERR(ips->adjust)) {
+       /*
+        * Set up the work queue and monitor thread. The monitor thread
+        * will wake up ips_adjust thread.
+        */
+       ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor");
+       if (IS_ERR(ips->monitor)) {
                dev_err(&dev->dev,
-                       "failed to create thermal adjust thread, aborting\n");
+                       "failed to create thermal monitor thread, aborting\n");
                ret = -ENOMEM;
                goto error_thread_cleanup;
        }
@@ -1566,7 +1624,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return ret;
 
 error_thread_cleanup:
-       kthread_stop(ips->monitor);
+       kthread_stop(ips->adjust);
 error_free_irq:
        free_irq(ips->dev->irq, ips);
 error_unmap:
index e35ed128bdef439313a107106f36c47e03dc5b7e..2d61186ad5a2e96708fcec4beb0a8402eb2bc09f 100644 (file)
@@ -3093,7 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
        TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
 };
 
-typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
+typedef u16 tpacpi_keymap_entry_t;
+typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
 
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
@@ -3230,7 +3231,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
        };
 
 #define TPACPI_HOTKEY_MAP_SIZE         sizeof(tpacpi_keymap_t)
-#define TPACPI_HOTKEY_MAP_TYPESIZE     sizeof(tpacpi_keymap_t[0])
+#define TPACPI_HOTKEY_MAP_TYPESIZE     sizeof(tpacpi_keymap_entry_t)
 
        int res, i;
        int status;
index 936bae560fa1f730255bde8a94c9493c953efdfd..dc628cb2e762803b6f3374d33a99feae5b08640c 100644 (file)
@@ -233,6 +233,7 @@ static int calculate_capacity(enum apm_source source)
                empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
                now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
                avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+               break;
        case SOURCE_VOLTAGE:
                full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
                empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
index c61ffec2ff106ca7aa153dac55cebf5a77b495b1..2a10cd361181292f9d6bbef7ef38cda9772c839b 100644 (file)
@@ -185,8 +185,8 @@ static int pmic_scu_ipc_battery_property_get(struct battery_property *prop)
 {
        u32 data[3];
        u8 *p = (u8 *)&data[1];
-       int err = intel_scu_ipc_command(IPC_CMD_BATTERY_PROPERTY,
-                               IPCMSG_BATTERY, NULL, 0, data, 3);
+       int err = intel_scu_ipc_command(IPCMSG_BATTERY,
+                               IPC_CMD_BATTERY_PROPERTY, NULL, 0, data, 3);
 
        prop->capacity = data[0];
        prop->crnt = *p++;
@@ -207,7 +207,7 @@ static int pmic_scu_ipc_battery_property_get(struct battery_property *prop)
 
 static int pmic_scu_ipc_set_charger(int charger)
 {
-       return intel_scu_ipc_simple_command(charger, IPCMSG_BATTERY);
+       return intel_scu_ipc_simple_command(IPCMSG_BATTERY, charger);
 }
 
 /**
index 7d149a8d8d9b6cb7fe92f73b71536a723cbf6249..2ce2eb71d0f5be88e03495ea1de06e16902a461a 100644 (file)
@@ -215,7 +215,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
        struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
        int ret = -EINVAL;
 
-       if (info->vol_table && (index < (2 << info->vol_nbits))) {
+       if (info->vol_table && (index < (1 << info->vol_nbits))) {
                ret = info->vol_table[index];
                if (info->slope_double)
                        ret <<= 1;
@@ -233,7 +233,7 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
                max_uV = max_uV >> 1;
        }
        if (info->vol_table) {
-               for (i = 0; i < (2 << info->vol_nbits); i++) {
+               for (i = 0; i < (1 << info->vol_nbits); i++) {
                        if (!info->vol_table[i])
                                break;
                        if ((min_uV <= info->vol_table[i])
index 11790990277a3dbd9a96ca2ba398f505480f5e19..b349266a43de63c150b92ab36c8b49274958392b 100644 (file)
@@ -634,12 +634,9 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
                                "%s: failed to register regulator %s err %d\n",
                                __func__, ab3100_regulator_desc[i].name,
                                err);
-                       i--;
                        /* remove the already registered regulators */
-                       while (i > 0) {
+                       while (--i >= 0)
                                regulator_unregister(ab3100_regulators[i].rdev);
-                               i--;
-                       }
                        return err;
                }
 
index dc3f1a491675abe371a483f862b01b60d1489a47..28c7ae67cec9ea1d573c94b30d8732f7770340b0 100644 (file)
@@ -157,7 +157,7 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector)
        if (info->fixed_uV)
                return info->fixed_uV;
 
-       if (selector > info->voltages_len)
+       if (selector >= info->voltages_len)
                return -EINVAL;
 
        return info->supported_voltages[selector];
@@ -344,13 +344,14 @@ static inline struct ab8500_regulator_info *find_regulator_info(int id)
 static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
 {
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
-       struct ab8500_platform_data *pdata = dev_get_platdata(ab8500->dev);
+       struct ab8500_platform_data *pdata;
        int i, err;
 
        if (!ab8500) {
                dev_err(&pdev->dev, "null mfd parent\n");
                return -EINVAL;
        }
+       pdata = dev_get_platdata(ab8500->dev);
 
        /* register all regulators */
        for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
@@ -368,11 +369,9 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
                                        info->desc.name);
                        /* when we fail, un-register all earlier regulators */
-                       i--;
-                       while (i > 0) {
+                       while (--i >= 0) {
                                info = &ab8500_regulator_info[i];
                                regulator_unregister(info->regulator);
-                               i--;
                        }
                        return err;
                }
index d59d2f2314afc999b8c9b6b9b9eb1c68df02b08f..a4be41614eebd41fa5733c09a7e9645c64c72c59 100644 (file)
@@ -25,7 +25,7 @@ struct ad5398_chip_info {
        unsigned int current_level;
        unsigned int current_mask;
        unsigned int current_offset;
-       struct regulator_dev rdev;
+       struct regulator_dev *rdev;
 };
 
 static int ad5398_calc_current(struct ad5398_chip_info *chip,
@@ -211,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, ad5398_id);
 static int __devinit ad5398_probe(struct i2c_client *client,
                                const struct i2c_device_id *id)
 {
-       struct regulator_dev *rdev;
        struct regulator_init_data *init_data = client->dev.platform_data;
        struct ad5398_chip_info *chip;
        const struct ad5398_current_data_format *df =
@@ -233,9 +232,10 @@ static int __devinit ad5398_probe(struct i2c_client *client,
        chip->current_offset = df->current_offset;
        chip->current_mask = (chip->current_level - 1) << chip->current_offset;
 
-       rdev = regulator_register(&ad5398_reg, &client->dev, init_data, chip);
-       if (IS_ERR(rdev)) {
-               ret = PTR_ERR(rdev);
+       chip->rdev = regulator_register(&ad5398_reg, &client->dev,
+                                       init_data, chip);
+       if (IS_ERR(chip->rdev)) {
+               ret = PTR_ERR(chip->rdev);
                dev_err(&client->dev, "failed to register %s %s\n",
                        id->name, ad5398_reg.name);
                goto err;
@@ -254,9 +254,8 @@ static int __devexit ad5398_remove(struct i2c_client *client)
 {
        struct ad5398_chip_info *chip = i2c_get_clientdata(client);
 
-       regulator_unregister(&chip->rdev);
+       regulator_unregister(chip->rdev);
        kfree(chip);
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index 422a709d271d51d593899db82b0b930cf93f2847..cc8b337b9119de5e955aabe1935ad931a895c71a 100644 (file)
@@ -700,7 +700,7 @@ static void print_constraints(struct regulator_dev *rdev)
            constraints->min_uA != constraints->max_uA) {
                ret = _regulator_get_current_limit(rdev);
                if (ret > 0)
-                       count += sprintf(buf + count, "at %d uA ", ret / 1000);
+                       count += sprintf(buf + count, "at %d mA ", ret / 1000);
        }
 
        if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
@@ -2302,8 +2302,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        dev_set_name(&rdev->dev, "regulator.%d",
                     atomic_inc_return(&regulator_no) - 1);
        ret = device_register(&rdev->dev);
-       if (ret != 0)
+       if (ret != 0) {
+               put_device(&rdev->dev);
                goto clean;
+       }
 
        dev_set_drvdata(&rdev->dev, rdev);
 
index e49d2bd393f27cdd105f0ba9a16e7a9c96b99c62..b8cc6389a541a0e3cbc0cc4a60231c166cd2e2e1 100644 (file)
@@ -165,7 +165,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
        mutex_init(&pmic->mtx);
 
        for (i = 0; i < 3; i++) {
-               pmic->rdev[i] = regulator_register(&isl_rd[0], &i2c->dev,
+               pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
                                                init_data, pmic);
                if (IS_ERR(pmic->rdev[i])) {
                        dev_err(&i2c->dev, "failed to register %s\n", id->name);
@@ -191,8 +191,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
        struct isl_pmic *pmic = i2c_get_clientdata(i2c);
        int i;
 
-       i2c_set_clientdata(i2c, NULL);
-
        for (i = 0; i < 3; i++)
                regulator_unregister(pmic->rdev[i]);
 
index 8867c2710a6d07319d9ad1b6d926922b280f30dc..559cfa271a4452389577be87543ce6116bfc0ebf 100644 (file)
@@ -121,14 +121,14 @@ static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
        if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
                return -EINVAL;
 
-       if (min_uV >= 3000000)
-               selector = 3;
-       if (min_uV < 3000000)
-               selector = 2;
-       if (min_uV < 2500000)
-               selector = 1;
        if (min_uV < 1800000)
                selector = 0;
+       else if (min_uV < 2500000)
+               selector = 1;
+       else if (min_uV < 3000000)
+               selector = 2;
+       else if (min_uV >= 3000000)
+               selector = 3;
 
        if (max1586_v6_calc_voltage(selector) > max_uV)
                return -EINVAL;
index 4520ace3f7e707f82ccbf0fb068df921dfc6c2df..6b60a9c0366b3c5236fa7019844274c8b1155b3e 100644 (file)
@@ -330,7 +330,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
                /* set external clock frequency */
                info->extclk_freq = pdata->extclk_freq;
                max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK,
-                                info->extclk_freq);
+                                info->extclk_freq << 6);
        }
 
        if (pdata->ramp_timing) {
index ab67298799f95a573f7a901199ac966cdc79847b..a1baf1fbe00472e71845591e2d427715a720a226 100644 (file)
@@ -549,7 +549,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
        if (!max8998)
                return -ENOMEM;
 
-       size = sizeof(struct regulator_dev *) * (pdata->num_regulators + 1);
+       size = sizeof(struct regulator_dev *) * pdata->num_regulators;
        max8998->rdev = kzalloc(size, GFP_KERNEL);
        if (!max8998->rdev) {
                kfree(max8998);
@@ -557,7 +557,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
        }
 
        rdev = max8998->rdev;
+       max8998->dev = &pdev->dev;
        max8998->iodev = iodev;
+       max8998->num_regulators = pdata->num_regulators;
        platform_set_drvdata(pdev, max8998);
 
        for (i = 0; i < pdata->num_regulators; i++) {
@@ -583,7 +585,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
 
        return 0;
 err:
-       for (i = 0; i <= max8998->num_regulators; i++)
+       for (i = 0; i < max8998->num_regulators; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
 
@@ -599,7 +601,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev)
        struct regulator_dev **rdev = max8998->rdev;
        int i;
 
-       for (i = 0; i <= max8998->num_regulators; i++)
+       for (i = 0; i < max8998->num_regulators; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
 
index c239f42aa4a3efa4ba47743f3d031c00f750a81a..020f5878d7fff19bb35f58b7cb2745d10beeb484 100644 (file)
@@ -626,12 +626,6 @@ fail:
        return error;
 }
 
-/**
- * tps6507x_remove - TPS6507x driver i2c remove handler
- * @client: i2c driver client device structure
- *
- * Unregister TPS driver as an i2c client device driver
- */
 static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
 {
        struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
index 8cff1413a147f1822336160602c57d253f3d1902..51237fbb1bbb7e15f952296a9ffcb9f668418fc9 100644 (file)
@@ -133,7 +133,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
        mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
        val = (val & mask) >> ri->volt_shift;
 
-       if (val > ri->desc.n_voltages)
+       if (val >= ri->desc.n_voltages)
                BUG();
 
        return ri->voltages[val] * 1000;
@@ -150,7 +150,7 @@ static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev,
        if (ret)
                return ret;
 
-       return tps6586x_set_bits(parent, ri->go_reg, ri->go_bit);
+       return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
 }
 
 static int tps6586x_regulator_enable(struct regulator_dev *rdev)
index e686cdb61b97cd8a54ab7fbecb1312a41e333595..9edf8f692341d89ed3645459da80be221c94eeec 100644 (file)
@@ -215,8 +215,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
 
        case REGULATOR_MODE_IDLE:
                ret = wm831x_set_bits(wm831x, ctrl_reg,
-                                     WM831X_LDO1_LP_MODE,
-                                     WM831X_LDO1_LP_MODE);
+                                     WM831X_LDO1_LP_MODE, 0);
                if (ret < 0)
                        return ret;
 
@@ -225,10 +224,12 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
                                      WM831X_LDO1_ON_MODE);
                if (ret < 0)
                        return ret;
+               break;
 
        case REGULATOR_MODE_STANDBY:
                ret = wm831x_set_bits(wm831x, ctrl_reg,
-                                     WM831X_LDO1_LP_MODE, 0);
+                                     WM831X_LDO1_LP_MODE,
+                                     WM831X_LDO1_LP_MODE);
                if (ret < 0)
                        return ret;
 
index 0e6ed7db93643436eadaeee5fbc48b7fd8ed599f..fe4b8a8a9dfd43a88ba9df10a9496a1b732d4328 100644 (file)
@@ -1129,7 +1129,7 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
                        mode = REGULATOR_MODE_NORMAL;
        } else if (!active && !sleep)
                mode = REGULATOR_MODE_IDLE;
-       else if (!sleep)
+       else if (sleep)
                mode = REGULATOR_MODE_STANDBY;
 
        return mode;
index d26780ea254b5d9e9e296309dc23f2640418a7f5..261a07e0fb24c0dd7cd1d05d3d60c35d184b1e38 100644 (file)
@@ -235,6 +235,7 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev)
                err = PTR_ERR(rtc);
                return err;
        }
+       platform_set_drvdata(pdev, rtc);
 
        return 0;
 }
@@ -244,6 +245,7 @@ static int __exit ab3100_rtc_remove(struct platform_device *pdev)
        struct rtc_device *rtc = platform_get_drvdata(pdev);
 
        rtc_device_unregister(rtc);
+       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index 9daed8db83d3e5400559ac3c51c86d0e6b45f00d..9de8516e3531e70bad818747f41de4b8052486bd 100644 (file)
@@ -268,7 +268,6 @@ out_irq:
                free_irq(client->irq, client);
 
 out_free:
-       i2c_set_clientdata(client, NULL);
        kfree(ds3232);
        return ret;
 }
@@ -287,7 +286,6 @@ static int __devexit ds3232_remove(struct i2c_client *client)
        }
 
        rtc_device_unregister(ds3232->rtc);
-       i2c_set_clientdata(client, NULL);
        kfree(ds3232);
        return 0;
 }
index a0d3ec89d412ac57d683fa5a446720a375dfab22..f57a87f4ae96abb367a2e08d353378b31f2a19fa 100644 (file)
@@ -310,11 +310,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        s3c_rtc_setaie(alrm->enabled);
 
-       if (alrm->enabled)
-               enable_irq_wake(s3c_rtc_alarmno);
-       else
-               disable_irq_wake(s3c_rtc_alarmno);
-
        return 0;
 }
 
@@ -587,6 +582,10 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
                ticnt_en_save &= S3C64XX_RTCCON_TICEN;
        }
        s3c_rtc_enable(pdev, 0);
+
+       if (device_may_wakeup(&pdev->dev))
+               enable_irq_wake(s3c_rtc_alarmno);
+
        return 0;
 }
 
@@ -600,6 +599,10 @@ static int s3c_rtc_resume(struct platform_device *pdev)
                tmp = readb(s3c_rtc_base + S3C2410_RTCCON);
                writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON);
        }
+
+       if (device_may_wakeup(&pdev->dev))
+               disable_irq_wake(s3c_rtc_alarmno);
+
        return 0;
 }
 #else
index 6edf20b62de5bae28214275931f0db9fd1fcd1f2..2c7d2d9be4d0cd3099f63d2b2690242cc12eed50 100644 (file)
@@ -1154,7 +1154,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
                                dev_fsm, dev_fsm_len, GFP_KERNEL);
        if (priv->fsm == NULL) {
                CTCMY_DBF_DEV(SETUP, dev, "init_fsm error");
-               kfree(dev);
+               free_netdev(dev);
                return NULL;
        }
        fsm_newstate(priv->fsm, DEV_STATE_STOPPED);
@@ -1165,7 +1165,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
                grp = ctcmpc_init_mpc_group(priv);
                if (grp == NULL) {
                        MPC_DBF_DEV(SETUP, dev, "init_mpc_group error");
-                       kfree(dev);
+                       free_netdev(dev);
                        return NULL;
                }
                tasklet_init(&grp->mpc_tasklet2,
index 12900f7083b08819fdf31b3ab626d560bbfa01f8..3198c5335f0bcfae8f08680592164a0f1953281a 100644 (file)
@@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS
        int
        depends on ARM && PLAT_SAMSUNG
        default 2 if ARCH_S3C2400
+       default 6 if ARCH_S5P6450
        default 4 if SERIAL_SAMSUNG_UARTS_4
        default 3
        help
@@ -526,12 +527,12 @@ config SERIAL_S3C24A0
          Serial port support for the Samsung S3C24A0 SoC
 
 config SERIAL_S3C6400
-       tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support"
-       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100)
+       tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
+       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
        select SERIAL_SAMSUNG_UARTS_4
        default y
        help
-         Serial port support for the Samsung S3C6400, S3C6410, S5P6440
+         Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
          and S5PC100 SoCs
 
 config SERIAL_S5PV210
index 50441ffe8e3856592dbfdae368e9891b64078d50..2904aa044126dbc49729caacbcb3d236da900bc6 100644 (file)
@@ -472,14 +472,9 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
        spin_unlock_irqrestore(&uap->port.lock, flags);
 }
 
-static void pl010_set_ldisc(struct uart_port *port)
+static void pl010_set_ldisc(struct uart_port *port, int new)
 {
-       int line = port->line;
-
-       if (line >= port->state->port.tty->driver->num)
-               return;
-
-       if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+       if (new == N_PPS) {
                port->flags |= UPF_HARDPPS_CD;
                pl010_enable_ms(port);
        } else
index bc9af503907f4b24ac0845068701b2de1474a105..5dff45c76d32c5f026dc1ae408166a4f5e9ac6d2 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include <linux/serial_reg.h>
 #include <linux/circ_buf.h>
 #include <linux/delay.h>
@@ -1423,7 +1424,6 @@ static void hsu_global_init(void)
        }
 
        phsu = hsu;
-
        hsu_debugfs_init(hsu);
        return;
 
@@ -1435,18 +1435,20 @@ err_free_region:
 
 static void serial_hsu_remove(struct pci_dev *pdev)
 {
-       struct hsu_port *hsu;
-       int i;
+       void *priv = pci_get_drvdata(pdev);
+       struct uart_hsu_port *up;
 
-       hsu = pci_get_drvdata(pdev);
-       if (!hsu)
+       if (!priv)
                return;
 
-       for (i = 0; i < 3; i++)
-               uart_remove_one_port(&serial_hsu_reg, &hsu->port[i].port);
+       /* For port 0/1/2, priv is the address of uart_hsu_port */
+       if (pdev->device != 0x081E) {
+               up = priv;
+               uart_remove_one_port(&serial_hsu_reg, &up->port);
+       }
 
        pci_set_drvdata(pdev, NULL);
-       free_irq(hsu->irq, hsu);
+       free_irq(pdev->irq, priv);
        pci_disable_device(pdev);
 }
 
index 8dedb266f143f1cf801d84f34892a999b2dc9934..c4399e23565aca0c986fdecc56fc424dee2c1ee3 100644 (file)
@@ -500,6 +500,7 @@ static int __init mpc512x_psc_fifoc_init(void)
        psc_fifoc = of_iomap(np, 0);
        if (!psc_fifoc) {
                pr_err("%s: Can't map FIFOC\n", __func__);
+               of_node_put(np);
                return -ENODEV;
        }
 
index f6ad1ecbff79ec9688fbc024a2036f351efff26e..51c15f58e01ef84a8ce43ba8b62472f0e4d7bec0 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/ioport.h>
+#include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
index b1156ba8ad1452c113fff20740a1d01596ab3cb2..7ac2bf5167cd8052f7f82b1361258f93643a03bd 100644 (file)
@@ -1101,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
        dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
 
        port->mapbase = res->start;
-       port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000);
+       port->membase = S3C_VA_UART + (res->start & 0xfffff);
        ret = platform_get_irq(platdev, 0);
        if (ret < 0)
                port->irq = 0;
index 141c69554bd481d27863b852bbd79b364417643e..7d475b2a79e8bb7fee0cd8f1f048fc61d1b7db3c 100644 (file)
@@ -335,8 +335,6 @@ static int serial_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-       link->resource[0]->end = 8;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        if (do_sound) {
                link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -411,6 +409,27 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
 
 /*====================================================================*/
 
+static int pfc_config(struct pcmcia_device *p_dev)
+{
+       unsigned int port = 0;
+       struct serial_info *info = p_dev->priv;
+
+       if ((p_dev->resource[1]->end != 0) &&
+               (resource_size(p_dev->resource[1]) == 8)) {
+               port = p_dev->resource[1]->start;
+               info->slave = 1;
+       } else if ((info->manfid == MANFID_OSITECH) &&
+               (resource_size(p_dev->resource[0]) == 0x40)) {
+               port = p_dev->resource[0]->start + 0x28;
+               info->slave = 1;
+       }
+       if (info->slave)
+               return setup_serial(p_dev, info, port, p_dev->irq);
+
+       dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
+       return -ENODEV;
+}
+
 static int simple_config_check(struct pcmcia_device *p_dev,
                               cistpl_cftable_entry_t *cf,
                               cistpl_cftable_entry_t *dflt,
@@ -461,23 +480,8 @@ static int simple_config(struct pcmcia_device *link)
        struct serial_info *info = link->priv;
        int i = -ENODEV, try;
 
-       /* If the card is already configured, look up the port and irq */
-       if (link->function_config) {
-               unsigned int port = 0;
-               if ((link->resource[1]->end != 0) &&
-                       (resource_size(link->resource[1]) == 8)) {
-                       port = link->resource[1]->end;
-                       info->slave = 1;
-               } else if ((info->manfid == MANFID_OSITECH) &&
-                       (resource_size(link->resource[0]) == 0x40)) {
-                       port = link->resource[0]->start + 0x28;
-                       info->slave = 1;
-               }
-               if (info->slave) {
-                       return setup_serial(link, info, port,
-                                           link->irq);
-               }
-       }
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       link->resource[0]->end = 8;
 
        /* First pass: look for a config entry that looks normal.
         * Two tries: without IO aliases, then with aliases */
@@ -491,8 +495,7 @@ static int simple_config(struct pcmcia_device *link)
        if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
                goto found_port;
 
-       printk(KERN_NOTICE
-              "serial_cs: no usable port range found, giving up\n");
+       dev_warn(&link->dev, "no usable port range found, giving up\n");
        return -1;
 
 found_port:
@@ -558,6 +561,7 @@ static int multi_config(struct pcmcia_device *link)
        int i, base2 = 0;
 
        /* First, look for a generic full-sized window */
+       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
        link->resource[0]->end = info->multi * 8;
        if (pcmcia_loop_config(link, multi_config_check, &base2)) {
                /* If that didn't work, look for two windows */
@@ -565,15 +569,14 @@ static int multi_config(struct pcmcia_device *link)
                info->multi = 2;
                if (pcmcia_loop_config(link, multi_config_check_notpicky,
                                       &base2)) {
-                       printk(KERN_NOTICE "serial_cs: no usable port range"
+                       dev_warn(&link->dev, "no usable port range "
                               "found, giving up\n");
                        return -ENODEV;
                }
        }
 
        if (!link->irq)
-               dev_warn(&link->dev,
-                       "serial_cs: no usable IRQ found, continuing...\n");
+               dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
 
        /*
         * Apply any configuration quirks.
@@ -675,6 +678,7 @@ static int serial_config(struct pcmcia_device * link)
           multifunction cards that ask for appropriate IO port ranges */
        if ((info->multi == 0) &&
            (link->has_func_id) &&
+           (link->socket->pcmcia_pfc == 0) &&
            ((link->func_id == CISTPL_FUNCID_MULTI) ||
             (link->func_id == CISTPL_FUNCID_SERIAL)))
                pcmcia_loop_config(link, serial_check_for_multi, info);
@@ -685,7 +689,13 @@ static int serial_config(struct pcmcia_device * link)
        if (info->quirk && info->quirk->multi != -1)
                info->multi = info->quirk->multi;
 
-       if (info->multi > 1)
+       dev_info(&link->dev,
+               "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
+               link->manf_id, link->card_id,
+               link->socket->pcmcia_pfc, info->multi, info->quirk);
+       if (link->socket->pcmcia_pfc)
+               i = pfc_config(link);
+       else if (info->multi > 1)
                i = multi_config(link);
        else
                i = simple_config(link);
@@ -704,7 +714,7 @@ static int serial_config(struct pcmcia_device * link)
        return 0;
 
 failed:
-       dev_warn(&link->dev, "serial_cs: failed to initialize\n");
+       dev_warn(&link->dev, "failed to initialize\n");
        serial_remove(link);
        return -ENODEV;
 }
index acd35d1ebd12621e35a05324daa450992b081f17..4c37c4e28647e68f62e1eaadcc92ac887857bf44 100644 (file)
@@ -503,8 +503,9 @@ static void giveback(struct pl022 *pl022)
        msg->state = NULL;
        if (msg->complete)
                msg->complete(msg->context);
-       /* This message is completed, so let's turn off the clock! */
+       /* This message is completed, so let's turn off the clocks! */
        clk_disable(pl022->clk);
+       amba_pclk_disable(pl022->adev);
 }
 
 /**
@@ -1139,9 +1140,10 @@ static void pump_messages(struct work_struct *work)
        /* Setup the SPI using the per chip configuration */
        pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
        /*
-        * We enable the clock here, then the clock will be disabled when
+        * We enable the clocks here, then the clocks will be disabled when
         * giveback() is called in each method (poll/interrupt/DMA)
         */
+       amba_pclk_enable(pl022->adev);
        clk_enable(pl022->clk);
        restore_state(pl022);
        flush(pl022);
@@ -1786,11 +1788,9 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
        }
 
        /* Disable SSP */
-       clk_enable(pl022->clk);
        writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
               SSP_CR1(pl022->virtbase));
        load_ssp_default_config(pl022);
-       clk_disable(pl022->clk);
 
        status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022",
                             pl022);
@@ -1818,6 +1818,8 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
                goto err_spi_register;
        }
        dev_dbg(dev, "probe succeded\n");
+       /* Disable the silicon block pclk and clock it when needed */
+       amba_pclk_disable(adev);
        return 0;
 
  err_spi_register:
@@ -1879,9 +1881,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
                return status;
        }
 
-       clk_enable(pl022->clk);
+       amba_pclk_enable(adev);
        load_ssp_default_config(pl022);
-       clk_disable(pl022->clk);
+       amba_pclk_disable(adev);
        dev_dbg(&adev->dev, "suspended\n");
        return 0;
 }
@@ -1981,7 +1983,7 @@ static int __init pl022_init(void)
        return amba_driver_register(&pl022_driver);
 }
 
-module_init(pl022_init);
+subsys_initcall(pl022_init);
 
 static void __exit pl022_exit(void)
 {
index d256cb00604c55db5cc2ce25233b8d8e189c69be..56247853c298aac0de06eae049429ed5581727c4 100644 (file)
@@ -181,10 +181,6 @@ static void flush(struct dw_spi *dws)
        wait_till_not_busy(dws);
 }
 
-static void null_cs_control(u32 command)
-{
-}
-
 static int null_writer(struct dw_spi *dws)
 {
        u8 n_bytes = dws->n_bytes;
@@ -322,7 +318,7 @@ static void giveback(struct dw_spi *dws)
                                        struct spi_transfer,
                                        transfer_list);
 
-       if (!last_transfer->cs_change)
+       if (!last_transfer->cs_change && dws->cs_control)
                dws->cs_control(MRST_SPI_DEASSERT);
 
        msg->state = NULL;
@@ -396,6 +392,11 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 {
        struct dw_spi *dws = dev_id;
+       u16 irq_status, irq_mask = 0x3f;
+
+       irq_status = dw_readw(dws, isr) & irq_mask;
+       if (!irq_status)
+               return IRQ_NONE;
 
        if (!dws->cur_msg) {
                spi_mask_intr(dws, SPI_INT_TXEI);
@@ -544,13 +545,13 @@ static void pump_transfers(unsigned long data)
         */
        if (dws->cs_control) {
                if (dws->rx && dws->tx)
-                       chip->tmode = 0x00;
+                       chip->tmode = SPI_TMOD_TR;
                else if (dws->rx)
-                       chip->tmode = 0x02;
+                       chip->tmode = SPI_TMOD_RO;
                else
-                       chip->tmode = 0x01;
+                       chip->tmode = SPI_TMOD_TO;
 
-               cr0 &= ~(0x3 << SPI_MODE_OFFSET);
+               cr0 &= ~SPI_TMOD_MASK;
                cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
        }
 
@@ -699,9 +700,6 @@ static int dw_spi_setup(struct spi_device *spi)
                chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
                if (!chip)
                        return -ENOMEM;
-
-               chip->cs_control = null_cs_control;
-               chip->enable_dma = 0;
        }
 
        /*
@@ -883,7 +881,7 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
        dws->dma_inited = 0;
        dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
 
-       ret = request_irq(dws->irq, dw_spi_irq, 0,
+       ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
                        "dw_spi", dws);
        if (ret < 0) {
                dev_err(&master->dev, "can not get IRQ\n");
index a9e5c79ae52a04a43aebabeacfc2d3cc29e03e77..b5a78a1f4421a0c19aa8735bd49f076fd8f91b46 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/cache.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
@@ -86,6 +87,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
        const struct spi_device *spi = to_spi_device(dev);
        const struct spi_driver *sdrv = to_spi_driver(drv);
 
+       /* Attempt an OF style match */
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
        if (sdrv->id_table)
                return !!spi_match_id(sdrv->id_table, spi);
 
@@ -554,11 +559,9 @@ done:
 EXPORT_SYMBOL_GPL(spi_register_master);
 
 
-static int __unregister(struct device *dev, void *master_dev)
+static int __unregister(struct device *dev, void *null)
 {
-       /* note: before about 2.6.14-rc1 this would corrupt memory: */
-       if (dev != master_dev)
-               spi_unregister_device(to_spi_device(dev));
+       spi_unregister_device(to_spi_device(dev));
        return 0;
 }
 
@@ -576,8 +579,7 @@ void spi_unregister_master(struct spi_master *master)
 {
        int dummy;
 
-       dummy = device_for_each_child(master->dev.parent, &master->dev,
-                                       __unregister);
+       dummy = device_for_each_child(&master->dev, NULL, __unregister);
        device_unregister(&master->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_master);
index e24a63498acb84f7e4f9f83710aca3fadefcc177..63e51b011d508c8922bb047cfb94572049323493 100644 (file)
@@ -350,7 +350,7 @@ static int __init spi_gpio_probe(struct platform_device *pdev)
        spi_gpio->bitbang.master = spi_master_get(master);
        spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
 
-       if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) {
+       if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
                spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
                spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
                spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
index d31b57f7baaf3c3bf970294afd13a1396cecf46c..1dd86b835cd86a800aa8db8257e4a37422a33b8a 100644 (file)
@@ -408,11 +408,17 @@ static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi)
 
        xfer_ofs = mspi->xfer_in_progress->len - mspi->count;
 
-       out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
+       if (mspi->rx_dma == mspi->dma_dummy_rx)
+               out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma);
+       else
+               out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
        out_be16(&rx_bd->cbd_datlen, 0);
        out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP);
 
-       out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
+       if (mspi->tx_dma == mspi->dma_dummy_tx)
+               out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma);
+       else
+               out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
        out_be16(&tx_bd->cbd_datlen, xfer_len);
        out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP |
                                 BD_SC_LAST);
index 97365815a729a2d3c17d47d3815ffa38ff6c6526..c3038da2648aa4e621b0e6127b89c3017724cb55 100644 (file)
@@ -200,6 +200,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
                val = readl(regs + S3C64XX_SPI_STATUS);
        } while (TX_FIFO_LVL(val, sci) && loops--);
 
+       if (loops == 0)
+               dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
+
        /* Flush RxFIFO*/
        loops = msecs_to_loops(1);
        do {
@@ -210,6 +213,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
                        break;
        } while (loops--);
 
+       if (loops == 0)
+               dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n");
+
        val = readl(regs + S3C64XX_SPI_CH_CFG);
        val &= ~S3C64XX_SPI_CH_SW_RST;
        writel(val, regs + S3C64XX_SPI_CH_CFG);
@@ -320,16 +326,17 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
 
        /* millisecs to xfer 'len' bytes @ 'cur_speed' */
        ms = xfer->len * 8 * 1000 / sdd->cur_speed;
-       ms += 5; /* some tolerance */
+       ms += 10; /* some tolerance */
 
        if (dma_mode) {
                val = msecs_to_jiffies(ms) + 10;
                val = wait_for_completion_timeout(&sdd->xfer_completion, val);
        } else {
+               u32 status;
                val = msecs_to_loops(ms);
                do {
-                       val = readl(regs + S3C64XX_SPI_STATUS);
-               } while (RX_FIFO_LVL(val, sci) < xfer->len && --val);
+                       status = readl(regs + S3C64XX_SPI_STATUS);
+               } while (RX_FIFO_LVL(status, sci) < xfer->len && --val);
        }
 
        if (!val)
@@ -447,8 +454,8 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
        writel(val, regs + S3C64XX_SPI_CLK_CFG);
 }
 
-void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
-                               int size, enum s3c2410_dma_buffresult res)
+static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
+                                int size, enum s3c2410_dma_buffresult res)
 {
        struct s3c64xx_spi_driver_data *sdd = buf_id;
        unsigned long flags;
@@ -467,8 +474,8 @@ void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
        spin_unlock_irqrestore(&sdd->lock, flags);
 }
 
-void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
-                               int size, enum s3c2410_dma_buffresult res)
+static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
+                                int size, enum s3c2410_dma_buffresult res)
 {
        struct s3c64xx_spi_driver_data *sdd = buf_id;
        unsigned long flags;
@@ -508,8 +515,9 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
        list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 
                if (xfer->tx_buf != NULL) {
-                       xfer->tx_dma = dma_map_single(dev, xfer->tx_buf,
-                                               xfer->len, DMA_TO_DEVICE);
+                       xfer->tx_dma = dma_map_single(dev,
+                                       (void *)xfer->tx_buf, xfer->len,
+                                       DMA_TO_DEVICE);
                        if (dma_mapping_error(dev, xfer->tx_dma)) {
                                dev_err(dev, "dma_map_single Tx failed\n");
                                xfer->tx_dma = XFER_DMAADDR_INVALID;
@@ -919,6 +927,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       sci = pdev->dev.platform_data;
+       if (!sci->src_clk_name) {
+               dev_err(&pdev->dev,
+                       "Board init must call s3c64xx_spi_set_info()\n");
+               return -EINVAL;
+       }
+
        /* Check for availability of necessary resource */
 
        dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -946,8 +961,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       sci = pdev->dev.platform_data;
-
        platform_set_drvdata(pdev, master);
 
        sdd = spi_master_get_devdata(master);
@@ -1170,7 +1183,7 @@ static int __init s3c64xx_spi_init(void)
 {
        return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
 }
-module_init(s3c64xx_spi_init);
+subsys_initcall(s3c64xx_spi_init);
 
 static void __exit s3c64xx_spi_exit(void)
 {
index baa8b05b9e8d70a49ba2dcb63e5e8c3cea7ed341..6e973a79aa25b6fec509639687fc4e196a568397 100644 (file)
@@ -30,7 +30,6 @@
 #include "hash.h"
 
 #include <linux/if_arp.h>
-#include <linux/netfilter_bridge.h>
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
@@ -431,11 +430,6 @@ out:
        return NOTIFY_DONE;
 }
 
-static int batman_skb_recv_finish(struct sk_buff *skb)
-{
-       return NF_ACCEPT;
-}
-
 /* receive a packet with the batman ethertype coming on a hard
  * interface */
 int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
@@ -456,13 +450,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
        if (atomic_read(&module_state) != MODULE_ACTIVE)
                goto err_free;
 
-       /* if netfilter/ebtables wants to block incoming batman
-        * packets then give them a chance to do so here */
-       ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
-                     batman_skb_recv_finish);
-       if (ret != 1)
-               goto err_out;
-
        /* packet should hold at least type and version */
        if (unlikely(skb_headlen(skb) < 2))
                goto err_free;
index 055edee7b4e401be0f9142d222fab9a52631c150..da3c82e47bbd6365788b827f9a1ee2e4a48be226 100644 (file)
@@ -29,7 +29,6 @@
 #include "vis.h"
 #include "aggregation.h"
 
-#include <linux/netfilter_bridge.h>
 
 static void send_outstanding_bcast_packet(struct work_struct *work);
 
@@ -92,12 +91,9 @@ int send_skb_packet(struct sk_buff *skb,
 
        /* dev_queue_xmit() returns a negative result on error.  However on
         * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
-        * (which is > 0). This will not be treated as an error.
-        * Also, if netfilter/ebtables wants to block outgoing batman
-        * packets then giving them a chance to do so here */
+        * (which is > 0). This will not be treated as an error. */
 
-       return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-                      dev_queue_xmit);
+       return dev_queue_xmit(skb);
 send_skb_err:
        kfree_skb(skb);
        return NET_XMIT_DROP;
index 9952579425b99a477c29e488243337e9372b2200..1b3060eb2921c9da66fb2f0844de4a2d1afa4ce0 100644 (file)
@@ -80,5 +80,4 @@ struct st_proto_s {
 extern long st_register(struct st_proto_s *);
 extern long st_unregister(enum proto_type);
 
-extern struct platform_device *st_get_plat_device(void);
 #endif /* ST_H */
index 063c9b1db1ab655504f5908e7c4598418dafd0fd..b85d8bfdf600ad22cd4d62636b521bfb3ac38fa5 100644 (file)
@@ -38,7 +38,6 @@
 #include "st_ll.h"
 #include "st.h"
 
-#define VERBOSE
 /* strings to be used for rfkill entries and by
  * ST Core to be used for sysfs debug entry
  */
@@ -581,7 +580,7 @@ long st_register(struct st_proto_s *new_proto)
        long err = 0;
        unsigned long flags = 0;
 
-       st_kim_ref(&st_gdata);
+       st_kim_ref(&st_gdata, 0);
        pr_info("%s(%d) ", __func__, new_proto->type);
        if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
            || new_proto->reg_complete_cb == NULL) {
@@ -713,7 +712,7 @@ long st_unregister(enum proto_type type)
 
        pr_debug("%s: %d ", __func__, type);
 
-       st_kim_ref(&st_gdata);
+       st_kim_ref(&st_gdata, 0);
        if (type < ST_BT || type >= ST_MAX) {
                pr_err(" protocol %d not supported", type);
                return -EPROTONOSUPPORT;
@@ -767,7 +766,7 @@ long st_write(struct sk_buff *skb)
 #endif
        long len;
 
-       st_kim_ref(&st_gdata);
+       st_kim_ref(&st_gdata, 0);
        if (unlikely(skb == NULL || st_gdata == NULL
                || st_gdata->tty == NULL)) {
                pr_err("data/tty unavailable to perform write");
@@ -818,7 +817,7 @@ static int st_tty_open(struct tty_struct *tty)
        struct st_data_s *st_gdata;
        pr_info("%s ", __func__);
 
-       st_kim_ref(&st_gdata);
+       st_kim_ref(&st_gdata, 0);
        st_gdata->tty = tty;
        tty->disc_data = st_gdata;
 
index e0c32d149f5f294878d22597bec9c1bfc05660a4..8601320a679ee8ce5dda5ea9d36f8c85798dd23e 100644 (file)
@@ -117,7 +117,7 @@ int st_core_init(struct st_data_s **);
 void st_core_exit(struct st_data_s *);
 
 /* ask for reference from KIM */
-void st_kim_ref(struct st_data_s **);
+void st_kim_ref(struct st_data_s **, int);
 
 #define GPS_STUB_TEST
 #ifdef GPS_STUB_TEST
index b4a6c7fdc4e6ca59283dd3e64736c0efdfd97407..9e99463f76e8a0d048f7ec8667a455125d88cb0b 100644 (file)
@@ -72,10 +72,25 @@ const unsigned char *protocol_names[] = {
        PROTO_ENTRY(ST_GPS, "GPS"),
 };
 
+#define MAX_ST_DEVICES 3       /* Imagine 1 on each UART for now */
+struct platform_device *st_kim_devices[MAX_ST_DEVICES];
 
 /**********************************************************************/
 /* internal functions */
 
+/**
+ * st_get_plat_device -
+ *     function which returns the reference to the platform device
+ *     requested by id. As of now only 1 such device exists (id=0)
+ *     the context requesting for reference can get the id to be
+ *     requested by a. The protocol driver which is registering or
+ *     b. the tty device which is opened.
+ */
+static struct platform_device *st_get_plat_device(int id)
+{
+       return st_kim_devices[id];
+}
+
 /**
  * validate_firmware_response -
  *     function to return whether the firmware response was proper
@@ -353,7 +368,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
        struct kim_data_s       *kim_gdata;
        pr_info(" %s ", __func__);
 
-       kim_pdev = st_get_plat_device();
+       kim_pdev = st_get_plat_device(0);
        kim_gdata = dev_get_drvdata(&kim_pdev->dev);
 
        if (kim_gdata->gpios[type] == -1) {
@@ -574,12 +589,12 @@ static int kim_toggle_radio(void *data, bool blocked)
  *     This would enable multiple such platform devices to exist
  *     on a given platform
  */
-void st_kim_ref(struct st_data_s **core_data)
+void st_kim_ref(struct st_data_s **core_data, int id)
 {
        struct platform_device  *pdev;
        struct kim_data_s       *kim_gdata;
        /* get kim_gdata reference from platform device */
-       pdev = st_get_plat_device();
+       pdev = st_get_plat_device(id);
        kim_gdata = dev_get_drvdata(&pdev->dev);
        *core_data = kim_gdata->core_data;
 }
@@ -623,6 +638,7 @@ static int kim_probe(struct platform_device *pdev)
        long *gpios = pdev->dev.platform_data;
        struct kim_data_s       *kim_gdata;
 
+       st_kim_devices[pdev->id] = pdev;
        kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
        if (!kim_gdata) {
                pr_err("no mem to allocate");
index c725356cc3466ec5963290415765aab5fb50188a..de7ebb99d8f6cc61ff600b2d9580627f1a12e78d 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_TM6000
        tristate "TV Master TM5600/6000/6010 driver"
-       depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL
+       depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL
        select VIDEO_TUNER
        select MEDIA_TUNER_XC2028
        select MEDIA_TUNER_XC5000
index 32f7a0af6938094380e9de73b933f652f0a00612..54f7667cc7062b640f2fb97717f7c7c26768f2cf 100644 (file)
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable");
        }
 
 struct tm6000_ir_poll_result {
-       u8 rc_data[4];
+       u16 rc_data;
 };
 
 struct tm6000_IR {
@@ -60,9 +60,9 @@ struct tm6000_IR {
        int                     polling;
        struct delayed_work     work;
        u8                      wait:1;
+       u8                      key:1;
        struct urb              *int_urb;
        u8                      *urb_data;
-       u8                      key:1;
 
        int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
 
@@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb)
 
        if (urb->status != 0)
                printk(KERN_INFO "not ready\n");
-       else if (urb->actual_length > 0)
+       else if (urb->actual_length > 0) {
                memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
 
-       dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
-       ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
+               dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
+                       ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
 
-       ir->key = 1;
+               ir->key = 1;
+       }
 
        rc = usb_submit_urb(urb, GFP_ATOMIC);
 }
@@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir,
        int rc;
        u8 buf[2];
 
-       if (ir->wait && !&dev->int_in) {
-               poll_result->rc_data[0] = 0xff;
+       if (ir->wait && !&dev->int_in)
                return 0;
-       }
 
        if (&dev->int_in) {
-               poll_result->rc_data[0] = ir->urb_data[0];
-               poll_result->rc_data[1] = ir->urb_data[1];
+               if (ir->ir.ir_type == IR_TYPE_RC5)
+                       poll_result->rc_data = ir->urb_data[0];
+               else
+                       poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8;
        } else {
                tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
                msleep(10);
                tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
                msleep(10);
 
-               rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
-                USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1);
+               if (ir->ir.ir_type == IR_TYPE_RC5) {
+                       rc = tm6000_read_write_usb(dev, USB_DIR_IN |
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               REQ_02_GET_IR_CODE, 0, 0, buf, 1);
 
-               msleep(10);
+                       msleep(10);
 
-               dprintk("read data=%02x\n", buf[0]);
-               if (rc < 0)
-                       return rc;
+                       dprintk("read data=%02x\n", buf[0]);
+                       if (rc < 0)
+                               return rc;
 
-               poll_result->rc_data[0] = buf[0];
+                       poll_result->rc_data = buf[0];
+               } else {
+                       rc = tm6000_read_write_usb(dev, USB_DIR_IN |
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               REQ_02_GET_IR_CODE, 0, 0, buf, 2);
+
+                       msleep(10);
+
+                       dprintk("read data=%04x\n", buf[0] | buf[1] << 8);
+                       if (rc < 0)
+                               return rc;
+
+                       poll_result->rc_data = buf[0] | buf[1] << 8;
+               }
+               if ((poll_result->rc_data & 0x00ff) != 0xff)
+                       ir->key = 1;
        }
        return 0;
 }
@@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir)
                return;
        }
 
-       dprintk("ir->get_key result data=%02x %02x\n",
-               poll_result.rc_data[0], poll_result.rc_data[1]);
+       dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
 
-       if (poll_result.rc_data[0] != 0xff && ir->key == 1) {
+       if (ir->key) {
                ir_input_keydown(ir->input->input_dev, &ir->ir,
-                       poll_result.rc_data[0] | poll_result.rc_data[1] << 8);
+                               (u32)poll_result.rc_data);
 
                ir_input_nokey(ir->input->input_dev, &ir->ir);
                ir->key = 0;
index 0142338bcafe7fc0440edbf3c65a12d7f9b0df85..4bdb8362de827cdb5c820e2bcb3ca65f9a9226e7 100644 (file)
@@ -766,9 +766,14 @@ static int wpa_set_associate(PSDevice pDevice,
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
 
 
-       if (param->u.wpa_associate.wpa_ie &&
-           copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
-           return -EINVAL;
+       if (param->u.wpa_associate.wpa_ie_len) {
+               if (!param->u.wpa_associate.wpa_ie)
+                       return -EINVAL;
+               if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
+                       return -EINVAL;
+               if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
+                       return -EFAULT;
+       }
 
        if (param->u.wpa_associate.mode == 1)
            pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
index 7e594449600e004c7f6ba14fa2dce39ebee25d20..9eed5b52d9de22647f6ca7e94791cd97f6e60122 100644 (file)
@@ -91,12 +91,12 @@ config USB_DYNAMIC_MINORS
          If you are unsure about this, say N here.
 
 config USB_SUSPEND
-       bool "USB runtime power management (suspend/resume and wakeup)"
+       bool "USB runtime power management (autosuspend) and wakeup"
        depends on USB && PM_RUNTIME
        help
          If you say Y here, you can use driver calls or the sysfs
-         "power/level" file to suspend or resume individual USB
-         peripherals and to enable or disable autosuspend (see
+         "power/control" file to enable or disable autosuspend for
+         individual USB peripherals (see
          Documentation/usb/power-management.txt for more details).
 
          Also, USB "remote wakeup" signaling is supported, whereby some
index f06f5dbc8cdc22fbedfa463c05b18672cbb99516..1e6ccef2cf0cbd9e817e7045dccfb03918efa9d7 100644 (file)
@@ -159,9 +159,9 @@ void usb_major_cleanup(void)
 int usb_register_dev(struct usb_interface *intf,
                     struct usb_class_driver *class_driver)
 {
-       int retval = -EINVAL;
+       int retval;
        int minor_base = class_driver->minor_base;
-       int minor = 0;
+       int minor;
        char name[20];
        char *temp;
 
@@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf,
         */
        minor_base = 0;
 #endif
-       intf->minor = -1;
-
-       dbg ("looking for a minor, starting at %d", minor_base);
 
        if (class_driver->fops == NULL)
-               goto exit;
+               return -EINVAL;
+       if (intf->minor >= 0)
+               return -EADDRINUSE;
+
+       retval = init_usb_class();
+       if (retval)
+               return retval;
+
+       dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
 
        down_write(&minor_rwsem);
        for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
@@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf,
                        continue;
 
                usb_minors[minor] = class_driver->fops;
-
-               retval = 0;
+               intf->minor = minor;
                break;
        }
        up_write(&minor_rwsem);
-
-       if (retval)
-               goto exit;
-
-       retval = init_usb_class();
-       if (retval)
-               goto exit;
-
-       intf->minor = minor;
+       if (intf->minor < 0)
+               return -EXFULL;
 
        /* create a usb class device for this usb interface */
        snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
@@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf,
                                      "%s", temp);
        if (IS_ERR(intf->usb_dev)) {
                down_write(&minor_rwsem);
-               usb_minors[intf->minor] = NULL;
+               usb_minors[minor] = NULL;
+               intf->minor = -1;
                up_write(&minor_rwsem);
                retval = PTR_ERR(intf->usb_dev);
        }
-exit:
        return retval;
 }
 EXPORT_SYMBOL_GPL(usb_register_dev);
index 844683e503830485147910ff16ca035a90194d27..9f0ce7de0e366fb0066dfb92d6a6403aa5f4a2b3 100644 (file)
@@ -1802,6 +1802,7 @@ free_interfaces:
                intf->dev.groups = usb_interface_groups;
                intf->dev.dma_mask = dev->dev.dma_mask;
                INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
+               intf->minor = -1;
                device_initialize(&intf->dev);
                dev_set_name(&intf->dev, "%d-%s:%d.%d",
                        dev->bus->busnum, dev->devpath,
index 58b72d741d9313b1f393a033cd0ed4cb89ad32ac..a1e8d273103f77b2d237a5f68438b289b51bb92a 100644 (file)
@@ -119,6 +119,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                        ehci->broken_periodic = 1;
                        ehci_info(ehci, "using broken periodic workaround\n");
                }
+               if (pdev->device == 0x0806 || pdev->device == 0x0811
+                               || pdev->device == 0x0829) {
+                       ehci_info(ehci, "disable lpm for langwell/penwell\n");
+                       ehci->has_lpm = 0;
+               }
                break;
        case PCI_VENDOR_ID_TDI:
                if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
index 418163894775e36ff129aa96ba107f7e6145ca20..afef7b0a419567ab92643d0809a1da5f1a4f13a9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <mach/ohci.h>
+#include <mach/pxa3xx-u2d.h>
 
 /*
  * UHC: USB Host Controller (OHCI-like) register definitions
@@ -235,6 +236,9 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
        if (retval < 0)
                return retval;
 
+       if (cpu_is_pxa3xx())
+               pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+
        uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
        __raw_writel(uhchr, ohci->mmio_base + UHCHR);
        __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
@@ -251,6 +255,9 @@ static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
 
        inf = dev->platform_data;
 
+       if (cpu_is_pxa3xx())
+               pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+
        if (inf->exit)
                inf->exit(dev);
 
index 59dc3d351b60269f3c3872b859c0b39d7fcbe449..5ab5bb89bae3558cfe6f296e37931680afa0e323 100644 (file)
@@ -322,6 +322,7 @@ cppi_channel_allocate(struct dma_controller *c,
                                index, transmit ? 'T' : 'R', cppi_ch);
        cppi_ch->hw_ep = ep;
        cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;
+       cppi_ch->channel.max_len = 0x7fffffff;
 
        DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');
        return &cppi_ch->channel;
index c79a5e30d43735bb285300152ade427fd81dac6a..9e8639d4e862b65a2b23bc27a29fd09ba0b60ec1 100644 (file)
@@ -195,15 +195,14 @@ static const struct file_operations musb_regdump_fops = {
 
 static int musb_test_mode_open(struct inode *inode, struct file *file)
 {
-       file->private_data = inode->i_private;
-
        return single_open(file, musb_test_mode_show, inode->i_private);
 }
 
 static ssize_t musb_test_mode_write(struct file *file,
                const char __user *ubuf, size_t count, loff_t *ppos)
 {
-       struct musb             *musb = file->private_data;
+       struct seq_file         *s = file->private_data;
+       struct musb             *musb = s->private;
        u8                      test = 0;
        char                    buf[18];
 
index 6fca870e957ed3b5061f19deec76a9472d6d5211..d065e23f123ee755f9e6fe0e661823f48d917727 100644 (file)
@@ -300,6 +300,11 @@ static void txstate(struct musb *musb, struct musb_request *req)
 #ifndef        CONFIG_MUSB_PIO_ONLY
        if (is_dma_capable() && musb_ep->dma) {
                struct dma_controller   *c = musb->dma_controller;
+               size_t request_size;
+
+               /* setup DMA, then program endpoint CSR */
+               request_size = min_t(size_t, request->length - request->actual,
+                                       musb_ep->dma->max_len);
 
                use_dma = (request->dma != DMA_ADDR_INVALID);
 
@@ -307,11 +312,6 @@ static void txstate(struct musb *musb, struct musb_request *req)
 
 #ifdef CONFIG_USB_INVENTRA_DMA
                {
-                       size_t request_size;
-
-                       /* setup DMA, then program endpoint CSR */
-                       request_size = min_t(size_t, request->length,
-                                               musb_ep->dma->max_len);
                        if (request_size < musb_ep->packet_sz)
                                musb_ep->dma->desired_mode = 0;
                        else
@@ -373,8 +373,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
                use_dma = use_dma && c->channel_program(
                                musb_ep->dma, musb_ep->packet_sz,
                                0,
-                               request->dma,
-                               request->length);
+                               request->dma + request->actual,
+                               request_size);
                if (!use_dma) {
                        c->channel_release(musb_ep->dma);
                        musb_ep->dma = NULL;
@@ -386,8 +386,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
                use_dma = use_dma && c->channel_program(
                                musb_ep->dma, musb_ep->packet_sz,
                                request->zero,
-                               request->dma,
-                               request->length);
+                               request->dma + request->actual,
+                               request_size);
 #endif
        }
 #endif
@@ -501,26 +501,14 @@ void musb_g_tx(struct musb *musb, u8 epnum)
                                request->zero = 0;
                        }
 
-                       /* ... or if not, then complete it. */
-                       musb_g_giveback(musb_ep, request, 0);
-
-                       /*
-                        * Kickstart next transfer if appropriate;
-                        * the packet that just completed might not
-                        * be transmitted for hours or days.
-                        * REVISIT for double buffering...
-                        * FIXME revisit for stalls too...
-                        */
-                       musb_ep_select(mbase, epnum);
-                       csr = musb_readw(epio, MUSB_TXCSR);
-                       if (csr & MUSB_TXCSR_FIFONOTEMPTY)
-                               return;
-
-                       request = musb_ep->desc ? next_request(musb_ep) : NULL;
-                       if (!request) {
-                               DBG(4, "%s idle now\n",
-                                       musb_ep->end_point.name);
-                               return;
+                       if (request->actual == request->length) {
+                               musb_g_giveback(musb_ep, request, 0);
+                               request = musb_ep->desc ? next_request(musb_ep) : NULL;
+                               if (!request) {
+                                       DBG(4, "%s idle now\n",
+                                               musb_ep->end_point.name);
+                                       return;
+                               }
                        }
                }
 
@@ -568,11 +556,19 @@ static void rxstate(struct musb *musb, struct musb_request *req)
 {
        const u8                epnum = req->epnum;
        struct usb_request      *request = &req->request;
-       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
+       struct musb_ep          *musb_ep;
        void __iomem            *epio = musb->endpoints[epnum].regs;
        unsigned                fifo_count = 0;
-       u16                     len = musb_ep->packet_sz;
+       u16                     len;
        u16                     csr = musb_readw(epio, MUSB_RXCSR);
+       struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
+
+       if (hw_ep->is_shared_fifo)
+               musb_ep = &hw_ep->ep_in;
+       else
+               musb_ep = &hw_ep->ep_out;
+
+       len = musb_ep->packet_sz;
 
        /* We shouldn't get here while DMA is active, but we do... */
        if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
@@ -647,8 +643,8 @@ static void rxstate(struct musb *musb, struct musb_request *req)
         */
 
                                csr |= MUSB_RXCSR_DMAENAB;
-#ifdef USE_MODE1
                                csr |= MUSB_RXCSR_AUTOCLEAR;
+#ifdef USE_MODE1
                                /* csr |= MUSB_RXCSR_DMAMODE; */
 
                                /* this special sequence (enabling and then
@@ -663,10 +659,11 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                if (request->actual < request->length) {
                                        int transfer_size = 0;
 #ifdef USE_MODE1
-                                       transfer_size = min(request->length,
+                                       transfer_size = min(request->length - request->actual,
                                                        channel->max_len);
 #else
-                                       transfer_size = len;
+                                       transfer_size = min(request->length - request->actual,
+                                                       (unsigned)len);
 #endif
                                        if (transfer_size <= musb_ep->packet_sz)
                                                musb_ep->dma->desired_mode = 0;
@@ -740,9 +737,15 @@ void musb_g_rx(struct musb *musb, u8 epnum)
        u16                     csr;
        struct usb_request      *request;
        void __iomem            *mbase = musb->mregs;
-       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
+       struct musb_ep          *musb_ep;
        void __iomem            *epio = musb->endpoints[epnum].regs;
        struct dma_channel      *dma;
+       struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
+
+       if (hw_ep->is_shared_fifo)
+               musb_ep = &hw_ep->ep_in;
+       else
+               musb_ep = &hw_ep->ep_out;
 
        musb_ep_select(mbase, epnum);
 
@@ -1081,7 +1084,7 @@ struct free_record {
 /*
  * Context: controller locked, IRQs blocked.
  */
-static void musb_ep_restart(struct musb *musb, struct musb_request *req)
+void musb_ep_restart(struct musb *musb, struct musb_request *req)
 {
        DBG(3, "<== %s request %p len %u on hw_ep%d\n",
                req->tx ? "TX/IN" : "RX/OUT",
index c8b140325d82bf4bb6cd3ad85216fa24ec308ce7..572b1da7f2dc45ea1fd3d9bb67d3ea273d56cfae 100644 (file)
@@ -105,4 +105,6 @@ extern void musb_gadget_cleanup(struct musb *);
 
 extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
 
+extern void musb_ep_restart(struct musb *, struct musb_request *);
+
 #endif         /* __MUSB_GADGET_H */
index 59bef8f3a3585100310bbb43848ea56603a82c28..6dd03f4c5f4956983c2d1bf2552c248f6a1702a0 100644 (file)
@@ -261,6 +261,7 @@ __acquires(musb->lock)
                                        ctrlrequest->wIndex & 0x0f;
                                struct musb_ep          *musb_ep;
                                struct musb_hw_ep       *ep;
+                               struct musb_request     *request;
                                void __iomem            *regs;
                                int                     is_in;
                                u16                     csr;
@@ -302,6 +303,14 @@ __acquires(musb->lock)
                                        musb_writew(regs, MUSB_RXCSR, csr);
                                }
 
+                               /* Maybe start the first request in the queue */
+                               request = to_musb_request(
+                                               next_request(musb_ep));
+                               if (!musb_ep->busy && request) {
+                                       DBG(3, "restarting the request\n");
+                                       musb_ep_restart(musb, request);
+                               }
+
                                /* select ep0 again */
                                musb_ep_select(mbase, 0);
                                } break;
index 877d20b1dff973fd6975f258bb0b18267df1f5f5..9e65c47cc98b95761daba7186dd180550b954def 100644 (file)
@@ -660,6 +660,12 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
 
        qh->segsize = length;
 
+       /*
+        * Ensure the data reaches to main memory before starting
+        * DMA transfer
+        */
+       wmb();
+
        if (!dma->channel_program(channel, pkt_size, mode,
                        urb->transfer_dma + offset, length)) {
                dma->channel_release(channel);
index 05aaac1c3861e5be2f8d30c4311e7faa5a2c40a8..0bc97698af157d2cc25e4309a0da34ac2ad4e317 100644 (file)
@@ -347,11 +347,20 @@ static void twl4030_i2c_access(struct twl4030_usb *twl, int on)
        }
 }
 
-static void twl4030_phy_power(struct twl4030_usb *twl, int on)
+static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
 {
-       u8 pwr;
+       u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+
+       if (on)
+               pwr &= ~PHY_PWR_PHYPWD;
+       else
+               pwr |= PHY_PWR_PHYPWD;
 
-       pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+       WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+}
+
+static void twl4030_phy_power(struct twl4030_usb *twl, int on)
+{
        if (on) {
                regulator_enable(twl->usb3v1);
                regulator_enable(twl->usb1v8);
@@ -365,15 +374,13 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
                twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0,
                                                        VUSB_DEDICATED2);
                regulator_enable(twl->usb1v5);
-               pwr &= ~PHY_PWR_PHYPWD;
-               WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+               __twl4030_phy_power(twl, 1);
                twl4030_usb_write(twl, PHY_CLK_CTRL,
                                  twl4030_usb_read(twl, PHY_CLK_CTRL) |
                                        (PHY_CLK_CTRL_CLOCKGATING_EN |
                                                PHY_CLK_CTRL_CLK32K_EN));
-       } else  {
-               pwr |= PHY_PWR_PHYPWD;
-               WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+       } else {
+               __twl4030_phy_power(twl, 0);
                regulator_disable(twl->usb1v5);
                regulator_disable(twl->usb1v8);
                regulator_disable(twl->usb3v1);
@@ -387,19 +394,25 @@ static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
 
        twl4030_phy_power(twl, 0);
        twl->asleep = 1;
+       dev_dbg(twl->dev, "%s\n", __func__);
 }
 
-static void twl4030_phy_resume(struct twl4030_usb *twl)
+static void __twl4030_phy_resume(struct twl4030_usb *twl)
 {
-       if (!twl->asleep)
-               return;
-
        twl4030_phy_power(twl, 1);
        twl4030_i2c_access(twl, 1);
        twl4030_usb_set_mode(twl, twl->usb_mode);
        if (twl->usb_mode == T2_USB_MODE_ULPI)
                twl4030_i2c_access(twl, 0);
+}
+
+static void twl4030_phy_resume(struct twl4030_usb *twl)
+{
+       if (!twl->asleep)
+               return;
+       __twl4030_phy_resume(twl);
        twl->asleep = 0;
+       dev_dbg(twl->dev, "%s\n", __func__);
 }
 
 static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
@@ -408,8 +421,8 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
        twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY);
        twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY);
 
-       /* put VUSB3V1 LDO in active state */
-       twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
+       /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/
+       /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
 
        /* input to VUSB3V1 LDO is from VBAT, not VBUS */
        twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
@@ -502,6 +515,26 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
        return IRQ_HANDLED;
 }
 
+static void twl4030_usb_phy_init(struct twl4030_usb *twl)
+{
+       int status;
+
+       status = twl4030_usb_linkstat(twl);
+       if (status >= 0) {
+               if (status == USB_EVENT_NONE) {
+                       __twl4030_phy_power(twl, 0);
+                       twl->asleep = 1;
+               } else {
+                       __twl4030_phy_resume(twl);
+                       twl->asleep = 0;
+               }
+
+               blocking_notifier_call_chain(&twl->otg.notifier, status,
+                               twl->otg.gadget);
+       }
+       sysfs_notify(&twl->dev->kobj, NULL, "vbus");
+}
+
 static int twl4030_set_suspend(struct otg_transceiver *x, int suspend)
 {
        struct twl4030_usb *twl = xceiv_to_twl(x);
@@ -550,7 +583,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
        struct twl4030_usb_data *pdata = pdev->dev.platform_data;
        struct twl4030_usb      *twl;
        int                     status, err;
-       u8                      pwr;
 
        if (!pdata) {
                dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -569,10 +601,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
        twl->otg.set_peripheral = twl4030_set_peripheral;
        twl->otg.set_suspend    = twl4030_set_suspend;
        twl->usb_mode           = pdata->usb_mode;
-
-       pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
-
-       twl->asleep             = (pwr & PHY_PWR_PHYPWD);
+       twl->asleep = 1;
 
        /* init spinlock for workqueue */
        spin_lock_init(&twl->lock);
@@ -610,15 +639,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
                return status;
        }
 
-       /* The IRQ handler just handles changes from the previous states
-        * of the ID and VBUS pins ... in probe() we must initialize that
-        * previous state.  The easy way:  fake an IRQ.
-        *
-        * REVISIT:  a real IRQ might have happened already, if PREEMPT is
-        * enabled.  Else the IRQ may not yet be configured or enabled,
-        * because of scheduling delays.
+       /* Power down phy or make it work according to
+        * current link state.
         */
-       twl4030_usb_irq(twl->irq, twl);
+       twl4030_usb_phy_init(twl);
 
        dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
        return 0;
index 30922a7e3347494b5ca30b81ea77e53ea767e91e..aa665817a2720414a7e669b20499d62ebca4b6db 100644 (file)
@@ -2024,6 +2024,9 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
 
        case TIOCGICOUNT:
                cnow = mos7720_port->icount;
+
+               memset(&icount, 0, sizeof(struct serial_icounter_struct));
+
                icount.cts = cnow.cts;
                icount.dsr = cnow.dsr;
                icount.rng = cnow.rng;
index 1c9b6e9b2386e5032da1e3b8a095525222dc8cb5..1a42bc2137995bea0b70905cfe518674242141fd 100644 (file)
@@ -2285,6 +2285,9 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
        case TIOCGICOUNT:
                cnow = mos7840_port->icount;
                smp_rmb();
+
+               memset(&icount, 0, sizeof(struct serial_icounter_struct));
+
                icount.cts = cnow.cts;
                icount.dsr = cnow.dsr;
                icount.rng = cnow.rng;
index 29e850a7a2f9871b7c9658e0717f8926dc5bc4ac..7c8008225ee3a47ebef2cecaf005c0631fa93da1 100644 (file)
@@ -243,7 +243,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
        int r, nlogs = 0;
 
        while (datalen > 0) {
-               if (unlikely(headcount >= VHOST_NET_MAX_SG)) {
+               if (unlikely(seg >= VHOST_NET_MAX_SG)) {
                        r = -ENOBUFS;
                        goto err;
                }
index c579dcc9200ccabe0f1bcf79afed59577e4a6f38..dd3d6f7406f80092cdd8843acdd06c313e9cf164 100644 (file)
@@ -858,11 +858,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
                if (r < 0)
                        return r;
                len -= l;
-               if (!len)
+               if (!len) {
+                       if (vq->log_ctx)
+                               eventfd_signal(vq->log_ctx, 1);
                        return 0;
+               }
        }
-       if (vq->log_ctx)
-               eventfd_signal(vq->log_ctx, 1);
        /* Length written exceeds what we have stored. This is a bug. */
        BUG();
        return 0;
index 84f842331dfae0d7c4b194b42f283fae44e8a6af..7ccc967831f05bca5aba179bb88ff7880f55b92f 100644 (file)
@@ -3508,7 +3508,7 @@ static void fbcon_exit(void)
        softback_buf = 0UL;
 
        for (i = 0; i < FB_MAX; i++) {
-               int pending;
+               int pending = 0;
 
                mapped = 0;
                info = registered_fb[i];
@@ -3516,7 +3516,8 @@ static void fbcon_exit(void)
                if (info == NULL)
                        continue;
 
-               pending = cancel_work_sync(&info->queue);
+               if (info->queue.func)
+                       pending = cancel_work_sync(&info->queue);
                DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" :
                        "no"));
 
index 815f84b07933f7b97dc1fab249055531f6cc65b2..70477c2e4b619cd6a2ca5562771e15243cd647a3 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/screen_info.h>
 #include <linux/dmi.h>
-
+#include <linux/pci.h>
 #include <video/vga.h>
 
 static struct fb_var_screeninfo efifb_defined __devinitdata = {
@@ -39,17 +39,31 @@ enum {
        M_I20,          /* 20-Inch iMac */
        M_I20_SR,       /* 20-Inch iMac (Santa Rosa) */
        M_I24,          /* 24-Inch iMac */
+       M_I24_8_1,      /* 24-Inch iMac, 8,1th gen */
+       M_I24_10_1,     /* 24-Inch iMac, 10,1th gen */
+       M_I27_11_1,     /* 27-Inch iMac, 11,1th gen */
        M_MINI,         /* Mac Mini */
+       M_MINI_3_1,     /* Mac Mini, 3,1th gen */
+       M_MINI_4_1,     /* Mac Mini, 4,1th gen */
        M_MB,           /* MacBook */
        M_MB_2,         /* MacBook, 2nd rev. */
        M_MB_3,         /* MacBook, 3rd rev. */
+       M_MB_5_1,       /* MacBook, 5th rev. */
+       M_MB_6_1,       /* MacBook, 6th rev. */
+       M_MB_7_1,       /* MacBook, 7th rev. */
        M_MB_SR,        /* MacBook, 2nd gen, (Santa Rosa) */
        M_MBA,          /* MacBook Air */
        M_MBP,          /* MacBook Pro */
        M_MBP_2,        /* MacBook Pro 2nd gen */
+       M_MBP_2_2,      /* MacBook Pro 2,2nd gen */
        M_MBP_SR,       /* MacBook Pro (Santa Rosa) */
        M_MBP_4,        /* MacBook Pro, 4th gen */
        M_MBP_5_1,    /* MacBook Pro, 5,1th gen */
+       M_MBP_5_2,      /* MacBook Pro, 5,2th gen */
+       M_MBP_5_3,      /* MacBook Pro, 5,3rd gen */
+       M_MBP_6_1,      /* MacBook Pro, 6,1th gen */
+       M_MBP_6_2,      /* MacBook Pro, 6,2th gen */
+       M_MBP_7_1,      /* MacBook Pro, 7,1th gen */
        M_UNKNOWN       /* placeholder */
 };
 
@@ -64,14 +78,28 @@ static struct efifb_dmi_info {
        [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
        [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
        [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
+       [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 },
+       [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 },
+       [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 },
        [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
+       [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 },
+       [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 },
        [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
+       [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 },
+       [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 },
+       [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 },
        [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
        [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
        [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
+       [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 },
        [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
        [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
        [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
+       [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 },
+       [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 },
+       [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 },
+       [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 },
+       [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 },
        [M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
 };
 
@@ -92,7 +120,12 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1),
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1),
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
        /* At least one of these two will be right; maybe both? */
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
@@ -101,14 +134,23 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
        {},
 };
 
@@ -116,7 +158,7 @@ static int set_system(const struct dmi_system_id *id)
 {
        struct efifb_dmi_info *info = id->driver_data;
        if (info->base == 0)
-               return -ENODEV;
+               return 0;
 
        printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
                         "(%dx%d, stride %d)\n", id->ident,
@@ -124,18 +166,55 @@ static int set_system(const struct dmi_system_id *id)
                         info->stride);
 
        /* Trust the bootloader over the DMI tables */
-       if (screen_info.lfb_base == 0)
+       if (screen_info.lfb_base == 0) {
+#if defined(CONFIG_PCI)
+               struct pci_dev *dev = NULL;
+               int found_bar = 0;
+#endif
                screen_info.lfb_base = info->base;
-       if (screen_info.lfb_linelength == 0)
-               screen_info.lfb_linelength = info->stride;
-       if (screen_info.lfb_width == 0)
-               screen_info.lfb_width = info->width;
-       if (screen_info.lfb_height == 0)
-               screen_info.lfb_height = info->height;
-       if (screen_info.orig_video_isVGA == 0)
-               screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
 
-       return 0;
+#if defined(CONFIG_PCI)
+               /* make sure that the address in the table is actually on a
+                * VGA device's PCI BAR */
+
+               for_each_pci_dev(dev) {
+                       int i;
+                       if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+                               continue;
+                       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+                               resource_size_t start, end;
+
+                               start = pci_resource_start(dev, i);
+                               if (start == 0)
+                                       break;
+                               end = pci_resource_end(dev, i);
+                               if (screen_info.lfb_base >= start &&
+                                               screen_info.lfb_base < end) {
+                                       found_bar = 1;
+                               }
+                       }
+               }
+               if (!found_bar)
+                       screen_info.lfb_base = 0;
+#endif
+       }
+       if (screen_info.lfb_base) {
+               if (screen_info.lfb_linelength == 0)
+                       screen_info.lfb_linelength = info->stride;
+               if (screen_info.lfb_width == 0)
+                       screen_info.lfb_width = info->width;
+               if (screen_info.lfb_height == 0)
+                       screen_info.lfb_height = info->height;
+               if (screen_info.orig_video_isVGA == 0)
+                       screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
+       } else {
+               screen_info.lfb_linelength = 0;
+               screen_info.lfb_width = 0;
+               screen_info.lfb_height = 0;
+               screen_info.orig_video_isVGA = 0;
+               return 0;
+       }
+       return 1;
 }
 
 static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
index 5d786bd3e304f1a174e682461d7d94a265ae2119..cea6403ae71c16ffbcded14282db1552244f8833 100644 (file)
@@ -298,8 +298,8 @@ static void set_dma_control0(struct pxa168fb_info *fbi)
         * Set bit to enable graphics DMA.
         */
        x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
-       x |= fbi->active ? 0x00000100 : 0;
-       fbi->active = 0;
+       x &= ~CFG_GRA_ENA_MASK;
+       x |= fbi->active ? CFG_GRA_ENA(1) : CFG_GRA_ENA(0);
 
        /*
         * If we are in a pseudo-color mode, we need to enable
@@ -784,12 +784,53 @@ failed:
        return ret;
 }
 
+static int __devexit pxa168fb_remove(struct platform_device *pdev)
+{
+       struct pxa168fb_info *fbi = platform_get_drvdata(pdev);
+       struct fb_info *info;
+       int irq;
+       unsigned int data;
+
+       if (!fbi)
+               return 0;
+
+       /* disable DMA transfer */
+       data = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
+       data &= ~CFG_GRA_ENA_MASK;
+       writel(data, fbi->reg_base + LCD_SPU_DMA_CTRL0);
+
+       info = fbi->info;
+
+       unregister_framebuffer(info);
+
+       writel(GRA_FRAME_IRQ0_ENA(0x0), fbi->reg_base + SPU_IRQ_ENA);
+
+       if (info->cmap.len)
+               fb_dealloc_cmap(&info->cmap);
+
+       irq = platform_get_irq(pdev, 0);
+       free_irq(irq, fbi);
+
+       dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+                               info->screen_base, info->fix.smem_start);
+
+       iounmap(fbi->reg_base);
+
+       clk_disable(fbi->clk);
+       clk_put(fbi->clk);
+
+       framebuffer_release(info);
+
+       return 0;
+}
+
 static struct platform_driver pxa168fb_driver = {
        .driver         = {
                .name   = "pxa168-fb",
                .owner  = THIS_MODULE,
        },
        .probe          = pxa168fb_probe,
+       .remove         = __devexit_p(pxa168fb_remove),
 };
 
 static int __init pxa168fb_init(void)
@@ -798,6 +839,12 @@ static int __init pxa168fb_init(void)
 }
 module_init(pxa168fb_init);
 
+static void __exit pxa168fb_exit(void)
+{
+       platform_driver_unregister(&pxa168fb_driver);
+}
+module_exit(pxa168fb_exit);
+
 MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> "
              "Green Wan <gwan@marvell.com>");
 MODULE_DESCRIPTION("Framebuffer driver for PXA168/910");
index 559bf1727a2b8f252a193d6fac276aed56124428..b52f8e4ef1fdbe3cd19c70d4fb282d15f5b99f85 100644 (file)
@@ -1701,6 +1701,9 @@ static int        sisfb_ioctl(struct fb_info *info, unsigned int cmd,
                break;
 
           case FBIOGET_VBLANK:
+
+               memset(&sisvbblank, 0, sizeof(struct fb_vblank));
+
                sisvbblank.count = 0;
                sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
 
index da03c074e32aad8b909c4b11c57a4c5a9f9d9285..4d553d0b8d7a450b9337a9b4375856c5b304217c 100644 (file)
@@ -25,6 +25,8 @@ int viafb_ioctl_get_viafb_info(u_long arg)
 {
        struct viafb_ioctl_info viainfo;
 
+       memset(&viainfo, 0, sizeof(struct viafb_ioctl_info));
+
        viainfo.viafb_id = VIAID;
        viainfo.vendor_id = PCI_VIA_VENDOR_ID;
 
index b036677df8c445420906c722d00611dedcaf8b0a..24efd8ea41bb04bab6830cfddfd2281881ec9ae7 100644 (file)
@@ -213,11 +213,11 @@ config OMAP_WATCHDOG
          here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
 
 config PNX4008_WATCHDOG
-       tristate "PNX4008 Watchdog"
-       depends on ARCH_PNX4008
+       tristate "PNX4008 and LPC32XX Watchdog"
+       depends on ARCH_PNX4008 || ARCH_LPC32XX
        help
          Say Y here if to include support for the watchdog timer
-         in the PNX4008 processor.
+         in the PNX4008 or LPC32XX processor.
          This driver can be built as a module by choosing M. The module
          will be called pnx4008_wdt.
 
index 88c83aa5730318b512d86a7a048dc60a9758de46..f31493e65b380cd63fef6d55132dd96e7af32d63 100644 (file)
@@ -305,7 +305,7 @@ static int __init sbwdog_init(void)
        if (ret) {
                printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
                                                ident.identity, ret);
-               return ret;
+               goto out;
        }
 
        ret = misc_register(&sbwdog_miscdev);
@@ -313,14 +313,20 @@ static int __init sbwdog_init(void)
                printk(KERN_INFO "%s: timeout is %ld.%ld secs\n",
                                ident.identity,
                                timeout / 1000000, (timeout / 100000) % 10);
-       } else
-               free_irq(1, (void *)user_dog);
+               return 0;
+       }
+       free_irq(1, (void *)user_dog);
+out:
+       unregister_reboot_notifier(&sbwdog_notifier);
+
        return ret;
 }
 
 static void __exit sbwdog_exit(void)
 {
        misc_deregister(&sbwdog_miscdev);
+       free_irq(1, (void *)user_dog);
+       unregister_reboot_notifier(&sbwdog_notifier);
 }
 
 module_init(sbwdog_init);
index 458c499c1223c6f73aaab93f9a6bdc7c816de5a2..18cdeb4c4258a67ccdba77fc517596eaa71819b9 100644 (file)
@@ -449,6 +449,9 @@ static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
        wdt->pdev = pdev;
        mutex_init(&wdt->lock);
 
+       /* make sure that the watchdog is disabled */
+       ts72xx_wdt_stop(wdt);
+
        error = misc_register(&ts72xx_wdt_miscdev);
        if (error) {
                dev_err(&pdev->dev, "failed to register miscdev\n");
index 29bac5118877ef2028a781e6b409e2fe36463a99..d409495876f11b24fabaebc01d57f02224fe459f 100644 (file)
@@ -755,7 +755,10 @@ int register_xenstore_notifier(struct notifier_block *nb)
 {
        int ret = 0;
 
-       blocking_notifier_chain_register(&xenstore_chain, nb);
+       if (xenstored_ready > 0)
+               ret = nb->notifier_call(nb, 0, NULL);
+       else
+               blocking_notifier_chain_register(&xenstore_chain, nb);
 
        return ret;
 }
@@ -769,7 +772,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 
 void xenbus_probe(struct work_struct *unused)
 {
-       BUG_ON((xenstored_ready <= 0));
+       xenstored_ready = 1;
 
        /* Enumerate devices in xenstore and watch for changes. */
        xenbus_probe_devices(&xenbus_frontend);
@@ -835,8 +838,8 @@ static int __init xenbus_init(void)
                        xen_store_evtchn = xen_start_info->store_evtchn;
                        xen_store_mfn = xen_start_info->store_mfn;
                        xen_store_interface = mfn_to_virt(xen_store_mfn);
+                       xenstored_ready = 1;
                }
-               xenstored_ready = 1;
        }
 
        /* Initialize the interface to xenstore. */
index 16c8a2a98c1bb6b93fbc8634cb1986cf555bad0e..899f168fd19cc4d4aca48e6d26e51aa08b34db59 100644 (file)
@@ -292,9 +292,11 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
 
        fid = filp->private_data;
        P9_DPRINTK(P9_DEBUG_VFS,
-                       "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid);
+                       "v9fs_dir_release: inode: %p filp: %p fid: %d\n",
+                       inode, filp, fid ? fid->fid : -1);
        filemap_write_and_wait(inode->i_mapping);
-       p9_client_clunk(fid);
+       if (fid)
+               p9_client_clunk(fid);
        return 0;
 }
 
index c7c23eab94403468d161eac3bd254dfde1e27610..9e670d527646fc4abe2be6f0dfc992f4a3178042 100644 (file)
@@ -730,7 +730,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
                P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
                goto error;
        }
-       dentry->d_op = &v9fs_cached_dentry_operations;
+       if (v9ses->cache)
+               dentry->d_op = &v9fs_cached_dentry_operations;
+       else
+               dentry->d_op = &v9fs_dentry_operations;
        d_instantiate(dentry, inode);
        err = v9fs_fid_add(dentry, fid);
        if (err < 0)
@@ -1128,6 +1131,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
        v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
                generic_fillattr(dentry->d_inode, stat);
 
+       p9stat_free(st);
        kfree(st);
        return 0;
 }
@@ -1489,6 +1493,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
 
        retval = strnlen(buffer, buflen);
 done:
+       p9stat_free(st);
        kfree(st);
        return retval;
 }
@@ -1942,7 +1947,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
        .unlink = v9fs_vfs_unlink,
        .mkdir = v9fs_vfs_mkdir,
        .rmdir = v9fs_vfs_rmdir,
-       .mknod = v9fs_vfs_mknod_dotl,
+       .mknod = v9fs_vfs_mknod,
        .rename = v9fs_vfs_rename,
        .getattr = v9fs_vfs_getattr,
        .setattr = v9fs_vfs_setattr,
index f9311077de6842091df9f257e3e6d91c641a0622..1d12ba0ed3db52fa55e2e6ff4aa48ade2cae1a88 100644 (file)
@@ -122,6 +122,10 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
        fid = v9fs_session_init(v9ses, dev_name, data);
        if (IS_ERR(fid)) {
                retval = PTR_ERR(fid);
+               /*
+                * we need to call session_close to tear down some
+                * of the data structure setup by session_init
+                */
                goto close_session;
        }
 
@@ -144,7 +148,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
                retval = -ENOMEM;
                goto release_sb;
        }
-
        sb->s_root = root;
 
        if (v9fs_proto_dotl(v9ses)) {
@@ -152,7 +155,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
                st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
                if (IS_ERR(st)) {
                        retval = PTR_ERR(st);
-                       goto clunk_fid;
+                       goto release_sb;
                }
 
                v9fs_stat2inode_dotl(st, root->d_inode);
@@ -162,7 +165,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
                st = p9_client_stat(fid);
                if (IS_ERR(st)) {
                        retval = PTR_ERR(st);
-                       goto clunk_fid;
+                       goto release_sb;
                }
 
                root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
@@ -174,19 +177,24 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
 
        v9fs_fid_add(root, fid);
 
-P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
+       P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
        simple_set_mnt(mnt, sb);
        return 0;
 
 clunk_fid:
        p9_client_clunk(fid);
-
 close_session:
        v9fs_session_close(v9ses);
        kfree(v9ses);
        return retval;
-
 release_sb:
+       /*
+        * we will do the session_close and root dentry release
+        * in the below call. But we need to clunk fid, because we haven't
+        * attached the fid to dentry so it won't get clunked
+        * automatically.
+        */
+       p9_client_clunk(fid);
        deactivate_locked_super(sb);
        return retval;
 }
index 3006b5bc33d697a2f773b2d81016fda57ee5ff68..250b0a73c8a8ca92b78c3a0282d2425ce7649dcf 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -712,8 +712,16 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
         */
        ret = retry(iocb);
 
-       if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED)
+       if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
+               /*
+                * There's no easy way to restart the syscall since other AIO's
+                * may be already running. Just fail this IO with EINTR.
+                */
+               if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR ||
+                            ret == -ERESTARTNOHAND || ret == -ERESTART_RESTARTBLOCK))
+                       ret = -EINTR;
                aio_complete(iocb, ret, 0);
+       }
 out:
        spin_lock_irq(&ctx->ctx_lock);
 
@@ -1659,6 +1667,9 @@ long do_io_submit(aio_context_t ctx_id, long nr,
        if (unlikely(nr < 0))
                return -EINVAL;
 
+       if (unlikely(nr > LONG_MAX/sizeof(*iocbpp)))
+               nr = LONG_MAX/sizeof(*iocbpp);
+
        if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp)))))
                return -EFAULT;
 
index f96eff04e11ab4a8b23f7489ee4b0de50e67e152..a6395bdb26aeb13b7b98c74df4f77780c1c95412 100644 (file)
@@ -134,10 +134,6 @@ static int aout_core_dump(struct coredump_params *cprm)
                if (!dump_write(file, dump_start, dump_size))
                        goto end_coredump;
        }
-/* Finally dump the task struct.  Not be used by gdb, but could be useful */
-       set_fs(KERNEL_DS);
-       if (!dump_write(file, current, sizeof(*current)))
-               goto end_coredump;
 end_coredump:
        set_fs(fs);
        return has_dumped;
index bc87b9c1d27ea8e253f5a1b9b395a287ede4106e..0fcd2640c23fdda2c7fd99415b730837c591eba8 100644 (file)
@@ -3,6 +3,7 @@ config CEPH_FS
        depends on INET && EXPERIMENTAL
        select LIBCRC32C
        select CRYPTO_AES
+       select CRYPTO
        help
          Choose Y or M here to include support for mounting the
          experimental Ceph distributed file system.  Ceph is an extremely
index 4cfce1ee31faaf4f2f6aab966acd5d6001753940..efbc604001c8bbfa3b96eb107529f0f03256b1a1 100644 (file)
@@ -411,8 +411,8 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
        if (i_size < page_off + len)
                len = i_size - page_off;
 
-       dout("writepage %p page %p index %lu on %llu~%u\n",
-            inode, page, page->index, page_off, len);
+       dout("writepage %p page %p index %lu on %llu~%u snapc %p\n",
+            inode, page, page->index, page_off, len, snapc);
 
        writeback_stat = atomic_long_inc_return(&client->writeback_count);
        if (writeback_stat >
@@ -766,7 +766,8 @@ get_more_pages:
                        /* ok */
                        if (locked_pages == 0) {
                                /* prepare async write request */
-                               offset = page->index << PAGE_CACHE_SHIFT;
+                               offset = (unsigned long long)page->index
+                                       << PAGE_CACHE_SHIFT;
                                len = wsize;
                                req = ceph_osdc_new_request(&client->osdc,
                                            &ci->i_layout,
index a2069b6680aed83eb0be0af7c584b4a619ae239a..5e9da996a1519c42880872267d7609cc82eb2dc2 100644 (file)
@@ -814,7 +814,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
                used |= CEPH_CAP_PIN;
        if (ci->i_rd_ref)
                used |= CEPH_CAP_FILE_RD;
-       if (ci->i_rdcache_ref || ci->i_rdcache_gen)
+       if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages)
                used |= CEPH_CAP_FILE_CACHE;
        if (ci->i_wr_ref)
                used |= CEPH_CAP_FILE_WR;
@@ -1195,10 +1195,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
  * asynchronously back to the MDS once sync writes complete and dirty
  * data is written out.
  *
+ * Unless @again is true, skip cap_snaps that were already sent to
+ * the MDS (i.e., during this session).
+ *
  * Called under i_lock.  Takes s_mutex as needed.
  */
 void __ceph_flush_snaps(struct ceph_inode_info *ci,
-                       struct ceph_mds_session **psession)
+                       struct ceph_mds_session **psession,
+                       int again)
                __releases(ci->vfs_inode->i_lock)
                __acquires(ci->vfs_inode->i_lock)
 {
@@ -1227,7 +1231,7 @@ retry:
                 * pages to be written out.
                 */
                if (capsnap->dirty_pages || capsnap->writing)
-                       continue;
+                       break;
 
                /*
                 * if cap writeback already occurred, we should have dropped
@@ -1240,6 +1244,13 @@ retry:
                        dout("no auth cap (migrating?), doing nothing\n");
                        goto out;
                }
+
+               /* only flush each capsnap once */
+               if (!again && !list_empty(&capsnap->flushing_item)) {
+                       dout("already flushed %p, skipping\n", capsnap);
+                       continue;
+               }
+
                mds = ci->i_auth_cap->session->s_mds;
                mseq = ci->i_auth_cap->mseq;
 
@@ -1276,8 +1287,8 @@ retry:
                              &session->s_cap_snaps_flushing);
                spin_unlock(&inode->i_lock);
 
-               dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
-                    inode, capsnap, next_follows, capsnap->size);
+               dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n",
+                    inode, capsnap, capsnap->follows, capsnap->flush_tid);
                send_cap_msg(session, ceph_vino(inode).ino, 0,
                             CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
                             capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
@@ -1314,7 +1325,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
        struct inode *inode = &ci->vfs_inode;
 
        spin_lock(&inode->i_lock);
-       __ceph_flush_snaps(ci, NULL);
+       __ceph_flush_snaps(ci, NULL, 0);
        spin_unlock(&inode->i_lock);
 }
 
@@ -1477,7 +1488,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 
        /* flush snaps first time around only */
        if (!list_empty(&ci->i_cap_snaps))
-               __ceph_flush_snaps(ci, &session);
+               __ceph_flush_snaps(ci, &session, 0);
        goto retry_locked;
 retry:
        spin_lock(&inode->i_lock);
@@ -1894,7 +1905,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
                if (cap && cap->session == session) {
                        dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
                             cap, capsnap);
-                       __ceph_flush_snaps(ci, &session);
+                       __ceph_flush_snaps(ci, &session, 1);
                } else {
                        pr_err("%p auth cap %p not mds%d ???\n", inode,
                               cap, session->s_mds);
@@ -2272,7 +2283,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        int mds = session->s_mds;
-       int seq = le32_to_cpu(grant->seq);
+       unsigned seq = le32_to_cpu(grant->seq);
+       unsigned issue_seq = le32_to_cpu(grant->issue_seq);
        int newcaps = le32_to_cpu(grant->caps);
        int issued, implemented, used, wanted, dirty;
        u64 size = le64_to_cpu(grant->size);
@@ -2284,8 +2296,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        int revoked_rdcache = 0;
        int queue_invalidate = 0;
 
-       dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
-            inode, cap, mds, seq, ceph_cap_string(newcaps));
+       dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n",
+            inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps));
        dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
                inode->i_size);
 
@@ -2381,6 +2393,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        }
 
        cap->seq = seq;
+       cap->issue_seq = issue_seq;
 
        /* file layout may have changed */
        ci->i_layout = grant->layout;
@@ -2763,15 +2776,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                if (op == CEPH_CAP_OP_IMPORT)
                        __queue_cap_release(session, vino.ino, cap_id,
                                            mseq, seq);
-
-               /*
-                * send any full release message to try to move things
-                * along for the mds (who clearly thinks we still have this
-                * cap).
-                */
-               ceph_add_cap_releases(mdsc, session);
-               ceph_send_cap_releases(mdsc, session);
-               goto done;
+               goto flush_cap_releases;
        }
 
        /* these will work even if we don't have a cap yet */
@@ -2799,7 +2804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                dout(" no cap on %p ino %llx.%llx from mds%d\n",
                     inode, ceph_ino(inode), ceph_snap(inode), mds);
                spin_unlock(&inode->i_lock);
-               goto done;
+               goto flush_cap_releases;
        }
 
        /* note that each of these drops i_lock for us */
@@ -2823,6 +2828,17 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                       ceph_cap_op_name(op));
        }
 
+       goto done;
+
+flush_cap_releases:
+       /*
+        * send any full release message to try to move things
+        * along for the mds (who clearly thinks we still have this
+        * cap).
+        */
+       ceph_add_cap_releases(mdsc, session);
+       ceph_send_cap_releases(mdsc, session);
+
 done:
        mutex_unlock(&session->s_mutex);
 done_unlocked:
index 6e4f43ff23ec587050eab1b0e735e8d519827c85..a1986eb52045b8184d6ab31e46b8a2497295e9ba 100644 (file)
@@ -1021,11 +1021,15 @@ out_touch:
 static void ceph_dentry_release(struct dentry *dentry)
 {
        struct ceph_dentry_info *di = ceph_dentry(dentry);
-       struct inode *parent_inode = dentry->d_parent->d_inode;
-       u64 snapid = ceph_snap(parent_inode);
+       struct inode *parent_inode = NULL;
+       u64 snapid = CEPH_NOSNAP;
 
+       if (!IS_ROOT(dentry)) {
+               parent_inode = dentry->d_parent->d_inode;
+               if (parent_inode)
+                       snapid = ceph_snap(parent_inode);
+       }
        dout("dentry_release %p parent %p\n", dentry, parent_inode);
-
        if (parent_inode && snapid != CEPH_SNAPDIR) {
                struct ceph_inode_info *ci = ceph_inode(parent_inode);
 
index 4480cb1c63e7c69b107628481388cf1e35f49b8d..e38423e82f2ebe3f311a3f173964181c5ebe1860 100644 (file)
@@ -42,32 +42,37 @@ struct ceph_nfs_confh {
 static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
                          int connectable)
 {
+       int type;
        struct ceph_nfs_fh *fh = (void *)rawfh;
        struct ceph_nfs_confh *cfh = (void *)rawfh;
        struct dentry *parent = dentry->d_parent;
        struct inode *inode = dentry->d_inode;
-       int type;
+       int connected_handle_length = sizeof(*cfh)/4;
+       int handle_length = sizeof(*fh)/4;
 
        /* don't re-export snaps */
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EINVAL;
 
-       if (*max_len >= sizeof(*cfh)) {
+       if (*max_len >= connected_handle_length) {
                dout("encode_fh %p connectable\n", dentry);
                cfh->ino = ceph_ino(dentry->d_inode);
                cfh->parent_ino = ceph_ino(parent->d_inode);
                cfh->parent_name_hash = parent->d_name.hash;
-               *max_len = sizeof(*cfh);
+               *max_len = connected_handle_length;
                type = 2;
-       } else if (*max_len > sizeof(*fh)) {
-               if (connectable)
-                       return -ENOSPC;
+       } else if (*max_len >= handle_length) {
+               if (connectable) {
+                       *max_len = connected_handle_length;
+                       return 255;
+               }
                dout("encode_fh %p\n", dentry);
                fh->ino = ceph_ino(dentry->d_inode);
-               *max_len = sizeof(*fh);
+               *max_len = handle_length;
                type = 1;
        } else {
-               return -ENOSPC;
+               *max_len = handle_length;
+               return 255;
        }
        return type;
 }
index 8c044a4f045751c62420e67664705f981efe238a..66e4da6dba229716ff3349fe87f5dfe62fe62db1 100644 (file)
@@ -697,7 +697,7 @@ more:
                         * start_request so that a tid has been assigned.
                         */
                        spin_lock(&ci->i_unsafe_lock);
-                       list_add(&ci->i_unsafe_writes, &req->r_unsafe_item);
+                       list_add(&req->r_unsafe_item, &ci->i_unsafe_writes);
                        spin_unlock(&ci->i_unsafe_lock);
                        ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
                }
index e7cca414da03bcbd7549889a5ecb00d05ee11901..62377ec37edf05c14cf8567c0d22e19e02762253 100644 (file)
@@ -845,7 +845,7 @@ static void ceph_set_dentry_offset(struct dentry *dn)
  * the caller) if we fail.
  */
 static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
-                                   bool *prehash)
+                                   bool *prehash, bool set_offset)
 {
        struct dentry *realdn;
 
@@ -877,7 +877,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
        }
        if ((!prehash || *prehash) && d_unhashed(dn))
                d_rehash(dn);
-       ceph_set_dentry_offset(dn);
+       if (set_offset)
+               ceph_set_dentry_offset(dn);
 out:
        return dn;
 }
@@ -1062,7 +1063,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                                d_delete(dn);
                                goto done;
                        }
-                       dn = splice_dentry(dn, in, &have_lease);
+                       dn = splice_dentry(dn, in, &have_lease, true);
                        if (IS_ERR(dn)) {
                                err = PTR_ERR(dn);
                                goto done;
@@ -1105,7 +1106,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                        goto done;
                }
                dout(" linking snapped dir %p to dn %p\n", in, dn);
-               dn = splice_dentry(dn, in, NULL);
+               dn = splice_dentry(dn, in, NULL, true);
                if (IS_ERR(dn)) {
                        err = PTR_ERR(dn);
                        goto done;
@@ -1237,7 +1238,7 @@ retry_lookup:
                                err = PTR_ERR(in);
                                goto out;
                        }
-                       dn = splice_dentry(dn, in, NULL);
+                       dn = splice_dentry(dn, in, NULL, false);
                        if (IS_ERR(dn))
                                dn = NULL;
                }
index f091b1351786368de18757d8cb262a19d1006bf1..fad95f8f2608bc4e86c0876bedd81cb5be46a4ef 100644 (file)
@@ -2374,6 +2374,8 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
                                                num_fcntl_locks,
                                                num_flock_locks);
                unlock_kernel();
+       } else {
+               err = ceph_pagelist_append(pagelist, &rec, reclen);
        }
 
 out_free:
index dfced1dacbcdcb47178f2c9676275869c2105296..3b5571b8ce22e2ef8abdcf3d2dd4da1598bf6233 100644 (file)
@@ -549,7 +549,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
  */
 static void __cancel_request(struct ceph_osd_request *req)
 {
-       if (req->r_sent) {
+       if (req->r_sent && req->r_osd) {
                ceph_con_revoke(&req->r_osd->o_con, req->r_request);
                req->r_sent = 0;
        }
index b6859f47d364ba2134121d48fa6cc720f3b6b1a4..46a368b6dce5378f3b7a486b60700c52f65a809b 100644 (file)
@@ -5,10 +5,18 @@
 
 #include "pagelist.h"
 
+static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
+{
+       struct page *page = list_entry(pl->head.prev, struct page,
+                                      lru);
+       kunmap(page);
+}
+
 int ceph_pagelist_release(struct ceph_pagelist *pl)
 {
        if (pl->mapped_tail)
-               kunmap(pl->mapped_tail);
+               ceph_pagelist_unmap_tail(pl);
+
        while (!list_empty(&pl->head)) {
                struct page *page = list_first_entry(&pl->head, struct page,
                                                     lru);
@@ -26,7 +34,7 @@ static int ceph_pagelist_addpage(struct ceph_pagelist *pl)
        pl->room += PAGE_SIZE;
        list_add_tail(&page->lru, &pl->head);
        if (pl->mapped_tail)
-               kunmap(pl->mapped_tail);
+               ceph_pagelist_unmap_tail(pl);
        pl->mapped_tail = kmap(page);
        return 0;
 }
index 4868b9dcac5a6cc7a4d00610780572f335ef68f2..190b6c4a6f2b91aace658f8de7664f75cc0bdcc4 100644 (file)
@@ -119,6 +119,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
        INIT_LIST_HEAD(&realm->children);
        INIT_LIST_HEAD(&realm->child_item);
        INIT_LIST_HEAD(&realm->empty_item);
+       INIT_LIST_HEAD(&realm->dirty_item);
        INIT_LIST_HEAD(&realm->inodes_with_caps);
        spin_lock_init(&realm->inodes_with_caps_lock);
        __insert_snap_realm(&mdsc->snap_realms, realm);
@@ -467,7 +468,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
                INIT_LIST_HEAD(&capsnap->ci_item);
                INIT_LIST_HEAD(&capsnap->flushing_item);
 
-               capsnap->follows = snapc->seq - 1;
+               capsnap->follows = snapc->seq;
                capsnap->issued = __ceph_caps_issued(ci, NULL);
                capsnap->dirty = dirty;
 
@@ -604,6 +605,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
        struct ceph_snap_realm *realm;
        int invalidate = 0;
        int err = -ENOMEM;
+       LIST_HEAD(dirty_realms);
 
        dout("update_snap_trace deletion=%d\n", deletion);
 more:
@@ -626,24 +628,6 @@ more:
                }
        }
 
-       if (le64_to_cpu(ri->seq) > realm->seq) {
-               dout("update_snap_trace updating %llx %p %lld -> %lld\n",
-                    realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
-               /*
-                * if the realm seq has changed, queue a cap_snap for every
-                * inode with open caps.  we do this _before_ we update
-                * the realm info so that we prepare for writeback under the
-                * _previous_ snap context.
-                *
-                * ...unless it's a snap deletion!
-                */
-               if (!deletion)
-                       queue_realm_cap_snaps(realm);
-       } else {
-               dout("update_snap_trace %llx %p seq %lld unchanged\n",
-                    realm->ino, realm, realm->seq);
-       }
-
        /* ensure the parent is correct */
        err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
        if (err < 0)
@@ -651,6 +635,8 @@ more:
        invalidate += err;
 
        if (le64_to_cpu(ri->seq) > realm->seq) {
+               dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+                    realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
                /* update realm parameters, snap lists */
                realm->seq = le64_to_cpu(ri->seq);
                realm->created = le64_to_cpu(ri->created);
@@ -668,9 +654,17 @@ more:
                if (err < 0)
                        goto fail;
 
+               /* queue realm for cap_snap creation */
+               list_add(&realm->dirty_item, &dirty_realms);
+
                invalidate = 1;
        } else if (!realm->cached_context) {
+               dout("update_snap_trace %llx %p seq %lld new\n",
+                    realm->ino, realm, realm->seq);
                invalidate = 1;
+       } else {
+               dout("update_snap_trace %llx %p seq %lld unchanged\n",
+                    realm->ino, realm, realm->seq);
        }
 
        dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
@@ -683,6 +677,14 @@ more:
        if (invalidate)
                rebuild_snap_realms(realm);
 
+       /*
+        * queue cap snaps _after_ we've built the new snap contexts,
+        * so that i_head_snapc can be set appropriately.
+        */
+       list_for_each_entry(realm, &dirty_realms, dirty_item) {
+               queue_realm_cap_snaps(realm);
+       }
+
        __cleanup_empty_realms(mdsc);
        return 0;
 
@@ -715,7 +717,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
                igrab(inode);
                spin_unlock(&mdsc->snap_flush_lock);
                spin_lock(&inode->i_lock);
-               __ceph_flush_snaps(ci, &session);
+               __ceph_flush_snaps(ci, &session, 0);
                spin_unlock(&inode->i_lock);
                iput(inode);
                spin_lock(&mdsc->snap_flush_lock);
@@ -816,6 +818,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
                        };
                        struct inode *inode = ceph_find_inode(sb, vino);
                        struct ceph_inode_info *ci;
+                       struct ceph_snap_realm *oldrealm;
 
                        if (!inode)
                                continue;
@@ -841,18 +844,19 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
                        dout(" will move %p to split realm %llx %p\n",
                             inode, realm->ino, realm);
                        /*
-                        * Remove the inode from the realm's inode
-                        * list, but don't add it to the new realm
-                        * yet.  We don't want the cap_snap to be
-                        * queued (again) by ceph_update_snap_trace()
-                        * below.  Queue it _now_, under the old context.
+                        * Move the inode to the new realm
                         */
                        spin_lock(&realm->inodes_with_caps_lock);
                        list_del_init(&ci->i_snap_realm_item);
+                       list_add(&ci->i_snap_realm_item,
+                                &realm->inodes_with_caps);
+                       oldrealm = ci->i_snap_realm;
+                       ci->i_snap_realm = realm;
                        spin_unlock(&realm->inodes_with_caps_lock);
                        spin_unlock(&inode->i_lock);
 
-                       ceph_queue_cap_snap(ci);
+                       ceph_get_snap_realm(mdsc, realm);
+                       ceph_put_snap_realm(mdsc, oldrealm);
 
                        iput(inode);
                        continue;
@@ -880,43 +884,9 @@ skip_inode:
        ceph_update_snap_trace(mdsc, p, e,
                               op == CEPH_SNAP_OP_DESTROY);
 
-       if (op == CEPH_SNAP_OP_SPLIT) {
-               /*
-                * ok, _now_ add the inodes into the new realm.
-                */
-               for (i = 0; i < num_split_inos; i++) {
-                       struct ceph_vino vino = {
-                               .ino = le64_to_cpu(split_inos[i]),
-                               .snap = CEPH_NOSNAP,
-                       };
-                       struct inode *inode = ceph_find_inode(sb, vino);
-                       struct ceph_inode_info *ci;
-
-                       if (!inode)
-                               continue;
-                       ci = ceph_inode(inode);
-                       spin_lock(&inode->i_lock);
-                       if (list_empty(&ci->i_snap_realm_item)) {
-                               struct ceph_snap_realm *oldrealm =
-                                       ci->i_snap_realm;
-
-                               dout(" moving %p to split realm %llx %p\n",
-                                    inode, realm->ino, realm);
-                               spin_lock(&realm->inodes_with_caps_lock);
-                               list_add(&ci->i_snap_realm_item,
-                                        &realm->inodes_with_caps);
-                               ci->i_snap_realm = realm;
-                               spin_unlock(&realm->inodes_with_caps_lock);
-                               ceph_get_snap_realm(mdsc, realm);
-                               ceph_put_snap_realm(mdsc, oldrealm);
-                       }
-                       spin_unlock(&inode->i_lock);
-                       iput(inode);
-               }
-
+       if (op == CEPH_SNAP_OP_SPLIT)
                /* we took a reference when we created the realm, above */
                ceph_put_snap_realm(mdsc, realm);
-       }
 
        __cleanup_empty_realms(mdsc);
 
index c33897ae5725e82ca269606b78d54214d8abf7af..b87638e84c4bc266e9b325f12e7fb98fc78e8986 100644 (file)
@@ -690,6 +690,8 @@ struct ceph_snap_realm {
 
        struct list_head empty_item;     /* if i have ref==0 */
 
+       struct list_head dirty_item;     /* if realm needs new context */
+
        /* the current set of snaps for this realm */
        struct ceph_snap_context *cached_context;
 
@@ -826,7 +828,8 @@ extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
 extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
                                       struct ceph_snap_context *snapc);
 extern void __ceph_flush_snaps(struct ceph_inode_info *ci,
-                              struct ceph_mds_session **psession);
+                              struct ceph_mds_session **psession,
+                              int again);
 extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
                            struct ceph_mds_session *session);
 extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
index f80a4f25123c3fa912daa1eb4080e69dab3d58fb..143d393881cbd86865063649dd9b27773a5dcf57 100644 (file)
@@ -40,7 +40,9 @@ struct backing_dev_info directly_mappable_cdev_bdi = {
 #endif
                /* permit direct mmap, for read, write or exec */
                BDI_CAP_MAP_DIRECT |
-               BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP),
+               BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP |
+               /* no writeback happens */
+               BDI_CAP_NO_ACCT_AND_WRITEBACK),
 };
 
 static struct kobj_map *cdev_map;
index 0da1debd499d1845420753f50ef7b7da6765c237..917b7d449bb2a6248c28c23284cf82d9c032f285 100644 (file)
@@ -2,8 +2,6 @@ config CIFS
        tristate "CIFS support (advanced network filesystem, SMBFS successor)"
        depends on INET
        select NLS
-       select CRYPTO_MD5
-       select CRYPTO_ARC4
        help
          This is the client VFS module for the Common Internet File System
          (CIFS) protocol which is the successor to the Server Message Block
index 21f0fbd86989a6811dd6323668f0836079f7e621..cfd1ce34e0bc7b8c4794c81e1aa937e7f009ca75 100644 (file)
@@ -597,13 +597,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                                if (compare_oid(oid, oidlen, MSKRB5_OID,
                                                MSKRB5_OID_LEN))
                                        server->sec_mskerberos = true;
-                               if (compare_oid(oid, oidlen, KRB5U2U_OID,
+                               else if (compare_oid(oid, oidlen, KRB5U2U_OID,
                                                     KRB5U2U_OID_LEN))
                                        server->sec_kerberosu2u = true;
-                               if (compare_oid(oid, oidlen, KRB5_OID,
+                               else if (compare_oid(oid, oidlen, KRB5_OID,
                                                     KRB5_OID_LEN))
                                        server->sec_kerberos = true;
-                               if (compare_oid(oid, oidlen, NTLMSSP_OID,
+                               else if (compare_oid(oid, oidlen, NTLMSSP_OID,
                                                     NTLMSSP_OID_LEN))
                                        server->sec_ntlmssp = true;
 
index 709f2296bdb4930b2eee0dcb7dd341f94ca42e9b..35042d8f733865c77b31ee8d10dd097d4f0a16d8 100644 (file)
@@ -27,7 +27,6 @@
 #include "md5.h"
 #include "cifs_unicode.h"
 #include "cifsproto.h"
-#include "ntlmssp.h"
 #include <linux/ctype.h>
 #include <linux/random.h>
 
@@ -43,43 +42,21 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
                       unsigned char *p24);
 
 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
-                       struct TCP_Server_Info *server, char *signature)
+                                   const struct mac_key *key, char *signature)
 {
-       int rc;
+       struct  MD5Context context;
 
-       if (cifs_pdu == NULL || server == NULL || signature == NULL)
+       if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
                return -EINVAL;
 
-       if (!server->ntlmssp.sdescmd5) {
-               cERROR(1,
-                       "cifs_calculate_signature: can't generate signature\n");
-               return -1;
-       }
-
-       rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash);
-       if (rc) {
-               cERROR(1, "cifs_calculate_signature: oould not init md5\n");
-               return rc;
-       }
-
-       if (server->secType == RawNTLMSSP)
-               crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                       server->session_key.data.ntlmv2.key,
-                       CIFS_NTLMV2_SESSKEY_SIZE);
-       else
-               crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                       (char *)&server->session_key.data,
-                       server->session_key.len);
-
-       crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                       cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
+       cifs_MD5_init(&context);
+       cifs_MD5_update(&context, (char *)&key->data, key->len);
+       cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
 
-       rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature);
-
-       return rc;
+       cifs_MD5_final(signature, &context);
+       return 0;
 }
 
-
 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
                  __u32 *pexpected_response_sequence_number)
 {
@@ -101,7 +78,8 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
        server->sequence_number++;
        spin_unlock(&GlobalMid_Lock);
 
-       rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
+       rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key,
+                                     smb_signature);
        if (rc)
                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
        else
@@ -111,39 +89,21 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
 }
 
 static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
-                       struct TCP_Server_Info *server, char *signature)
+                               const struct mac_key *key, char *signature)
 {
+       struct  MD5Context context;
        int i;
-       int rc;
 
-       if (iov == NULL || server == NULL || signature == NULL)
+       if ((iov == NULL) || (signature == NULL) || (key == NULL))
                return -EINVAL;
 
-       if (!server->ntlmssp.sdescmd5) {
-               cERROR(1, "cifs_calc_signature2: can't generate signature\n");
-               return -1;
-       }
-
-       rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash);
-       if (rc) {
-               cERROR(1, "cifs_calc_signature2: oould not init md5\n");
-               return rc;
-       }
-
-       if (server->secType == RawNTLMSSP)
-               crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                       server->session_key.data.ntlmv2.key,
-                       CIFS_NTLMV2_SESSKEY_SIZE);
-       else
-               crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                       (char *)&server->session_key.data,
-                       server->session_key.len);
-
+       cifs_MD5_init(&context);
+       cifs_MD5_update(&context, (char *)&key->data, key->len);
        for (i = 0; i < n_vec; i++) {
                if (iov[i].iov_len == 0)
                        continue;
                if (iov[i].iov_base == NULL) {
-                       cERROR(1, "cifs_calc_signature2: null iovec entry");
+                       cERROR(1, "null iovec entry");
                        return -EIO;
                }
                /* The first entry includes a length field (which does not get
@@ -151,18 +111,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
                if (i == 0) {
                        if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
                                break; /* nothing to sign or corrupt header */
-                       crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                               iov[i].iov_base + 4, iov[i].iov_len - 4);
+                       cifs_MD5_update(&context, iov[0].iov_base+4,
+                                 iov[0].iov_len-4);
                } else
-                       crypto_shash_update(&server->ntlmssp.sdescmd5->shash,
-                               iov[i].iov_base, iov[i].iov_len);
+                       cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len);
        }
 
-       rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature);
+       cifs_MD5_final(signature, &context);
 
-       return rc;
+       return 0;
 }
 
+
 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
                   __u32 *pexpected_response_sequence_number)
 {
@@ -185,7 +145,8 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
        server->sequence_number++;
        spin_unlock(&GlobalMid_Lock);
 
-       rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
+       rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key,
+                                     smb_signature);
        if (rc)
                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
        else
@@ -195,14 +156,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
 }
 
 int cifs_verify_signature(struct smb_hdr *cifs_pdu,
-                         struct TCP_Server_Info *server,
+                         const struct mac_key *mac_key,
                          __u32 expected_sequence_number)
 {
-       int rc;
+       unsigned int rc;
        char server_response_sig[8];
        char what_we_think_sig_should_be[20];
 
-       if (cifs_pdu == NULL || server == NULL)
+       if ((cifs_pdu == NULL) || (mac_key == NULL))
                return -EINVAL;
 
        if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
@@ -231,7 +192,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
                                        cpu_to_le32(expected_sequence_number);
        cifs_pdu->Signature.Sequence.Reserved = 0;
 
-       rc = cifs_calculate_signature(cifs_pdu, server,
+       rc = cifs_calculate_signature(cifs_pdu, mac_key,
                what_we_think_sig_should_be);
 
        if (rc)
@@ -248,7 +209,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 }
 
 /* We fill in key by putting in 40 byte array which was allocated by caller */
-int cifs_calculate_session_key(struct session_key *key, const char *rn,
+int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
                           const char *password)
 {
        char temp_key[16];
@@ -306,52 +267,38 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
 {
        int rc = 0;
        int len;
-       char nt_hash[CIFS_NTHASH_SIZE];
+       char nt_hash[16];
+       struct HMACMD5Context *pctxt;
        wchar_t *user;
        wchar_t *domain;
-       wchar_t *server;
 
-       if (!ses->server->ntlmssp.sdeschmacmd5) {
-               cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
-               return -1;
-       }
+       pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
+
+       if (pctxt == NULL)
+               return -ENOMEM;
 
        /* calculate md4 hash of password */
        E_md4hash(ses->password, nt_hash);
 
-       crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash,
-                               CIFS_NTHASH_SIZE);
-
-       rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash);
-       if (rc) {
-               cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
-               return rc;
-       }
+       /* convert Domainname to unicode and uppercase */
+       hmac_md5_init_limK_to_64(nt_hash, 16, pctxt);
 
        /* convert ses->userName to unicode and uppercase */
        len = strlen(ses->userName);
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
-       if (user == NULL) {
-               cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
-               rc = -ENOMEM;
+       if (user == NULL)
                goto calc_exit_2;
-       }
        len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
        UniStrupr(user);
-
-       crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
-                               (char *)user, 2 * len);
+       hmac_md5_update((char *)user, 2*len, pctxt);
 
        /* convert ses->domainName to unicode and uppercase */
        if (ses->domainName) {
                len = strlen(ses->domainName);
 
                domain = kmalloc(2 + (len * 2), GFP_KERNEL);
-               if (domain == NULL) {
-                       cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
-                       rc = -ENOMEM;
+               if (domain == NULL)
                        goto calc_exit_1;
-               }
                len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
                                        nls_cp);
                /* the following line was removed since it didn't work well
@@ -359,292 +306,65 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
                   Maybe converting the domain name earlier makes sense */
                /* UniStrupr(domain); */
 
-               crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
-                                       (char *)domain, 2 * len);
+               hmac_md5_update((char *)domain, 2*len, pctxt);
 
                kfree(domain);
-       } else if (ses->serverName) {
-               len = strlen(ses->serverName);
-
-               server = kmalloc(2 + (len * 2), GFP_KERNEL);
-               if (server == NULL) {
-                       cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
-                       rc = -ENOMEM;
-                       goto calc_exit_1;
-               }
-               len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
-                                       nls_cp);
-               /* the following line was removed since it didn't work well
-                  with lower cased domain name that passed as an option.
-                  Maybe converting the domain name earlier makes sense */
-               /* UniStrupr(domain); */
-
-               crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
-                                       (char *)server, 2 * len);
-
-               kfree(server);
        }
-
-       rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash,
-                                       ses->server->ntlmv2_hash);
-
 calc_exit_1:
        kfree(user);
 calc_exit_2:
        /* BB FIXME what about bytes 24 through 40 of the signing key?
           compare with the NTLM example */
+       hmac_md5_final(ses->server->ntlmv2_hash, pctxt);
 
+       kfree(pctxt);
        return rc;
 }
 
-static int
-find_domain_name(struct cifsSesInfo *ses)
-{
-       int rc = 0;
-       unsigned int attrsize;
-       unsigned int type;
-       unsigned char *blobptr;
-       struct ntlmssp2_name *attrptr;
-
-       if (ses->server->tiblob) {
-               blobptr = ses->server->tiblob;
-               attrptr = (struct ntlmssp2_name *) blobptr;
-
-               while ((type = attrptr->type) != 0) {
-                       blobptr += 2; /* advance attr type */
-                       attrsize = attrptr->length;
-                       blobptr += 2; /* advance attr size */
-                       if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
-                               if (!ses->domainName) {
-                                       ses->domainName =
-                                               kmalloc(attrptr->length + 1,
-                                                               GFP_KERNEL);
-                                       if (!ses->domainName)
-                                                       return -ENOMEM;
-                                       cifs_from_ucs2(ses->domainName,
-                                               (__le16 *)blobptr,
-                                               attrptr->length,
-                                               attrptr->length,
-                                               load_nls_default(), false);
-                               }
-                       }
-                       blobptr += attrsize; /* advance attr  value */
-                       attrptr = (struct ntlmssp2_name *) blobptr;
-               }
-       } else {
-               ses->server->tilen = 2 * sizeof(struct ntlmssp2_name);
-               ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL);
-               if (!ses->server->tiblob) {
-                       ses->server->tilen = 0;
-                       cERROR(1, "Challenge target info allocation failure");
-                       return -ENOMEM;
-               }
-               memset(ses->server->tiblob, 0x0, ses->server->tilen);
-               attrptr = (struct ntlmssp2_name *) ses->server->tiblob;
-               attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
-       }
-
-       return rc;
-}
-
-static int
-CalcNTLMv2_response(const struct TCP_Server_Info *server,
-                        char *v2_session_response)
-{
-       int rc;
-
-       if (!server->ntlmssp.sdeschmacmd5) {
-               cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
-               return -1;
-       }
-
-       crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash,
-               CIFS_HMAC_MD5_HASH_SIZE);
-
-       rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash);
-       if (rc) {
-               cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
-               return rc;
-       }
-
-       memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
-               server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE);
-       crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash,
-               v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
-               sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE);
-
-       if (server->tilen)
-               crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash,
-                                       server->tiblob, server->tilen);
-
-       rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash,
-                                       v2_session_response);
-
-       return rc;
-}
-
-int
-setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
+void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
                      const struct nls_table *nls_cp)
 {
-       int rc = 0;
+       int rc;
        struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
+       struct HMACMD5Context context;
 
        buf->blob_signature = cpu_to_le32(0x00000101);
        buf->reserved = 0;
        buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
        get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
        buf->reserved2 = 0;
-
-       if (!ses->domainName) {
-               rc = find_domain_name(ses);
-               if (rc) {
-                       cERROR(1, "could not get domain/server name rc %d", rc);
-                       return rc;
-               }
-       }
+       buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
+       buf->names[0].length = 0;
+       buf->names[1].type = 0;
+       buf->names[1].length = 0;
 
        /* calculate buf->ntlmv2_hash */
        rc = calc_ntlmv2_hash(ses, nls_cp);
-       if (rc) {
-               cERROR(1, "could not get v2 hash rc %d", rc);
-               return rc;
-       }
-       rc = CalcNTLMv2_response(ses->server, resp_buf);
-       if (rc) {
+       if (rc)
                cERROR(1, "could not get v2 hash rc %d", rc);
-               return rc;
-       }
-
-       if (!ses->server->ntlmssp.sdeschmacmd5) {
-               cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
-               return -1;
-       }
-
-       crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
-                       ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
+       CalcNTLMv2_response(ses, resp_buf);
 
-       rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash);
-       if (rc) {
-               cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n");
-               return rc;
-       }
+       /* now calculate the MAC key for NTLMv2 */
+       hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
+       hmac_md5_update(resp_buf, 16, &context);
+       hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context);
 
-       crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash,
-                               resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
-
-       rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash,
-               ses->server->session_key.data.ntlmv2.key);
-
-       memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
-                       sizeof(struct ntlmv2_resp));
-       ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp);
-
-       return rc;
+       memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
+              sizeof(struct ntlmv2_resp));
+       ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
 }
 
-int
-calc_seckey(struct TCP_Server_Info *server)
-{
-       int rc;
-       unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE];
-       struct crypto_blkcipher *tfm_arc4;
-       struct scatterlist sgin, sgout;
-       struct blkcipher_desc desc;
-
-       get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
-
-       tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)",
-                                               0, CRYPTO_ALG_ASYNC);
-       if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
-               cERROR(1, "could not allocate " "master crypto API arc4\n");
-               return 1;
-       }
-
-       desc.tfm = tfm_arc4;
-
-       crypto_blkcipher_setkey(tfm_arc4,
-               server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE);
-       sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE);
-       sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
-       rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
-
-       if (!rc)
-               memcpy(server->session_key.data.ntlmv2.key,
-                               sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
-
-       crypto_free_blkcipher(tfm_arc4);
-
-       return 0;
-}
-
-void
-cifs_crypto_shash_release(struct TCP_Server_Info *server)
-{
-       if (server->ntlmssp.md5)
-               crypto_free_shash(server->ntlmssp.md5);
-
-       if (server->ntlmssp.hmacmd5)
-               crypto_free_shash(server->ntlmssp.hmacmd5);
-
-       kfree(server->ntlmssp.sdeschmacmd5);
-
-       kfree(server->ntlmssp.sdescmd5);
-}
-
-int
-cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
+void CalcNTLMv2_response(const struct cifsSesInfo *ses,
+                        char *v2_session_response)
 {
-       int rc;
-       unsigned int size;
-
-       server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
-       if (!server->ntlmssp.hmacmd5 ||
-                       IS_ERR(server->ntlmssp.hmacmd5)) {
-               cERROR(1, "could not allocate crypto hmacmd5\n");
-               return 1;
-       }
-
-       server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0);
-       if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) {
-               cERROR(1, "could not allocate crypto md5\n");
-               rc = 1;
-               goto cifs_crypto_shash_allocate_ret1;
-       }
-
-       size = sizeof(struct shash_desc) +
-                       crypto_shash_descsize(server->ntlmssp.hmacmd5);
-       server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
-       if (!server->ntlmssp.sdeschmacmd5) {
-               cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
-               rc = -ENOMEM;
-               goto cifs_crypto_shash_allocate_ret2;
-       }
-       server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5;
-       server->ntlmssp.sdeschmacmd5->shash.flags = 0x0;
+       struct HMACMD5Context context;
+       /* rest of v2 struct already generated */
+       memcpy(v2_session_response + 8, ses->server->cryptKey, 8);
+       hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
 
+       hmac_md5_update(v2_session_response+8,
+                       sizeof(struct ntlmv2_resp) - 8, &context);
 
-       size = sizeof(struct shash_desc) +
-                       crypto_shash_descsize(server->ntlmssp.md5);
-       server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL);
-       if (!server->ntlmssp.sdescmd5) {
-               cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
-               rc = -ENOMEM;
-               goto cifs_crypto_shash_allocate_ret3;
-       }
-       server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5;
-       server->ntlmssp.sdescmd5->shash.flags = 0x0;
-
-       return 0;
-
-cifs_crypto_shash_allocate_ret3:
-       kfree(server->ntlmssp.sdeschmacmd5);
-
-cifs_crypto_shash_allocate_ret2:
-       crypto_free_shash(server->ntlmssp.md5);
-
-cifs_crypto_shash_allocate_ret1:
-       crypto_free_shash(server->ntlmssp.hmacmd5);
-
-       return rc;
+       hmac_md5_final(v2_session_response, &context);
+/*     cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
 }
index c9d0cfc086ebcb609b504afdec6431e89ac75db9..0cdfb8c32ac68c34a98f5cdf412250c0eacdec2b 100644 (file)
@@ -25,9 +25,6 @@
 #include <linux/workqueue.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
-#include <crypto/internal/hash.h>
-#include <linux/scatterlist.h>
-
 /*
  * The sizes of various internal tables and strings
  */
@@ -100,7 +97,7 @@ enum protocolEnum {
        /* Netbios frames protocol not supported at this time */
 };
 
-struct session_key {
+struct mac_key {
        unsigned int len;
        union {
                char ntlm[CIFS_SESS_KEY_SIZE + 16];
@@ -123,21 +120,6 @@ struct cifs_cred {
        struct cifs_ace *aces;
 };
 
-struct sdesc {
-       struct shash_desc shash;
-       char ctx[];
-};
-
-struct ntlmssp_auth {
-       __u32 client_flags;
-       __u32 server_flags;
-       unsigned char ciphertext[CIFS_CPHTXT_SIZE];
-       struct crypto_shash *hmacmd5;
-       struct crypto_shash *md5;
-       struct sdesc *sdeschmacmd5;
-       struct sdesc *sdescmd5;
-};
-
 /*
  *****************************************************************
  * Except the CIFS PDUs themselves all the
@@ -200,14 +182,11 @@ struct TCP_Server_Info {
        /* 16th byte of RFC1001 workstation name is always null */
        char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
        __u32 sequence_number; /* needed for CIFS PDU signature */
-       struct session_key session_key;
+       struct mac_key mac_signing_key;
        char ntlmv2_hash[16];
        unsigned long lstrp; /* when we got last response from this server */
        u16 dialect; /* dialect index that server chose */
        /* extended security flavors that server supports */
-       unsigned int tilen; /* length of the target info blob */
-       unsigned char *tiblob; /* target info blob in challenge response */
-       struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */
        bool    sec_kerberos;           /* supports plain Kerberos */
        bool    sec_mskerberos;         /* supports legacy MS Kerberos */
        bool    sec_kerberosu2u;        /* supports U2U Kerberos */
index 320e0fd0ba7b5f988b559e060173dc61c2aa064c..14d036d8db111f2719f9e50576e94024a105adfc 100644 (file)
  * Size of the session key (crypto key encrypted with the password
  */
 #define CIFS_SESS_KEY_SIZE (24)
-#define CIFS_CLIENT_CHALLENGE_SIZE (8)
-#define CIFS_SERVER_CHALLENGE_SIZE (8)
-#define CIFS_HMAC_MD5_HASH_SIZE (16)
-#define CIFS_CPHTXT_SIZE (16)
-#define CIFS_NTLMV2_SESSKEY_SIZE (16)
-#define CIFS_NTHASH_SIZE (16)
 
 /*
  * Maximum user name length
@@ -669,6 +663,7 @@ struct ntlmv2_resp {
        __le64  time;
        __u64  client_chal; /* random */
        __u32  reserved2;
+       struct ntlmssp2_name names[2];
        /* array of name entries could follow ending in minimum 4 byte struct */
 } __attribute__((packed));
 
index 1378d9133844f08a369057608ed9d312bebc732f..1d60c655e3e0b70fc54ab5a48c2b6f3ffd01477c 100644 (file)
@@ -87,8 +87,9 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
                        struct TCP_Server_Info *server);
 extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
+extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port);
 extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
-                               unsigned short int port);
+                               const unsigned short int port);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
                            const struct cifsTconInfo *, int /* length of
@@ -361,15 +362,13 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
                          __u32 *);
 extern int cifs_verify_signature(struct smb_hdr *,
-                                struct TCP_Server_Info *server,
+                                const struct mac_key *mac_key,
                                __u32 expected_sequence_number);
-extern int cifs_calculate_session_key(struct session_key *key, const char *rn,
+extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
                                 const char *pass);
-extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
+extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
+extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
                             const struct nls_table *);
-extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
-extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
-extern int calc_seckey(struct TCP_Server_Info *);
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern void calc_lanman_hash(const char *password, const char *cryptkey,
                                bool encrypt, char *lnm_session_key);
index 4bda920d1f754548ea705b94b13be9a1db321699..7e83b356cc9e3a93c2bc1b0e915d118884170474 100644 (file)
@@ -232,7 +232,7 @@ static int
 small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                void **request_buf)
 {
-       int rc = 0;
+       int rc;
 
        rc = cifs_reconnect_tcon(tcon, smb_command);
        if (rc)
@@ -250,7 +250,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
        if (tcon != NULL)
                cifs_stats_inc(&tcon->num_smbs_sent);
 
-       return rc;
+       return 0;
 }
 
 int
@@ -281,16 +281,9 @@ small_smb_init_no_tc(const int smb_command, const int wct,
 
 /* If the return code is zero, this function must fill in request_buf pointer */
 static int
-smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
-        void **request_buf /* returned */ ,
-        void **response_buf /* returned */ )
+__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+                       void **request_buf, void **response_buf)
 {
-       int rc = 0;
-
-       rc = cifs_reconnect_tcon(tcon, smb_command);
-       if (rc)
-               return rc;
-
        *request_buf = cifs_buf_get();
        if (*request_buf == NULL) {
                /* BB should we add a retry in here if not a writepage? */
@@ -309,7 +302,31 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
        if (tcon != NULL)
                cifs_stats_inc(&tcon->num_smbs_sent);
 
-       return rc;
+       return 0;
+}
+
+/* If the return code is zero, this function must fill in request_buf pointer */
+static int
+smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+        void **request_buf, void **response_buf)
+{
+       int rc;
+
+       rc = cifs_reconnect_tcon(tcon, smb_command);
+       if (rc)
+               return rc;
+
+       return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
+}
+
+static int
+smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
+                       void **request_buf, void **response_buf)
+{
+       if (tcon->ses->need_reconnect || tcon->need_reconnect)
+               return -EHOSTDOWN;
+
+       return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
 }
 
 static int validate_t2(struct smb_t2_rsp *pSMB)
@@ -604,14 +621,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        else
                                rc = -EINVAL;
 
-                       if (server->secType == Kerberos) {
-                               if (!server->sec_kerberos &&
-                                               !server->sec_mskerberos)
-                                       rc = -EOPNOTSUPP;
-                       } else if (server->secType == RawNTLMSSP) {
-                               if (!server->sec_ntlmssp)
-                                       rc = -EOPNOTSUPP;
-                       } else
+                       if (server->sec_kerberos || server->sec_mskerberos)
+                               server->secType = Kerberos;
+                       else if (server->sec_ntlmssp)
+                               server->secType = RawNTLMSSP;
+                       else
                                rc = -EOPNOTSUPP;
                }
        } else
@@ -4537,8 +4551,8 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
 
        cFYI(1, "In QFSUnixInfo");
 QFSUnixRetry:
-       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-                     (void **) &pSMBr);
+       rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
+                                  (void **) &pSMB, (void **) &pSMBr);
        if (rc)
                return rc;
 
@@ -4607,8 +4621,8 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
        cFYI(1, "In SETFSUnixInfo");
 SETFSUnixRetry:
        /* BB switch to small buf init to save memory */
-       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-                     (void **) &pSMBr);
+       rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
+                                       (void **) &pSMB, (void **) &pSMBr);
        if (rc)
                return rc;
 
index ec0ea4a43bdb4efc0f3734f439b6af78af97a2f4..88c84a38bccb182c313316a172bbae39ba2ee38f 100644 (file)
@@ -400,7 +400,9 @@ incomplete_rcv:
                        cFYI(1, "call to reconnect done");
                        csocket = server->ssocket;
                        continue;
-               } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
+               } else if (length == -ERESTARTSYS ||
+                          length == -EAGAIN ||
+                          length == -EINTR) {
                        msleep(1); /* minimum sleep to prevent looping
                                allowing socket to clear and app threads to set
                                tcpStatus CifsNeedReconnect if server hung */
@@ -414,18 +416,6 @@ incomplete_rcv:
                        } else
                                continue;
                } else if (length <= 0) {
-                       if (server->tcpStatus == CifsNew) {
-                               cFYI(1, "tcp session abend after SMBnegprot");
-                               /* some servers kill the TCP session rather than
-                                  returning an SMB negprot error, in which
-                                  case reconnecting here is not going to help,
-                                  and so simply return error to mount */
-                               break;
-                       }
-                       if (!try_to_freeze() && (length == -EINTR)) {
-                               cFYI(1, "cifsd thread killed");
-                               break;
-                       }
                        cFYI(1, "Reconnect after unexpected peek error %d",
                                length);
                        cifs_reconnect(server);
@@ -466,27 +456,19 @@ incomplete_rcv:
                           an error on SMB negprot response */
                        cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
                                pdu_length);
-                       if (server->tcpStatus == CifsNew) {
-                               /* if nack on negprot (rather than
-                               ret of smb negprot error) reconnecting
-                               not going to help, ret error to mount */
-                               break;
-                       } else {
-                               /* give server a second to
-                               clean up before reconnect attempt */
-                               msleep(1000);
-                               /* always try 445 first on reconnect
-                               since we get NACK on some if we ever
-                               connected to port 139 (the NACK is
-                               since we do not begin with RFC1001
-                               session initialize frame) */
-                               server->addr.sockAddr.sin_port =
-                                       htons(CIFS_PORT);
-                               cifs_reconnect(server);
-                               csocket = server->ssocket;
-                               wake_up(&server->response_q);
-                               continue;
-                       }
+                       /* give server a second to clean up  */
+                       msleep(1000);
+                       /* always try 445 first on reconnect since we get NACK
+                        * on some if we ever connected to port 139 (the NACK
+                        * is since we do not begin with RFC1001 session
+                        * initialize frame)
+                        */
+                       cifs_set_port((struct sockaddr *)
+                                       &server->addr.sockAddr, CIFS_PORT);
+                       cifs_reconnect(server);
+                       csocket = server->ssocket;
+                       wake_up(&server->response_q);
+                       continue;
                } else if (temp != (char) 0) {
                        cERROR(1, "Unknown RFC 1002 frame");
                        cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
@@ -522,8 +504,7 @@ incomplete_rcv:
                     total_read += length) {
                        length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
                                                pdu_length - total_read, 0);
-                       if ((server->tcpStatus == CifsExiting) ||
-                           (length == -EINTR)) {
+                       if (server->tcpStatus == CifsExiting) {
                                /* then will exit */
                                reconnect = 2;
                                break;
@@ -534,8 +515,9 @@ incomplete_rcv:
                                /* Now we will reread sock */
                                reconnect = 1;
                                break;
-                       } else if ((length == -ERESTARTSYS) ||
-                                  (length == -EAGAIN)) {
+                       } else if (length == -ERESTARTSYS ||
+                                  length == -EAGAIN ||
+                                  length == -EINTR) {
                                msleep(1); /* minimum sleep to prevent looping,
                                              allowing socket to clear and app
                                              threads to set tcpStatus
@@ -1708,7 +1690,6 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
                CIFSSMBLogoff(xid, ses);
                _FreeXid(xid);
        }
-       cifs_crypto_shash_release(server);
        sesInfoFree(ses);
        cifs_put_tcp_session(server);
 }
@@ -1725,9 +1706,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
        if (ses) {
                cFYI(1, "Existing smb sess found (status=%d)", ses->status);
 
-               /* existing SMB ses has a server reference already */
-               cifs_put_tcp_session(server);
-
                mutex_lock(&ses->session_mutex);
                rc = cifs_negotiate_protocol(xid, ses);
                if (rc) {
@@ -1750,6 +1728,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
                        }
                }
                mutex_unlock(&ses->session_mutex);
+
+               /* existing SMB ses has a server reference already */
+               cifs_put_tcp_session(server);
                FreeXid(xid);
                return ses;
        }
@@ -1788,23 +1769,13 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
        ses->linux_uid = volume_info->linux_uid;
        ses->overrideSecFlg = volume_info->secFlg;
 
-       rc = cifs_crypto_shash_allocate(server);
-       if (rc) {
-               cERROR(1, "could not setup hash structures rc %d", rc);
-               goto get_ses_fail;
-       }
-       server->tilen = 0;
-       server->tiblob = NULL;
-
        mutex_lock(&ses->session_mutex);
        rc = cifs_negotiate_protocol(xid, ses);
        if (!rc)
                rc = cifs_setup_session(xid, ses, volume_info->local_nls);
        mutex_unlock(&ses->session_mutex);
-       if (rc) {
-               cifs_crypto_shash_release(ses->server);
+       if (rc)
                goto get_ses_fail;
-       }
 
        /* success, put it on the list */
        write_lock(&cifs_tcp_ses_lock);
index 86a164f08a74a51399c2152799ec178c93902fa6..53cce8cc2224f4abe4754d2cc320a05a6f36d215 100644 (file)
@@ -801,6 +801,8 @@ retry_iget5_locked:
                        inode->i_flags |= S_NOATIME | S_NOCMTIME;
                if (inode->i_state & I_NEW) {
                        inode->i_ino = hash;
+                       if (S_ISREG(inode->i_mode))
+                               inode->i_data.backing_dev_info = sb->s_bdi;
 #ifdef CONFIG_CIFS_FSCACHE
                        /* initialize per-inode cache cookie pointer */
                        CIFS_I(inode)->fscache = NULL;
@@ -1462,28 +1464,17 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
 {
        char *fromName = NULL;
        char *toName = NULL;
-       struct cifs_sb_info *cifs_sb_source;
-       struct cifs_sb_info *cifs_sb_target;
+       struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *tcon;
        FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
        FILE_UNIX_BASIC_INFO *info_buf_target;
        int xid, rc, tmprc;
 
-       cifs_sb_target = CIFS_SB(target_dir->i_sb);
-       cifs_sb_source = CIFS_SB(source_dir->i_sb);
-       tcon = cifs_sb_source->tcon;
+       cifs_sb = CIFS_SB(source_dir->i_sb);
+       tcon = cifs_sb->tcon;
 
        xid = GetXid();
 
-       /*
-        * BB: this might be allowed if same server, but different share.
-        * Consider adding support for this
-        */
-       if (tcon != cifs_sb_target->tcon) {
-               rc = -EXDEV;
-               goto cifs_rename_exit;
-       }
-
        /*
         * we already have the rename sem so we do not need to
         * grab it again here to protect the path integrity
@@ -1519,17 +1510,16 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
                info_buf_target = info_buf_source + 1;
                tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
                                        info_buf_source,
-                                       cifs_sb_source->local_nls,
-                                       cifs_sb_source->mnt_cifs_flags &
+                                       cifs_sb->local_nls,
+                                       cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
                if (tmprc != 0)
                        goto unlink_target;
 
-               tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
-                                       toName, info_buf_target,
-                                       cifs_sb_target->local_nls,
-                                       /* remap based on source sb */
-                                       cifs_sb_source->mnt_cifs_flags &
+               tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName,
+                                       info_buf_target,
+                                       cifs_sb->local_nls,
+                                       cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 
                if (tmprc == 0 && (info_buf_source->UniqueId ==
index f97851119e6c1b965530f57062b3ae97b53f4e00..9aad47a2d62f6d861035e1ce0b8b6876804aed61 100644 (file)
@@ -206,26 +206,30 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len)
 }
 
 int
-cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
-                  const unsigned short int port)
+cifs_set_port(struct sockaddr *addr, const unsigned short int port)
 {
-       if (!cifs_convert_address(dst, src, len))
-               return 0;
-
-       switch (dst->sa_family) {
+       switch (addr->sa_family) {
        case AF_INET:
-               ((struct sockaddr_in *)dst)->sin_port = htons(port);
+               ((struct sockaddr_in *)addr)->sin_port = htons(port);
                break;
        case AF_INET6:
-               ((struct sockaddr_in6 *)dst)->sin6_port = htons(port);
+               ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
                break;
        default:
                return 0;
        }
-
        return 1;
 }
 
+int
+cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
+                  const unsigned short int port)
+{
+       if (!cifs_convert_address(dst, src, len))
+               return 0;
+       return cifs_set_port(dst, port);
+}
+
 /*****************************************************************************
 convert a NT status code to a dos class/code
  *****************************************************************************/
index 1db0f0746a5b4242f927e9203d8749711180918c..49c9a4e7531979c3e65615dd277ad4b0815ed0ae 100644 (file)
 #define NTLMSSP_NEGOTIATE_KEY_XCH   0x40000000
 #define NTLMSSP_NEGOTIATE_56        0x80000000
 
-/* Define AV Pair Field IDs */
-#define NTLMSSP_AV_EOL                 0
-#define NTLMSSP_AV_NB_COMPUTER_NAME    1
-#define NTLMSSP_AV_NB_DOMAIN_NAME      2
-#define NTLMSSP_AV_DNS_COMPUTER_NAME   3
-#define NTLMSSP_AV_DNS_DOMAIN_NAME     4
-#define NTLMSSP_AV_DNS_TREE_NAME       5
-#define NTLMSSP_AV_FLAGS               6
-#define NTLMSSP_AV_TIMESTAMP           7
-#define NTLMSSP_AV_RESTRICTION         8
-#define NTLMSSP_AV_TARGET_NAME         9
-#define NTLMSSP_AV_CHANNEL_BINDINGS    10
-
 /* Although typedefs are not commonly used for structure definitions */
 /* in the Linux kernel, in this particular case they are useful      */
 /* to more closely match the standards document for NTLMSSP from     */
index 795095f4eac69ba204257a597522e465dafac371..0a57cb7db5dd7554030e599cd111379e343083df 100644 (file)
@@ -383,9 +383,6 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
                                    struct cifsSesInfo *ses)
 {
-       unsigned int tioffset; /* challeng message target info area */
-       unsigned int tilen; /* challeng message target info area length  */
-
        CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
 
        if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
@@ -408,20 +405,6 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        /* BB spec says that if AvId field of MsvAvTimestamp is populated then
                we must set the MIC field of the AUTHENTICATE_MESSAGE */
 
-       ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags);
-
-       tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
-       tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
-       ses->server->tilen = tilen;
-       if (tilen) {
-               ses->server->tiblob = kmalloc(tilen, GFP_KERNEL);
-               if (!ses->server->tiblob) {
-                       cERROR(1, "Challenge target info allocation failure");
-                       return -ENOMEM;
-               }
-               memcpy(ses->server->tiblob,  bcc_ptr + tioffset, tilen);
-       }
-
        return 0;
 }
 
@@ -442,13 +425,12 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
        /* BB is NTLMV2 session security format easier to use here? */
        flags = NTLMSSP_NEGOTIATE_56 |  NTLMSSP_REQUEST_TARGET |
                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-               NTLMSSP_NEGOTIATE_NTLM;
+               NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
        if (ses->server->secMode &
-          (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
-               flags |= NTLMSSP_NEGOTIATE_SIGN |
-                       NTLMSSP_NEGOTIATE_KEY_XCH |
-                       NTLMSSP_NEGOTIATE_EXTENDED_SEC;
-       }
+          (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+               flags |= NTLMSSP_NEGOTIATE_SIGN;
+       if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
+               flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
        sec_blob->NegotiateFlags |= cpu_to_le32(flags);
 
@@ -469,12 +451,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                                   struct cifsSesInfo *ses,
                                   const struct nls_table *nls_cp, bool first)
 {
-       int rc;
-       unsigned int size;
        AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
        __u32 flags;
        unsigned char *tmp;
-       struct ntlmv2_resp ntlmv2_response = {};
+       char ntlm_session_key[CIFS_SESS_KEY_SIZE];
 
        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
        sec_blob->MessageType = NtLmAuthenticate;
@@ -497,25 +477,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        sec_blob->LmChallengeResponse.Length = 0;
        sec_blob->LmChallengeResponse.MaximumLength = 0;
 
-       sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
-       rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
-       if (rc) {
-               cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc);
-               goto setup_ntlmv2_ret;
-       }
-       size =  sizeof(struct ntlmv2_resp);
-       memcpy(tmp, (char *)&ntlmv2_response, size);
-       tmp += size;
-       if (ses->server->tilen > 0) {
-               memcpy(tmp, ses->server->tiblob, ses->server->tilen);
-               tmp += ses->server->tilen;
-       } else
-               ses->server->tilen = 0;
+       /* calculate session key,  BB what about adding similar ntlmv2 path? */
+       SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
+       if (first)
+               cifs_calculate_mac_key(&ses->server->mac_signing_key,
+                                      ntlm_session_key, ses->password);
 
-       sec_blob->NtChallengeResponse.Length = cpu_to_le16(size +
-                               ses->server->tilen);
+       memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
+       sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
+       sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
        sec_blob->NtChallengeResponse.MaximumLength =
-               cpu_to_le16(size + ses->server->tilen);
+                               cpu_to_le16(CIFS_SESS_KEY_SIZE);
+
+       tmp += CIFS_SESS_KEY_SIZE;
 
        if (ses->domainName == NULL) {
                sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -527,6 +501,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
                                    MAX_USERNAME_SIZE, nls_cp);
                len *= 2; /* unicode is 2 bytes each */
+               len += 2; /* trailing null */
                sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
                sec_blob->DomainName.Length = cpu_to_le16(len);
                sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
@@ -543,6 +518,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
                                    MAX_USERNAME_SIZE, nls_cp);
                len *= 2; /* unicode is 2 bytes each */
+               len += 2; /* trailing null */
                sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
                sec_blob->UserName.Length = cpu_to_le16(len);
                sec_blob->UserName.MaximumLength = cpu_to_le16(len);
@@ -554,26 +530,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        sec_blob->WorkstationName.MaximumLength = 0;
        tmp += 2;
 
-       if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
-                       !calc_seckey(ses->server)) {
-               memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
-               sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
-               sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
-               sec_blob->SessionKey.MaximumLength =
-                       cpu_to_le16(CIFS_CPHTXT_SIZE);
-               tmp += CIFS_CPHTXT_SIZE;
-       } else {
-               sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
-               sec_blob->SessionKey.Length = 0;
-               sec_blob->SessionKey.MaximumLength = 0;
-       }
-
-       ses->server->sequence_number = 0;
-
-setup_ntlmv2_ret:
-       if (ses->server->tilen > 0)
-               kfree(ses->server->tiblob);
-
+       sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+       sec_blob->SessionKey.Length = 0;
+       sec_blob->SessionKey.MaximumLength = 0;
        return tmp - pbuffer;
 }
 
@@ -587,14 +546,15 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
        return;
 }
 
-static int setup_ntlmssp_auth_req(char *ntlmsspblob,
+static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
                                  struct cifsSesInfo *ses,
                                  const struct nls_table *nls, bool first_time)
 {
        int bloblen;
 
-       bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls,
+       bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
                                          first_time);
+       pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
 
        return bloblen;
 }
@@ -730,7 +690,7 @@ ssetup_ntlmssp_authenticate:
 
                if (first_time) /* should this be moved into common code
                                  with similar ntlmv2 path? */
-                       cifs_calculate_session_key(&ses->server->session_key,
+                       cifs_calculate_mac_key(&ses->server->mac_signing_key,
                                ntlm_session_key, ses->password);
                /* copy session key */
 
@@ -769,21 +729,12 @@ ssetup_ntlmssp_authenticate:
                        cpu_to_le16(sizeof(struct ntlmv2_resp));
 
                /* calculate session key */
-               rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
-               if (rc) {
-                       kfree(v2_sess_key);
-                       goto ssetup_exit;
-               }
+               setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
                /* FIXME: calculate MAC key */
                memcpy(bcc_ptr, (char *)v2_sess_key,
                       sizeof(struct ntlmv2_resp));
                bcc_ptr += sizeof(struct ntlmv2_resp);
                kfree(v2_sess_key);
-               if (ses->server->tilen > 0) {
-                       memcpy(bcc_ptr, ses->server->tiblob,
-                               ses->server->tilen);
-                       bcc_ptr += ses->server->tilen;
-               }
                if (ses->capabilities & CAP_UNICODE) {
                        if (iov[0].iov_len % 2) {
                                *bcc_ptr = 0;
@@ -814,15 +765,15 @@ ssetup_ntlmssp_authenticate:
                }
                /* bail out if key is too long */
                if (msg->sesskey_len >
-                   sizeof(ses->server->session_key.data.krb5)) {
+                   sizeof(ses->server->mac_signing_key.data.krb5)) {
                        cERROR(1, "Kerberos signing key too long (%u bytes)",
                                msg->sesskey_len);
                        rc = -EOVERFLOW;
                        goto ssetup_exit;
                }
                if (first_time) {
-                       ses->server->session_key.len = msg->sesskey_len;
-                       memcpy(ses->server->session_key.data.krb5,
+                       ses->server->mac_signing_key.len = msg->sesskey_len;
+                       memcpy(ses->server->mac_signing_key.data.krb5,
                                msg->data, msg->sesskey_len);
                }
                pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -864,28 +815,12 @@ ssetup_ntlmssp_authenticate:
                        if (phase == NtLmNegotiate) {
                                setup_ntlmssp_neg_req(pSMB, ses);
                                iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
-                               iov[1].iov_base = &pSMB->req.SecurityBlob[0];
                        } else if (phase == NtLmAuthenticate) {
                                int blob_len;
-                               char *ntlmsspblob;
-
-                               ntlmsspblob = kmalloc(5 *
-                                       sizeof(struct _AUTHENTICATE_MESSAGE),
-                                       GFP_KERNEL);
-                               if (!ntlmsspblob) {
-                                       cERROR(1, "Can't allocate NTLMSSP");
-                                       rc = -ENOMEM;
-                                       goto ssetup_exit;
-                               }
-
-                               blob_len = setup_ntlmssp_auth_req(ntlmsspblob,
-                                                               ses,
-                                                               nls_cp,
-                                                               first_time);
+                               blob_len = setup_ntlmssp_auth_req(pSMB, ses,
+                                                                 nls_cp,
+                                                                 first_time);
                                iov[1].iov_len = blob_len;
-                               iov[1].iov_base = ntlmsspblob;
-                               pSMB->req.SecurityBlobLength =
-                                       cpu_to_le16(blob_len);
                                /* Make sure that we tell the server that we
                                   are using the uid that it just gave us back
                                   on the response (challenge) */
@@ -895,6 +830,7 @@ ssetup_ntlmssp_authenticate:
                                rc = -ENOSYS;
                                goto ssetup_exit;
                        }
+                       iov[1].iov_base = &pSMB->req.SecurityBlob[0];
                        /* unicode strings must be word aligned */
                        if ((iov[0].iov_len + iov[1].iov_len) % 2) {
                                *bcc_ptr = 0;
index e0588cdf4cc5d5a1e8a73c1190c21f2d6cbe4986..82f78c4d6978ceafdab5789182193b899a435202 100644 (file)
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                    (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                             SECMODE_SIGN_ENABLED))) {
                        rc = cifs_verify_signature(midQ->resp_buf,
-                                               ses->server,
+                                               &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
                                cERROR(1, "Unexpected SMB signature");
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                    (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                             SECMODE_SIGN_ENABLED))) {
                        rc = cifs_verify_signature(out_buf,
-                                               ses->server,
+                                               &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
                                cERROR(1, "Unexpected SMB signature");
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
            (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                     SECMODE_SIGN_ENABLED))) {
                rc = cifs_verify_signature(out_buf,
-                                          ses->server,
+                                          &ses->server->mac_signing_key,
                                           midQ->sequence_number+1);
                if (rc) {
                        cERROR(1, "Unexpected SMB signature");
index de89645777c7c2b06cb62b3657cd72b26a9c4f9e..116af7546cf0de6ef076e04ad74b4a2e9aa4bade 100644 (file)
@@ -184,8 +184,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
        }
 
        /* adjust outsize. is this useful ?? */
-        req->uc_outSize = nbytes;      
-        req->uc_flags |= REQ_WRITE;
+       req->uc_outSize = nbytes;
+       req->uc_flags |= CODA_REQ_WRITE;
        count = nbytes;
 
        /* Convert filedescriptor into a file handle */
index 718c7062aec129844cda361e2f4b8a143aa31861..0644a154672b93012a4d7a7f864ba7f505b43213 100644 (file)
@@ -1153,7 +1153,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
 {
        compat_ssize_t tot_len;
        struct iovec iovstack[UIO_FASTIOV];
-       struct iovec *iov;
+       struct iovec *iov = iovstack;
        ssize_t ret;
        io_fn_t fn;
        iov_fn_t fnv;
index 828dd2461d6beb7c37ed7df74ef11177c2bcba6d..03278c984ba0c5cc6fd33c32b0f5e60da743d85c 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -2014,3 +2014,41 @@ fail_creds:
 fail:
        return;
 }
+
+/*
+ * Core dumping helper functions.  These are the only things you should
+ * do on a core-file: use only these functions to write out all the
+ * necessary info.
+ */
+int dump_write(struct file *file, const void *addr, int nr)
+{
+       return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+}
+
+int dump_seek(struct file *file, loff_t off)
+{
+       int ret = 1;
+
+       if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
+               if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
+                       return 0;
+       } else {
+               char *buf = (char *)get_zeroed_page(GFP_KERNEL);
+
+               if (!buf)
+                       return 0;
+               while (off > 0) {
+                       unsigned long n = off;
+
+                       if (n > PAGE_SIZE)
+                               n = PAGE_SIZE;
+                       if (!dump_write(file, buf, n)) {
+                               ret = 0;
+                               break;
+                       }
+                       off -= n;
+               }
+               free_page((unsigned long)buf);
+       }
+       return ret;
+}
index eb7368ebd8cdc294c7ec4b2d1ad0d4953f699981..3eadd97324b140e679f269480b3737823fd008cb 100644 (file)
@@ -54,6 +54,9 @@ struct page_collect {
        unsigned nr_pages;
        unsigned long length;
        loff_t pg_first; /* keep 64bit also in 32-arches */
+       bool read_4_write; /* This means two things: that the read is sync
+                           * And the pages should not be unlocked.
+                           */
 };
 
 static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
@@ -71,6 +74,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
        pcol->nr_pages = 0;
        pcol->length = 0;
        pcol->pg_first = -1;
+       pcol->read_4_write = false;
 }
 
 static void _pcol_reset(struct page_collect *pcol)
@@ -347,7 +351,8 @@ static int readpage_strip(void *data, struct page *page)
                if (PageError(page))
                        ClearPageError(page);
 
-               unlock_page(page);
+               if (!pcol->read_4_write)
+                       unlock_page(page);
                EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
                             " splitting\n", inode->i_ino, page->index);
 
@@ -428,6 +433,7 @@ static int _readpage(struct page *page, bool is_sync)
        /* readpage_strip might call read_exec(,is_sync==false) at several
         * places but not if we have a single page.
         */
+       pcol.read_4_write = is_sync;
        ret = readpage_strip(&pcol, page);
        if (ret) {
                EXOFS_ERR("_readpage => %d\n", ret);
index 81e086d8aa5733c7a86a966827bf7ea18d29baa4..ab38fef1c9a1a52eab7128fa6a7dad217d4ad744 100644 (file)
@@ -52,8 +52,6 @@ struct wb_writeback_work {
 #define CREATE_TRACE_POINTS
 #include <trace/events/writeback.h>
 
-#define inode_to_bdi(inode)    ((inode)->i_mapping->backing_dev_info)
-
 /*
  * We don't actually have pdflush, but this one is exported though /proc...
  */
@@ -71,6 +69,16 @@ int writeback_in_progress(struct backing_dev_info *bdi)
        return test_bit(BDI_writeback_running, &bdi->state);
 }
 
+static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
+{
+       struct super_block *sb = inode->i_sb;
+
+       if (strcmp(sb->s_type->name, "bdev") == 0)
+               return inode->i_mapping->backing_dev_info;
+
+       return sb->s_bdi;
+}
+
 static void bdi_queue_work(struct backing_dev_info *bdi,
                struct wb_writeback_work *work)
 {
index d367af1514efe696b50a73374fffe77784c65b6a..cde755cca5642d41fb9cbbe05ac2d01f70f53c69 100644 (file)
@@ -1354,7 +1354,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
        loff_t file_size;
        unsigned int num;
        unsigned int offset;
-       size_t total_len;
+       size_t total_len = 0;
 
        req = fuse_get_req(fc);
        if (IS_ERR(req))
index cde1248a62255ae9bdb03b4c2757a71e973fa089..ac750bd31a6f311e8a3dfc859a257c6f85b2f79d 100644 (file)
@@ -932,7 +932,7 @@ int gfs2_logd(void *data)
 
                do {
                        prepare_to_wait(&sdp->sd_logd_waitq, &wait,
-                                       TASK_UNINTERRUPTIBLE);
+                                       TASK_INTERRUPTIBLE);
                        if (!gfs2_ail_flush_reqd(sdp) &&
                            !gfs2_jrnl_flush_reqd(sdp) &&
                            !kthread_should_stop())
index 6c2aad49d7318054b57c22b58c6b4eaa0be50178..f7e13db613cbce9a3014b826c9d00414169f4de8 100644 (file)
@@ -63,6 +63,7 @@ config NFS_V3_ACL
 config NFS_V4
        bool "NFS client support for NFS version 4"
        depends on NFS_FS
+       select SUNRPC_GSS
        help
          This option enables support for version 4 of the NFS protocol
          (RFC 3530) in the kernel's NFS client.
index 4e7df2adb2125724a4ea9ade0fc767606d54c4b3..e7340729af896e2bce1097fe4f8521618680173e 100644 (file)
@@ -275,7 +275,7 @@ static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
            sin1->sin6_scope_id != sin2->sin6_scope_id)
                return 0;
 
-       return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr);
+       return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
 }
 #else  /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
 static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
index eb51bd6201da0cd361d8265b4c6b0e3edee50ec9..05bf3c0dc751d5d489b1c7be2cf594005caf1695 100644 (file)
@@ -723,10 +723,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
                default:
                        BUG();
        }
-       if (res < 0)
-               dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager"
-                       " - error %d!\n",
-                               __func__, res);
        return res;
 }
 
index ec3966e4706b2f70d8709199f86456392a6e6584..f4cbf0c306c64d6583cbfffaa14cfbc7a467dfaa 100644 (file)
@@ -431,7 +431,15 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
                goto out_err;
 
        error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
+       if (unlikely(error == -ESTALE)) {
+               struct dentry *pd_dentry;
 
+               pd_dentry = dget_parent(dentry);
+               if (pd_dentry != NULL) {
+                       nfs_zap_caches(pd_dentry->d_inode);
+                       dput(pd_dentry);
+               }
+       }
        nfs_free_fattr(res.fattr);
        if (error < 0)
                goto out_err;
index 95932f523aef2b2b7ef4686b8bb4a18383b4a395..4264377552e207f57550b9e72d53776e0689ca81 100644 (file)
@@ -69,6 +69,7 @@ config NFSD_V4
        depends on NFSD && PROC_FS && EXPERIMENTAL
        select NFSD_V3
        select FS_POSIX_ACL
+       select SUNRPC_GSS
        help
          This option enables support in your system's NFS server for
          version 4 of the NFS protocol (RFC 3530).
index cdfb8c6a420674cbde75467a09d6a158977a4b61..c16f8d8331b5afcd80baec98cbdbc4594c66142d 100644 (file)
@@ -196,8 +196,6 @@ fh_lock(struct svc_fh *fhp)
 static inline void
 fh_unlock(struct svc_fh *fhp)
 {
-       BUG_ON(!fhp->fh_dentry);
-
        if (fhp->fh_locked) {
                fill_post_wcc(fhp);
                mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
index 22c629eedd82d70425704ee86b4ddf816b7bd174..b388443c3a09b01574b78befaabbf7fe03f9eeb4 100644 (file)
@@ -3,4 +3,4 @@ config FSNOTIFY
 
 source "fs/notify/dnotify/Kconfig"
 source "fs/notify/inotify/Kconfig"
-source "fs/notify/fanotify/Kconfig"
+#source "fs/notify/fanotify/Kconfig"
index a76e0aa5cd3fc5188a392639618858a7e7e34092..391915093fe1c494a58ec8feae54cd576fd2464a 100644 (file)
@@ -209,7 +209,10 @@ static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
        }
 
        inode->i_mode = new_mode;
+       inode->i_ctime = CURRENT_TIME;
        di->i_mode = cpu_to_le16(inode->i_mode);
+       di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+       di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
 
        ocfs2_journal_dirty(handle, di_bh);
 
index 1361997cf205d132a04ddeb87760aa233c3e707d..cbe2f057cc2826cb6af4ed833319fe27c4bd565f 100644 (file)
@@ -977,7 +977,7 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
 int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                           size_t caller_veclen, u8 target_node, int *status)
 {
-       int ret;
+       int ret = 0;
        struct o2net_msg *msg = NULL;
        size_t veclen, caller_bytes = 0;
        struct kvec *vec = NULL;
index f04ebcfffc4a5e1516c2a7307ffa8032db8e19d7..c49f6de0e7abb6e096ddc56e795957e0194bb8dd 100644 (file)
@@ -3931,6 +3931,15 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
                goto out_commit;
        }
 
+       cpos = split_hash;
+       ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
+                                      data_ac, meta_ac, new_dx_leaves,
+                                      num_dx_leaves);
+       if (ret) {
+               mlog_errno(ret);
+               goto out_commit;
+       }
+
        for (i = 0; i < num_dx_leaves; i++) {
                ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir),
                                              orig_dx_leaves[i],
@@ -3939,15 +3948,14 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
                        mlog_errno(ret);
                        goto out_commit;
                }
-       }
 
-       cpos = split_hash;
-       ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
-                                      data_ac, meta_ac, new_dx_leaves,
-                                      num_dx_leaves);
-       if (ret) {
-               mlog_errno(ret);
-               goto out_commit;
+               ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir),
+                                             new_dx_leaves[i],
+                                             OCFS2_JOURNAL_ACCESS_WRITE);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out_commit;
+               }
        }
 
        ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf,
index 4b6ae2c13b47a85c6a31f6f7d2a1072099354935..765298908f1d3905bbabf3c5e597a8bf72ebd4a9 100644 (file)
@@ -1030,6 +1030,7 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
                         struct dlm_lock_resource *res);
 void dlm_clean_master_list(struct dlm_ctxt *dlm,
                           u8 dead_node);
+void dlm_force_free_mles(struct dlm_ctxt *dlm);
 int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 int __dlm_lockres_has_locks(struct dlm_lock_resource *res);
 int __dlm_lockres_unused(struct dlm_lock_resource *res);
index 5efdd37dfe484f2f6207ac2c7c6927fda0cc1ea0..901ca52bf86b293639ea39c8e1f460b66bc1f265 100644 (file)
@@ -636,8 +636,14 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
        spin_lock(&dlm->track_lock);
        if (oldres)
                track_list = &oldres->tracking;
-       else
+       else {
                track_list = &dlm->tracking_list;
+               if (list_empty(track_list)) {
+                       dl = NULL;
+                       spin_unlock(&dlm->track_lock);
+                       goto bail;
+               }
+       }
 
        list_for_each_entry(res, track_list, tracking) {
                if (&res->tracking == &dlm->tracking_list)
@@ -660,6 +666,7 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
        } else
                dl = NULL;
 
+bail:
        /* passed to seq_show */
        return dl;
 }
index 153abb5abef024d2ca63f6d4a23ee1c126b89f13..11a5c87fd7f7c00de41c61c00fae625e46675973 100644 (file)
@@ -693,6 +693,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
 
                dlm_mark_domain_leaving(dlm);
                dlm_leave_domain(dlm);
+               dlm_force_free_mles(dlm);
                dlm_complete_dlm_shutdown(dlm);
        }
        dlm_put(dlm);
index ffb4c68dafa495bc739165eb30f718f1eb0865ec..f564b0e5f80d8c89e08eeba4a5e133b24cb67373 100644 (file)
@@ -3433,3 +3433,43 @@ void dlm_lockres_release_ast(struct dlm_ctxt *dlm,
        wake_up(&res->wq);
        wake_up(&dlm->migration_wq);
 }
+
+void dlm_force_free_mles(struct dlm_ctxt *dlm)
+{
+       int i;
+       struct hlist_head *bucket;
+       struct dlm_master_list_entry *mle;
+       struct hlist_node *tmp, *list;
+
+       /*
+        * We notified all other nodes that we are exiting the domain and
+        * marked the dlm state to DLM_CTXT_LEAVING. If any mles are still
+        * around we force free them and wake any processes that are waiting
+        * on the mles
+        */
+       spin_lock(&dlm->spinlock);
+       spin_lock(&dlm->master_lock);
+
+       BUG_ON(dlm->dlm_state != DLM_CTXT_LEAVING);
+       BUG_ON((find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 0) < O2NM_MAX_NODES));
+
+       for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+               bucket = dlm_master_hash(dlm, i);
+               hlist_for_each_safe(list, tmp, bucket) {
+                       mle = hlist_entry(list, struct dlm_master_list_entry,
+                                         master_hash_node);
+                       if (mle->type != DLM_MLE_BLOCK) {
+                               mlog(ML_ERROR, "bad mle: %p\n", mle);
+                               dlm_print_one_mle(mle);
+                       }
+                       atomic_set(&mle->woken, 1);
+                       wake_up(&mle->wq);
+
+                       __dlm_unlink_mle(dlm, mle);
+                       __dlm_mle_detach_hb_events(dlm, mle);
+                       __dlm_put_mle(mle);
+               }
+       }
+       spin_unlock(&dlm->master_lock);
+       spin_unlock(&dlm->spinlock);
+}
index d1ce48e1b3d6029e5861cf2863cbb0a544511b40..1d596d8c4a4a55dfd185ecaff4d7d9900bf10b24 100644 (file)
@@ -84,6 +84,7 @@ enum {
        OI_LS_PARENT,
        OI_LS_RENAME1,
        OI_LS_RENAME2,
+       OI_LS_REFLINK_TARGET,
 };
 
 int ocfs2_dlm_init(struct ocfs2_super *osb);
index 33f1c9a8258d1d4de5a17fe1ebf1d0d39c4098c3..fa31d05e41b7e558fa24df43682dbd107b568c76 100644 (file)
 #define OCFS2_HAS_REFCOUNT_FL   (0x0010)
 
 /* Inode attributes, keep in sync with EXT2 */
-#define OCFS2_SECRM_FL         (0x00000001)    /* Secure deletion */
-#define OCFS2_UNRM_FL          (0x00000002)    /* Undelete */
-#define OCFS2_COMPR_FL         (0x00000004)    /* Compress file */
-#define OCFS2_SYNC_FL          (0x00000008)    /* Synchronous updates */
-#define OCFS2_IMMUTABLE_FL     (0x00000010)    /* Immutable file */
-#define OCFS2_APPEND_FL                (0x00000020)    /* writes to file may only append */
-#define OCFS2_NODUMP_FL                (0x00000040)    /* do not dump file */
-#define OCFS2_NOATIME_FL       (0x00000080)    /* do not update atime */
-#define OCFS2_DIRSYNC_FL       (0x00010000)    /* dirsync behaviour (directories only) */
-
-#define OCFS2_FL_VISIBLE       (0x000100FF)    /* User visible flags */
-#define OCFS2_FL_MODIFIABLE    (0x000100FF)    /* User modifiable flags */
+#define OCFS2_SECRM_FL                 FS_SECRM_FL     /* Secure deletion */
+#define OCFS2_UNRM_FL                  FS_UNRM_FL      /* Undelete */
+#define OCFS2_COMPR_FL                 FS_COMPR_FL     /* Compress file */
+#define OCFS2_SYNC_FL                  FS_SYNC_FL      /* Synchronous updates */
+#define OCFS2_IMMUTABLE_FL             FS_IMMUTABLE_FL /* Immutable file */
+#define OCFS2_APPEND_FL                        FS_APPEND_FL    /* writes to file may only append */
+#define OCFS2_NODUMP_FL                        FS_NODUMP_FL    /* do not dump file */
+#define OCFS2_NOATIME_FL               FS_NOATIME_FL   /* do not update atime */
+/* Reserved for compression usage... */
+#define OCFS2_DIRTY_FL                 FS_DIRTY_FL
+#define OCFS2_COMPRBLK_FL              FS_COMPRBLK_FL  /* One or more compressed clusters */
+#define OCFS2_NOCOMP_FL                        FS_NOCOMP_FL    /* Don't compress */
+#define OCFS2_ECOMPR_FL                        FS_ECOMPR_FL    /* Compression error */
+/* End compression flags --- maybe not all used */
+#define OCFS2_BTREE_FL                 FS_BTREE_FL     /* btree format dir */
+#define OCFS2_INDEX_FL                 FS_INDEX_FL     /* hash-indexed directory */
+#define OCFS2_IMAGIC_FL                        FS_IMAGIC_FL    /* AFS directory */
+#define OCFS2_JOURNAL_DATA_FL          FS_JOURNAL_DATA_FL /* Reserved for ext3 */
+#define OCFS2_NOTAIL_FL                        FS_NOTAIL_FL    /* file tail should not be merged */
+#define OCFS2_DIRSYNC_FL               FS_DIRSYNC_FL   /* dirsync behaviour (directories only) */
+#define OCFS2_TOPDIR_FL                        FS_TOPDIR_FL    /* Top of directory hierarchies*/
+#define OCFS2_RESERVED_FL              FS_RESERVED_FL  /* reserved for ext2 lib */
+
+#define OCFS2_FL_VISIBLE               FS_FL_USER_VISIBLE      /* User visible flags */
+#define OCFS2_FL_MODIFIABLE            FS_FL_USER_MODIFIABLE   /* User modifiable flags */
 
 /*
  * Extent record flags (e_node.leaf.flags)
index 2d3420af1a839e0e13626a34c289cd2227bf095a..5d241505690b71e2ec0b259cbc39f1ed46d683d5 100644 (file)
 /*
  * ioctl commands
  */
-#define OCFS2_IOC_GETFLAGS     _IOR('f', 1, long)
-#define OCFS2_IOC_SETFLAGS     _IOW('f', 2, long)
-#define OCFS2_IOC32_GETFLAGS   _IOR('f', 1, int)
-#define OCFS2_IOC32_SETFLAGS   _IOW('f', 2, int)
+#define OCFS2_IOC_GETFLAGS     FS_IOC_GETFLAGS
+#define OCFS2_IOC_SETFLAGS     FS_IOC_SETFLAGS
+#define OCFS2_IOC32_GETFLAGS   FS_IOC32_GETFLAGS
+#define OCFS2_IOC32_SETFLAGS   FS_IOC32_SETFLAGS
 
 /*
  * Space reservation / allocation / free ioctls and argument structure
index 0afeda83120fa0e54bd2c9cc7e1f4f08c6e836bf..efdd7560740655beba6f53dccef235b5ce89cdbf 100644 (file)
@@ -4201,8 +4201,9 @@ static int __ocfs2_reflink(struct dentry *old_dentry,
                goto out;
        }
 
-       mutex_lock(&new_inode->i_mutex);
-       ret = ocfs2_inode_lock(new_inode, &new_bh, 1);
+       mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD);
+       ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1,
+                                     OI_LS_REFLINK_TARGET);
        if (ret) {
                mlog_errno(ret);
                goto out_unlock;
index d8b6e4259b80022cb824326f4ce2c665089b5818..3e78db361bc70b3ffc327a6f21b6d4580305d0eb 100644 (file)
@@ -732,25 +732,23 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap,
                           struct ocfs2_alloc_reservation *resv,
                           int *cstart, int *clen)
 {
-       unsigned int wanted = *clen;
-
        if (resv == NULL || ocfs2_resmap_disabled(resmap))
                return -ENOSPC;
 
        spin_lock(&resv_lock);
 
-       /*
-        * We don't want to over-allocate for temporary
-        * windows. Otherwise, we run the risk of fragmenting the
-        * allocation space.
-        */
-       wanted = ocfs2_resv_window_bits(resmap, resv);
-       if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen)
-               wanted = *clen;
-
        if (ocfs2_resv_empty(resv)) {
-               mlog(0, "empty reservation, find new window\n");
+               /*
+                * We don't want to over-allocate for temporary
+                * windows. Otherwise, we run the risk of fragmenting the
+                * allocation space.
+                */
+               unsigned int wanted = ocfs2_resv_window_bits(resmap, resv);
 
+               if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen)
+                       wanted = *clen;
+
+               mlog(0, "empty reservation, find new window\n");
                /*
                 * Try to get a window here. If it works, we must fall
                 * through and test the bitmap . This avoids some
index 8a286f54dca1f30a1d65b0d6cbb5baa0fa8c063c..849c2f0e0a0e664e983adf61f620abedf87fcb72 100644 (file)
@@ -357,7 +357,7 @@ out:
 static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb,
                                          struct ocfs2_group_desc *bg,
                                          struct ocfs2_chain_list *cl,
-                                         u64 p_blkno, u32 clusters)
+                                         u64 p_blkno, unsigned int clusters)
 {
        struct ocfs2_extent_list *el = &bg->bg_list;
        struct ocfs2_extent_rec *rec;
@@ -369,7 +369,7 @@ static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb,
        rec->e_blkno = cpu_to_le64(p_blkno);
        rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) /
                                  le16_to_cpu(cl->cl_bpc));
-       rec->e_leaf_clusters = cpu_to_le32(clusters);
+       rec->e_leaf_clusters = cpu_to_le16(clusters);
        le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc));
        le16_add_cpu(&bg->bg_free_bits_count,
                     clusters * le16_to_cpu(cl->cl_bpc));
index 32499d213fc4f80f37efde6f71196283236896bf..9975457c981f904ca18a512dd7bcbe0f092ac664 100644 (file)
@@ -128,7 +128,7 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry,
        }
 
        /* Fast symlinks can't be large */
-       len = strlen(target);
+       len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb));
        link = kzalloc(len + 1, GFP_NOFS);
        if (!link) {
                status = -ENOMEM;
index d03469f618012ea4aff64b62f1f77e3e8b8ec47d..06fa5e77c40ef7aa0a3c0483ddbf3b9dd59f9dcf 100644 (file)
@@ -1286,13 +1286,11 @@ int ocfs2_xattr_get_nolock(struct inode *inode,
        xis.inode_bh = xbs.inode_bh = di_bh;
        di = (struct ocfs2_dinode *)di_bh->b_data;
 
-       down_read(&oi->ip_xattr_sem);
        ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer,
                                    buffer_size, &xis);
        if (ret == -ENODATA && di->i_xattr_loc)
                ret = ocfs2_xattr_block_get(inode, name_index, name, buffer,
                                            buffer_size, &xbs);
-       up_read(&oi->ip_xattr_sem);
 
        return ret;
 }
@@ -1316,8 +1314,10 @@ static int ocfs2_xattr_get(struct inode *inode,
                mlog_errno(ret);
                return ret;
        }
+       down_read(&OCFS2_I(inode)->ip_xattr_sem);
        ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
                                     name, buffer, buffer_size);
+       up_read(&OCFS2_I(inode)->ip_xattr_sem);
 
        ocfs2_inode_unlock(inode, 0);
 
index a1c43e7c8a7be4ce70c729f3338eae09097f4025..8e4addaa542458badbe0e62da644ec1c64194f99 100644 (file)
@@ -2675,7 +2675,7 @@ static const struct pid_entry tgid_base_stuff[] = {
        INF("auxv",       S_IRUSR, proc_pid_auxv),
        ONE("status",     S_IRUGO, proc_pid_status),
        ONE("personality", S_IRUSR, proc_pid_personality),
-       INF("limits",     S_IRUSR, proc_pid_limits),
+       INF("limits",     S_IRUGO, proc_pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",      S_IRUGO|S_IWUSR, proc_pid_sched_operations),
 #endif
@@ -3011,7 +3011,7 @@ static const struct pid_entry tid_base_stuff[] = {
        INF("auxv",      S_IRUSR, proc_pid_auxv),
        ONE("status",    S_IRUGO, proc_pid_status),
        ONE("personality", S_IRUSR, proc_pid_personality),
-       INF("limits",    S_IRUSR, proc_pid_limits),
+       INF("limits",    S_IRUGO, proc_pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",     S_IRUGO|S_IWUSR, proc_pid_sched_operations),
 #endif
index 271afc48b9a5d58dd2874d41f8a08dfcae644481..1dbca4e8cc164d08276d4a1f5a875e7726fc7020 100644 (file)
@@ -363,13 +363,13 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
                        mss->referenced += PAGE_SIZE;
                mapcount = page_mapcount(page);
                if (mapcount >= 2) {
-                       if (pte_dirty(ptent))
+                       if (pte_dirty(ptent) || PageDirty(page))
                                mss->shared_dirty += PAGE_SIZE;
                        else
                                mss->shared_clean += PAGE_SIZE;
                        mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount;
                } else {
-                       if (pte_dirty(ptent))
+                       if (pte_dirty(ptent) || PageDirty(page))
                                mss->private_dirty += PAGE_SIZE;
                        else
                                mss->private_clean += PAGE_SIZE;
index 91c817ff02c3847a874e1e99f7638b1148869a77..2367fb3f70bc6ba468ab0ccb628b5b88fabac955 100644 (file)
@@ -163,7 +163,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
 
 static const struct file_operations proc_vmcore_operations = {
        .read           = read_vmcore,
-       .llseek         = generic_file_llseek,
+       .llseek         = default_llseek,
 };
 
 static struct vmcore* __init get_new_element(void)
index f53505de071217399e39bf2013304ba46bd0c7f5..5cbb81e134aca031b21e3c88661400ff1c1b174f 100644 (file)
@@ -170,6 +170,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
 int reiserfs_unpack(struct inode *inode, struct file *filp)
 {
        int retval = 0;
+       int depth;
        int index;
        struct page *page;
        struct address_space *mapping;
@@ -188,8 +189,8 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
        /* we need to make sure nobody is changing the file size beneath
         ** us
         */
-       mutex_lock(&inode->i_mutex);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
+       depth = reiserfs_write_lock_once(inode->i_sb);
 
        write_from = inode->i_size & (blocksize - 1);
        /* if we are on a block boundary, we are already unpacked.  */
@@ -224,6 +225,6 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
 
       out:
        mutex_unlock(&inode->i_mutex);
-       reiserfs_write_unlock(inode->i_sb);
+       reiserfs_write_unlock_once(inode->i_sb, depth);
        return retval;
 }
index d59c4a65d492c9b6b0713accaec1ab1c2ba7ea5f..81976ffed7d6f031f1bef0d7a5995cbbebbed69b 100644 (file)
@@ -668,14 +668,11 @@ xfs_inode_set_reclaim_tag(
        xfs_perag_put(pag);
 }
 
-void
-__xfs_inode_clear_reclaim_tag(
-       xfs_mount_t     *mp,
+STATIC void
+__xfs_inode_clear_reclaim(
        xfs_perag_t     *pag,
        xfs_inode_t     *ip)
 {
-       radix_tree_tag_clear(&pag->pag_ici_root,
-                       XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
        pag->pag_ici_reclaimable--;
        if (!pag->pag_ici_reclaimable) {
                /* clear the reclaim tag from the perag radix tree */
@@ -689,6 +686,17 @@ __xfs_inode_clear_reclaim_tag(
        }
 }
 
+void
+__xfs_inode_clear_reclaim_tag(
+       xfs_mount_t     *mp,
+       xfs_perag_t     *pag,
+       xfs_inode_t     *ip)
+{
+       radix_tree_tag_clear(&pag->pag_ici_root,
+                       XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
+       __xfs_inode_clear_reclaim(pag, ip);
+}
+
 /*
  * Inodes in different states need to be treated differently, and the return
  * value of xfs_iflush is not sufficient to get this right. The following table
@@ -838,6 +846,7 @@ reclaim:
        if (!radix_tree_delete(&pag->pag_ici_root,
                                XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino)))
                ASSERT(0);
+       __xfs_inode_clear_reclaim(pag, ip);
        write_unlock(&pag->pag_ici_lock);
 
        /*
index ed575fb4b49597806200f676680ff787d5be9d12..7e206fc1fa362ed4bb761a8f5ad11ef39c2dd5c0 100644 (file)
@@ -405,9 +405,15 @@ xlog_cil_push(
        new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS);
        new_ctx->ticket = xlog_cil_ticket_alloc(log);
 
-       /* lock out transaction commit, but don't block on background push */
+       /*
+        * Lock out transaction commit, but don't block for background pushes
+        * unless we are well over the CIL space limit. See the definition of
+        * XLOG_CIL_HARD_SPACE_LIMIT() for the full explanation of the logic
+        * used here.
+        */
        if (!down_write_trylock(&cil->xc_ctx_lock)) {
-               if (!push_seq)
+               if (!push_seq &&
+                   cil->xc_ctx->space_used < XLOG_CIL_HARD_SPACE_LIMIT(log))
                        goto out_free_ticket;
                down_write(&cil->xc_ctx_lock);
        }
@@ -422,7 +428,7 @@ xlog_cil_push(
                goto out_skip;
 
        /* check for a previously pushed seqeunce */
-       if (push_seq < cil->xc_ctx->sequence)
+       if (push_seq && push_seq < cil->xc_ctx->sequence)
                goto out_skip;
 
        /*
index ced52b98b322e3eb1be0e0c7dfc70f6096d0cd80..edcdfe01617f673bc1047caca3acc243f66a0658 100644 (file)
@@ -426,13 +426,13 @@ struct xfs_cil {
 };
 
 /*
- * The amount of log space we should the CIL to aggregate is difficult to size.
- * Whatever we chose we have to make we can get a reservation for the log space
- * effectively, that it is large enough to capture sufficient relogging to
- * reduce log buffer IO significantly, but it is not too large for the log or
- * induces too much latency when writing out through the iclogs. We track both
- * space consumed and the number of vectors in the checkpoint context, so we
- * need to decide which to use for limiting.
+ * The amount of log space we allow the CIL to aggregate is difficult to size.
+ * Whatever we choose, we have to make sure we can get a reservation for the
+ * log space effectively, that it is large enough to capture sufficient
+ * relogging to reduce log buffer IO significantly, but it is not too large for
+ * the log or induces too much latency when writing out through the iclogs. We
+ * track both space consumed and the number of vectors in the checkpoint
+ * context, so we need to decide which to use for limiting.
  *
  * Every log buffer we write out during a push needs a header reserved, which
  * is at least one sector and more for v2 logs. Hence we need a reservation of
@@ -459,16 +459,21 @@ struct xfs_cil {
  * checkpoint transaction ticket is specific to the checkpoint context, rather
  * than the CIL itself.
  *
- * With dynamic reservations, we can basically make up arbitrary limits for the
- * checkpoint size so long as they don't violate any other size rules.  Hence
- * the initial maximum size for the checkpoint transaction will be set to a
- * quarter of the log or 8MB, which ever is smaller. 8MB is an arbitrary limit
- * right now based on the latency of writing out a large amount of data through
- * the circular iclog buffers.
+ * With dynamic reservations, we can effectively make up arbitrary limits for
+ * the checkpoint size so long as they don't violate any other size rules.
+ * Recovery imposes a rule that no transaction exceed half the log, so we are
+ * limited by that.  Furthermore, the log transaction reservation subsystem
+ * tries to keep 25% of the log free, so we need to keep below that limit or we
+ * risk running out of free log space to start any new transactions.
+ *
+ * In order to keep background CIL push efficient, we will set a lower
+ * threshold at which background pushing is attempted without blocking current
+ * transaction commits.  A separate, higher bound defines when CIL pushes are
+ * enforced to ensure we stay within our maximum checkpoint size bounds.
+ * threshold, yet give us plenty of space for aggregation on large logs.
  */
-
-#define XLOG_CIL_SPACE_LIMIT(log)      \
-       (min((log->l_logsize >> 2), (8 * 1024 * 1024)))
+#define XLOG_CIL_SPACE_LIMIT(log)      (log->l_logsize >> 3)
+#define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4))
 
 /*
  * The reservation head lsn is not made up of a cycle number and block number.
index c0786d446a00b88adf144ab97f05af06679cccf7..984cdc62e30bc52da4cef907f3dd5094aa5ffd71 100644 (file)
@@ -55,7 +55,7 @@
 extern u8 acpi_gbl_permanent_mmap;
 
 /*
- * Globals that are publically available, allowing for
+ * Globals that are publicly available, allowing for
  * run time configuration
  */
 extern u32 acpi_dbg_level;
index 7809d230adee3f90c9537f6c00ec66bb53c1bd27..4c9461a4f9e67b4b3e67c5bb73192aed44695079 100644 (file)
@@ -612,7 +612,7 @@ struct drm_gem_object {
        struct kref refcount;
 
        /** Handle count of this object. Each handle also holds a reference */
-       struct kref handlecount;
+       atomic_t handle_count; /* number of handles on this object */
 
        /** Related drm device */
        struct drm_device *dev;
@@ -808,7 +808,6 @@ struct drm_driver {
         */
        int (*gem_init_object) (struct drm_gem_object *obj);
        void (*gem_free_object) (struct drm_gem_object *obj);
-       void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
 
        /* vga arb irq handler */
        void (*vgaarb_irq)(struct drm_device *dev, bool state);
@@ -1175,6 +1174,7 @@ extern int drm_release(struct inode *inode, struct file *filp);
 extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
 extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma);
 extern void drm_vm_open_locked(struct vm_area_struct *vma);
+extern void drm_vm_close_locked(struct vm_area_struct *vma);
 extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map);
 extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev);
 extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
@@ -1455,12 +1455,11 @@ int drm_gem_init(struct drm_device *dev);
 void drm_gem_destroy(struct drm_device *dev);
 void drm_gem_object_release(struct drm_gem_object *obj);
 void drm_gem_object_free(struct kref *kref);
-void drm_gem_object_free_unlocked(struct kref *kref);
 struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
                                            size_t size);
 int drm_gem_object_init(struct drm_device *dev,
                        struct drm_gem_object *obj, size_t size);
-void drm_gem_object_handle_free(struct kref *kref);
+void drm_gem_object_handle_free(struct drm_gem_object *obj);
 void drm_gem_vm_open(struct vm_area_struct *vma);
 void drm_gem_vm_close(struct vm_area_struct *vma);
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -1483,8 +1482,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj)
 static inline void
 drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
 {
-       if (obj != NULL)
-               kref_put(&obj->refcount, drm_gem_object_free_unlocked);
+       if (obj != NULL) {
+               struct drm_device *dev = obj->dev;
+               mutex_lock(&dev->struct_mutex);
+               kref_put(&obj->refcount, drm_gem_object_free);
+               mutex_unlock(&dev->struct_mutex);
+       }
 }
 
 int drm_gem_handle_create(struct drm_file *file_priv,
@@ -1495,7 +1498,7 @@ static inline void
 drm_gem_object_handle_reference(struct drm_gem_object *obj)
 {
        drm_gem_object_reference(obj);
-       kref_get(&obj->handlecount);
+       atomic_inc(&obj->handle_count);
 }
 
 static inline void
@@ -1504,12 +1507,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj)
        if (obj == NULL)
                return;
 
+       if (atomic_read(&obj->handle_count) == 0)
+               return;
        /*
         * Must bump handle count first as this may be the last
         * ref, in which case the object would disappear before we
         * checked for a name
         */
-       kref_put(&obj->handlecount, drm_gem_object_handle_free);
+       if (atomic_dec_and_test(&obj->handle_count))
+               drm_gem_object_handle_free(obj);
        drm_gem_object_unreference(obj);
 }
 
@@ -1519,12 +1525,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
        if (obj == NULL)
                return;
 
+       if (atomic_read(&obj->handle_count) == 0)
+               return;
+
        /*
        * Must bump handle count first as this may be the last
        * ref, in which case the object would disappear before we
        * checked for a name
        */
-       kref_put(&obj->handlecount, drm_gem_object_handle_free);
+
+       if (atomic_dec_and_test(&obj->handle_count))
+               drm_gem_object_handle_free(obj);
        drm_gem_object_unreference_unlocked(obj);
 }
 
index c9f3cc5949a82eb0ae5ba4b463891df5f96806dd..3e5a51af757c76ba07f514d00265a5e7300b6627 100644 (file)
@@ -386,7 +386,15 @@ struct drm_connector_funcs {
        void (*dpms)(struct drm_connector *connector, int mode);
        void (*save)(struct drm_connector *connector);
        void (*restore)(struct drm_connector *connector);
-       enum drm_connector_status (*detect)(struct drm_connector *connector);
+
+       /* Check to see if anything is attached to the connector.
+        * @force is set to false whilst polling, true when checking the
+        * connector due to user request. @force can be used by the driver
+        * to avoid expensive, destructive operations during automated
+        * probing.
+        */
+       enum drm_connector_status (*detect)(struct drm_connector *connector,
+                                           bool force);
        int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
        int (*set_property)(struct drm_connector *connector, struct drm_property *property,
                             uint64_t val);
index 3a9940ef728bb5d2412c4cb54d84ed746e15d870..883c1d4398996d8ba807ca5d54940cec28c7809e 100644 (file)
@@ -85,7 +85,6 @@
        {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
-       {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
        {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
index 267a86c74e2e5cc089dfb5c72a1f1da3dbdae721..2040e6c4f1729a7de3001d5077277b8521427fb9 100644 (file)
@@ -246,9 +246,11 @@ struct ttm_buffer_object {
 
        atomic_t reserved;
 
-
        /**
         * Members protected by the bo::lock
+        * In addition, setting sync_obj to anything else
+        * than NULL requires bo::reserved to be held. This allows for
+        * checking NULL while reserved but not holding bo::lock.
         */
 
        void *sync_obj_arg;
index 626b629429ff2fc3f30fcf63b25fb52211f184c0..4e8ea8c8ec1e7f6fc04ebf992294b63cb23b1bbb 100644 (file)
@@ -118,7 +118,6 @@ header-y += eventpoll.h
 header-y += ext2_fs.h
 header-y += fadvise.h
 header-y += falloc.h
-header-y += fanotify.h
 header-y += fb.h
 header-y += fcntl.h
 header-y += fd.h
index 9ddc8780e8db7bfe45496587bc47e5fb00d12073..5778b559d59c3222ee825897b7430523aa96c353 100644 (file)
@@ -360,5 +360,8 @@ extern ssize_t compat_rw_copy_check_uvector(int type,
                const struct compat_iovec __user *uvector, unsigned long nr_segs,
                unsigned long fast_segs, struct iovec *fast_pointer,
                struct iovec **ret_pointer);
+
+extern void __user *compat_alloc_user_space(unsigned long len);
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
index 8ba66a9d9022c7d0ddbbcb984b8839dabb2b91f8..ba4b85a6d9b8bc71853de37df2a36b865707b745 100644 (file)
@@ -9,37 +9,7 @@
  * These are the only things you should do on a core-file: use only these
  * functions to write out all the necessary info.
  */
-static inline int dump_write(struct file *file, const void *addr, int nr)
-{
-       return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-static inline int dump_seek(struct file *file, loff_t off)
-{
-       int ret = 1;
-
-       if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
-               if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
-                       return 0;
-       } else {
-               char *buf = (char *)get_zeroed_page(GFP_KERNEL);
-
-               if (!buf)
-                       return 0;
-               while (off > 0) {
-                       unsigned long n = off;
-
-                       if (n > PAGE_SIZE)
-                               n = PAGE_SIZE;
-                       if (!dump_write(file, buf, n)) {
-                               ret = 0;
-                               break;
-                       }
-                       off -= n;
-               }
-               free_page((unsigned long)buf);
-       }
-       return ret;
-}
+extern int dump_write(struct file *file, const void *addr, int nr);
+extern int dump_seek(struct file *file, loff_t off);
 
 #endif /* _LINUX_COREDUMP_H */
index 36ca9721a0c28a0150b05153b4f442d2c558d6d4..1be416bbbb82540802a0a742ba2c22934a9a6659 100644 (file)
@@ -53,6 +53,7 @@ struct cpuidle_state {
 #define CPUIDLE_FLAG_BALANCED  (0x40) /* medium latency, moderate savings */
 #define CPUIDLE_FLAG_DEEP      (0x80) /* high latency, large savings */
 #define CPUIDLE_FLAG_IGNORE    (0x100) /* ignore during this idle period */
+#define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
 
index ce29b8151198b6c0d40b8f420efe9c2c920d9b4f..ba8319ae5fcc3e75edc0d52240da0b16e18da68d 100644 (file)
@@ -102,6 +102,9 @@ static inline u64 dma_get_mask(struct device *dev)
        return DMA_BIT_MASK(32);
 }
 
+#ifdef ARCH_HAS_DMA_SET_COHERENT_MASK
+int dma_set_coherent_mask(struct device *dev, u64 mask);
+#else
 static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
 {
        if (!dma_supported(dev, mask))
@@ -109,6 +112,7 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
        dev->coherent_dma_mask = mask;
        return 0;
 }
+#endif
 
 extern u64 dma_get_required_mask(struct device *dev);
 
index c61d4ca27bcc26906699101b4f8eee7ce8e8525b..e2106495cc11383ad9a14d7ac119400b18a8f83a 100644 (file)
@@ -548,7 +548,7 @@ static inline bool dma_dev_has_pq_continue(struct dma_device *dma)
        return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE;
 }
 
-static unsigned short dma_dev_to_maxpq(struct dma_device *dma)
+static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
 {
        return dma->max_pq & ~DMA_HAS_PQ_CONTINUE;
 }
index 926b50322a469c9d16c48ed35e10c4c12bd695f3..4fd978e7eb83ef8d689d0d313b5441b0631ea275 100644 (file)
@@ -93,6 +93,7 @@ struct elevator_queue
        struct elevator_type *elevator_type;
        struct mutex sysfs_lock;
        struct hlist_head *hash;
+       unsigned int registered:1;
 };
 
 /*
index 76041b6147582ef62eb0daedafbf1771a8e844c6..63d069bd80b702c392d4052bf2be937f90763692 100644 (file)
@@ -1093,6 +1093,10 @@ struct file_lock {
 
 #include <linux/fcntl.h>
 
+/* temporary stubs for BKL removal */
+#define lock_flocks() lock_kernel()
+#define unlock_flocks() unlock_kernel()
+
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
 
 #ifdef CONFIG_FILE_LOCKING
index 03f616b78cfa8b857e727ea220a60c05a87bb89f..e41f7dd1ae676eb778a00c0f7cdced047312eff7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/errno.h>
 
 struct device;
+struct gpio_chip;
 
 /*
  * Some platforms don't support the GPIO programming interface.
index 8a6b9fdc7ffae0c20335b8a2c73726396a934ee2..aace066bad8f067758cda4d341b9ce8941d2ae1c 100644 (file)
@@ -686,17 +686,16 @@ extern int module_sysfs_initialized;
 
 
 #ifdef CONFIG_GENERIC_BUG
-int  module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
                         struct module *);
 void module_bug_cleanup(struct module *);
 
 #else  /* !CONFIG_GENERIC_BUG */
 
-static inline int  module_bug_finalize(const Elf_Ehdr *hdr,
+static inline void module_bug_finalize(const Elf_Ehdr *hdr,
                                        const Elf_Shdr *sechdrs,
                                        struct module *mod)
 {
-       return 0;
 }
 static inline void module_bug_cleanup(struct module *mod) {}
 #endif /* CONFIG_GENERIC_BUG */
index 59d066936ab9e0414d2cddc5123a9b7e0ac3c3ad..123566912d7312f276bf975cd1a48c97b2ffa830 100644 (file)
@@ -27,8 +27,6 @@
 
 #define MAX_LINKS 32           
 
-struct net;
-
 struct sockaddr_nl {
        sa_family_t     nl_family;      /* AF_NETLINK   */
        unsigned short  nl_pad;         /* zero         */
@@ -151,6 +149,8 @@ struct nlattr {
 #include <linux/capability.h>
 #include <linux/skbuff.h>
 
+struct net;
+
 static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
 {
        return (struct nlmsghdr *)skb->data;
index 791d5109f34c12207de65f06cca05fa4b35b44b8..50d8009be86c023cbee9607cb728927ba86fb531 100644 (file)
@@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb)
        unsigned long flags;
        bool ret = false;
 
-       rcu_read_lock_bh();
+       local_irq_save(flags);
        npinfo = rcu_dereference_bh(skb->dev->npinfo);
 
        if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
                goto out;
 
-       spin_lock_irqsave(&npinfo->rx_lock, flags);
+       spin_lock(&npinfo->rx_lock);
        /* check rx_flags again with the lock held */
        if (npinfo->rx_flags && __netpoll_rx(skb))
                ret = true;
-       spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+       spin_unlock(&npinfo->rx_lock);
 
 out:
-       rcu_read_unlock_bh();
+       local_irq_restore(flags);
        return ret;
 }
 
index 10d33309e9a61351aa4d3597540f201c97dc9294..570fddeb0388f62b7b8dd0a32ec5136123856033 100644 (file)
 #define PCI_DEVICE_ID_VLSI_82C147      0x0105
 #define PCI_DEVICE_ID_VLSI_VAS96011    0x0702
 
+/* AMD RD890 Chipset */
+#define PCI_DEVICE_ID_RD890_IOMMU      0x5a23
+
 #define PCI_VENDOR_ID_ADL              0x1005
 #define PCI_DEVICE_ID_ADL_2301         0x2301
 
index d50ba858cfe0c15325ff5fcf410d7a18f1a8aad3..d1a9193960f17601d4637bfae03f3c9a3ac5bc83 100644 (file)
@@ -274,8 +274,14 @@ static inline int dquot_alloc_space(struct inode *inode, qsize_t nr)
        int ret;
 
        ret = dquot_alloc_space_nodirty(inode, nr);
-       if (!ret)
-               mark_inode_dirty_sync(inode);
+       if (!ret) {
+               /*
+                * Mark inode fully dirty. Since we are allocating blocks, inode
+                * would become fully dirty soon anyway and it reportedly
+                * reduces inode_lock contention.
+                */
+               mark_inode_dirty(inode);
+       }
        return ret;
 }
 
index 9fbc54a2585d42cb9276adf2c2d168f53e883f63..83af1f8d8b746cde3b8369d7125f3cdfe07da6d3 100644 (file)
@@ -454,7 +454,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
  * Makes rcu_dereference_check() do the dirty work.
  */
 #define rcu_dereference_bh(p) \
-               rcu_dereference_check(p, rcu_read_lock_bh_held())
+               rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled())
 
 /**
  * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched
index a2fada9becb60c47fcbf8143b3b3c67d291731b8..a8f56e1ec7602705d70ca326e620f1a8927e3925 100644 (file)
@@ -322,7 +322,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
                                          int offset, 
                                          unsigned int len, __wsum *csump);
 
-extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
+extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
                             int offset, int len);
index cc813f95a2f2b6a4ddf19d04ed1b60fc321c9712..c91302f3a25789b8045b34d9c0a9fa814c29b0ae 100644 (file)
@@ -14,7 +14,9 @@
 #define SPI_MODE_OFFSET                        6
 #define SPI_SCPH_OFFSET                        6
 #define SPI_SCOL_OFFSET                        7
+
 #define SPI_TMOD_OFFSET                        8
+#define SPI_TMOD_MASK                  (0x3 << SPI_TMOD_OFFSET)
 #define        SPI_TMOD_TR                     0x0             /* xmit & recv */
 #define SPI_TMOD_TO                    0x1             /* xmit only */
 #define SPI_TMOD_RO                    0x2             /* recv only */
index 569dc722a600d55834055cf22474858ef69f5bae..85f38a63f098a2c55989f1e5d4e070595e525a99 100644 (file)
@@ -30,7 +30,7 @@ struct rpc_inode;
  * The high-level client handle
  */
 struct rpc_clnt {
-       struct kref             cl_kref;        /* Number of references */
+       atomic_t                cl_count;       /* Number of references */
        struct list_head        cl_clients;     /* Global list of clients */
        struct list_head        cl_tasks;       /* List of tasks */
        spinlock_t              cl_lock;        /* spinlock */
index 0836ccc5712146f87d13e9e35a9480e980708392..3efc9f3f43a0862cad51aa325e08c9f24d129f8e 100644 (file)
@@ -614,6 +614,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
                (wait)->private = current;                              \
                (wait)->func = autoremove_wake_function;                \
                INIT_LIST_HEAD(&(wait)->task_list);                     \
+               (wait)->flags = 0;                                      \
        } while (0)
 
 /**
index f11100f964824c250b4eacb21e96e36640527ac6..25e02c941bac34a5322510f0461998b1054259fc 100644 (file)
@@ -235,6 +235,10 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
 #define work_clear_pending(work) \
        clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))
 
+/*
+ * Workqueue flags and constants.  For details, please refer to
+ * Documentation/workqueue.txt.
+ */
 enum {
        WQ_NON_REENTRANT        = 1 << 0, /* guarantee non-reentrance */
        WQ_UNBOUND              = 1 << 1, /* not bound to any cpu */
index 97e07f46a0fae22f1cba1eb3073f5661cc97b95a..aa4ebb42a5652b2261b1a2dbbbe133cbd5fbfe51 100644 (file)
@@ -48,6 +48,7 @@ struct videobuf_dmabuf {
 
        /* for userland buffer */
        int                 offset;
+       size_t              size;
        struct page         **pages;
 
        /* for kernel buffers */
index 45375b41a2a0d44e62a370813ab4fdcbe046e3b3..4d40c4d0230baeffbafcb57cb6fac99a1f0174b3 100644 (file)
@@ -121,6 +121,7 @@ static inline int addrconf_finite_timeout(unsigned long timeout)
  *     IPv6 Address Label subsystem (addrlabel.c)
  */
 extern int                     ipv6_addr_label_init(void);
+extern void                    ipv6_addr_label_cleanup(void);
 extern void                    ipv6_addr_label_rtnl_register(void);
 extern u32                     ipv6_addr_label(struct net *net,
                                                const struct in6_addr *addr,
index 27a902d9b3a9a431c6b3162a4c6fe479aa99504c..30fce0128dd72fa0281795bc0ae03809b85bc9d0 100644 (file)
@@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l
 {
        struct sk_buff *skb;
 
+       release_sock(sk);
        if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
                skb_reserve(skb, BT_SKB_RESERVE);
                bt_cb(skb)->incoming  = 0;
        }
+       lock_sock(sk);
+
+       if (!skb && *err)
+               return NULL;
+
+       *err = sock_error(sk);
+       if (*err)
+               goto out;
+
+       if (sk->sk_shutdown) {
+               *err = -ECONNRESET;
+               goto out;
+       }
 
        return skb;
+
+out:
+       kfree_skb(skb);
+       return NULL;
 }
 
 int bt_err(__u16 code);
index 81d1413a87010967684febe7344169baa7d828ef..02386505033d975e666cd924a3bafe3ca02bb100 100644 (file)
@@ -242,6 +242,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += skb->len;
        skb->rxhash = 0;
+       skb_set_queue_mapping(skb, 0);
        skb_dst_drop(skb);
        nf_reset(skb);
 }
index bd732d62e1c3a3181c7c324d695b02e1548970e0..7e5e73bfa4dec8e2d45c834507f74d86484b8715 100644 (file)
@@ -199,6 +199,8 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
                fl.fl_ip_sport = sport;
                fl.fl_ip_dport = dport;
                fl.proto = protocol;
+               if (inet_sk(sk)->transparent)
+                       fl.flags |= FLOWI_FLAG_ANYSRC;
                ip_rt_put(*rp);
                *rp = NULL;
                security_sk_classify_flow(sk, &fl);
index eaa9582779d029a9362c32b3816fed8c157e4d3e..3e4b33e36602caade361654d0561a65b3fba2224 100644 (file)
@@ -475,8 +475,22 @@ extern unsigned int tcp_current_mss(struct sock *sk);
 /* Bound MSS / TSO packet size with the half of the window */
 static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
 {
-       if (tp->max_window && pktsize > (tp->max_window >> 1))
-               return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
+       int cutoff;
+
+       /* When peer uses tiny windows, there is no use in packetizing
+        * to sub-MSS pieces for the sake of SWS or making sure there
+        * are enough packets in the pipe for fast recovery.
+        *
+        * On the other hand, for extremely large MSS devices, handling
+        * smaller than MSS windows in this way does make sense.
+        */
+       if (tp->max_window >= 512)
+               cutoff = (tp->max_window >> 1);
+       else
+               cutoff = tp->max_window;
+
+       if (cutoff && pktsize > cutoff)
+               return max_t(int, cutoff, 68U - tp->tcp_header_len);
        else
                return pktsize;
 }
index fc8f36dd0f5c5145932c45aa8e9f441697dcb0ec..4f53532d4c2f0f6e20d200fabafe1ac51dd1632c 100644 (file)
@@ -298,8 +298,8 @@ struct xfrm_state_afinfo {
        const struct xfrm_type  *type_map[IPPROTO_MAX];
        struct xfrm_mode        *mode_map[XFRM_MODE_MAX];
        int                     (*init_flags)(struct xfrm_state *x);
-       void                    (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
-                                               struct xfrm_tmpl *tmpl,
+       void                    (*init_tempsel)(struct xfrm_selector *sel, struct flowi *fl);
+       void                    (*init_temprop)(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
                                                xfrm_address_t *daddr, xfrm_address_t *saddr);
        int                     (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
        int                     (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
index 40a8f462a8224b298690cb07892f93afe8c15214..0e0d49bbb867f239be5690968227c53e7c0226c0 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -743,6 +743,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
            {
                struct semid_ds out;
 
+               memset(&out, 0, sizeof(out));
+
                ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm);
 
                out.sem_otime   = in->sem_otime;
index e167efce8423e2cdaf2709412c36cc3ae642c90f..c9e2ec0b34a8cc38cda604273618a22c8d2d928c 100644 (file)
@@ -1126,3 +1126,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
 
        return 0;
 }
+
+/*
+ * Allocate user-space memory for the duration of a single system call,
+ * in order to marshall parameters inside a compat thunk.
+ */
+void __user *compat_alloc_user_space(unsigned long len)
+{
+       void __user *ptr;
+
+       /* If len would occupy more than half of the entire compat space... */
+       if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
+               return NULL;
+
+       ptr = arch_compat_alloc_user_space(len);
+
+       if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
+               return NULL;
+
+       return ptr;
+}
+EXPORT_SYMBOL_GPL(compat_alloc_user_space);
index b7e9d60a675d3a08a1096ce725380229217d9fa3..c445f8cc408d777dd7a94aec3fa78c07e1d98b98 100644 (file)
@@ -356,10 +356,10 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                if (IS_ERR(pol))
                        goto fail_nomem_policy;
                vma_set_policy(tmp, pol);
+               tmp->vm_mm = mm;
                if (anon_vma_fork(tmp, mpnt))
                        goto fail_nomem_anon_vma_fork;
                tmp->vm_flags &= ~VM_LOCKED;
-               tmp->vm_mm = mm;
                tmp->vm_next = tmp->vm_prev = NULL;
                file = tmp->vm_file;
                if (file) {
index d71a987fd2bf2ba5e698f9b69fccb59db4a1bb30..c7c2aed9e2dcc2e52669e7d3880be0666c496bff 100644 (file)
@@ -433,7 +433,8 @@ register_user_hw_breakpoint(struct perf_event_attr *attr,
                            perf_overflow_handler_t triggered,
                            struct task_struct *tsk)
 {
-       return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered);
+       return perf_event_create_kernel_counter(attr, -1, task_pid_vnr(tsk),
+                                               triggered);
 }
 EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
 
index 6b5580c57644dc1804b02fd85648e7100d5d75dd..01a0700e873f53ca60084da3c0c1142bebf49b16 100644 (file)
@@ -365,8 +365,6 @@ static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl,
        n = setup_sgl_buf(sgl, fifo->data + off, nents, l);
        n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l);
 
-       if (n)
-               sg_mark_end(sgl + n - 1);
        return n;
 }
 
index d0b5f8db11b4a4183c229e2a44f433a99f58090a..ccd641991842f4990906946f895fd5062a0389c3 100644 (file)
@@ -1537,6 +1537,7 @@ static int __unlink_module(void *_mod)
 {
        struct module *mod = _mod;
        list_del(&mod->list);
+       module_bug_cleanup(mod);
        return 0;
 }
 
@@ -2625,6 +2626,7 @@ static struct module *load_module(void __user *umod,
        if (err < 0)
                goto ddebug;
 
+       module_bug_finalize(info.hdr, info.sechdrs, mod);
        list_add_rcu(&mod->list, &modules);
        mutex_unlock(&module_mutex);
 
@@ -2650,6 +2652,8 @@ static struct module *load_module(void __user *umod,
        mutex_lock(&module_mutex);
        /* Unlink carefully: kallsyms could be walking list. */
        list_del_rcu(&mod->list);
+       module_bug_cleanup(mod);
+
  ddebug:
        if (!mod->taints)
                dynamic_debug_remove(info.debug);
index db5b56064687e453c0df1cc118b975ea047bdcae..b98bed3d8182685ffff2b840c0ff4809b4f65cb8 100644 (file)
@@ -2202,15 +2202,13 @@ static void perf_event_for_each(struct perf_event *event,
 static int perf_event_period(struct perf_event *event, u64 __user *arg)
 {
        struct perf_event_context *ctx = event->ctx;
-       unsigned long size;
        int ret = 0;
        u64 value;
 
        if (!event->attr.sample_period)
                return -EINVAL;
 
-       size = copy_from_user(&value, arg, sizeof(value));
-       if (size != sizeof(value))
+       if (copy_from_user(&value, arg, sizeof(value)))
                return -EFAULT;
 
        if (!value)
index ed09d4f2a69c5b4c1412d350c7c834a655732f2a..dc85ceb908322cad7196339f4df8dd58c37b1cec 100644 (file)
@@ -3513,9 +3513,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
        rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
 
        if (total) {
-               u64 temp;
+               u64 temp = rtime;
 
-               temp = (u64)(rtime * utime);
+               temp *= utime;
                do_div(temp, total);
                utime = (cputime_t)temp;
        } else
@@ -3546,9 +3546,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
        rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
 
        if (total) {
-               u64 temp;
+               u64 temp = rtime;
 
-               temp = (u64)(rtime * cputime.utime);
+               temp *= cputime.utime;
                do_div(temp, total);
                utime = (cputime_t)temp;
        } else
index 9b5b4f86b742e80b6e653f967b509b60487d49e9..db3f674ca49dbe93a611716b650bb8c715464da3 100644 (file)
@@ -54,13 +54,13 @@ enum sched_tunable_scaling sysctl_sched_tunable_scaling
  * Minimal preemption granularity for CPU-bound tasks:
  * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds)
  */
-unsigned int sysctl_sched_min_granularity = 2000000ULL;
-unsigned int normalized_sysctl_sched_min_granularity = 2000000ULL;
+unsigned int sysctl_sched_min_granularity = 750000ULL;
+unsigned int normalized_sysctl_sched_min_granularity = 750000ULL;
 
 /*
  * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
  */
-static unsigned int sched_nr_latency = 3;
+static unsigned int sched_nr_latency = 8;
 
 /*
  * After fork, child runs first. If set to 0 (default) then
@@ -3630,7 +3630,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu)
        if (time_before(now, nohz.next_balance))
                return 0;
 
-       if (!rq->nr_running)
+       if (rq->idle_at_tick)
                return 0;
 
        first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
index bded65187780f5f288bd779920a5c04c190528dc..919562c3d6b720d58ff246b2c412114d77c0b419 100644 (file)
@@ -2214,6 +2214,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
                err |= __put_user(from->si_addr, &to->si_addr);
 #ifdef __ARCH_SI_TRAPNO
                err |= __put_user(from->si_trapno, &to->si_trapno);
+#endif
+#ifdef BUS_MCEERR_AO
+               /* 
+                * Other callers might not initialize the si_lsb field,
+                * so check explicitely for the right codes here.
+                */
+               if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)
+                       err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
 #endif
                break;
        case __SI_CHLD:
index 75c970c715d399f1385d72e92e0c47c509e568dc..ed6aacfcb7efb307fe313ea798e7074f2c8f4f92 100644 (file)
@@ -365,9 +365,10 @@ call:
 EXPORT_SYMBOL_GPL(smp_call_function_any);
 
 /**
- * __smp_call_function_single(): Run a function on another CPU
+ * __smp_call_function_single(): Run a function on a specific CPU
  * @cpu: The CPU to run on.
  * @data: Pre-allocated and setup data structure
+ * @wait: If true, wait until function has completed on specified CPU.
  *
  * Like smp_call_function_single(), but allow caller to pass in a
  * pre-allocated data structure. Useful for embedding @data inside
@@ -376,8 +377,10 @@ EXPORT_SYMBOL_GPL(smp_call_function_any);
 void __smp_call_function_single(int cpu, struct call_single_data *data,
                                int wait)
 {
-       csd_lock(data);
+       unsigned int this_cpu;
+       unsigned long flags;
 
+       this_cpu = get_cpu();
        /*
         * Can deadlock when called with interrupts disabled.
         * We allow cpu's that are not yet online though, as no one else can
@@ -387,7 +390,15 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
        WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled()
                     && !oops_in_progress);
 
-       generic_exec_single(cpu, data, wait);
+       if (cpu == this_cpu) {
+               local_irq_save(flags);
+               data->func(data->info);
+               local_irq_restore(flags);
+       } else {
+               csd_lock(data);
+               generic_exec_single(cpu, data, wait);
+       }
+       put_cpu();
 }
 
 /**
index f88552c6d2275be1216187f07b1e0e1b22b93af2..3a45c224770fb82fa4bd76f9c7d4f2f989ee5aa9 100644 (file)
@@ -2485,7 +2485,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
                kbuf[left] = 0;
        }
 
-       for (; left && vleft--; i++, min++, max++, first=0) {
+       for (; left && vleft--; i++, first = 0) {
                unsigned long val;
 
                if (write) {
index 492197e2f86cda2792603186b59ad3fdd17c448d..bca96377fd4e8667df513dfd91ea56931e35578f 100644 (file)
@@ -405,7 +405,7 @@ static inline int test_time_stamp(u64 delta)
 #define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2))
 
 /* Max number of timestamps that can fit on a page */
-#define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_STAMP)
+#define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_EXTEND)
 
 int ring_buffer_print_page_header(struct trace_seq *s)
 {
index 727f24e563aef326b8eba951d2a31a9aa864d32b..f77afd93922968d0c216bee148c0f10ed0ccaa72 100644 (file)
@@ -1,19 +1,26 @@
 /*
- * linux/kernel/workqueue.c
+ * kernel/workqueue.c - generic async execution with shared worker pool
  *
- * Generic mechanism for defining kernel helper threads for running
- * arbitrary tasks in process context.
+ * Copyright (C) 2002          Ingo Molnar
  *
- * Started by Ingo Molnar, Copyright (C) 2002
+ *   Derived from the taskqueue/keventd code by:
+ *     David Woodhouse <dwmw2@infradead.org>
+ *     Andrew Morton
+ *     Kai Petzke <wpp@marie.physik.tu-berlin.de>
+ *     Theodore Ts'o <tytso@mit.edu>
  *
- * Derived from the taskqueue/keventd code by:
+ * Made to use alloc_percpu by Christoph Lameter.
  *
- *   David Woodhouse <dwmw2@infradead.org>
- *   Andrew Morton
- *   Kai Petzke <wpp@marie.physik.tu-berlin.de>
- *   Theodore Ts'o <tytso@mit.edu>
+ * Copyright (C) 2010          SUSE Linux Products GmbH
+ * Copyright (C) 2010          Tejun Heo <tj@kernel.org>
  *
- * Made to use alloc_percpu by Christoph Lameter.
+ * This is the generic async execution mechanism.  Work items as are
+ * executed in process context.  The worker pool is shared and
+ * automatically managed.  There is one worker pool for each CPU and
+ * one extra for works which are better served by workers which are
+ * not bound to any specific CPU.
+ *
+ * Please read Documentation/workqueue.txt for details.
  */
 
 #include <linux/module.h>
index 7cdfad88128fa5d3d3076d552fbde276ef500d66..19552096d16b06bd2dac2a9b10212e482a4d0da3 100644 (file)
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -72,8 +72,8 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr)
        return NULL;
 }
 
-int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-                       struct module *mod)
+void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+                        struct module *mod)
 {
        char *secstrings;
        unsigned int i;
@@ -97,8 +97,6 @@ int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
         * could potentially lead to deadlock and thus be counter-productive.
         */
        list_add(&mod->bug_list, &module_bug_list);
-
-       return 0;
 }
 
 void module_bug_cleanup(struct module *mod)
index 4b5cb794c38bb270b8b72b70a47de265ec05c210..a7616fa3162e844f5b3c7090c1911543c826147e 100644 (file)
@@ -70,7 +70,7 @@ static void merge_and_restore_back_links(void *priv,
                 * element comparison is needed, so the client's cmp()
                 * routine can invoke cond_resched() periodically.
                 */
-               (*cmp)(priv, tail, tail);
+               (*cmp)(priv, tail->next, tail->next);
 
                tail->next->prev = tail;
                tail = tail->next;
index c2bf86f470ed0044ab7366d5e6ea95a4aea2adf2..65d420499a615bf68a3be8313c3b0d8b1b330178 100644 (file)
@@ -30,6 +30,7 @@ EXPORT_SYMBOL_GPL(default_backing_dev_info);
 
 struct backing_dev_info noop_backing_dev_info = {
        .name           = "noop",
+       .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
 };
 EXPORT_SYMBOL_GPL(noop_backing_dev_info);
 
@@ -243,6 +244,7 @@ static int __init default_bdi_init(void)
        err = bdi_init(&default_backing_dev_info);
        if (!err)
                bdi_register(&default_backing_dev_info, NULL, "default");
+       err = bdi_init(&noop_backing_dev_info);
 
        return err;
 }
index 46f5dacf90a2cd62427fdf89b67fa01ef8af68e0..ec520c7b28dffedb5027de6b27834831938671cd 100644 (file)
@@ -125,7 +125,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
 {
        struct mm_struct *mm = current->mm;
        struct address_space *mapping;
-       unsigned long end = start + size;
        struct vm_area_struct *vma;
        int err = -EINVAL;
        int has_write_lock = 0;
@@ -142,6 +141,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        if (start + size <= start)
                return err;
 
+       /* Does pgoff wrap? */
+       if (pgoff + (size >> PAGE_SHIFT) < pgoff)
+               return err;
+
        /* Can we represent this offset inside this architecture's pte's? */
 #if PTE_FILE_MAX_BITS < BITS_PER_LONG
        if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS))
@@ -168,7 +171,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        if (!(vma->vm_flags & VM_CAN_NONLINEAR))
                goto out;
 
-       if (end <= start || start < vma->vm_start || end > vma->vm_end)
+       if (start < vma->vm_start || start + size > vma->vm_end)
                goto out;
 
        /* Must set VM_NONLINEAR before any pages are populated. */
index cc5be788a39fe132c72cbc1d2fb1c03f71708575..c03273807182dde1d9dd2e905c0db11a6dfe2441 100644 (file)
@@ -2324,11 +2324,8 @@ retry_avoidcopy:
         * and just make the page writable */
        avoidcopy = (page_mapcount(old_page) == 1);
        if (avoidcopy) {
-               if (!trylock_page(old_page)) {
-                       if (PageAnon(old_page))
-                               page_move_anon_rmap(old_page, vma, address);
-               } else
-                       unlock_page(old_page);
+               if (PageAnon(old_page))
+                       page_move_anon_rmap(old_page, vma, address);
                set_huge_ptep_writable(vma, address, ptep);
                return 0;
        }
@@ -2404,7 +2401,7 @@ retry_avoidcopy:
                set_huge_pte_at(mm, address, ptep,
                                make_huge_pte(vma, new_page, 1));
                page_remove_rmap(old_page);
-               hugepage_add_anon_rmap(new_page, vma, address);
+               hugepage_add_new_anon_rmap(new_page, vma, address);
                /* Make the old page be freed below */
                new_page = old_page;
                mmu_notifier_invalidate_range_end(mm,
@@ -2631,10 +2628,16 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                                                                vma, address);
        }
 
-       if (!pagecache_page) {
-               page = pte_page(entry);
+       /*
+        * hugetlb_cow() requires page locks of pte_page(entry) and
+        * pagecache_page, so here we need take the former one
+        * when page != pagecache_page or !pagecache_page.
+        * Note that locking order is always pagecache_page -> page,
+        * so no worry about deadlock.
+        */
+       page = pte_page(entry);
+       if (page != pagecache_page)
                lock_page(page);
-       }
 
        spin_lock(&mm->page_table_lock);
        /* Check for a racing update before calling hugetlb_cow */
@@ -2661,9 +2664,8 @@ out_page_table_lock:
        if (pagecache_page) {
                unlock_page(pagecache_page);
                put_page(pagecache_page);
-       } else {
-               unlock_page(page);
        }
+       unlock_page(page);
 
 out_mutex:
        mutex_unlock(&hugetlb_instantiation_mutex);
index b1873cf03ed986bcb062259da8f1c4093a97160b..65ab5c7067d994ad934c4f4bd5fd5809235a0756 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -712,7 +712,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
        if (!ptep)
                goto out;
 
-       if (pte_write(*ptep)) {
+       if (pte_write(*ptep) || pte_dirty(*ptep)) {
                pte_t entry;
 
                swapped = PageSwapCache(page);
@@ -735,7 +735,9 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
                        set_pte_at(mm, addr, ptep, entry);
                        goto out_unlock;
                }
-               entry = pte_wrprotect(entry);
+               if (pte_dirty(entry))
+                       set_page_dirty(page);
+               entry = pte_mkclean(pte_wrprotect(entry));
                set_pte_at_notify(mm, addr, ptep, entry);
        }
        *orig_pte = *ptep;
index 3eed583895a6f31eb434a252697371c7daa6bbd4..9be3cf8a5da462d4b1b4103eef61f8d5a9a6e06c 100644 (file)
@@ -3587,9 +3587,13 @@ unlock:
 
 static void mem_cgroup_threshold(struct mem_cgroup *memcg)
 {
-       __mem_cgroup_threshold(memcg, false);
-       if (do_swap_account)
-               __mem_cgroup_threshold(memcg, true);
+       while (memcg) {
+               __mem_cgroup_threshold(memcg, false);
+               if (do_swap_account)
+                       __mem_cgroup_threshold(memcg, true);
+
+               memcg = parent_mem_cgroup(memcg);
+       }
 }
 
 static int compare_thresholds(const void *a, const void *b)
index 9c26eeca13425886690cddaf6dd45954fd3f0097..757f6b0accfe84d959b7fe5899b5916ad0ed1f14 100644 (file)
@@ -183,7 +183,7 @@ EXPORT_SYMBOL_GPL(hwpoison_filter);
  * signal.
  */
 static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno,
-                       unsigned long pfn)
+                       unsigned long pfn, struct page *page)
 {
        struct siginfo si;
        int ret;
@@ -198,7 +198,7 @@ static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno,
 #ifdef __ARCH_SI_TRAPNO
        si.si_trapno = trapno;
 #endif
-       si.si_addr_lsb = PAGE_SHIFT;
+       si.si_addr_lsb = compound_order(compound_head(page)) + PAGE_SHIFT;
        /*
         * Don't use force here, it's convenient if the signal
         * can be temporarily blocked.
@@ -235,7 +235,7 @@ void shake_page(struct page *p, int access)
                int nr;
                do {
                        nr = shrink_slab(1000, GFP_KERNEL, 1000);
-                       if (page_count(p) == 0)
+                       if (page_count(p) == 1)
                                break;
                } while (nr > 10);
        }
@@ -327,7 +327,7 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
  * wrong earlier.
  */
 static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno,
-                         int fail, unsigned long pfn)
+                         int fail, struct page *page, unsigned long pfn)
 {
        struct to_kill *tk, *next;
 
@@ -352,7 +352,7 @@ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno,
                         * process anyways.
                         */
                        else if (kill_proc_ao(tk->tsk, tk->addr, trapno,
-                                             pfn) < 0)
+                                             pfn, page) < 0)
                                printk(KERN_ERR
                "MCE %#lx: Cannot send advisory machine check signal to %s:%d\n",
                                        pfn, tk->tsk->comm, tk->tsk->pid);
@@ -928,7 +928,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * any accesses to the poisoned memory.
         */
        kill_procs_ao(&tokill, !!PageDirty(hpage), trapno,
-                     ret != SWAP_SUCCESS, pfn);
+                     ret != SWAP_SUCCESS, p, pfn);
 
        return ret;
 }
index 71b161b73bb503be50556e9ff302ca0c7eaba396..0e18b4d649ec82abc83c208e5f9dce9cbb2cf905 100644 (file)
@@ -2680,10 +2680,12 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
        delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 
        /*
-        * Make sure try_to_free_swap didn't release the swapcache
-        * from under us. The page pin isn't enough to prevent that.
+        * Make sure try_to_free_swap or reuse_swap_page or swapoff did not
+        * release the swapcache from under us.  The page pin, and pte_same
+        * test below, are not enough to exclude that.  Even if it is still
+        * swapcache, we need to check that the page's swap has not changed.
         */
-       if (unlikely(!PageSwapCache(page)))
+       if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val))
                goto out_page;
 
        if (ksm_might_need_to_copy(page, vma, address)) {
index 6128dc8e5ede709cada129438fbac101895aa09d..00161a48a45100c611ebaa053f0b1f1486d09f29 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2009,6 +2009,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
                        removed_exe_file_vma(mm);
                fput(new->vm_file);
        }
+       unlink_anon_vmas(new);
  out_free_mpol:
        mpol_put(pol);
  out_free_vma:
index fc81cb22869ef54e6871daf39f51b32e3377aa98..4029583a10241aaa84e3937ee216740e0a88a363 100644 (file)
@@ -121,8 +121,8 @@ struct task_struct *find_lock_task_mm(struct task_struct *p)
 }
 
 /* return true if the task is not adequate as candidate victim task. */
-static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem,
-                          const nodemask_t *nodemask)
+static bool oom_unkillable_task(struct task_struct *p,
+               const struct mem_cgroup *mem, const nodemask_t *nodemask)
 {
        if (is_global_init(p))
                return true;
@@ -208,8 +208,13 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem,
         */
        points += p->signal->oom_score_adj;
 
-       if (points < 0)
-               return 0;
+       /*
+        * Never return 0 for an eligible task that may be killed since it's
+        * possible that no single user task uses more than 0.1% of memory and
+        * no single admin tasks uses more than 3.0%.
+        */
+       if (points <= 0)
+               return 1;
        return (points < 1000) ? points : 1000;
 }
 
@@ -339,26 +344,24 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
 /**
  * dump_tasks - dump current memory state of all system tasks
  * @mem: current's memory controller, if constrained
+ * @nodemask: nodemask passed to page allocator for mempolicy ooms
  *
- * Dumps the current memory state of all system tasks, excluding kernel threads.
+ * Dumps the current memory state of all eligible tasks.  Tasks not in the same
+ * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes
+ * are not shown.
  * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj
  * value, oom_score_adj value, and name.
  *
- * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are
- * shown.
- *
  * Call with tasklist_lock read-locked.
  */
-static void dump_tasks(const struct mem_cgroup *mem)
+static void dump_tasks(const struct mem_cgroup *mem, const nodemask_t *nodemask)
 {
        struct task_struct *p;
        struct task_struct *task;
 
        pr_info("[ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name\n");
        for_each_process(p) {
-               if (p->flags & PF_KTHREAD)
-                       continue;
-               if (mem && !task_in_mem_cgroup(p, mem))
+               if (oom_unkillable_task(p, mem, nodemask))
                        continue;
 
                task = find_lock_task_mm(p);
@@ -381,7 +384,7 @@ static void dump_tasks(const struct mem_cgroup *mem)
 }
 
 static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
-                                                       struct mem_cgroup *mem)
+                       struct mem_cgroup *mem, const nodemask_t *nodemask)
 {
        task_lock(current);
        pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
@@ -394,7 +397,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
        mem_cgroup_print_oom_info(mem, p);
        show_mem();
        if (sysctl_oom_dump_tasks)
-               dump_tasks(mem);
+               dump_tasks(mem, nodemask);
 }
 
 #define K(x) ((x) << (PAGE_SHIFT-10))
@@ -436,7 +439,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
        unsigned int victim_points = 0;
 
        if (printk_ratelimit())
-               dump_header(p, gfp_mask, order, mem);
+               dump_header(p, gfp_mask, order, mem, nodemask);
 
        /*
         * If the task is already exiting, don't alarm the sysadmin or kill
@@ -482,7 +485,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
  * Determines whether the kernel must panic because of the panic_on_oom sysctl.
  */
 static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
-                               int order)
+                               int order, const nodemask_t *nodemask)
 {
        if (likely(!sysctl_panic_on_oom))
                return;
@@ -496,7 +499,7 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
                        return;
        }
        read_lock(&tasklist_lock);
-       dump_header(NULL, gfp_mask, order, NULL);
+       dump_header(NULL, gfp_mask, order, NULL, nodemask);
        read_unlock(&tasklist_lock);
        panic("Out of memory: %s panic_on_oom is enabled\n",
                sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
@@ -509,7 +512,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
        unsigned int points = 0;
        struct task_struct *p;
 
-       check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0);
+       check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL);
        limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT;
        read_lock(&tasklist_lock);
 retry:
@@ -641,6 +644,7 @@ static void clear_system_oom(void)
 void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
                int order, nodemask_t *nodemask)
 {
+       const nodemask_t *mpol_mask;
        struct task_struct *p;
        unsigned long totalpages;
        unsigned long freed = 0;
@@ -670,7 +674,8 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
         */
        constraint = constrained_alloc(zonelist, gfp_mask, nodemask,
                                                &totalpages);
-       check_panic_on_oom(constraint, gfp_mask, order);
+       mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL;
+       check_panic_on_oom(constraint, gfp_mask, order, mpol_mask);
 
        read_lock(&tasklist_lock);
        if (sysctl_oom_kill_allocating_task &&
@@ -688,15 +693,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
        }
 
 retry:
-       p = select_bad_process(&points, totalpages, NULL,
-                       constraint == CONSTRAINT_MEMORY_POLICY ? nodemask :
-                                                                NULL);
+       p = select_bad_process(&points, totalpages, NULL, mpol_mask);
        if (PTR_ERR(p) == -1UL)
                goto out;
 
        /* Found nothing?!?! Either we hang forever, or we panic. */
        if (!p) {
-               dump_header(NULL, gfp_mask, order, NULL);
+               dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
                read_unlock(&tasklist_lock);
                panic("Out of memory and no killable processes...\n");
        }
index a8cfa9cc6e86e5d6912a39bc3f5c9d18fb97b7cf..f12ad1836abe115b1b8e3bf4b9187c01249e8a30 100644 (file)
@@ -5182,9 +5182,9 @@ void *__init alloc_large_system_hash(const char *tablename,
        if (!table)
                panic("Failed to allocate %s hash table\n", tablename);
 
-       printk(KERN_INFO "%s hash table entries: %d (order: %d, %lu bytes)\n",
+       printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
               tablename,
-              (1U << log2qty),
+              (1UL << log2qty),
               ilog2(size) - PAGE_SHIFT,
               size);
 
index 58c572b18b07ffbca4e2120d4e1600705db5fc0e..c76ef3891e0da1c71ac3d1b2d4b1db0abdfe8b9f 100644 (file)
@@ -1401,9 +1401,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 
                        if (pcpu_first_unit_cpu == NR_CPUS)
                                pcpu_first_unit_cpu = cpu;
+                       pcpu_last_unit_cpu = cpu;
                }
        }
-       pcpu_last_unit_cpu = cpu;
        pcpu_nr_units = unit;
 
        for_each_possible_cpu(cpu)
index f6f0d2dda2eae8480860cf57f5a9cfce69820716..92e6757f196ed4e3b3598c1f8b7214616a4cbe39 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -381,7 +381,13 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
        if (PageAnon(page)) {
-               if (vma->anon_vma->root != page_anon_vma(page)->root)
+               struct anon_vma *page__anon_vma = page_anon_vma(page);
+               /*
+                * Note: swapoff's unuse_vma() is more efficient with this
+                * check, and needs it to match anon_vma when KSM is active.
+                */
+               if (!vma->anon_vma || !page__anon_vma ||
+                   vma->anon_vma->root != page__anon_vma->root)
                        return -EFAULT;
        } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
                if (!vma->vm_file ||
@@ -1564,13 +1570,14 @@ static void __hugepage_set_anon_rmap(struct page *page,
        struct vm_area_struct *vma, unsigned long address, int exclusive)
 {
        struct anon_vma *anon_vma = vma->anon_vma;
+
        BUG_ON(!anon_vma);
-       if (!exclusive) {
-               struct anon_vma_chain *avc;
-               avc = list_entry(vma->anon_vma_chain.prev,
-                                struct anon_vma_chain, same_vma);
-               anon_vma = avc->anon_vma;
-       }
+
+       if (PageAnon(page))
+               return;
+       if (!exclusive)
+               anon_vma = anon_vma->root;
+
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
        page->mapping = (struct address_space *) anon_vma;
        page->index = linear_page_index(vma, address);
@@ -1581,6 +1588,8 @@ void hugepage_add_anon_rmap(struct page *page,
 {
        struct anon_vma *anon_vma = vma->anon_vma;
        int first;
+
+       BUG_ON(!PageLocked(page));
        BUG_ON(!anon_vma);
        BUG_ON(address < vma->vm_start || address >= vma->vm_end);
        first = atomic_inc_and_test(&page->_mapcount);
index c391c320dbafcda04260923f36336891283b614f..c5dfabf25f115a34df8f9111843af28a8d58d906 100644 (file)
@@ -1804,12 +1804,11 @@ static void shrink_zone(int priority, struct zone *zone,
  * If a zone is deemed to be full of pinned pages then just give it a light
  * scan then give up on it.
  */
-static bool shrink_zones(int priority, struct zonelist *zonelist,
+static void shrink_zones(int priority, struct zonelist *zonelist,
                                        struct scan_control *sc)
 {
        struct zoneref *z;
        struct zone *zone;
-       bool all_unreclaimable = true;
 
        for_each_zone_zonelist_nodemask(zone, z, zonelist,
                                        gfp_zone(sc->gfp_mask), sc->nodemask) {
@@ -1827,8 +1826,38 @@ static bool shrink_zones(int priority, struct zonelist *zonelist,
                }
 
                shrink_zone(priority, zone, sc);
-               all_unreclaimable = false;
        }
+}
+
+static bool zone_reclaimable(struct zone *zone)
+{
+       return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
+}
+
+/*
+ * As hibernation is going on, kswapd is freezed so that it can't mark
+ * the zone into all_unreclaimable. It can't handle OOM during hibernation.
+ * So let's check zone's unreclaimable in direct reclaim as well as kswapd.
+ */
+static bool all_unreclaimable(struct zonelist *zonelist,
+               struct scan_control *sc)
+{
+       struct zoneref *z;
+       struct zone *zone;
+       bool all_unreclaimable = true;
+
+       for_each_zone_zonelist_nodemask(zone, z, zonelist,
+                       gfp_zone(sc->gfp_mask), sc->nodemask) {
+               if (!populated_zone(zone))
+                       continue;
+               if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
+                       continue;
+               if (zone_reclaimable(zone)) {
+                       all_unreclaimable = false;
+                       break;
+               }
+       }
+
        return all_unreclaimable;
 }
 
@@ -1852,7 +1881,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
                                        struct scan_control *sc)
 {
        int priority;
-       bool all_unreclaimable;
        unsigned long total_scanned = 0;
        struct reclaim_state *reclaim_state = current->reclaim_state;
        struct zoneref *z;
@@ -1869,7 +1897,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
                sc->nr_scanned = 0;
                if (!priority)
                        disable_swap_token();
-               all_unreclaimable = shrink_zones(priority, zonelist, sc);
+               shrink_zones(priority, zonelist, sc);
                /*
                 * Don't shrink slabs when reclaiming memory from
                 * over limit cgroups
@@ -1931,7 +1959,7 @@ out:
                return sc->nr_reclaimed;
 
        /* top priority shrink_zones still had more to do? don't OOM, then */
-       if (scanning_global_lru(sc) && !all_unreclaimable)
+       if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
                return 1;
 
        return 0;
@@ -2197,8 +2225,7 @@ loop_again:
                        total_scanned += sc.nr_scanned;
                        if (zone->all_unreclaimable)
                                continue;
-                       if (nr_slab == 0 &&
-                           zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6))
+                       if (nr_slab == 0 && !zone_reclaimable(zone))
                                zone->all_unreclaimable = 1;
                        /*
                         * If we've done a decent amount of scanning and
index 01ddb0472f86c511f49ff8a602a726dd60550ff0..0eb96f7e44befb0155e364749f38eb37af0c2354 100644 (file)
@@ -24,8 +24,11 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 
        if (vlan_dev)
                skb->dev = vlan_dev;
-       else if (vlan_id)
-               goto drop;
+       else if (vlan_id) {
+               if (!(skb->dev->flags & IFF_PROMISC))
+                       goto drop;
+               skb->pkt_type = PACKET_OTHERHOST;
+       }
 
        return (polling ? netif_receive_skb(skb) : netif_rx(skb));
 
@@ -102,8 +105,11 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 
        if (vlan_dev)
                skb->dev = vlan_dev;
-       else if (vlan_id)
-               goto drop;
+       else if (vlan_id) {
+               if (!(skb->dev->flags & IFF_PROMISC))
+                       goto drop;
+               skb->pkt_type = PACKET_OTHERHOST;
+       }
 
        for (p = napi->gro_list; p; p = p->next) {
                NAPI_GRO_CB(p)->same_flow =
index dc6f2f26d0230b1462ea1ea583c6fda5dc5b49c5..9eb72505308fc697d2857737f8dd3f4ec04d5bd3 100644 (file)
@@ -331,8 +331,10 @@ static void p9_tag_cleanup(struct p9_client *c)
                }
        }
 
-       if (c->tagpool)
+       if (c->tagpool) {
+               p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
                p9_idpool_destroy(c->tagpool);
+       }
 
        /* free requests associated with tags */
        for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
@@ -944,6 +946,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
        int16_t nwqids, count;
 
        err = 0;
+       wqids = NULL;
        clnt = oldfid->clnt;
        if (clone) {
                fid = p9_fid_create(clnt);
@@ -994,9 +997,11 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
        else
                fid->qid = oldfid->qid;
 
+       kfree(wqids);
        return fid;
 
 clunk_fid:
+       kfree(wqids);
        p9_client_clunk(fid);
        fid = NULL;
 
index 0ea20c30466c7b5758e419fd51c3cba70c9797d7..17c5ba7551a55e79c2c38e22a8fe2fdaa8e00979 100644 (file)
@@ -426,8 +426,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
 
        /* Allocate an fcall for the reply */
        rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL);
-       if (!rpl_context)
+       if (!rpl_context) {
+               err = -ENOMEM;
                goto err_close;
+       }
 
        /*
         * If the request has a buffer, steal it, otherwise
@@ -445,8 +447,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
        }
        rpl_context->rc = req->rc;
        if (!rpl_context->rc) {
-               kfree(rpl_context);
-               goto err_close;
+               err = -ENOMEM;
+               goto err_free2;
        }
 
        /*
@@ -458,11 +460,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
         */
        if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
                err = post_recv(client, rpl_context);
-               if (err) {
-                       kfree(rpl_context->rc);
-                       kfree(rpl_context);
-                       goto err_close;
-               }
+               if (err)
+                       goto err_free1;
        } else
                atomic_dec(&rdma->rq_count);
 
@@ -471,8 +470,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
 
        /* Post the request */
        c = kmalloc(sizeof *c, GFP_KERNEL);
-       if (!c)
-               goto err_close;
+       if (!c) {
+               err = -ENOMEM;
+               goto err_free1;
+       }
        c->req = req;
 
        c->busa = ib_dma_map_single(rdma->cm_id->device,
@@ -499,9 +500,15 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
        return ib_post_send(rdma->qp, &wr, &bad_wr);
 
  error:
+       kfree(c);
+       kfree(rpl_context->rc);
+       kfree(rpl_context);
        P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
        return -EIO;
-
+ err_free1:
+       kfree(rpl_context->rc);
+ err_free2:
+       kfree(rpl_context);
  err_close:
        spin_lock_irqsave(&rdma->req_lock, flags);
        if (rdma->state < P9_RDMA_CLOSING) {
index dcfbe99ff81c8c0ac56031e1cbbd56bb7ed2fcd4..b88515936e4b3310741e6beefac62376bfe9d832 100644 (file)
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 
        mutex_lock(&virtio_9p_lock);
        list_for_each_entry(chan, &virtio_chan_list, chan_list) {
-               if (!strncmp(devname, chan->tag, chan->tag_len)) {
+               if (!strncmp(devname, chan->tag, chan->tag_len) &&
+                   strlen(devname) == chan->tag_len) {
                        if (!chan->inuse) {
                                chan->inuse = true;
                                found = 1;
index e330594d3709e6d382b2e5168cea989127793aa1..e926884c1675c04c3d150ddc83eaa89f91a0cb4a 100644 (file)
@@ -217,7 +217,7 @@ source "net/dns_resolver/Kconfig"
 
 config RPS
        boolean
-       depends on SMP && SYSFS
+       depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
        default y
 
 menu "Network testing"
index 651babdfab3845ebd11eb6cc89fe85eae1d3f8ca..ad2b232a2055fbc241828832078087c62e4c4315 100644 (file)
@@ -399,12 +399,6 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
                        unregister_netdev(net_dev);
                        free_netdev(net_dev);
                }
-               read_lock_irq(&devs_lock);
-               if (list_empty(&br2684_devs)) {
-                       /* last br2684 device */
-                       unregister_atmdevice_notifier(&atm_dev_notifier);
-               }
-               read_unlock_irq(&devs_lock);
                return;
        }
 
@@ -675,7 +669,6 @@ static int br2684_create(void __user *arg)
 
        if (list_empty(&br2684_devs)) {
                /* 1st br2684 device */
-               register_atmdevice_notifier(&atm_dev_notifier);
                brdev->number = 1;
        } else
                brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
@@ -815,6 +808,7 @@ static int __init br2684_init(void)
                return -ENOMEM;
 #endif
        register_atm_ioctl(&br2684_ioctl_ops);
+       register_atmdevice_notifier(&atm_dev_notifier);
        return 0;
 }
 
@@ -830,9 +824,7 @@ static void __exit br2684_exit(void)
 #endif
 
 
-       /* if not already empty */
-       if (!list_empty(&br2684_devs))
-               unregister_atmdevice_notifier(&atm_dev_notifier);
+       unregister_atmdevice_notifier(&atm_dev_notifier);
 
        while (!list_empty(&br2684_devs)) {
                net_dev = list_entry_brdev(br2684_devs.next);
index 622b471e14e03dbc3752697851022a59aebffbe0..74bcc662c3dd8c5e7ec33a393560cc9bbf313b57 100644 (file)
@@ -778,7 +778,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
        eg->packets_rcvd++;
        mpc->eg_ops->put(eg);
 
-       memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
+       memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data));
        netif_rx(new_skb);
 }
 
index fadf26b4ed7c432eba09800b4532683fc44cc02d..0b54b7dd84010a52147a54155c4f8db2b61752a7 100644 (file)
@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
 
 static void l2cap_streaming_send(struct sock *sk)
 {
-       struct sk_buff *skb, *tx_skb;
+       struct sk_buff *skb;
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        u16 control, fcs;
 
-       while ((skb = sk->sk_send_head)) {
-               tx_skb = skb_clone(skb, GFP_ATOMIC);
-
-               control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+       while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
+               control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
                control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
-               put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+               put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
 
                if (pi->fcs == L2CAP_FCS_CRC16) {
-                       fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
-                       put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
+                       fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
+                       put_unaligned_le16(fcs, skb->data + skb->len - 2);
                }
 
-               l2cap_do_send(sk, tx_skb);
+               l2cap_do_send(sk, skb);
 
                pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
-
-               if (skb_queue_is_last(TX_QUEUE(sk), skb))
-                       sk->sk_send_head = NULL;
-               else
-                       sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
-
-               skb = skb_dequeue(TX_QUEUE(sk));
-               kfree_skb(skb);
        }
 }
 
@@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 
        switch (optname) {
        case L2CAP_OPTIONS:
+               if (sk->sk_state == BT_CONNECTED) {
+                       err = -EINVAL;
+                       break;
+               }
+
                opts.imtu     = l2cap_pi(sk)->imtu;
                opts.omtu     = l2cap_pi(sk)->omtu;
                opts.flush_to = l2cap_pi(sk)->flush_to;
@@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
                case L2CAP_CONF_MTU:
                        if (val < L2CAP_DEFAULT_MIN_MTU) {
                                *result = L2CAP_CONF_UNACCEPT;
-                               pi->omtu = L2CAP_DEFAULT_MIN_MTU;
+                               pi->imtu = L2CAP_DEFAULT_MIN_MTU;
                        } else
-                               pi->omtu = val;
-                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+                               pi->imtu = val;
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
                        break;
 
                case L2CAP_CONF_FLUSH_TO:
@@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
        return 0;
 }
 
+static inline void set_default_fcs(struct l2cap_pinfo *pi)
+{
+       /* FCS is enabled only in ERTM or streaming mode, if one or both
+        * sides request it.
+        */
+       if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
+               pi->fcs = L2CAP_FCS_NONE;
+       else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
+               pi->fcs = L2CAP_FCS_CRC16;
+}
+
 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
        struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (!sk)
                return -ENOENT;
 
-       if (sk->sk_state != BT_CONFIG) {
-               struct l2cap_cmd_rej rej;
-
-               rej.reason = cpu_to_le16(0x0002);
-               l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
-                               sizeof(rej), &rej);
+       if (sk->sk_state == BT_DISCONN)
                goto unlock;
-       }
 
        /* Reject if config buffer is too small. */
        len = cmd_len - sizeof(*req);
@@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
                goto unlock;
 
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-               if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
-                   l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
-                       l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
+               set_default_fcs(l2cap_pi(sk));
 
                sk->sk_state = BT_CONNECTED;
 
@@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-               if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
-                   l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
-                       l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
+               set_default_fcs(l2cap_pi(sk));
 
                sk->sk_state = BT_CONNECTED;
                l2cap_pi(sk)->next_tx_seq = 0;
index 44a623275951e4b481abf1942fb2587867891dca..194b3a04cfd38a3b4a13817d5aecace4f355ea49 100644 (file)
@@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
 static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
 {
        struct sock *sk = d->owner, *parent;
+       unsigned long flags;
+
        if (!sk)
                return;
 
        BT_DBG("dlc %p state %ld err %d", d, d->state, err);
 
+       local_irq_save(flags);
        bh_lock_sock(sk);
 
        if (err)
@@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
        }
 
        bh_unlock_sock(sk);
+       local_irq_restore(flags);
 
        if (parent && sock_flag(sk, SOCK_ZAPPED)) {
                /* We have to drop DLC lock here, otherwise
index 8ce9047861166740a17a2448cb1d4f668fba1d21..4bf28f25f368b399a6ef220e06c08c0f5d2621f5 100644 (file)
@@ -827,6 +827,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
        long timeo;
        int err;
        int ifindex, headroom, tailroom;
+       unsigned int mtu;
        struct net_device *dev;
 
        lock_sock(sk);
@@ -896,15 +897,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
                cf_sk->sk.sk_state = CAIF_DISCONNECTED;
                goto out;
        }
-       dev = dev_get_by_index(sock_net(sk), ifindex);
+
+       err = -ENODEV;
+       rcu_read_lock();
+       dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
+       if (!dev) {
+               rcu_read_unlock();
+               goto out;
+       }
        cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom);
+       mtu = dev->mtu;
+       rcu_read_unlock();
+
        cf_sk->tailroom = tailroom;
-       cf_sk->maxframe = dev->mtu - (headroom + tailroom);
-       dev_put(dev);
+       cf_sk->maxframe = mtu - (headroom + tailroom);
        if (cf_sk->maxframe < 1) {
-               pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n",
-                       __func__, dev->mtu);
-               err = -ENODEV;
+               pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n",
+                          __func__, mtu);
                goto out;
        }
 
index b9b22a3c4c8fa36ea3412e22a816d0c738562831..660dd41aaaa6629c0d59547e04d23353ba935af8 100644 (file)
@@ -4845,7 +4845,7 @@ static void rollback_registered_many(struct list_head *head)
        dev = list_first_entry(head, struct net_device, unreg_list);
        call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
 
-       synchronize_net();
+       rcu_barrier();
 
        list_for_each_entry(dev, head, unreg_list)
                dev_put(dev);
index 7a85367b3c2f8010af24bbd6b6f4249698f9d78d..8451ab481095fc523c47fa01ccb11392b15dbc30 100644 (file)
@@ -348,7 +348,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
        if (info.cmd == ETHTOOL_GRXCLSRLALL) {
                if (info.rule_cnt > 0) {
                        if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
-                               rule_buf = kmalloc(info.rule_cnt * sizeof(u32),
+                               rule_buf = kzalloc(info.rule_cnt * sizeof(u32),
                                                   GFP_USER);
                        if (!rule_buf)
                                return -ENOMEM;
@@ -397,7 +397,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
            (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index))
                return -ENOMEM;
        full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size;
-       indir = kmalloc(full_size, GFP_USER);
+       indir = kzalloc(full_size, GFP_USER);
        if (!indir)
                return -ENOMEM;
 
@@ -538,7 +538,7 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
 
        gstrings.len = ret;
 
-       data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
+       data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
        if (!data)
                return -ENOMEM;
 
@@ -775,7 +775,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
        if (regs.len > reglen)
                regs.len = reglen;
 
-       regbuf = kmalloc(reglen, GFP_USER);
+       regbuf = kzalloc(reglen, GFP_USER);
        if (!regbuf)
                return -ENOMEM;
 
index 1cd98df412dfd52daee9cc9105ceddfea0d87a59..e6b133b77ccb5615d65bcdac0ecc01b759808c76 100644 (file)
  *     in any case.
  */
 
-int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
+long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
 {
-       int size, err, ct;
+       int size, ct;
+       long err;
 
        if (m->msg_namelen) {
                if (mode == VERIFY_READ) {
index b05b9b6ddb8700989e63e8597f6946ffd205bdba..ef30e9d286e703cccaffbd5ee10394cc167fe057 100644 (file)
@@ -1351,9 +1351,9 @@ int sock_i_uid(struct sock *sk)
 {
        int uid;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0;
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
        return uid;
 }
 EXPORT_SYMBOL(sock_i_uid);
@@ -1362,9 +1362,9 @@ unsigned long sock_i_ino(struct sock *sk)
 {
        unsigned long ino;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
        return ino;
 }
 EXPORT_SYMBOL(sock_i_ino);
index d959e0f41528ce71d69f4aafea0f6d028d72607a..f5df85dcd20bc7f790aec8f58967f55e02586444 100644 (file)
@@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
 
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                sk->sk_write_pending++;
-               sk_wait_event(sk, &current_timeo, !sk->sk_err &&
-                                                 !(sk->sk_shutdown & SEND_SHUTDOWN) &&
-                                                 sk_stream_memory_free(sk) &&
-                                                 vm_wait);
+               sk_wait_event(sk, &current_timeo, sk->sk_err ||
+                                                 (sk->sk_shutdown & SEND_SHUTDOWN) ||
+                                                 (sk_stream_memory_free(sk) &&
+                                                 !vm_wait));
                sk->sk_write_pending--;
 
                if (vm_wait) {
index 571f8950ed06f585f4dca482037d4b7985c256af..7cd7760144f7dd1998276f4e2976e4a4a1c8135d 100644 (file)
@@ -217,6 +217,7 @@ config NET_IPIP
 
 config NET_IPGRE
        tristate "IP: GRE tunnels over IP"
+       depends on IPV6 || IPV6=n
        help
          Tunneling means encapsulating data of one protocol type within
          another protocol and sending it over a channel that understands the
@@ -412,7 +413,7 @@ config INET_XFRM_MODE_BEET
          If unsure, say Y.
 
 config INET_LRO
-       bool "Large Receive Offload (ipv4/tcp)"
+       tristate "Large Receive Offload (ipv4/tcp)"
        default y
        ---help---
          Support for Large Receive Offload (ipv4/tcp).
index a1ad0e7180d2bd7051df4f78bed75fbb7612da40..2a4bb76f2132957da25326ce98653b249d9ccaaf 100644 (file)
@@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                igmpv3_clear_delrec(in_dev);
        } else if (len < 12) {
                return; /* ignore bogus packet; freed by caller */
+       } else if (IGMP_V1_SEEN(in_dev)) {
+               /* This is a v3 query with v1 queriers present */
+               max_delay = IGMP_Query_Response_Interval;
+               group = 0;
+       } else if (IGMP_V2_SEEN(in_dev)) {
+               /* this is a v3 query with v2 queriers present;
+                * Interpretation of the max_delay code is problematic here.
+                * A real v2 host would use ih_code directly, while v3 has a
+                * different encoding. We use the v3 encoding as more likely
+                * to be intended in a v3 query.
+                */
+               max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
        } else { /* v3 */
                if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
                        return;
index 945b20a5ad5006b6a8ebf84b22756f7573436c1f..35c93e8b6a4694561c838641e546b609e8cbfaa0 100644 (file)
@@ -45,7 +45,7 @@
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
 
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 #include <net/ip6_route.h>
@@ -699,7 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
                        if ((dst = rt->rt_gateway) == 0)
                                goto tx_error_icmp;
                }
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                else if (skb->protocol == htons(ETH_P_IPV6)) {
                        struct in6_addr *addr6;
                        int addr_type;
@@ -774,7 +774,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
                        goto tx_error;
                }
        }
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        else if (skb->protocol == htons(ETH_P_IPV6)) {
                struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
 
@@ -850,7 +850,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
        if ((iph->ttl = tiph->ttl) == 0) {
                if (skb->protocol == htons(ETH_P_IP))
                        iph->ttl = old_iph->ttl;
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                else if (skb->protocol == htons(ETH_P_IPV6))
                        iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
 #endif
index 04b69896df5fc743021efd4d4a1705b7de146333..7649d7750075d184896a9da6d37ed9a35ea5f403 100644 (file)
@@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
         * we can switch to copy when see the first bad fragment.
         */
        if (skb_has_frags(skb)) {
-               struct sk_buff *frag;
+               struct sk_buff *frag, *frag2;
                int first_len = skb_pagelen(skb);
-               int truesizes = 0;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
@@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                        if (frag->len > mtu ||
                            ((frag->len & 7) && frag->next) ||
                            skb_headroom(frag) < hlen)
-                           goto slow_path;
+                               goto slow_path_clean;
 
                        /* Partially cloned skb? */
                        if (skb_shared(frag))
-                               goto slow_path;
+                               goto slow_path_clean;
 
                        BUG_ON(frag->sk);
                        if (skb->sk) {
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
                        }
-                       truesizes += frag->truesize;
+                       skb->truesize -= frag->truesize;
                }
 
                /* Everything is OK. Generate! */
@@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                frag = skb_shinfo(skb)->frag_list;
                skb_frag_list_init(skb);
                skb->data_len = first_len - skb_headlen(skb);
-               skb->truesize -= truesizes;
                skb->len = first_len;
                iph->tot_len = htons(first_len);
                iph->frag_off = htons(IP_MF);
@@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                }
                IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
                return err;
+
+slow_path_clean:
+               skb_walk_frags(skb, frag2) {
+                       if (frag2 == frag)
+                               break;
+                       frag2->sk = NULL;
+                       frag2->destructor = NULL;
+                       skb->truesize += frag2->truesize;
+               }
        }
 
 slow_path:
index 6c40a8c46e7984843275af12bfbac9a241e8e4c6..64b70ad162e370dbeb5b60adda5dd811182fc0f5 100644 (file)
@@ -1129,6 +1129,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_HDRINCL:
                val = inet->hdrincl;
                break;
+       case IP_NODEFRAG:
+               val = inet->nodefrag;
+               break;
        case IP_MTU_DISCOVER:
                val = inet->pmtudisc;
                break;
index b254dafaf4294548b7d36d9b54ce29832f8658e3..43eec80c0e7c55a2f6dc20790a30603236b7d93f 100644 (file)
@@ -112,6 +112,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        /* ip_route_me_harder expects skb->dst to be set */
        skb_dst_set_noref(nskb, skb_dst(oldskb));
 
+       nskb->protocol = htons(ETH_P_IP);
        if (ip_route_me_harder(nskb, addr_type))
                goto free_nskb;
 
index eab8de32f200af74828bbf0fb3187ff578451e9b..f3a9b42b16c620a7f569e00039beea13bc75bc3c 100644 (file)
@@ -66,9 +66,11 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
                                          const struct net_device *out,
                                          int (*okfn)(struct sk_buff *))
 {
+       struct sock *sk = skb->sk;
        struct inet_sock *inet = inet_sk(skb->sk);
 
-       if (inet && inet->nodefrag)
+       if (sk && (sk->sk_family == PF_INET) &&
+           inet->nodefrag)
                return NF_ACCEPT;
 
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
index 1679e2c0963d9b83e34f1f8d6a34b7702a603e2c..ee5f419d0a56d01c6533d6ee45f70a7405480150 100644 (file)
@@ -893,13 +893,15 @@ static void fast_csum(__sum16 *csum,
        unsigned char s[4];
 
        if (offset & 1) {
-               s[0] = s[2] = 0;
+               s[0] = ~0;
                s[1] = ~*optr;
+               s[2] = 0;
                s[3] = *nptr;
        } else {
-               s[1] = s[3] = 0;
                s[0] = ~*optr;
+               s[1] = ~0;
                s[2] = *nptr;
+               s[3] = 0;
        }
 
        *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
index 6298f75d5e93c4ad4e838a1982143207e7d3f855..ac6559cb54f9f650986e4dd86996349e328cd92a 100644 (file)
@@ -1231,7 +1231,7 @@ restart:
                        }
 
                        if (net_ratelimit())
-                               printk(KERN_WARNING "Neighbour table overflow.\n");
+                               printk(KERN_WARNING "ipv4: Neighbour table overflow.\n");
                        rt_drop(rt);
                        return -ENOBUFS;
                }
index 3fb1428e526eedb521057a49624fa28dde8b41cd..f115ea68a4efa264c59b20f61222db97a6050a9d 100644 (file)
@@ -386,8 +386,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
         */
 
        mask = 0;
-       if (sk->sk_err)
-               mask = POLLERR;
 
        /*
         * POLLHUP is certainly not done right. But poll() doesn't
@@ -457,6 +455,11 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                if (tp->urg_data & TCP_URG_VALID)
                        mask |= POLLPRI;
        }
+       /* This barrier is coupled with smp_wmb() in tcp_reset() */
+       smp_rmb();
+       if (sk->sk_err)
+               mask |= POLLERR;
+
        return mask;
 }
 EXPORT_SYMBOL(tcp_poll);
@@ -940,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        sg = sk->sk_route_caps & NETIF_F_SG;
 
        while (--iovlen >= 0) {
-               int seglen = iov->iov_len;
+               size_t seglen = iov->iov_len;
                unsigned char __user *from = iov->iov_base;
 
                iov++;
index e663b78a2ef6b6286b549aa65b418fe385f32184..b55f60f6fcbe934c1364ee3aece309dff4d1be4b 100644 (file)
@@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
                        cnt += tcp_skb_pcount(skb);
 
                if (cnt > packets) {
-                       if (tcp_is_sack(tp) || (oldcnt >= packets))
+                       if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) ||
+                           (oldcnt >= packets))
                                break;
 
                        mss = skb_shinfo(skb)->gso_size;
@@ -4048,6 +4049,8 @@ static void tcp_reset(struct sock *sk)
        default:
                sk->sk_err = ECONNRESET;
        }
+       /* This barrier is coupled with smp_rmb() in tcp_poll() */
+       smp_wmb();
 
        if (!sock_flag(sk, SOCK_DEAD))
                sk->sk_error_report(sk);
index c35b469e851c298814d69583bd593ec1c580dde5..74c54b30600f618522e07581c43130eea031f2db 100644 (file)
@@ -135,13 +135,16 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
 
 /* This function calculates a "timeout" which is equivalent to the timeout of a
  * TCP connection after "boundary" unsuccessful, exponentially backed-off
- * retransmissions with an initial RTO of TCP_RTO_MIN.
+ * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if
+ * syn_set flag is set.
  */
 static bool retransmits_timed_out(struct sock *sk,
-                                 unsigned int boundary)
+                                 unsigned int boundary,
+                                 bool syn_set)
 {
        unsigned int timeout, linear_backoff_thresh;
        unsigned int start_ts;
+       unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN;
 
        if (!inet_csk(sk)->icsk_retransmits)
                return false;
@@ -151,12 +154,12 @@ static bool retransmits_timed_out(struct sock *sk,
        else
                start_ts = tcp_sk(sk)->retrans_stamp;
 
-       linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
+       linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
 
        if (boundary <= linear_backoff_thresh)
-               timeout = ((2 << boundary) - 1) * TCP_RTO_MIN;
+               timeout = ((2 << boundary) - 1) * rto_base;
        else
-               timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN +
+               timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
                          (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
 
        return (tcp_time_stamp - start_ts) >= timeout;
@@ -167,14 +170,15 @@ static int tcp_write_timeout(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        int retry_until;
-       bool do_reset;
+       bool do_reset, syn_set = 0;
 
        if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
                if (icsk->icsk_retransmits)
                        dst_negative_advice(sk);
                retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
+               syn_set = 1;
        } else {
-               if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
+               if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) {
                        /* Black hole detection */
                        tcp_mtu_probing(icsk, sk);
 
@@ -187,14 +191,14 @@ static int tcp_write_timeout(struct sock *sk)
 
                        retry_until = tcp_orphan_retries(sk, alive);
                        do_reset = alive ||
-                                  !retransmits_timed_out(sk, retry_until);
+                                  !retransmits_timed_out(sk, retry_until, 0);
 
                        if (tcp_out_of_resources(sk, do_reset))
                                return 1;
                }
        }
 
-       if (retransmits_timed_out(sk, retry_until)) {
+       if (retransmits_timed_out(sk, retry_until, syn_set)) {
                /* Has it gone just too far? */
                tcp_write_err(sk);
                return 1;
@@ -436,7 +440,7 @@ out_reset_timer:
                icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
        }
        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
-       if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1))
+       if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0))
                __sk_dst_reset(sk);
 
 out:;
index 869078d4eeb957a4982ab62e5d408e8fbf42117c..a580349f0b8ab53c77b04b00d504de0bf1f83e09 100644 (file)
@@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *net,
 
 static int xfrm4_get_tos(struct flowi *fl)
 {
-       return fl->fl4_tos;
+       return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */
 }
 
 static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
index 1ef1366a0a03775eed25ab5ef0b083aed593726e..47947624eccc58fe7fcfcdbff19fb655a07ddedc 100644 (file)
@@ -21,21 +21,25 @@ static int xfrm4_init_flags(struct xfrm_state *x)
 }
 
 static void
-__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
-                    struct xfrm_tmpl *tmpl,
-                    xfrm_address_t *daddr, xfrm_address_t *saddr)
+__xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl)
+{
+       sel->daddr.a4 = fl->fl4_dst;
+       sel->saddr.a4 = fl->fl4_src;
+       sel->dport = xfrm_flowi_dport(fl);
+       sel->dport_mask = htons(0xffff);
+       sel->sport = xfrm_flowi_sport(fl);
+       sel->sport_mask = htons(0xffff);
+       sel->family = AF_INET;
+       sel->prefixlen_d = 32;
+       sel->prefixlen_s = 32;
+       sel->proto = fl->proto;
+       sel->ifindex = fl->oif;
+}
+
+static void
+xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
+                  xfrm_address_t *daddr, xfrm_address_t *saddr)
 {
-       x->sel.daddr.a4 = fl->fl4_dst;
-       x->sel.saddr.a4 = fl->fl4_src;
-       x->sel.dport = xfrm_flowi_dport(fl);
-       x->sel.dport_mask = htons(0xffff);
-       x->sel.sport = xfrm_flowi_sport(fl);
-       x->sel.sport_mask = htons(0xffff);
-       x->sel.family = AF_INET;
-       x->sel.prefixlen_d = 32;
-       x->sel.prefixlen_s = 32;
-       x->sel.proto = fl->proto;
-       x->sel.ifindex = fl->oif;
        x->id = tmpl->id;
        if (x->id.daddr.a4 == 0)
                x->id.daddr.a4 = daddr->a4;
@@ -70,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
        .owner                  = THIS_MODULE,
        .init_flags             = xfrm4_init_flags,
        .init_tempsel           = __xfrm4_init_tempsel,
+       .init_temprop           = xfrm4_init_temprop,
        .output                 = xfrm4_output,
        .extract_input          = xfrm4_extract_input,
        .extract_output         = xfrm4_extract_output,
index ab70a3fbcafafee9a080ea0f8c6eab2ce04fc37e..324fac3b6c16db0238d1139649038bcaa9aaced2 100644 (file)
@@ -4637,10 +4637,12 @@ int __init addrconf_init(void)
        if (err < 0) {
                printk(KERN_CRIT "IPv6 Addrconf:"
                       " cannot initialize default policy table: %d.\n", err);
-               return err;
+               goto out;
        }
 
-       register_pernet_subsys(&addrconf_ops);
+       err = register_pernet_subsys(&addrconf_ops);
+       if (err < 0)
+               goto out_addrlabel;
 
        /* The addrconf netdev notifier requires that loopback_dev
         * has it's ipv6 private information allocated and setup
@@ -4692,7 +4694,9 @@ errout:
        unregister_netdevice_notifier(&ipv6_dev_notf);
 errlo:
        unregister_pernet_subsys(&addrconf_ops);
-
+out_addrlabel:
+       ipv6_addr_label_cleanup();
+out:
        return err;
 }
 
@@ -4703,6 +4707,7 @@ void addrconf_cleanup(void)
 
        unregister_netdevice_notifier(&ipv6_dev_notf);
        unregister_pernet_subsys(&addrconf_ops);
+       ipv6_addr_label_cleanup();
 
        rtnl_lock();
 
index f0e774cea386696a72560d9306f441a46817a96d..8175f802651bec4481080823a73f60a21d3a2f36 100644 (file)
@@ -393,6 +393,11 @@ int __init ipv6_addr_label_init(void)
        return register_pernet_subsys(&ipv6_addr_label_ops);
 }
 
+void ipv6_addr_label_cleanup(void)
+{
+       unregister_pernet_subsys(&ipv6_addr_label_ops);
+}
+
 static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
        [IFAL_ADDRESS]          = { .len = sizeof(struct in6_addr), },
        [IFAL_LABEL]            = { .len = sizeof(u32), },
index d40b330c0ee698af62f51f90caf86b2e6cf04c9f..980912ed7a388bd2404b8cb934b2b61e67e12a6c 100644 (file)
@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
        if (skb_has_frags(skb)) {
                int first_len = skb_pagelen(skb);
-               int truesizes = 0;
+               struct sk_buff *frag2;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                        if (frag->len > mtu ||
                            ((frag->len & 7) && frag->next) ||
                            skb_headroom(frag) < hlen)
-                           goto slow_path;
+                               goto slow_path_clean;
 
                        /* Partially cloned skb? */
                        if (skb_shared(frag))
-                               goto slow_path;
+                               goto slow_path_clean;
 
                        BUG_ON(frag->sk);
                        if (skb->sk) {
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
-                               truesizes += frag->truesize;
                        }
+                       skb->truesize -= frag->truesize;
                }
 
                err = 0;
@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
                first_len = skb_pagelen(skb);
                skb->data_len = first_len - skb_headlen(skb);
-               skb->truesize -= truesizes;
                skb->len = first_len;
                ipv6_hdr(skb)->payload_len = htons(first_len -
                                                   sizeof(struct ipv6hdr));
@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                              IPSTATS_MIB_FRAGFAILS);
                dst_release(&rt->dst);
                return err;
+
+slow_path_clean:
+               skb_walk_frags(skb, frag2) {
+                       if (frag2 == frag)
+                               break;
+                       frag2->sk = NULL;
+                       frag2->destructor = NULL;
+                       skb->truesize += frag2->truesize;
+               }
        }
 
 slow_path:
index d126365ac0463bc075d62446562a8d9f07d548a2..a275c6e1e25c23884d7d1859e46a2ee82c00acef 100644 (file)
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
 
                        if (net_ratelimit())
                                printk(KERN_WARNING
-                                      "Neighbour table overflow.\n");
+                                      "ipv6: Neighbour table overflow.\n");
                        dst_free(&rt->dst);
                        return NULL;
                }
@@ -1556,14 +1556,13 @@ out:
  *     i.e. Path MTU discovery
  */
 
-void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
-                       struct net_device *dev, u32 pmtu)
+static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
+                            struct net *net, u32 pmtu, int ifindex)
 {
        struct rt6_info *rt, *nrt;
-       struct net *net = dev_net(dev);
        int allfrag = 0;
 
-       rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0);
+       rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
        if (rt == NULL)
                return;
 
@@ -1631,6 +1630,27 @@ out:
        dst_release(&rt->dst);
 }
 
+void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
+                       struct net_device *dev, u32 pmtu)
+{
+       struct net *net = dev_net(dev);
+
+       /*
+        * RFC 1981 states that a node "MUST reduce the size of the packets it
+        * is sending along the path" that caused the Packet Too Big message.
+        * Since it's not possible in the general case to determine which
+        * interface was used to send the original packet, we update the MTU
+        * on the interface that will be used to send future packets. We also
+        * update the MTU on the interface that received the Packet Too Big in
+        * case the original packet was forced out that interface with
+        * SO_BINDTODEVICE or similar. This is the next best thing to the
+        * correct behaviour, which would be to update the MTU on all
+        * interfaces.
+        */
+       rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
+       rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
+}
+
 /*
  *     Misc support functions
  */
index f417b77fa0e15762715a9498974fbd8f5071401d..a67575d472a320f306002a88959f0d0f9a73af09 100644 (file)
 #include <net/addrconf.h>
 
 static void
-__xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
-                    struct xfrm_tmpl *tmpl,
-                    xfrm_address_t *daddr, xfrm_address_t *saddr)
+__xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl)
 {
        /* Initialize temporary selector matching only
         * to current session. */
-       ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
-       ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
-       x->sel.dport = xfrm_flowi_dport(fl);
-       x->sel.dport_mask = htons(0xffff);
-       x->sel.sport = xfrm_flowi_sport(fl);
-       x->sel.sport_mask = htons(0xffff);
-       x->sel.family = AF_INET6;
-       x->sel.prefixlen_d = 128;
-       x->sel.prefixlen_s = 128;
-       x->sel.proto = fl->proto;
-       x->sel.ifindex = fl->oif;
+       ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst);
+       ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src);
+       sel->dport = xfrm_flowi_dport(fl);
+       sel->dport_mask = htons(0xffff);
+       sel->sport = xfrm_flowi_sport(fl);
+       sel->sport_mask = htons(0xffff);
+       sel->family = AF_INET6;
+       sel->prefixlen_d = 128;
+       sel->prefixlen_s = 128;
+       sel->proto = fl->proto;
+       sel->ifindex = fl->oif;
+}
+
+static void
+xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl,
+                  xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
        x->id = tmpl->id;
        if (ipv6_addr_any((struct in6_addr*)&x->id.daddr))
                memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr));
@@ -168,6 +172,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
        .eth_proto              = htons(ETH_P_IPV6),
        .owner                  = THIS_MODULE,
        .init_tempsel           = __xfrm6_init_tempsel,
+       .init_temprop           = xfrm6_init_temprop,
        .tmpl_sort              = __xfrm6_tmpl_sort,
        .state_sort             = __xfrm6_state_sort,
        .output                 = xfrm6_output,
index 023ba820236f391a01595418873b7c5e0df3ece8..582612998211d24aa8d4aea919eed1ba1e994db3 100644 (file)
@@ -1024,7 +1024,8 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
 {
        struct sock *sk = sock->sk;
        struct llc_sock *llc = llc_sk(sk);
-       int rc = -EINVAL, opt;
+       unsigned int opt;
+       int rc = -EINVAL;
 
        lock_sock(sk);
        if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
index e4dae0244d76b677ee89ef0b35dd51ccf7807e06..cf4aea3ba30f3c822be7a2c19a8fef87cdb8aadf 100644 (file)
@@ -689,7 +689,7 @@ static void llc_station_rcv(struct sk_buff *skb)
 
 int __init llc_station_init(void)
 {
-       u16 rc = -ENOBUFS;
+       int rc = -ENOBUFS;
        struct sk_buff *skb;
        struct llc_station_state_ev *ev;
 
index c893f236acea771076b5572b42c82162c3684913..8f23401832b7729d28c9e0791a78ce8acd797728 100644 (file)
@@ -175,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 
        set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
 
+       del_timer_sync(&tid_tx->addba_resp_timer);
+
        /*
         * After this packets are no longer handed right through
         * to the driver but are put onto tid_tx->pending instead,
index fa0f37e4afe4901226b0ccd668ae6a88c136eeb2..28624282c5f36ad5bed8f74c0e8bf7df42ee2d6c 100644 (file)
@@ -2199,9 +2199,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
        struct net_device *prev_dev = NULL;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 
-       if (status->flag & RX_FLAG_INTERNAL_CMTR)
-               goto out_free_skb;
-
        if (skb_headroom(skb) < sizeof(*rthdr) &&
            pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
                goto out_free_skb;
@@ -2260,7 +2257,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
        } else
                goto out_free_skb;
 
-       status->flag |= RX_FLAG_INTERNAL_CMTR;
        return;
 
  out_free_skb:
index 10caec5ea8fa7740d9617605adf1590eefa2a730..34da67995d94ae91c8982776fd3e9104c161079f 100644 (file)
@@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                                skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (skb2) {
                                        skb2->dev = prev_dev;
-                                       netif_receive_skb(skb2);
+                                       netif_rx(skb2);
                                }
                        }
 
@@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        }
        if (prev_dev) {
                skb->dev = prev_dev;
-               netif_receive_skb(skb);
+               netif_rx(skb);
                skb = NULL;
        }
        rcu_read_unlock();
index 7dcf7a404190e6aa3fa06e642f54279e2f30fba9..8d9e4c949b9618eafc4a7b301d305a15cab805b6 100644 (file)
@@ -48,15 +48,17 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
 {
        unsigned int off, len;
        struct nf_ct_ext_type *t;
+       size_t alloc_size;
 
        rcu_read_lock();
        t = rcu_dereference(nf_ct_ext_types[id]);
        BUG_ON(t == NULL);
        off = ALIGN(sizeof(struct nf_ct_ext), t->align);
        len = off + t->len;
+       alloc_size = t->alloc_size;
        rcu_read_unlock();
 
-       *ext = kzalloc(t->alloc_size, gfp);
+       *ext = kzalloc(alloc_size, gfp);
        if (!*ext)
                return NULL;
 
index 53d892210a049363fa3ab04f6e17b04fa9969bbe..f64de95448669242cf23ac5d8a38987c2f8cd344 100644 (file)
@@ -1376,7 +1376,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
        unsigned int msglen, origlen;
        const char *dptr, *end;
        s16 diff, tdiff = 0;
-       int ret;
+       int ret = NF_ACCEPT;
        typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
 
        if (ctinfo != IP_CT_ESTABLISHED &&
index 5490fc37c92dfa5363a2992fd67fd4f145f65360..daab8c4a903ca20103c1c5d6ebe997fdb657f581 100644 (file)
@@ -70,7 +70,11 @@ nf_tproxy_destructor(struct sk_buff *skb)
 int
 nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
 {
-       if (inet_sk(sk)->transparent) {
+       bool transparent = (sk->sk_state == TCP_TIME_WAIT) ?
+                               inet_twsk(sk)->tw_transparent :
+                               inet_sk(sk)->transparent;
+
+       if (transparent) {
                skb_orphan(skb);
                skb->sk = sk;
                skb->destructor = nf_tproxy_destructor;
index b2a3ae6cad78e28324e23b857dc0a5773f569786..15003021f4f0a8706e540150425b4f995dc582a6 100644 (file)
@@ -225,12 +225,13 @@ static void pipe_grant_credits(struct sock *sk)
 static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
 {
        struct pep_sock *pn = pep_sk(sk);
-       struct pnpipehdr *hdr = pnp_hdr(skb);
+       struct pnpipehdr *hdr;
        int wake = 0;
 
        if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
                return -EINVAL;
 
+       hdr = pnp_hdr(skb);
        if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
                LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
                                (unsigned)hdr->data[0]);
index c397524c039cdb28140ff5f6c0fe2359cebfa3b5..c519939e8da98fd3ae8252355a0ebb9efac4acd5 100644 (file)
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk)
        struct rds_connection *conn;
        struct rds_tcp_connection *tc;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        conn = sk->sk_user_data;
        if (conn == NULL) {
                state_change = sk->sk_state_change;
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk)
                        break;
        }
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
        state_change(sk);
 }
 
index 975183fe6950a34b242ef55db011e6f04c1c6772..27844f231d103a4e49e542d670eaca66d01e761d 100644 (file)
@@ -114,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
 
        rdsdebug("listen data ready sk %p\n", sk);
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        ready = sk->sk_user_data;
        if (ready == NULL) { /* check for teardown race */
                ready = sk->sk_data_ready;
@@ -131,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
                queue_work(rds_wq, &rds_tcp_listen_work);
 
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
        ready(sk, bytes);
 }
 
index 1aba6878fa5dc42d4c54473350fde61d714a184c..e43797404102efcc2ed45117456e839b5425adb1 100644 (file)
@@ -324,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
 
        rdsdebug("data ready sk %p bytes %d\n", sk, bytes);
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        conn = sk->sk_user_data;
        if (conn == NULL) { /* check for teardown race */
                ready = sk->sk_data_ready;
@@ -338,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
        if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
                queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
        ready(sk, bytes);
 }
 
index a28b895ff0d10194730463b218e3ccb526cdea50..2f012a07d94d16d3aa01d4c78d0894e939dfd751 100644 (file)
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk)
        struct rds_connection *conn;
        struct rds_tcp_connection *tc;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        conn = sk->sk_user_data;
        if (conn == NULL) {
                write_space = sk->sk_write_space;
@@ -244,7 +244,7 @@ void rds_tcp_write_space(struct sock *sk)
                queue_delayed_work(rds_wq, &conn->c_send_w, 0);
 
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 
        /*
         * write_space is only called when data leaves tcp's send queue if
index 8e45e76a95f51cdca332263ee7e32108f0beb95c..d952e7eac18867501a0bf7d2034c621c2fd08df7 100644 (file)
@@ -679,7 +679,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
                return -EINVAL;
 
-       if (addr->srose_ndigis > ROSE_MAX_DIGIS)
+       if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
                return -EINVAL;
 
        if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
@@ -739,7 +739,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
        if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1)
                return -EINVAL;
 
-       if (addr->srose_ndigis > ROSE_MAX_DIGIS)
+       if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
                return -EINVAL;
 
        /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */
index 7416a5c73b2a993550991ac66eca7cc254c6f2e6..b0c2a82178afa032ce1d09b0e9f400afb2b578f5 100644 (file)
@@ -137,7 +137,7 @@ next_knode:
                        int toff = off + key->off + (off2 & key->offmask);
                        __be32 *data, _data;
 
-                       if (skb_headroom(skb) + toff < 0)
+                       if (skb_headroom(skb) + toff > INT_MAX)
                                goto out;
 
                        data = skb_header_pointer(skb, toff, 4, &_data);
index 3406627895298324fdd9d27186ad8c9c8d9a9964..6318e1136b83de86f1b73150a0a5199522293f4f 100644 (file)
@@ -255,10 +255,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
                        error = -EINVAL;
                        goto err_out;
                }
-               if (!list_empty(&flow->list)) {
-                       error = -EEXIST;
-                       goto err_out;
-               }
        } else {
                int i;
                unsigned long cl;
index 86366390038a1cae0b536874fd037464f2a1678f..ddbbf7c81fa1d62adf50600b6c788d6769ff5d32 100644 (file)
@@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
                id = ntohs(hmacs->hmac_ids[i]);
 
                /* Check the id is in the supported range */
-               if (id > SCTP_AUTH_HMAC_ID_MAX)
+               if (id > SCTP_AUTH_HMAC_ID_MAX) {
+                       id = 0;
                        continue;
+               }
 
                /* See is we support the id.  Supported IDs have name and
                 * length fields set, so that we can allocated and use
                 * them.  We can safely just check for name, for without the
                 * name, we can't allocate the TFM.
                 */
-               if (!sctp_hmac_list[id].hmac_name)
+               if (!sctp_hmac_list[id].hmac_name) {
+                       id = 0;
                        continue;
+               }
 
                break;
        }
index a646681f5acdffe30cd7b5b2f06c3bbf413609a6..bcc4590ccaf21bb988a7827614f71a39ffa31318 100644 (file)
@@ -92,7 +92,6 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
        SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__,
                          packet, vtag);
 
-       sctp_packet_reset(packet);
        packet->vtag = vtag;
 
        if (ecn_capable && sctp_packet_empty(packet)) {
index ca44917872d2553b98f4e2f3601f95fe0f2c414f..fbb70770ad05d05807d25b5527e5616a621f58e8 100644 (file)
@@ -916,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
        /* Walk through the addrs buffer and count the number of addresses. */
        addr_buf = kaddrs;
        while (walk_size < addrs_size) {
+               if (walk_size + sizeof(sa_family_t) > addrs_size) {
+                       kfree(kaddrs);
+                       return -EINVAL;
+               }
+
                sa_addr = (struct sockaddr *)addr_buf;
                af = sctp_get_af_specific(sa_addr->sa_family);
 
@@ -1002,9 +1007,13 @@ static int __sctp_connect(struct sock* sk,
        /* Walk through the addrs buffer and count the number of addresses. */
        addr_buf = kaddrs;
        while (walk_size < addrs_size) {
+               if (walk_size + sizeof(sa_family_t) > addrs_size) {
+                       err = -EINVAL;
+                       goto out_free;
+               }
+
                sa_addr = (union sctp_addr *)addr_buf;
                af = sctp_get_af_specific(sa_addr->sa.sa_family);
-               port = ntohs(sa_addr->v4.sin_port);
 
                /* If the address family is not supported or if this address
                 * causes the address buffer to overflow return EINVAL.
@@ -1014,6 +1023,8 @@ static int __sctp_connect(struct sock* sk,
                        goto out_free;
                }
 
+               port = ntohs(sa_addr->v4.sin_port);
+
                /* Save current address so we can work with it */
                memcpy(&to, sa_addr, af->sockaddr_len);
 
index 36cb66022a279e96869de77c3c9cebbbe9824ff4..e9eaaf7d43c18104167692f801794bdacf89b97e 100644 (file)
@@ -38,7 +38,7 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
 static LIST_HEAD(cred_unused);
 static unsigned long number_cred_unused;
 
-#define MAX_HASHTABLE_BITS (10) 
+#define MAX_HASHTABLE_BITS (14)
 static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
 {
        unsigned long num;
index dcfc66bab2bb16f9872aca4adc6b258b55afe05a..12c4859828146cbdff7a0e9c38a039eaa3395426 100644 (file)
@@ -745,17 +745,18 @@ gss_pipe_release(struct inode *inode)
        struct rpc_inode *rpci = RPC_I(inode);
        struct gss_upcall_msg *gss_msg;
 
+restart:
        spin_lock(&inode->i_lock);
-       while (!list_empty(&rpci->in_downcall)) {
+       list_for_each_entry(gss_msg, &rpci->in_downcall, list) {
 
-               gss_msg = list_entry(rpci->in_downcall.next,
-                               struct gss_upcall_msg, list);
+               if (!list_empty(&gss_msg->msg.list))
+                       continue;
                gss_msg->msg.errno = -EPIPE;
                atomic_inc(&gss_msg->count);
                __gss_unhash_msg(gss_msg);
                spin_unlock(&inode->i_lock);
                gss_release_msg(gss_msg);
-               spin_lock(&inode->i_lock);
+               goto restart;
        }
        spin_unlock(&inode->i_lock);
 
index 032644610524306ea0e01383b3c4ea54888b10ab..778e5dfc5144910f83609b8bf48ca2a35011110d 100644 (file)
@@ -237,6 +237,7 @@ get_key(const void *p, const void *end,
        if (!supported_gss_krb5_enctype(alg)) {
                printk(KERN_WARNING "gss_kerberos_mech: unsupported "
                        "encryption key algorithm %d\n", alg);
+               p = ERR_PTR(-EINVAL);
                goto out_err;
        }
        p = simple_get_netobj(p, end, &key);
@@ -282,15 +283,19 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
        ctx->enctype = ENCTYPE_DES_CBC_RAW;
 
        ctx->gk5e = get_gss_krb5_enctype(ctx->enctype);
-       if (ctx->gk5e == NULL)
+       if (ctx->gk5e == NULL) {
+               p = ERR_PTR(-EINVAL);
                goto out_err;
+       }
 
        /* The downcall format was designed before we completely understood
         * the uses of the context fields; so it includes some stuff we
         * just give some minimal sanity-checking, and some we ignore
         * completely (like the next twenty bytes): */
-       if (unlikely(p + 20 > end || p + 20 < p))
+       if (unlikely(p + 20 > end || p + 20 < p)) {
+               p = ERR_PTR(-EFAULT);
                goto out_err;
+       }
        p += 20;
        p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
        if (IS_ERR(p))
@@ -619,6 +624,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
        if (ctx->seq_send64 != ctx->seq_send) {
                dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__,
                        (long unsigned)ctx->seq_send64, ctx->seq_send);
+               p = ERR_PTR(-EINVAL);
                goto out_err;
        }
        p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype));
index dc3f1f5ed8654da469bd477803eb3530ea9659b7..adade3d313f279bde98674e2e7ed21496267f9e7 100644 (file)
@@ -100,6 +100,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
        if (version != 1) {
                dprintk("RPC:       unknown spkm3 token format: "
                                "obsolete nfs-utils?\n");
+               p = ERR_PTR(-EINVAL);
                goto out_err_free_ctx;
        }
 
@@ -135,8 +136,10 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
        if (IS_ERR(p))
                goto out_err_free_intg_alg;
 
-       if (p != end)
+       if (p != end) {
+               p = ERR_PTR(-EFAULT);
                goto out_err_free_intg_key;
+       }
 
        ctx_id->internal_ctx_id = ctx;
 
index 2388d83b68ff75dc4644d1b5808ef19224cd469b..fa5549079d79ca7709d3a68bc686b77f10b08243 100644 (file)
@@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
                        goto out_no_principal;
        }
 
-       kref_init(&clnt->cl_kref);
+       atomic_set(&clnt->cl_count, 1);
 
        err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
        if (err < 0)
@@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt)
                if (new->cl_principal == NULL)
                        goto out_no_principal;
        }
-       kref_init(&new->cl_kref);
+       atomic_set(&new->cl_count, 1);
        err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
        if (err != 0)
                goto out_no_path;
        if (new->cl_auth)
                atomic_inc(&new->cl_auth->au_count);
        xprt_get(clnt->cl_xprt);
-       kref_get(&clnt->cl_kref);
+       atomic_inc(&clnt->cl_count);
        rpc_register_client(new);
        rpciod_up();
        return new;
@@ -465,10 +465,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client);
  * Free an RPC client
  */
 static void
-rpc_free_client(struct kref *kref)
+rpc_free_client(struct rpc_clnt *clnt)
 {
-       struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
-
        dprintk("RPC:       destroying %s client for %s\n",
                        clnt->cl_protname, clnt->cl_server);
        if (!IS_ERR(clnt->cl_path.dentry)) {
@@ -495,12 +493,10 @@ out_free:
  * Free an RPC client
  */
 static void
-rpc_free_auth(struct kref *kref)
+rpc_free_auth(struct rpc_clnt *clnt)
 {
-       struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
-
        if (clnt->cl_auth == NULL) {
-               rpc_free_client(kref);
+               rpc_free_client(clnt);
                return;
        }
 
@@ -509,10 +505,11 @@ rpc_free_auth(struct kref *kref)
         *       release remaining GSS contexts. This mechanism ensures
         *       that it can do so safely.
         */
-       kref_init(kref);
+       atomic_inc(&clnt->cl_count);
        rpcauth_release(clnt->cl_auth);
        clnt->cl_auth = NULL;
-       kref_put(kref, rpc_free_client);
+       if (atomic_dec_and_test(&clnt->cl_count))
+               rpc_free_client(clnt);
 }
 
 /*
@@ -525,7 +522,8 @@ rpc_release_client(struct rpc_clnt *clnt)
 
        if (list_empty(&clnt->cl_tasks))
                wake_up(&destroy_wait);
-       kref_put(&clnt->cl_kref, rpc_free_auth);
+       if (atomic_dec_and_test(&clnt->cl_count))
+               rpc_free_auth(clnt);
 }
 
 /**
@@ -588,7 +586,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
        if (clnt != NULL) {
                rpc_task_release_client(task);
                task->tk_client = clnt;
-               kref_get(&clnt->cl_kref);
+               atomic_inc(&clnt->cl_count);
                if (clnt->cl_softrtry)
                        task->tk_flags |= RPC_TASK_SOFT;
                /* Add to the client's list of all tasks */
@@ -931,7 +929,7 @@ call_reserveresult(struct rpc_task *task)
        task->tk_status = 0;
        if (status >= 0) {
                if (task->tk_rqstp) {
-                       task->tk_action = call_allocate;
+                       task->tk_action = call_refresh;
                        return;
                }
 
@@ -966,13 +964,54 @@ call_reserveresult(struct rpc_task *task)
 }
 
 /*
- * 2.  Allocate the buffer. For details, see sched.c:rpc_malloc.
+ * 2.  Bind and/or refresh the credentials
+ */
+static void
+call_refresh(struct rpc_task *task)
+{
+       dprint_status(task);
+
+       task->tk_action = call_refreshresult;
+       task->tk_status = 0;
+       task->tk_client->cl_stats->rpcauthrefresh++;
+       rpcauth_refreshcred(task);
+}
+
+/*
+ * 2a. Process the results of a credential refresh
+ */
+static void
+call_refreshresult(struct rpc_task *task)
+{
+       int status = task->tk_status;
+
+       dprint_status(task);
+
+       task->tk_status = 0;
+       task->tk_action = call_allocate;
+       if (status >= 0 && rpcauth_uptodatecred(task))
+               return;
+       switch (status) {
+       case -EACCES:
+               rpc_exit(task, -EACCES);
+               return;
+       case -ENOMEM:
+               rpc_exit(task, -ENOMEM);
+               return;
+       case -ETIMEDOUT:
+               rpc_delay(task, 3*HZ);
+       }
+       task->tk_action = call_refresh;
+}
+
+/*
+ * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc.
  *     (Note: buffer memory is freed in xprt_release).
  */
 static void
 call_allocate(struct rpc_task *task)
 {
-       unsigned int slack = task->tk_client->cl_auth->au_cslack;
+       unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack;
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = task->tk_xprt;
        struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -980,7 +1019,7 @@ call_allocate(struct rpc_task *task)
        dprint_status(task);
 
        task->tk_status = 0;
-       task->tk_action = call_refresh;
+       task->tk_action = call_bind;
 
        if (req->rq_buffer)
                return;
@@ -1017,47 +1056,6 @@ call_allocate(struct rpc_task *task)
        rpc_exit(task, -ERESTARTSYS);
 }
 
-/*
- * 2a. Bind and/or refresh the credentials
- */
-static void
-call_refresh(struct rpc_task *task)
-{
-       dprint_status(task);
-
-       task->tk_action = call_refreshresult;
-       task->tk_status = 0;
-       task->tk_client->cl_stats->rpcauthrefresh++;
-       rpcauth_refreshcred(task);
-}
-
-/*
- * 2b. Process the results of a credential refresh
- */
-static void
-call_refreshresult(struct rpc_task *task)
-{
-       int status = task->tk_status;
-
-       dprint_status(task);
-
-       task->tk_status = 0;
-       task->tk_action = call_bind;
-       if (status >= 0 && rpcauth_uptodatecred(task))
-               return;
-       switch (status) {
-       case -EACCES:
-               rpc_exit(task, -EACCES);
-               return;
-       case -ENOMEM:
-               rpc_exit(task, -ENOMEM);
-               return;
-       case -ETIMEDOUT:
-               rpc_delay(task, 3*HZ);
-       }
-       task->tk_action = call_refresh;
-}
-
 static inline int
 rpc_task_need_encode(struct rpc_task *task)
 {
index 95ccbcf45d3eb64c6ee84c4767c85e7c5a9ee694..8c8eef2b8f26a205bef37706b900c6936a492ed8 100644 (file)
@@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
                return;
        do {
                msg = list_entry(head->next, struct rpc_pipe_msg, list);
-               list_del(&msg->list);
+               list_del_init(&msg->list);
                msg->errno = err;
                destroy_msg(msg);
        } while (!list_empty(head));
@@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
        if (msg != NULL) {
                spin_lock(&inode->i_lock);
                msg->errno = -EAGAIN;
-               list_del(&msg->list);
+               list_del_init(&msg->list);
                spin_unlock(&inode->i_lock);
                rpci->ops->destroy_msg(msg);
        }
@@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
        if (res < 0 || msg->len == msg->copied) {
                filp->private_data = NULL;
                spin_lock(&inode->i_lock);
-               list_del(&msg->list);
+               list_del_init(&msg->list);
                spin_unlock(&inode->i_lock);
                rpci->ops->destroy_msg(msg);
        }
@@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v)
 static int
 rpc_info_open(struct inode *inode, struct file *file)
 {
-       struct rpc_clnt *clnt;
+       struct rpc_clnt *clnt = NULL;
        int ret = single_open(file, rpc_show_info, NULL);
 
        if (!ret) {
                struct seq_file *m = file->private_data;
-               mutex_lock(&inode->i_mutex);
-               clnt = RPC_I(inode)->private;
-               if (clnt) {
-                       kref_get(&clnt->cl_kref);
+
+               spin_lock(&file->f_path.dentry->d_lock);
+               if (!d_unhashed(file->f_path.dentry))
+                       clnt = RPC_I(inode)->private;
+               if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {
+                       spin_unlock(&file->f_path.dentry->d_lock);
                        m->private = clnt;
                } else {
+                       spin_unlock(&file->f_path.dentry->d_lock);
                        single_release(inode, file);
                        ret = -EINVAL;
                }
-               mutex_unlock(&inode->i_mutex);
        }
        return ret;
 }
index b6309db5622689deaf1c76a6acb1f6a09a02602c..fe9306bf10cc7f3bba4590ddf853c2ac39eadae9 100644 (file)
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len)
        u32 _xid;
        __be32 *xp;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        dprintk("RPC:       xs_udp_data_ready...\n");
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len)
  dropit:
        skb_free_datagram(sk, skb);
  out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
 
        dprintk("RPC:       xs_tcp_data_ready...\n");
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
        if (xprt->shutdown)
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
                read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
        } while (read > 0);
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /*
@@ -1301,7 +1301,7 @@ static void xs_tcp_state_change(struct sock *sk)
 {
        struct rpc_xprt *xprt;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
        dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
@@ -1313,7 +1313,7 @@ static void xs_tcp_state_change(struct sock *sk)
 
        switch (sk->sk_state) {
        case TCP_ESTABLISHED:
-               spin_lock_bh(&xprt->transport_lock);
+               spin_lock(&xprt->transport_lock);
                if (!xprt_test_and_set_connected(xprt)) {
                        struct sock_xprt *transport = container_of(xprt,
                                        struct sock_xprt, xprt);
@@ -1327,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk)
 
                        xprt_wake_pending_tasks(xprt, -EAGAIN);
                }
-               spin_unlock_bh(&xprt->transport_lock);
+               spin_unlock(&xprt->transport_lock);
                break;
        case TCP_FIN_WAIT1:
                /* The client initiated a shutdown of the socket */
@@ -1365,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk)
                xs_sock_mark_closed(xprt);
        }
  out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /**
@@ -1376,7 +1376,7 @@ static void xs_error_report(struct sock *sk)
 {
        struct rpc_xprt *xprt;
 
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
        dprintk("RPC:       %s client %p...\n"
@@ -1384,7 +1384,7 @@ static void xs_error_report(struct sock *sk)
                        __func__, xprt, sk->sk_err);
        xprt_wake_pending_tasks(xprt, -EAGAIN);
 out:
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_write_space(struct sock *sk)
@@ -1416,13 +1416,13 @@ static void xs_write_space(struct sock *sk)
  */
 static void xs_udp_write_space(struct sock *sk)
 {
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
 
        /* from net/core/sock.c:sock_def_write_space */
        if (sock_writeable(sk))
                xs_write_space(sk);
 
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /**
@@ -1437,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk)
  */
 static void xs_tcp_write_space(struct sock *sk)
 {
-       read_lock(&sk->sk_callback_lock);
+       read_lock_bh(&sk->sk_callback_lock);
 
        /* from net/core/stream.c:sk_stream_write_space */
        if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
                xs_write_space(sk);
 
-       read_unlock(&sk->sk_callback_lock);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
index 3feb28e41c5347b85175f57daf223918620723b2..674d426a9d24f9aab7657d1e8ecf342e3be87438 100644 (file)
@@ -152,7 +152,7 @@ static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd,
        } else if (!iwp->pointer)
                return -EFAULT;
 
-       extra = kmalloc(extra_size, GFP_KERNEL);
+       extra = kzalloc(extra_size, GFP_KERNEL);
        if (!extra)
                return -ENOMEM;
 
index a3cca0a94346319dec462ef7ef2fb7df2265945e..64f2ae1fdc15e2a63a28fc7073fc0e1f957cee44 100644 (file)
@@ -101,7 +101,7 @@ resume:
                        err = -EHOSTUNREACH;
                        goto error_nolock;
                }
-               skb_dst_set_noref(skb, dst);
+               skb_dst_set(skb, dst_clone(dst));
                x = dst->xfrm;
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
index 2b3ed7ad49338f3ec2d64caf1dd589c2aefc4264..cbab6e1a8c9c4043fcfdba5bdc17c5e9d5dea45c 100644 (file)
@@ -1175,9 +1175,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
                    tmpl->mode == XFRM_MODE_BEET) {
                        remote = &tmpl->id.daddr;
                        local = &tmpl->saddr;
-                       family = tmpl->encap_family;
-                       if (xfrm_addr_any(local, family)) {
-                               error = xfrm_get_saddr(net, &tmp, remote, family);
+                       if (xfrm_addr_any(local, tmpl->encap_family)) {
+                               error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family);
                                if (error)
                                        goto fail;
                                local = &tmp;
index 5208b12fbfb4942d4142f79ddb41ccb1420a4c93..eb96ce52f1789dd881116e76a08169189b50f02c 100644 (file)
@@ -656,15 +656,23 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
 EXPORT_SYMBOL(xfrm_sad_getinfo);
 
 static int
-xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
-                 struct xfrm_tmpl *tmpl,
-                 xfrm_address_t *daddr, xfrm_address_t *saddr,
-                 unsigned short family)
+xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl,
+                   struct xfrm_tmpl *tmpl,
+                   xfrm_address_t *daddr, xfrm_address_t *saddr,
+                   unsigned short family)
 {
        struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
        if (!afinfo)
                return -1;
-       afinfo->init_tempsel(x, fl, tmpl, daddr, saddr);
+       afinfo->init_tempsel(&x->sel, fl);
+
+       if (family != tmpl->encap_family) {
+               xfrm_state_put_afinfo(afinfo);
+               afinfo = xfrm_state_get_afinfo(tmpl->encap_family);
+               if (!afinfo)
+                       return -1;
+       }
+       afinfo->init_temprop(x, tmpl, daddr, saddr);
        xfrm_state_put_afinfo(afinfo);
        return 0;
 }
@@ -790,37 +798,38 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
        int error = 0;
        struct xfrm_state *best = NULL;
        u32 mark = pol->mark.v & pol->mark.m;
+       unsigned short encap_family = tmpl->encap_family;
 
        to_put = NULL;
 
        spin_lock_bh(&xfrm_state_lock);
-       h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family);
+       h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
        hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
-               if (x->props.family == family &&
+               if (x->props.family == encap_family &&
                    x->props.reqid == tmpl->reqid &&
                    (mark & x->mark.m) == x->mark.v &&
                    !(x->props.flags & XFRM_STATE_WILDRECV) &&
-                   xfrm_state_addr_check(x, daddr, saddr, family) &&
+                   xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
                    tmpl->mode == x->props.mode &&
                    tmpl->id.proto == x->id.proto &&
                    (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
-                       xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
+                       xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr,
                                           &best, &acquire_in_progress, &error);
        }
        if (best)
                goto found;
 
-       h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family);
+       h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family);
        hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) {
-               if (x->props.family == family &&
+               if (x->props.family == encap_family &&
                    x->props.reqid == tmpl->reqid &&
                    (mark & x->mark.m) == x->mark.v &&
                    !(x->props.flags & XFRM_STATE_WILDRECV) &&
-                   xfrm_state_addr_check(x, daddr, saddr, family) &&
+                   xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
                    tmpl->mode == x->props.mode &&
                    tmpl->id.proto == x->id.proto &&
                    (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
-                       xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
+                       xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr,
                                           &best, &acquire_in_progress, &error);
        }
 
@@ -829,7 +838,7 @@ found:
        if (!x && !error && !acquire_in_progress) {
                if (tmpl->id.spi &&
                    (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
-                                             tmpl->id.proto, family)) != NULL) {
+                                             tmpl->id.proto, encap_family)) != NULL) {
                        to_put = x0;
                        error = -EEXIST;
                        goto out;
@@ -839,9 +848,9 @@ found:
                        error = -ENOMEM;
                        goto out;
                }
-               /* Initialize temporary selector matching only
+               /* Initialize temporary state matching only
                 * to current session. */
-               xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
+               xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family);
                memcpy(&x->mark, &pol->mark, sizeof(x->mark));
 
                error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
@@ -856,10 +865,10 @@ found:
                        x->km.state = XFRM_STATE_ACQ;
                        list_add(&x->km.all, &net->xfrm.state_all);
                        hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
-                       h = xfrm_src_hash(net, daddr, saddr, family);
+                       h = xfrm_src_hash(net, daddr, saddr, encap_family);
                        hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
                        if (x->id.spi) {
-                               h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family);
+                               h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family);
                                hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
                        }
                        x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
index ee03a4f0b64f4361af8c850b3123b8d457bec0bf..06473791c08adb7c5b0a7080ea9600d927c09d94 100644 (file)
@@ -24,6 +24,7 @@ static int __init example_init(void)
 {
        int                     i;
        unsigned int            ret;
+       unsigned int            nents;
        struct scatterlist      sg[10];
 
        printk(KERN_INFO "DMA fifo test start\n");
@@ -61,9 +62,9 @@ static int __init example_init(void)
         * byte at the beginning, after the kfifo_skip().
         */
        sg_init_table(sg, ARRAY_SIZE(sg));
-       ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
-       printk(KERN_INFO "DMA sgl entries: %d\n", ret);
-       if (!ret) {
+       nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
+       printk(KERN_INFO "DMA sgl entries: %d\n", nents);
+       if (!nents) {
                /* fifo is full and no sgl was created */
                printk(KERN_WARNING "error kfifo_dma_in_prepare\n");
                return -EIO;
@@ -71,7 +72,7 @@ static int __init example_init(void)
 
        /* receive data */
        printk(KERN_INFO "scatterlist for receive:\n");
-       for (i = 0; i < ARRAY_SIZE(sg); i++) {
+       for (i = 0; i < nents; i++) {
                printk(KERN_INFO
                "sg[%d] -> "
                "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
@@ -91,16 +92,16 @@ static int __init example_init(void)
        kfifo_dma_in_finish(&fifo, ret);
 
        /* Prepare to transmit data, example: 8 bytes */
-       ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
-       printk(KERN_INFO "DMA sgl entries: %d\n", ret);
-       if (!ret) {
+       nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
+       printk(KERN_INFO "DMA sgl entries: %d\n", nents);
+       if (!nents) {
                /* no data was available and no sgl was created */
                printk(KERN_WARNING "error kfifo_dma_out_prepare\n");
                return -EIO;
        }
 
        printk(KERN_INFO "scatterlist for transmit:\n");
-       for (i = 0; i < ARRAY_SIZE(sg); i++) {
+       for (i = 0; i < nents; i++) {
                printk(KERN_INFO
                "sg[%d] -> "
                "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
index 5b7c86ea43a1e3f27484ccfc83f8d2992ad548a4..7ef429cd5cb38f9bd07889aad8f5ab8f3983e27b 100644 (file)
@@ -427,7 +427,7 @@ static void check_conf(struct menu *menu)
                                if (sym->name && !sym_is_choice_value(sym)) {
                                        printf("CONFIG_%s\n", sym->name);
                                }
-                       } else {
+                       } else if (input_mode != oldnoconfig) {
                                if (!conf_cnt++)
                                        printf(_("*\n* Restart config...\n*\n"));
                                rootEntry = menu_get_parent_menu(menu);
index 6ee2e4fb148146ace18b2e5a7414e6a89d5d3e2f..170459c224a13d94be08b00b72b63c1503303ed1 100644 (file)
@@ -165,7 +165,6 @@ struct menu {
        struct symbol *sym;
        struct property *prompt;
        struct expr *dep;
-       struct expr *dir_dep;
        unsigned int flags;
        char *help;
        struct file *file;
index 4fb590247f330bb75215fe88eb749d42da8b489e..edda8b49619d9e66ff70e16dd8ef68caf4a86bc6 100644 (file)
@@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e)
 void menu_add_dep(struct expr *dep)
 {
        current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
-       current_entry->dir_dep = current_entry->dep;
 }
 
 void menu_set_type(int type)
@@ -291,10 +290,6 @@ void menu_finalize(struct menu *parent)
                for (menu = parent->list; menu; menu = menu->next)
                        menu_finalize(menu);
        } else if (sym) {
-               /* ignore inherited dependencies for dir_dep */
-               sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
-               sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
-
                basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
                basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
                basedep = expr_eliminate_dups(expr_transform(basedep));
@@ -325,6 +320,8 @@ void menu_finalize(struct menu *parent)
                        parent->next = last_menu->next;
                        last_menu->next = NULL;
                }
+
+               sym->dir_dep.expr = parent->dep;
        }
        for (menu = parent->list; menu; menu = menu->next) {
                if (sym && sym_is_choice(sym) &&
index 943712ca6c0a6a0eb5bbf97dbba2a2d20e495b47..1f8b305449db354b103c6eb7ced09095c801dc1b 100644 (file)
@@ -350,6 +350,7 @@ void sym_calc_value(struct symbol *sym)
                                }
                        }
                calc_newval:
+#if 0
                        if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
                                fprintf(stderr, "warning: (");
                                expr_fprint(sym->rev_dep.expr, stderr);
@@ -358,6 +359,7 @@ void sym_calc_value(struct symbol *sym)
                                expr_fprint(sym->dir_dep.expr, stderr);
                                fprintf(stderr, ")\n");
                        }
+#endif
                        newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
                }
                if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
index ef43995119a453401dd768adfa5ae41a2602dd3a..c668b447c72594494417f6be50795f3b49f860bf 100644 (file)
@@ -1416,15 +1416,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r)
        const pid_t gpid = task_pid_nr(current);
        static const int tomoyo_buffer_len = 4096;
        char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
+       pid_t ppid;
        if (!buffer)
                return NULL;
        do_gettimeofday(&tv);
+       rcu_read_lock();
+       ppid = task_tgid_vnr(current->real_parent);
+       rcu_read_unlock();
        snprintf(buffer, tomoyo_buffer_len - 1,
                 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
                 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
                 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
                 tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
-                (pid_t) sys_getpid(), (pid_t) sys_getppid(),
+                task_tgid_vnr(current), ppid,
                 current_uid(), current_gid(), current_euid(),
                 current_egid(), current_suid(), current_sgid(),
                 current_fsuid(), current_fsgid());
index 04454cb7b24a534e84c8873a8babeb9614a8da60..7c66bd898782ce0c6fa8ea037cd19dfd78fc8bfe 100644 (file)
@@ -689,9 +689,6 @@ struct tomoyo_profile {
 
 /********** Function prototypes. **********/
 
-extern asmlinkage long sys_getpid(void);
-extern asmlinkage long sys_getppid(void);
-
 /* Check whether the given string starts with the given keyword. */
 bool tomoyo_str_starts(char **src, const char *find);
 /* Get tomoyo_realpath() of current process. */
index 070aab4901914870a0af43faef27e82e761acc32..45a818002d990f664cffadd066488a21c76fedd7 100644 (file)
@@ -31,6 +31,7 @@
 
 /* max number of user-defined controls */
 #define MAX_USER_CONTROLS      32
+#define MAX_CONTROL_COUNT      1028
 
 struct snd_kctl_ioctl {
        struct list_head list;          /* list of all ioctls */
@@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
        
        if (snd_BUG_ON(!control || !control->count))
                return NULL;
+
+       if (control->count > MAX_CONTROL_COUNT)
+               return NULL;
+
        kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
        if (kctl == NULL) {
                snd_printk(KERN_ERR "Cannot allocate control instance\n");
index 204af48c5cc17f2f59632bb2089aa03c7b593664..ac242a377aea8068f859bce49aae6825aae5d001 100644 (file)
@@ -372,14 +372,17 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
                                                  struct snd_info_buffer *buffer)
 {
        struct snd_pcm_substream *substream = entry->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime;
+
+       mutex_lock(&substream->pcm->open_mutex);
+       runtime = substream->runtime;
        if (!runtime) {
                snd_iprintf(buffer, "closed\n");
-               return;
+               goto unlock;
        }
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                snd_iprintf(buffer, "no setup\n");
-               return;
+               goto unlock;
        }
        snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
        snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
@@ -398,20 +401,25 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
                snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
        }
 #endif
+ unlock:
+       mutex_unlock(&substream->pcm->open_mutex);
 }
 
 static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
                                                  struct snd_info_buffer *buffer)
 {
        struct snd_pcm_substream *substream = entry->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime;
+
+       mutex_lock(&substream->pcm->open_mutex);
+       runtime = substream->runtime;
        if (!runtime) {
                snd_iprintf(buffer, "closed\n");
-               return;
+               goto unlock;
        }
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                snd_iprintf(buffer, "no setup\n");
-               return;
+               goto unlock;
        }
        snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
        snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
@@ -421,24 +429,29 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
        snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
        snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
        snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
+ unlock:
+       mutex_unlock(&substream->pcm->open_mutex);
 }
 
 static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
                                               struct snd_info_buffer *buffer)
 {
        struct snd_pcm_substream *substream = entry->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_pcm_runtime *runtime;
        struct snd_pcm_status status;
        int err;
+
+       mutex_lock(&substream->pcm->open_mutex);
+       runtime = substream->runtime;
        if (!runtime) {
                snd_iprintf(buffer, "closed\n");
-               return;
+               goto unlock;
        }
        memset(&status, 0, sizeof(status));
        err = snd_pcm_status(substream, &status);
        if (err < 0) {
                snd_iprintf(buffer, "error %d\n", err);
-               return;
+               goto unlock;
        }
        snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
        snd_iprintf(buffer, "owner_pid   : %d\n", pid_vnr(substream->pid));
@@ -452,6 +465,8 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
        snd_iprintf(buffer, "-----\n");
        snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);
        snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);
+ unlock:
+       mutex_unlock(&substream->pcm->open_mutex);
 }
 
 #ifdef CONFIG_SND_PCM_XRUN_DEBUG
index 134fc6c2e08dc01eeda84a730545b0532f0588fe..d4eb2ef8078416cc8d06e5d80f3ec3bb467a4f1b 100644 (file)
@@ -1992,6 +1992,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
                substream->ops->close(substream);
                substream->hw_opened = 0;
        }
+       if (pm_qos_request_active(&substream->latency_pm_qos_req))
+               pm_qos_remove_request(&substream->latency_pm_qos_req);
        if (substream->pcm_release) {
                substream->pcm_release(substream);
                substream->pcm_release = NULL;
index 1adb8a3c2b62db229f9ba0b580d930d288e74c14..42d7844ecd0bfa66ddf3db96527ccc18c79f7485 100644 (file)
@@ -900,7 +900,7 @@ static int proc_init(struct snd_akm4xxx *ak)
        return 0;
 }
 #else /* !CONFIG_PROC_FS */
-static int proc_init(struct snd_akm4xxx *ak) {}
+static int proc_init(struct snd_akm4xxx *ak) { return 0; }
 #endif
 
 int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
index 92aa762ffb7e97c998db3ca1da3a5cddc2968139..07f803e6d203a41615db0923cf073f7eadc283b6 100644 (file)
@@ -391,11 +391,11 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case SND_DEV_DSP:
        case SND_DEV_DSP16:
        case SND_DEV_AUDIO:
-               return audio_ioctl(dev, file, cmd, p);
+               ret = audio_ioctl(dev, file, cmd, p);
                break;
 
        case SND_DEV_MIDIN:
-               return MIDIbuf_ioctl(dev, file, cmd, p);
+               ret = MIDIbuf_ioctl(dev, file, cmd, p);
                break;
 
        }
index 1053fff4bd0a7bc5b1dbe07de0c1a7a3d0df68db..34940a07905192590a056efe734e155d66f575f7 100644 (file)
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, ICH10},"
                         "{Intel, PCH},"
                         "{Intel, CPT},"
+                        "{Intel, PBG},"
                         "{Intel, SCH},"
                         "{ATI, SB450},"
                         "{ATI, SB600},"
@@ -2749,6 +2750,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
+       /* PBG */
+       { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH },
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
        /* ATI SB 450/600 */
index b697fd2a6f8b8cd19a84840fd8e05369226981db..10bbbaf6ebc3d2b0531ba2fb1ab7e3f2be1f8994 100644 (file)
@@ -3641,6 +3641,7 @@ static struct snd_pci_quirk ad1984_cfg_tbl[] = {
        /* Lenovo Thinkpad T61/X61 */
        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
        SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
+       SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
        {}
 };
 
index 71f9d6475b09e2b4d52d38b60130918dff8235b2..972e7c453b3d6c8320d58b6aebe6ef41fc259920 100644 (file)
@@ -3092,6 +3092,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
+       SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
index 69b950d527c31d966846a3c6e8f0ff30bdbe886c..baa108b9d6aacaf88be2999aa35515d2400bb9fd 100644 (file)
@@ -84,7 +84,7 @@ static struct hda_verb nvhdmi_basic_init_7x[] = {
 #else
 /* support all rates and formats */
 #define SUPPORTED_RATES \
-       (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+       (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
        SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
         SNDRV_PCM_RATE_192000)
 #define SUPPORTED_MAXBPS       24
index bcbf9160ed81af7a805007f152067908f9970840..a432e6efd19bbe7bbce3ad9b6607c44661f912cf 100644 (file)
@@ -1594,12 +1594,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
        }
 
        if (spec->autocfg.dig_in_pin) {
-               hda_nid_t dig_nid;
-               err = snd_hda_get_connections(codec,
-                                             spec->autocfg.dig_in_pin,
-                                             &dig_nid, 1);
-               if (err > 0)
-                       spec->dig_in_nid = dig_nid;
+               dig_nid = codec->start_nid;
+               for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
+                       unsigned int wcaps = get_wcaps(codec, dig_nid);
+                       if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
+                               continue;
+                       if (!(wcaps & AC_WCAP_DIGITAL))
+                               continue;
+                       if (!(wcaps & AC_WCAP_CONN_LIST))
+                               continue;
+                       err = get_connection_index(codec, dig_nid,
+                                                  spec->autocfg.dig_in_pin);
+                       if (err >= 0) {
+                               spec->dig_in_nid = dig_nid;
+                               break;
+                       }
+               }
        }
 }
 
@@ -14453,6 +14463,7 @@ static void alc269_auto_init(struct hda_codec *codec)
 
 enum {
        ALC269_FIXUP_SONY_VAIO,
+       ALC269_FIXUP_DELL_M101Z,
 };
 
 static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
@@ -14464,11 +14475,20 @@ static const struct alc_fixup alc269_fixups[] = {
        [ALC269_FIXUP_SONY_VAIO] = {
                .verbs = alc269_sony_vaio_fixup_verbs
        },
+       [ALC269_FIXUP_DELL_M101Z] = {
+               .verbs = (const struct hda_verb[]) {
+                       /* Enables internal speaker */
+                       {0x20, AC_VERB_SET_COEF_INDEX, 13},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
+                       {}
+               }
+       },
 };
 
 static struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
+       SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        {}
 };
 
index 95148e58026cfb045793d3ba26d570f26108c284..c16c5ba0fda0fe61387d6924a6b84307b0dedcbb 100644 (file)
@@ -1747,6 +1747,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                      "HP dv6", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
                      "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
+                     "HP DV6", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
index 289cb4dacfc79ec012b6efb174054efaa0afe855..6c0a11adb2a84511b83b23b69d5efce9fb2085c6 100644 (file)
@@ -543,6 +543,10 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
                chip->model.suspend = claro_suspend;
                chip->model.resume = claro_resume;
                chip->model.set_adc_params = set_ak5385_params;
+               chip->model.device_config = PLAYBACK_0_TO_I2S |
+                                           PLAYBACK_1_TO_SPDIF |
+                                           CAPTURE_0_FROM_I2S_2 |
+                                           CAPTURE_1_FROM_SPDIF;
                break;
        }
        if (id->driver_data == MODEL_MERIDIAN ||
index b92adef8e81e7ae61eef5681925610b87f03a502..d6fa7bfd9aa123d7f8bb8142a8def39888129434 100644 (file)
@@ -4609,6 +4609,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
                if (err < 0)
                        return err;
 
+               memset(&info, 0, sizeof(info));
                spin_lock_irqsave(&hdsp->lock, flags);
                info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
                info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
index 547b713d720449a7bdd746ca04fbf5a6cbe84931..0c98ef9156d8fd919f81711fe7b798be7c0ca7d8 100644 (file)
@@ -4127,6 +4127,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
 
        case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
 
+               memset(&info, 0, sizeof(info));
                spin_lock_irq(&hdspm->lock);
                info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
                info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
index 2f12da4da561f6eeec98a028d7163c68e112b5dd..581a670e826192ee7267859144cc70e89f9a7a8e 100644 (file)
@@ -579,7 +579,7 @@ static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
                                  rate * delay_ms / 1000)
                * substream->runtime->channels;
 
-       pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n",
+       pr_debug("%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n",
                 __func__,
                 delay_ms,
                 rate,
index 1b61c23ff300be0ef2c593cf5e813e20aeb2cb5d..f1b1bc4bacfb7134d588469cbcd0b5032747f0ae 100644 (file)
@@ -94,8 +94,7 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
 
                if ((pos + len) > prtd->dma_end) {
                        len  = prtd->dma_end - pos;
-                       pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n",
-                              __func__, len);
+                       pr_debug("%s: corrected dma len %ld\n", __func__, len);
                }
 
                ret = s3c2410_dma_enqueue(prtd->params->channel,
index b823a5c9b9bc81d81b8f64f4847483eae3f253bc..87e2b7fcbf176d9f429506b285dcc2f6ac05d7bc 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 
 #include <cpu/sh7722.h>
@@ -40,12 +41,12 @@ static struct clk_ops siumckb_clk_ops = {
 };
 
 static struct clk siumckb_clk = {
-       .name           = "siumckb_clk",
-       .id             = -1,
        .ops            = &siumckb_clk_ops,
        .rate           = 0, /* initialised at run-time */
 };
 
+static struct clk_lookup *siumckb_lookup;
+
 static int migor_hw_params(struct snd_pcm_substream *substream,
                           struct snd_pcm_hw_params *params)
 {
@@ -180,6 +181,13 @@ static int __init migor_init(void)
        if (ret < 0)
                return ret;
 
+       siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL);
+       if (!siumckb_lookup) {
+               ret = -ENOMEM;
+               goto eclkdevalloc;
+       }
+       clkdev_add(siumckb_lookup);
+
        /* Port number used on this machine: port B */
        migor_snd_device = platform_device_alloc("soc-audio", 1);
        if (!migor_snd_device) {
@@ -200,12 +208,15 @@ static int __init migor_init(void)
 epdevadd:
        platform_device_put(migor_snd_device);
 epdevalloc:
+       clkdev_drop(siumckb_lookup);
+eclkdevalloc:
        clk_unregister(&siumckb_clk);
        return ret;
 }
 
 static void __exit migor_exit(void)
 {
+       clkdev_drop(siumckb_lookup);
        clk_unregister(&siumckb_clk);
        platform_device_unregister(migor_snd_device);
 }
index adbc68ce90508221cc919121fc19e062fd309f44..f6b0d2829ea96d438d1e84550272c6a7bda80b4c 100644 (file)
@@ -203,8 +203,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
        data[1] = (value >> 8) & 0xff;
        data[2] = value & 0xff;
 
-       if (!snd_soc_codec_volatile_register(codec, reg))
-               reg_cache[reg] = value;
+       if (!snd_soc_codec_volatile_register(codec, reg)
+               && reg < codec->reg_cache_size)
+                       reg_cache[reg] = value;
 
        if (codec->cache_only) {
                codec->cache_sync = 1;
index 4f1fa77c1feb0b7a854ab8a85bd21682cbc66377..1950e19af1cf6b23be56f0250bcf8cbb52b3d9f3 100644 (file)
@@ -1017,7 +1017,7 @@ builtin-revert.o wt-status.o: wt-status.h
 # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
 # we depend the various files onto their directories.
 DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
-$(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS)))
+$(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS)))
 # In the second step, we make a rule to actually create these directories
 $(sort $(dir $(DIRECTORY_DEPS))):
        $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
index ef7aa0a0c5265191e8120e76f9f134b5e241fa53..95aaf565c704fb6ea67cee78d49e177f0ba8f595 100644 (file)
@@ -73,6 +73,18 @@ void get_term_dimensions(struct winsize *ws);
 #define cpu_relax()    asm volatile("":::"memory")
 #endif
 
+#ifdef __mips__
+#include "../../arch/mips/include/asm/unistd.h"
+#define rmb()          asm volatile(                                   \
+                               ".set   mips2\n\t"                      \
+                               "sync\n\t"                              \
+                               ".set   mips0"                          \
+                               : /* no output */                       \
+                               : /* no input */                        \
+                               : "memory")
+#define cpu_relax()    asm volatile("" ::: "memory")
+#endif
+
 #include <time.h>
 #include <unistd.h>
 #include <sys/types.h>
index 7ea983acfaea521a425f7eb33250e319b0a3a960..f7af2fca965d5c206973f73ccd25b8b3607e02e5 100644 (file)
@@ -97,7 +97,7 @@ void setup_python_scripting(void)
        register_python_scripting(&python_scripting_unsupported_ops);
 }
 #else
-struct scripting_ops python_scripting_ops;
+extern struct scripting_ops python_scripting_ops;
 
 void setup_python_scripting(void)
 {
@@ -158,7 +158,7 @@ void setup_perl_scripting(void)
        register_perl_scripting(&perl_scripting_unsupported_ops);
 }
 #else
-struct scripting_ops perl_scripting_ops;
+extern struct scripting_ops perl_scripting_ops;
 
 void setup_perl_scripting(void)
 {
index dafdf6775d77f44d69abf1980b1a9cfe4ab053dc..6866aa4c41e09cfd0239559cc903506a351a549c 100644 (file)
@@ -773,7 +773,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
 
                        switch (key) {
                        case 'a':
-                               if (browser->selection->map == NULL &&
+                               if (browser->selection->map == NULL ||
                                    browser->selection->map->dso->annotate_warned)
                                        continue;
                                goto do_annotate;
index 66cf65b510b11c1c245db3b6a435e040ac3606fc..c1f1e3c6298462f8ed4d672257dac3b4da081b33 100644 (file)
@@ -218,7 +218,6 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
        events = file->f_op->poll(file, &irqfd->pt);
 
        list_add_tail(&irqfd->list, &kvm->irqfds.items);
-       spin_unlock_irq(&kvm->irqfds.lock);
 
        /*
         * Check if there was an event already pending on the eventfd
@@ -227,6 +226,8 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
        if (events & POLLIN)
                schedule_work(&irqfd->inject);
 
+       spin_unlock_irq(&kvm->irqfds.lock);
+
        /*
         * do not drop the file until the irqfd is fully initialized, otherwise
         * we might race against the POLLHUP
index d4853a54771a04a2bb3e126b1aa54ec13e5c29d0..5186e728c53ed7e27ba6d32df31d37f7aa140ebc 100644 (file)
@@ -1970,10 +1970,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
 
 asmlinkage void kvm_handle_fault_on_reboot(void)
 {
-       if (kvm_rebooting)
+       if (kvm_rebooting) {
                /* spin while reset goes on */
+               local_irq_enable();
                while (true)
                        ;
+       }
        /* Fault while not rebooting.  We want the trace. */
        BUG();
 }